From 66cc697b25413a571b2cfb37d83497e69e73d7d9 Mon Sep 17 00:00:00 2001 From: MickaelK Date: Tue, 19 Nov 2024 14:54:36 +1100 Subject: [PATCH] feature (tag): tag feature behind canary flag --- public/assets/components/breadcrumb.js | 2 +- public/assets/components/sidebar.css | 10 ++- public/assets/components/sidebar.js | 71 +++++++++++++++---- public/assets/pages/filespage/ctrl_submenu.js | 15 ++-- public/assets/pages/filespage/modal_embed.js | 10 --- public/assets/pages/filespage/modal_tag.css | 27 ++++--- public/assets/pages/filespage/modal_tag.js | 47 ++++++------ server/ctrl/static.go | 2 +- 8 files changed, 109 insertions(+), 75 deletions(-) delete mode 100644 public/assets/pages/filespage/modal_embed.js diff --git a/public/assets/components/breadcrumb.js b/public/assets/components/breadcrumb.js index 74148fd8..a6490c3e 100644 --- a/public/assets/components/breadcrumb.js +++ b/public/assets/components/breadcrumb.js @@ -119,7 +119,7 @@ class ComponentBreadcrumb extends HTMLElement { return `
- + ${tmpl}
diff --git a/public/assets/components/sidebar.css b/public/assets/components/sidebar.css index 6f907332..85129b93 100644 --- a/public/assets/components/sidebar.css +++ b/public/assets/components/sidebar.css @@ -16,7 +16,8 @@ .component_filemanager_shell .component_sidebar > div { direction: ltr; } .component_filemanager_shell .component_sidebar h3 { display: flex; - margin-bottom: 10px; + margin-bottom: 5px; + margin-top: 20px; color: var(--light); font-size: 0.9rem; opacity: 0.8; @@ -29,10 +30,11 @@ body.touch-no .component_filemanager_shell .component_sidebar h3 img:hover { .component_filemanager_shell .component_sidebar h3 img { padding-right: 4px; cursor: pointer; + width: 16px; } .component_filemanager_shell .component_sidebar h3 input::placeholder { text-transform: capitalize; - color: var(--color); + color: var(--light); } .component_filemanager_shell .component_sidebar h3 input { border: none; @@ -41,7 +43,8 @@ body.touch-no .component_filemanager_shell .component_sidebar h3 img:hover { font-size: inherit; background: inherit; } -.component_filemanager_shell .component_sidebar [data-bind="your-files"] > ul { margin-left: 0px; } +.component_filemanager_shell .component_sidebar [data-bind="your-files"] { margin-bottom: 30px; } +.component_filemanager_shell .component_sidebar [data-bind] > ul { margin-left: 0px; } .component_filemanager_shell .component_sidebar ul { margin-top: 0px; padding: 0; @@ -87,4 +90,5 @@ body.touch-no .component_filemanager_shell .component_sidebar h3 img:hover { } .component_filemanager_shell .component_sidebar a > div { padding-left: 2px; + text-transform: capitalize; } diff --git a/public/assets/components/sidebar.js b/public/assets/components/sidebar.js index 687e47a9..4014b613 100644 --- a/public/assets/components/sidebar.js +++ b/public/assets/components/sidebar.js @@ -1,4 +1,4 @@ -import { createElement, onDestroy } from "../lib/skeleton/index.js"; +import { createElement, createRender, onDestroy } from "../lib/skeleton/index.js"; import rxjs, { effect, onClick } from "../lib/rx.js"; import { fromHref, toHref } from "../lib/skeleton/router.js"; import { qs, qsa } from "../lib/dom.js"; @@ -29,13 +29,11 @@ export default async function ctrlSidebar(render, nRestart = 0) {
- +

+ tag + ${t("Tags")} +

+
`)); @@ -70,6 +68,14 @@ export default async function ctrlSidebar(render, nRestart = 0) { forceRefresh(); }))); + // fature: navigation pane + ctrlNavigationPane(render, { $sidebar, nRestart }); + + // feature: tag viewer + ctrlTagPane(createRender(qs($sidebar, `[data-bind="your-tags"]`))); +} + +async function ctrlNavigationPane(render, { $sidebar, nRestart }) { // feature: setup the DOM const $files = qs($sidebar, `[data-bind="your-files"]`); if (state.$cache) { @@ -88,7 +94,7 @@ export default async function ctrlSidebar(render, nRestart = 0) { for (let i = 0; i { - const $list = await createListOfFiles(path); + const $list = await _createListOfFiles(path); try { const $ul = qs($sidebar, `[data-path="${path}"] ul`); $ul.replaceWith($list); @@ -111,7 +117,7 @@ export default async function ctrlSidebar(render, nRestart = 0) { })); cleaners.push(hooks.mutation.listen(async({ op, path }) => { if (["mv", "mkdir", "rm"].indexOf(op) === -1) return; - const $list = await createListOfFiles(path); + const $list = await _createListOfFiles(path); try { const $ul = qs($sidebar, `[data-path="${path}"] ul`); $ul.replaceWith($list); @@ -133,7 +139,7 @@ export default async function ctrlSidebar(render, nRestart = 0) { rxjs.debounceTime(200), rxjs.tap((e) => { const inputValue = e.target.value.toLowerCase(); - qsa($sidebar, "li a").forEach(($li) => { + qsa($sidebar, "[data-bind=\"your-files\"] li a").forEach(($li) => { if (inputValue === "") { $li.classList.remove("hidden"); $sidebar.classList.remove("search"); @@ -148,7 +154,7 @@ export default async function ctrlSidebar(render, nRestart = 0) { )); } -async function createListOfFiles(path, currentName, fullpath) { +async function _createListOfFiles(path, currentName, fullpath) { const r = await cache().get(path); const whats = r === null ? (currentName ? [currentName] : []) @@ -161,7 +167,7 @@ async function createListOfFiles(path, currentName, fullpath) { const currpath = path + whats[i] + "/"; const $li = createElement(`
  • - + directory
    ${whats[i]}
    @@ -196,6 +202,43 @@ async function createListOfFiles(path, currentName, fullpath) { return $ul; } +async function ctrlTagPane(render) { + const $page = createElement(` +
      +
    • +
    + `); + render($page); + + // only enable this pane in canary mode until it's actually ready + if (new URLSearchParams(location.search).get("canary") !== "true") { + $page.classList.add("hidden"); + $page.parentElement.previousElementSibling.classList.add("hidden"); + return; + } + + const tags = [ + { name: t("Bookmark"), color: "green" }, + { name: "important", color: "red" }, + { name: "foobar", color: "saddlebrown" }, + ]; + const $tmpl = (name, color) => createElement(` + + + + +
    ${name}
    +
    + `); + const $fragment = document.createDocumentFragment(); + tags.forEach(({ name, color }) => { + $fragment.appendChild($tmpl(name, color)); + }); + qs($page, `[data-bind="taglist"]`).appendChild($fragment); + +} + + export function init() { return loadCSS(import.meta.url, "./sidebar.css"); } diff --git a/public/assets/pages/filespage/ctrl_submenu.js b/public/assets/pages/filespage/ctrl_submenu.js index 464f1270..27a95068 100644 --- a/public/assets/pages/filespage/ctrl_submenu.js +++ b/public/assets/pages/filespage/ctrl_submenu.js @@ -12,7 +12,6 @@ import "../../components/icon.js"; import { createModal } from "../../components/modal.js"; import componentShare from "./modal_share.js"; -import componentEmbed from "./modal_embed.js"; import componentTag from "./modal_tag.js"; import componentRename from "./modal_rename.js"; import componentDelete from "./modal_delete.js"; @@ -116,10 +115,7 @@ function componentLeft(render, { $scroll }) { - - `))), @@ -135,11 +131,12 @@ function componentLeft(render, { $scroll }) { targetHeight: 315, }), { path: expandSelection()[0].path }); })), - onClick(qs($page, `[data-action="embed"]`)).pipe(rxjs.tap(() => { - componentEmbed(createModal(modalOpt)); - })), onClick(qs($page, `[data-action="tag"]`)).pipe(rxjs.tap(() => { - componentTag(createModal(modalOpt)); + componentTag(createModal({ + ...modalOpt, + withButtonsLeft: null, + withButtonsRight: null, + }, { path: expandSelection()[0].path })); })), onClick(qs($page, `[data-action="rename"]`)).pipe(rxjs.mergeMap(() => { const path = expandSelection()[0].path; diff --git a/public/assets/pages/filespage/modal_embed.js b/public/assets/pages/filespage/modal_embed.js deleted file mode 100644 index 39e988c7..00000000 --- a/public/assets/pages/filespage/modal_embed.js +++ /dev/null @@ -1,10 +0,0 @@ -import { createElement } from "../../lib/skeleton/index.js"; - -export default function(render) { - const $modal = createElement(` -
    - EMBED CODE -
    - `); - render($modal); -} diff --git a/public/assets/pages/filespage/modal_tag.css b/public/assets/pages/filespage/modal_tag.css index f4d676b4..dd78b445 100644 --- a/public/assets/pages/filespage/modal_tag.css +++ b/public/assets/pages/filespage/modal_tag.css @@ -1,19 +1,26 @@ +.component_tag { + font-size: 1rem; +} .component_tag input { - font-size: 1.2em; + font-size: 1.15rem; + border: 2px solid var(--border); + border-radius: 3px; + padding: 2px 5px; + color: var(--color); } .component_tag input::placeholder { - font-weight: 100; + color: rgba(0,0,0,0.2); } .component_tag .box { display: flex; background: var(--bg-color); transition: background 0.1s ease; - padding: 5px 10px; + padding: 2px 5px 2px 8px; border-radius: 3px; + font-size: 0.95rem; } .component_tag .box.active { background: var(--primary); - color: var(--color); } .component_tag .box > div { flex-grow: 1; @@ -26,17 +33,7 @@ } .component_tag .box img[alt="close"] { width: 14px; - padding: 3px; -} -.component_tag .box .count { - opacity: 0.5; - font-size: 0.9rem; -} -.component_tag .box .count:before { - content: "["; -} -.component_tag .box .count:after { - content: "]"; + padding: 5px; } .component_tag .scroll-y { diff --git a/public/assets/pages/filespage/modal_tag.js b/public/assets/pages/filespage/modal_tag.js index ab7d4caa..e3a9fbf8 100644 --- a/public/assets/pages/filespage/modal_tag.js +++ b/public/assets/pages/filespage/modal_tag.js @@ -1,35 +1,38 @@ import { createElement } from "../../lib/skeleton/index.js"; +import { qs } from "../../lib/dom.js"; import t from "../../locales/index.js"; +const ICON_CLOSE = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MS45NzYgNTEuOTc2Ij4KICA8cGF0aCBzdHlsZT0iZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eTowLjUzMzMzMjg1O3N0cm9rZS13aWR0aDoxLjQ1NjgxMTE5IiBkPSJtIDQxLjAwNTMxLDQwLjg0NDA2MiBjIC0xLjEzNzc2OCwxLjEzNzc2NSAtMi45ODIwODgsMS4xMzc3NjUgLTQuMTE5ODYxLDAgTCAyNi4wNjg2MjgsMzAuMDI3MjM0IDE0LjczNzU1MSw0MS4zNTgzMSBjIC0xLjEzNzc3MSwxLjEzNzc3MSAtMi45ODIwOTMsMS4xMzc3NzEgLTQuMTE5ODYxLDAgLTEuMTM3NzcyMiwtMS4xMzc3NjggLTEuMTM3NzcyMiwtMi45ODIwODggMCwtNC4xMTk4NjEgTCAyMS45NDg3NjYsMjUuOTA3MzcyIDExLjEzMTkzOCwxNS4wOTA1NTEgYyAtMS4xMzc3NjQ3LC0xLjEzNzc3MSAtMS4xMzc3NjQ3LC0yLjk4MzU1MyAwLC00LjExOTg2MSAxLjEzNzc3NCwtMS4xMzc3NzIxIDIuOTgyMDk4LC0xLjEzNzc3MjEgNC4xMTk4NjUsMCBMIDI2LjA2ODYyOCwyMS43ODc1MTIgMzYuMzY5NzM5LDExLjQ4NjM5OSBjIDEuMTM3NzY4LC0xLjEzNzc2OCAyLjk4MjA5MywtMS4xMzc3NjggNC4xMTk4NjIsMCAxLjEzNzc2NywxLjEzNzc2OSAxLjEzNzc2NywyLjk4MjA5NCAwLDQuMTE5ODYyIEwgMzAuMTg4NDg5LDI1LjkwNzM3MiA0MS4wMDUzMSwzNi43MjQxOTcgYyAxLjEzNzc3MSwxLjEzNzc2NyAxLjEzNzc3MSwyLjk4MjA5MSAwLDQuMTE5ODY1IHoiIC8+Cjwvc3ZnPgo="; + +const $tmpl = createElement(` +
    +
    Projects
    + close +
    +`); + export default function(render) { + const tags = [ + { name: "Bookmark", active: true }, + { name: "Projects" }, + { name: "Important" }, + ]; + const $modal = createElement(`
    -
    -
    -
    test 2
    - arrow_top - arrow_bottom - close -
    -
    -
    kjhjk 1
    - arrow_top - arrow_bottom - close -
    -
    -
    jh 2
    - arrow_top - arrow_bottom - close -
    -
    +
    `); - render($modal, ({ id }) => { - console.log("QUIT", id); + const $fragment = document.createDocumentFragment(); + tags.forEach(({ name, active }) => { + const $el = $tmpl.cloneNode(true); + $el.firstElementChild.innerText = name; + if (active) $el.classList.add("active"); + $fragment.appendChild($el); }); + qs($modal, `[data-bind="taglist"]`).appendChild($fragment); + render($modal, ({ id }) => { console.log("QUIT", id) }); } diff --git a/server/ctrl/static.go b/server/ctrl/static.go index 26415f8a..d469298e 100644 --- a/server/ctrl/static.go +++ b/server/ctrl/static.go @@ -271,7 +271,7 @@ func ServeFrontofficeHandler(ctx *App, res http.ResponseWriter, req *http.Reques "/assets/pages/filespage/model_files.js", "/assets/pages/filespage/helper.js", "/assets/pages/filespage/model_acl.js", "/assets/pages/filespage/state_config.js", "/assets/pages/filespage/state_newthing.js", "/assets/pages/filespage/state_selection.js", - "/assets/pages/filespage/modal_delete.js", "/assets/pages/filespage/modal_rename.js", "/assets/pages/filespage/modal_tag.js", "/assets/pages/filespage/modal_embed.js", + "/assets/pages/filespage/modal_delete.js", "/assets/pages/filespage/modal_rename.js", "/assets/pages/filespage/modal_tag.js", "/assets/components/form.js", "/assets/helpers/log.js", "/assets/lib/error.js", "/assets/model/config.js",