Make swagger load from trilium directly

This commit is contained in:
Zack Rauen 2023-09-28 20:59:17 -04:00
parent bde6d83625
commit 074ac0b725
3 changed files with 109 additions and 80 deletions

View File

@ -56,12 +56,19 @@ function $try<T extends (...a: unknown[]) => unknown>(func: T, ...args: Paramete
// Now layout changes
// $try(buildBreadcrumbs);
// $try(buildSidenav);
// TODO: Determine the difficulty of adding this in
// trilium directly using JSDOM.
$try(setupToC);
// Finally, other features
// TODO: how difficult this would be to implement via
// templates or trilium
$try(highlight);
// $try(injectSwagger, ETAPI_REF_NOTE_ID);
// "Standard" Modules I would recommend the new share
// theme have
$try(setupExpanders);
$try(setupMobileMenu);
$try(setupSearch);
@ -69,14 +76,10 @@ $try(setupThemeSelector);
// $try(makeMobileMenu);
/**
* This was removed because both the title change and the opengraph
* additions are now handled by a traefik plugin that rewrites
* the body of the http request, that way the change does not
* require client-side JS. This is important for sites wishing
* to display that information.
* This no longer uses a traefik plugin and instead a custom
* template being served through Trilium.
*
* TODO: Determine how reasonable it would be to move more
* of these modules over to a traefik rewrite plugin. This gives
* a better experience to end users, SEO, etc.
* TODO: Figure out some good attributes to use to populate
* this inside the template to make it more dynamic
*/
// $try(addOpenGraphMeta);

View File

@ -1,53 +1,59 @@
function anchorToId(anchor: HTMLAnchorElement) {
return anchor.href.replace("./", "");
}
// function anchorToId(anchor: HTMLAnchorElement) {
// return anchor.href.replace("./", "");
// }
//
// const stored = localStorage.getItem("expanded") ?? "[]";
// let parsed: string[];
// try {
// parsed = JSON.parse(stored) as string[];
// }
// catch (e) {
// parsed = [];
// }
// const state = new Set(parsed);
// const submenus = Array.from(document.querySelectorAll("#menu .submenu-item"));
// for (const sub of submenus) {
// try {
// if (state.has(anchorToId(sub.children[0] as HTMLAnchorElement))) sub.classList.add("expanded");
// }
// catch (e) {
// // TODO: create logger
// console.warn("Could not restore expanded state"); // eslint-disable-line no-console
// console.error(e); // eslint-disable-line no-console
// }
// }
const stored = localStorage.getItem("expanded") ?? "[]";
let parsed: string[];
try {
parsed = JSON.parse(stored) as string[];
}
catch (e) {
parsed = [];
}
const state = new Set(parsed);
const submenus = Array.from(document.querySelectorAll("#menu .submenu-item"));
for (const sub of submenus) {
try {
if (state.has(anchorToId(sub.children[0] as HTMLAnchorElement))) sub.classList.add("expanded");
}
catch (e) {
// TODO: create logger
console.warn("Could not restore expanded state"); // eslint-disable-line no-console
console.error(e); // eslint-disable-line no-console
// TODO: Swap this system to use type-book for full-link category
// In case a linked article lead to a new tree
const activeLink = document.querySelector("#menu a.active");
if (activeLink) {
let parent = activeLink.parentElement;
const mainMenu = document.getElementById("#menu");
while (parent && parent !== mainMenu) {
if (parent.matches(".submenu-item") && !parent.classList.contains("expanded")) {
parent.classList.add("expanded");
}
parent = parent.parentElement;
}
}
export default function setupExpanders() {
const expanders = Array.from(document.querySelectorAll("#menu .collapse-button"));
const expanders = Array.from(document.querySelectorAll("#menu .submenu-item"));
for (const ex of expanders) {
ex.addEventListener("click", e => {
if ((e.target as Element).closest(".submenu-item,.item") !== ex) return;
e.preventDefault();
e.stopPropagation();
// ex.parentElement.parentElement.classList.toggle("expanded");
ex.closest(".submenu-item")?.classList.toggle("expanded");
const id = anchorToId(ex.closest("a")!);
if (state.has(id)) state.delete(id);
else state.add(id);
localStorage.setItem("expanded", JSON.stringify([...state]));
ex.classList.toggle("expanded");
// const id = anchorToId(ex.closest("a")!);
// if (state.has(id)) state.delete(id);
// else state.add(id);
// // TODO: be able to remove all submenus of currently collapsed
// localStorage.setItem("expanded", JSON.stringify([...state]));
});
}
// In case a linked article lead to a new tree
const activeLink = document.querySelector("#menu a.active");
if (activeLink) {
let parent = activeLink.parentElement;
const mainMenu = document.getElementById("#menu");
while (parent && parent !== mainMenu) {
if (parent.matches(".submenu-item") && !parent.classList.contains("expanded")) {
parent.classList.add("expanded");
}
parent = parent.parentElement;
}
}
}

View File

@ -18,13 +18,35 @@
<!--<link href="../<%= assetPath %>/stylesheets/share.css" rel="stylesheet">-->
<% } %>
<% if (note.hasLabel("shareSwagger")) { %>
<link href="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css" rel="stylesheet">
<script src="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js"></script>
<link href="api/notes/woA8jsLWd4QR/download" rel="stylesheet">
<script src="api/notes/RYOdL9flwQfP/download"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const customServerYml = `- url: "{protocol}://{domain}:{port}/etapi"
variables:
protocol:
enum:
- http
- https
default: http
description: Protocol your server is being hosted with
domain:
default: localhost
description: Domain name or localhost or ip
port:
default: 37840
description: Port the app is served over`;
SwaggerUIBundle({
// url: `api/notes/<%= note.noteId %>/download`,
url: `<%= note.getLabelValue("shareSwagger") %>`,
dom_id: "#content"
dom_id: "#content",
responseInterceptor: resp => {
if (resp.url !== `<%= note.getLabelValue("shareSwagger") %>`) return resp;
resp.text = resp.text.replace("37740", "37840");
resp.text = resp.text.replace(`- url: http://localhost:8080/etapi`, customServerYml);
return resp;
}
});
});
</script>
@ -43,6 +65,7 @@
<% } %>
<%- header %>
<title><%= note.title %><% if (note.noteId !== subRoot.noteId) { %> - <%= subRoot.title %><% } %></title>
<!-- TODO: determine a good way to populate this via labels -->
<!-- HTML Meta Tags -->
<meta name="description" content="A website for guides, reference, showcase, inspiration, and more, all for Trilium Notes! Not convinced? Come see for yourself just what Trilium can do."
><!-- Facebook Meta Tags -->
@ -107,40 +130,37 @@ const themeClass = currentTheme === "light" ? " theme-light" : " theme-dark";
</div>
</div>
<div id="right-pane">
<div id="main">
<div id="main">
<% if (note.hasLabel("pageUrl")) { %>
<div id="noteClippedFrom">This note was originally clipped from <a href="<%= note.getLabelValue("pageUrl") %>"><%= note.getLabelValue("pageUrl") %></a></div>
<% } %>
<div id="content" class="type-<%= note.type %><% if (note.type === 'text') { %> ck-content<% } %><% if (isEmpty) { %> no-content<% } %>">
<h1 id="title"><%= note.title %></h1>
<% if (isEmpty && !note.hasVisibleChildren()) { %>
<p>This note has no content.</p>
<% } else { %>
<%- content %>
<% } %>
</div>
<% if (note.hasVisibleChildren()) { %>
<nav id="childLinks" class="<% if (isEmpty) { %>grid<% } else { %>list<% } %>">
<% if (!isEmpty) { %>
<span>Subpages:</span>
<div id="content" class="type-<%= note.type %><% if (note.type === 'text') { %> ck-content<% } %><% if (isEmpty) { %> no-content<% } %>">
<h1 id="title"><%= note.title %></h1>
<% if (isEmpty && (!note.hasVisibleChildren() && note.type !== "book")) { %>
<p>This note has no content.</p>
<% } else { %>
<%- content %>
<% } %>
</div>
<ul>
<% for (const childNote of note.getVisibleChildNotes()) { %>
<li>
<a href="<%= childNote.shareId %>"
class="type-<%= childNote.type %>"><%= childNote.title %></a>
</li>
<% if (note.hasVisibleChildren() || note.type === "book") { %>
<nav id="childLinks" class="<% if (isEmpty) { %>grid<% } else { %>list<% } %>">
<% if (!isEmpty) { %>
<span>Subpages:</span>
<% } %>
</ul>
</nav>
<% } else %>
</div>
<ul>
<%
const action = note.type === "book" ? "getChildNotes" : "getVisibleChildNotes";
for (const childNote of note[action]()) {
%>
<li>
<a href="<%= childNote.shareId %>"
class="type-<%= childNote.type %>"><%= childNote.title %></a>
</li>
<% } %>
</ul>
</nav>
<% } else %>
</div>
</div>
</div>
</body>