chore(headers): standardize across all 7 tools
Bring every tool's header in line with archive's pattern: [logo] [title] [version] [Add Local Directory] [⟳] ............... [◐] [?] ------------- header-left --------------- ----- header-right - Changes per tool: * browse: rename "Select Directory" → "Add Local Directory"; add the red-non-stable wrap to the build label (was missing); add a help panel + bundle shared/help.js. * classifier: rename selectDirectoryBtn → addDirectoryBtn, refreshBtn → refreshHeaderBtn for consistency. Update all JS callers and welcome-screen copy to the new label. * mdedit: same id rename. Move the previously-in-pane refresh button into the header. Stop renaming the dir button to "Directory: <name>" once a folder is loaded — instead use the shared btn--subtle variant to de-emphasize while keeping the standard label. * transmittal: convert non-standard <div class="app-header"> with spacer/icons containers to <header class="app-header"> with the canonical header-left/header-right pair. Move the publish split- button into header-left (Transmittal-specific primary action). Remove dead .app-header__spacer/__icons/header-icon-btn CSS now that nothing references those classes. * landing, form: add help-btn + help-panel + bundle shared/help.js. Each panel is tool-specific (project picker docs for landing, schema-driven form docs for form). Cross-cutting: * shared/base.css: promote .btn--subtle from browse/css/tree.css so any tool with an online mode can de-emphasize Add Local Directory consistently. Verified all 7 tools in headless Chromium: header structure correct, build label red on non-stable cuts, help panel opens + closes via button + Esc.
This commit is contained in:
parent
a7e84dae15
commit
bbb75a87af
17 changed files with 277 additions and 101 deletions
|
|
@ -34,6 +34,7 @@ concat_files \
|
|||
"../shared/zddc.js" \
|
||||
"../shared/zddc-filter.js" \
|
||||
"../shared/theme.js" \
|
||||
"../shared/help.js" \
|
||||
"../shared/preview-lib.js" \
|
||||
"js/init.js" \
|
||||
"js/loader.js" \
|
||||
|
|
@ -51,8 +52,13 @@ tool=browse
|
|||
compute_build_label "$tool" "$@"
|
||||
|
||||
# Replace template placeholders with concatenated CSS/JS + label.
|
||||
# Non-stable build labels (alpha/beta/dev-dirty) are wrapped in a red
|
||||
# span — same convention as every other tool (compute_build_label
|
||||
# sets $is_red=1 for non-stable cuts). Keeps the visual cue
|
||||
# consistent across tool headers.
|
||||
awk -v css_file="$css_temp" -v js_file="$js_temp" \
|
||||
-v build_label="$build_label" -v favicon="$favicon_data_uri" '
|
||||
-v build_label="$build_label" -v is_red="$is_red" \
|
||||
-v favicon="$favicon_data_uri" '
|
||||
/\{\{CSS_PLACEHOLDER\}\}/ {
|
||||
while ((getline line < css_file) > 0) print line
|
||||
close(css_file); next
|
||||
|
|
@ -61,8 +67,15 @@ awk -v css_file="$css_temp" -v js_file="$js_temp" \
|
|||
while ((getline line < js_file) > 0) print line
|
||||
close(js_file); next
|
||||
}
|
||||
{
|
||||
/\{\{BUILD_LABEL\}\}/ {
|
||||
if (is_red == "1") {
|
||||
gsub(/\{\{BUILD_LABEL\}\}/, "<span style=\"color:red;font-weight:bold\">" build_label "</span>")
|
||||
} else {
|
||||
gsub(/\{\{BUILD_LABEL\}\}/, build_label)
|
||||
}
|
||||
print; next
|
||||
}
|
||||
{
|
||||
gsub(/\{\{FAVICON\}\}/, favicon)
|
||||
print
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,22 +142,6 @@
|
|||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
/* Subtle button variant — used for "Select Directory" when the page
|
||||
is server-backed (the user usually doesn't need to switch to a
|
||||
local folder; we keep the option visible but quiet). */
|
||||
.btn.btn--subtle {
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
border-color: var(--border);
|
||||
box-shadow: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.btn.btn--subtle:hover {
|
||||
color: var(--text);
|
||||
background: var(--bg-hover, rgba(0,0,0,0.04));
|
||||
}
|
||||
|
||||
/* Table — folders + files in a tree */
|
||||
|
||||
.browse-table {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
<span class="app-header__title">ZDDC Browse</span>
|
||||
<span class="build-timestamp">{{BUILD_LABEL}}</span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Select Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh listing" aria-label="Refresh listing">⟳</button>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh listing" aria-label="Refresh listing" style="font-size:1.1rem;">⟳</button>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
<ul>
|
||||
<li><b>Online</b> — when this page is served by zddc-server, the
|
||||
listing for the current directory loads automatically.</li>
|
||||
<li><b>Local</b> — click <i>Select Directory</i> to pick any folder
|
||||
<li><b>Local</b> — click <i>Add Local Directory</i> to pick any folder
|
||||
on your computer (Chromium-based browsers).</li>
|
||||
</ul>
|
||||
<p>Once loaded: click a folder to expand it, <b>shift-click</b>
|
||||
|
|
@ -103,6 +103,87 @@
|
|||
|
||||
<div id="statusBar" class="status-bar"></div>
|
||||
|
||||
<!-- Help Panel -->
|
||||
<aside id="help-panel" class="help-panel" hidden aria-labelledby="help-panel-title">
|
||||
<div class="help-panel__header">
|
||||
<h2 id="help-panel-title" class="help-panel__title">Help — ZDDC Browse</h2>
|
||||
<button type="button" class="help-panel__close" id="help-panel-close" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="help-panel__body">
|
||||
<h3>What is Browse?</h3>
|
||||
<p>Browse is a directory listing for ZDDC archives — and any directory. It works in two modes:</p>
|
||||
<dl>
|
||||
<dt>Online</dt>
|
||||
<dd>When the page is served by zddc-server, the listing for the current
|
||||
URL directory loads automatically. Breadcrumbs link to ancestor folders.</dd>
|
||||
<dt>Local</dt>
|
||||
<dd>Click <strong>Add Local Directory</strong> to pick any folder on your
|
||||
computer. Local mode requires a Chromium-based browser (File System
|
||||
Access API).</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Tree navigation</h3>
|
||||
<dl>
|
||||
<dt>Click a folder</dt>
|
||||
<dd>Toggle expand/collapse on that folder.</dd>
|
||||
<dt>Shift-click a folder</dt>
|
||||
<dd>Recursive expand or collapse — applies to the whole subtree.</dd>
|
||||
<dt>Click a file</dt>
|
||||
<dd>Open in the preview popup. Modifier-click (Ctrl/Cmd) or middle-click
|
||||
opens in a new tab.</dd>
|
||||
<dt>ZIP files</dt>
|
||||
<dd>Behave as folders — click to inspect contents inline. JSZip is
|
||||
bundled, so this works offline.</dd>
|
||||
<dt>Column headers</dt>
|
||||
<dd>Click to sort; click again to reverse.</dd>
|
||||
<dt>Refresh</dt>
|
||||
<dd>Re-fetches the current directory listing — works for both
|
||||
local (re-enumerates the FS handle) and online (re-fetches the JSON).</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Filter rows</h3>
|
||||
<p>Two filter rows live in the table header:</p>
|
||||
<dl>
|
||||
<dt>📄 file row</dt>
|
||||
<dd>Filter by file name (left input) and/or extension (Type input).
|
||||
File matches stay visible together with their ancestor folders, so
|
||||
the path to each hit is always shown.</dd>
|
||||
<dt>📁 folder row</dt>
|
||||
<dd>Filter by folder name. Matching folders show with their entire
|
||||
subtree. Combined with file filter: file must also be inside a
|
||||
matching folder's subtree (intersection).</dd>
|
||||
</dl>
|
||||
<p>Filter syntax (shared across all ZDDC tools):</p>
|
||||
<dl>
|
||||
<dt><code>term</code></dt>
|
||||
<dd>Contains "term" (case-insensitive)</dd>
|
||||
<dt><code>!term</code></dt>
|
||||
<dd>Does not contain</dd>
|
||||
<dt><code>^term</code></dt>
|
||||
<dd>Starts with</dd>
|
||||
<dt><code>term$</code></dt>
|
||||
<dd>Ends with</dd>
|
||||
<dt><code>a b</code></dt>
|
||||
<dd>Both (AND)</dd>
|
||||
<dt><code>a | b</code></dt>
|
||||
<dd>Either (OR)</dd>
|
||||
<dt><code>el.*spc</code></dt>
|
||||
<dd>Regex — any-char + any-sequence</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Header buttons</h3>
|
||||
<dl>
|
||||
<dt>Add Local Directory</dt>
|
||||
<dd>Pick a folder from your computer. Works in both modes; in online
|
||||
mode it's de-emphasized but still available.</dd>
|
||||
<dt>⟳ Refresh</dt>
|
||||
<dd>Re-load the current directory listing.</dd>
|
||||
<dt>◐ Theme</dt>
|
||||
<dd>Cycle auto / light / dark.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
{{JS_PLACEHOLDER}}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
*/
|
||||
function showBrowserWarning() {
|
||||
const warning = document.getElementById('browserWarning');
|
||||
const selectBtn = document.getElementById('selectDirectoryBtn');
|
||||
const selectBtn = document.getElementById('addDirectoryBtn');
|
||||
if (warning) {
|
||||
warning.classList.remove('hidden');
|
||||
}
|
||||
|
|
@ -80,8 +80,8 @@
|
|||
mainApp: document.getElementById('mainApp'),
|
||||
|
||||
// Header buttons
|
||||
selectDirectoryBtn: document.getElementById('selectDirectoryBtn'),
|
||||
refreshBtn: document.getElementById('refreshBtn'),
|
||||
addDirectoryBtn: document.getElementById('addDirectoryBtn'),
|
||||
refreshHeaderBtn: document.getElementById('refreshHeaderBtn'),
|
||||
saveAllBtn: document.getElementById('saveAllBtn'),
|
||||
cancelAllBtn: document.getElementById('cancelAllBtn'),
|
||||
exportHashesBtn: document.getElementById('exportHashesBtn'),
|
||||
|
|
@ -115,8 +115,8 @@
|
|||
*/
|
||||
function setupEventListeners() {
|
||||
// Directory selection
|
||||
app.dom.selectDirectoryBtn.addEventListener('click', handleSelectDirectory);
|
||||
app.dom.refreshBtn.addEventListener('click', handleRefresh);
|
||||
app.dom.addDirectoryBtn.addEventListener('click', handleSelectDirectory);
|
||||
app.dom.refreshHeaderBtn.addEventListener('click', handleRefresh);
|
||||
|
||||
// Drag and drop on welcome screen
|
||||
setupWelcomeDragDrop();
|
||||
|
|
@ -278,7 +278,7 @@
|
|||
await app.modules.scanner.scanDirectory(dirHandle);
|
||||
|
||||
// Show refresh button now that a directory is loaded
|
||||
if (app.dom.refreshBtn) { app.dom.refreshBtn.classList.remove('hidden'); }
|
||||
if (app.dom.refreshHeaderBtn) { app.dom.refreshHeaderBtn.classList.remove('hidden'); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@
|
|||
<span class="app-header__title">ZDDC Classifier</span>
|
||||
<span class="build-timestamp">{{BUILD_LABEL}}</span>
|
||||
</div>
|
||||
<button id="selectDirectoryBtn" class="btn btn-primary">Select Directory</button>
|
||||
<button id="refreshBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory" aria-label="Refresh" style="font-size:1.1rem;">⟳</button>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory" aria-label="Refresh" style="font-size:1.1rem;">⟳</button>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
|
|
@ -149,7 +149,7 @@
|
|||
<li>Rename one file or all modified files at once</li>
|
||||
</ul>
|
||||
|
||||
<p>Click <strong>Select Directory</strong> to begin.</p>
|
||||
<p>Click <strong>Add Local Directory</strong> to begin.</p>
|
||||
|
||||
<p class="note">This application works entirely in your browser. No data is transmitted to any server.</p>
|
||||
</div>
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
|
||||
<h3>Getting Started</h3>
|
||||
<ol>
|
||||
<li>Click <strong>Select Directory</strong> to open a folder containing files to rename.</li>
|
||||
<li>Click <strong>Add Local Directory</strong> to open a folder containing files to rename.</li>
|
||||
<li>The folder tree on the left shows all sub-folders. Click a folder to load its files.</li>
|
||||
<li>Edit cells in the spreadsheet to set the new filename components.</li>
|
||||
<li>Click <strong>Save All</strong> (or save individual rows) to rename the files on disk.</li>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ concat_files \
|
|||
|
||||
concat_files \
|
||||
"../shared/theme.js" \
|
||||
"../shared/help.js" \
|
||||
"js/app.js" \
|
||||
"js/context.js" \
|
||||
"js/util.js" \
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
<button id="help-btn" class="btn btn-secondary" title="Help" aria-label="Help">?</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
@ -38,6 +39,51 @@
|
|||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Help Panel -->
|
||||
<aside id="help-panel" class="help-panel" hidden aria-labelledby="help-panel-title">
|
||||
<div class="help-panel__header">
|
||||
<h2 id="help-panel-title" class="help-panel__title">Help — ZDDC Form</h2>
|
||||
<button type="button" class="help-panel__close" id="help-panel-close" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="help-panel__body">
|
||||
<h3>What is this form?</h3>
|
||||
<p>This is a schema-driven form rendered by zddc-server. Every
|
||||
<code><name>.form.yaml</code> file in the archive becomes an
|
||||
editable form at <code><path>/<name>.form.html</code>.
|
||||
Submissions are saved as <code><name>/<id>.yaml</code>
|
||||
files alongside the schema, and re-render with their data filled in
|
||||
when revisited.</p>
|
||||
|
||||
<h3>Filling in the form</h3>
|
||||
<dl>
|
||||
<dt>Required fields</dt>
|
||||
<dd>Marked with an asterisk in their label. Submitting with a
|
||||
required field empty re-renders the form with an inline error.</dd>
|
||||
<dt>Validation</dt>
|
||||
<dd>Server-side via JSON Schema 2020-12 (subset). Client-side
|
||||
hints (<code>required</code>, <code>min</code>, <code>max</code>,
|
||||
<code>pattern</code>) are added where the schema specifies them.</dd>
|
||||
<dt>Submit</dt>
|
||||
<dd>POSTs to the same URL the form was loaded from. On success the
|
||||
browser navigates to the saved submission's URL. On failure the
|
||||
form re-renders with errors inline at each invalid field.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Editing existing submissions</h3>
|
||||
<p>Open the saved submission's URL — the form re-renders with its
|
||||
current data and any errors. Submitting overwrites the same file.
|
||||
History is in git via your normal commit cycle.</p>
|
||||
|
||||
<h3>Header buttons</h3>
|
||||
<dl>
|
||||
<dt>◐ Theme</dt>
|
||||
<dd>Cycle auto / light / dark.</dd>
|
||||
<dt>? Help</dt>
|
||||
<dd>This panel. Press <kbd>Esc</kbd> to close.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!--
|
||||
Server injects the form context here on render. Shape:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ concat_files \
|
|||
"../shared/zddc.js" \
|
||||
"../shared/zddc-filter.js" \
|
||||
"../shared/theme.js" \
|
||||
"../shared/help.js" \
|
||||
"js/landing.js" \
|
||||
> "$js_raw"
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
<button id="help-btn" class="btn btn-secondary" title="Help" aria-label="Help">?</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
@ -91,6 +92,52 @@
|
|||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Help Panel -->
|
||||
<aside id="help-panel" class="help-panel" hidden aria-labelledby="help-panel-title">
|
||||
<div class="help-panel__header">
|
||||
<h2 id="help-panel-title" class="help-panel__title">Help — ZDDC</h2>
|
||||
<button type="button" class="help-panel__close" id="help-panel-close" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="help-panel__body">
|
||||
<h3>What is this page?</h3>
|
||||
<p>This is the ZDDC archive landing page — a project picker. It lists every
|
||||
project (top-level directory) you have access to on this server, plus any
|
||||
<strong>groups</strong> you've defined for opening multiple projects at once.</p>
|
||||
|
||||
<h3>Projects</h3>
|
||||
<p>Click a project to open it. The project's archive view (list of folders +
|
||||
files, with all the standard ZDDC tools available inside) loads in the same
|
||||
tab. Use back/forward to navigate between projects and the picker.</p>
|
||||
|
||||
<h3>Groups</h3>
|
||||
<p>A group bundles a set of projects you commonly open together. Click
|
||||
<strong>+ New group</strong>, give it a name, click projects to include
|
||||
them, then save. Opening a group opens all its projects in one go.</p>
|
||||
<dl>
|
||||
<dt>Save group</dt>
|
||||
<dd>Persist the selection as a named group on this server (visible to
|
||||
other users with access to the same projects).</dd>
|
||||
<dt>Open selected</dt>
|
||||
<dd>Open the currently-checked projects without saving as a group.</dd>
|
||||
<dt>Cancel</dt>
|
||||
<dd>Exit select mode without saving.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Access</h3>
|
||||
<p>Projects and groups are filtered by your account's permissions.
|
||||
If a URL references a project you don't have access to, a warning banner
|
||||
appears and the inaccessible items are skipped silently.</p>
|
||||
|
||||
<h3>Header buttons</h3>
|
||||
<dl>
|
||||
<dt>◐ Theme</dt>
|
||||
<dd>Cycle auto / light / dark.</dd>
|
||||
<dt>? Help</dt>
|
||||
<dd>This panel. Press <kbd>Esc</kbd> to close.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
{{JS_PLACEHOLDER}}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const SCRATCHPAD_WELCOME = [
|
|||
'Use this **Scratchpad** for quick notes. Download it any time with the ⬇',
|
||||
'button on the Scratchpad row in the file list.',
|
||||
'',
|
||||
'Click **Select Directory** above to open a folder of Markdown files,',
|
||||
'Click **Add Local Directory** above to open a folder of Markdown files,',
|
||||
'or just start typing here.',
|
||||
'',
|
||||
].join('\n');
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@
|
|||
* Set up all event listeners for the application
|
||||
*/
|
||||
function setupEventListeners() {
|
||||
// Select directory button
|
||||
const selectDirectoryBtn = document.getElementById('select-directory');
|
||||
// Add Local Directory button (was id="select-directory" / "refresh-directory")
|
||||
const selectDirectoryBtn = document.getElementById('addDirectoryBtn');
|
||||
if (selectDirectoryBtn) {
|
||||
selectDirectoryBtn.addEventListener('click', openDirectory);
|
||||
}
|
||||
|
||||
// Refresh directory button
|
||||
const refreshDirectoryBtn = document.getElementById('refresh-directory');
|
||||
// Refresh button (now in header, was in file-nav pane)
|
||||
const refreshDirectoryBtn = document.getElementById('refreshHeaderBtn');
|
||||
if (refreshDirectoryBtn) {
|
||||
refreshDirectoryBtn.addEventListener('click', refreshDirectory);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,12 +171,19 @@ async function openDirectory() {
|
|||
* @param {string} directoryName - Name of the selected directory
|
||||
*/
|
||||
function updateDirectoryStatus(directoryName) {
|
||||
const selectDirectoryBtn = document.getElementById('select-directory');
|
||||
// Standardized header pattern (across all ZDDC tools): the button
|
||||
// keeps the label "Add Local Directory"; de-emphasize it once a
|
||||
// directory is loaded (the user can still click to pick another)
|
||||
// by applying the shared btn--subtle variant. The directory name
|
||||
// is shown in the file-nav pane, not on the button.
|
||||
const selectDirectoryBtn = document.getElementById('addDirectoryBtn');
|
||||
if (selectDirectoryBtn) {
|
||||
selectDirectoryBtn.textContent = `Directory: ${directoryName}`;
|
||||
selectDirectoryBtn.classList.remove('btn-primary');
|
||||
selectDirectoryBtn.classList.add('btn--subtle');
|
||||
selectDirectoryBtn.title = `Loaded: ${directoryName} — click to switch`;
|
||||
}
|
||||
|
||||
const refreshBtn = document.getElementById('refresh-directory');
|
||||
const refreshBtn = document.getElementById('refreshHeaderBtn');
|
||||
if (refreshBtn) {
|
||||
refreshBtn.classList.remove('hidden');
|
||||
}
|
||||
|
|
@ -677,8 +684,8 @@ async function loadServerDirectory() {
|
|||
|
||||
// Only enter server-source mode if the host actually serves JSON directory
|
||||
// listings (zddc-server / Caddy). On a plain static host the probe fails
|
||||
// and we must leave "Select Directory" visible so the user can still load
|
||||
// local files.
|
||||
// and we must leave "Add Local Directory" visible so the user can still
|
||||
// load local files.
|
||||
try {
|
||||
const resp = await fetch(baseUrl, { headers: { 'Accept': 'application/json' }, cache: 'no-cache' });
|
||||
if (!resp.ok) return;
|
||||
|
|
@ -703,12 +710,18 @@ async function loadServerDirectory() {
|
|||
entries: {},
|
||||
};
|
||||
|
||||
// Surface refresh, hide write-only controls. "Select Directory" stays
|
||||
// visible so the user can switch to a local folder at any time.
|
||||
const refreshBtn = document.getElementById('refresh-directory');
|
||||
// Surface refresh, hide write-only controls. "Add Local Directory"
|
||||
// stays visible (de-emphasized via btn--subtle) so the user can
|
||||
// switch to a local folder at any time.
|
||||
const refreshBtn = document.getElementById('refreshHeaderBtn');
|
||||
if (refreshBtn) refreshBtn.classList.remove('hidden');
|
||||
const newFileRootBtn = document.getElementById('new-file-root');
|
||||
if (newFileRootBtn) newFileRootBtn.classList.add('hidden');
|
||||
const addDirBtn = document.getElementById('addDirectoryBtn');
|
||||
if (addDirBtn) {
|
||||
addDirBtn.classList.remove('btn-primary');
|
||||
addDirBtn.classList.add('btn--subtle');
|
||||
}
|
||||
|
||||
const stats = await readServerDirectory(baseUrl, fileTree, 0);
|
||||
renderFileTree();
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||
* Initialize UI based on File System API availability
|
||||
*/
|
||||
function initializeApiAvailability() {
|
||||
const selectDirectoryBtn = document.getElementById('select-directory');
|
||||
const selectDirectoryBtn = document.getElementById('addDirectoryBtn');
|
||||
const welcomeHint = document.getElementById('welcome-hint');
|
||||
const welcomeFirefox = document.getElementById('welcome-firefox');
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@
|
|||
<span class="app-header__title">ZDDC Markdown</span>
|
||||
<span class="build-timestamp">{{BUILD_LABEL}}</span>
|
||||
</div>
|
||||
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary" title="Add a local directory">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh directory" aria-label="Refresh" style="font-size:1.1rem;">⟳</button>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
|
|
@ -45,7 +46,6 @@
|
|||
<span>Files</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<button id="new-file-root" class="btn btn-secondary btn-sm hidden" title="New file in root directory">+</button>
|
||||
<button id="refresh-directory" class="btn btn-secondary btn-sm hidden" title="Refresh directory">↻</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
<div class="pane content-pane flex-1 relative flex flex-col bg-white dark:bg-gray-900 overflow-hidden" id="main-content">
|
||||
<div id="welcome-screen" class="welcome-screen hidden flex-col items-center justify-center h-full text-gray-500 dark:text-gray-400 text-center p-6">
|
||||
<p id="welcome-hint" class="text-sm">Click <strong>Scratchpad</strong> in the file list to start editing,<br>or <strong>Select Directory</strong> to work with files.</p>
|
||||
<p id="welcome-hint" class="text-sm">Click <strong>Scratchpad</strong> in the file list to start editing,<br>or <strong>Add Local Directory</strong> to work with files.</p>
|
||||
<p id="welcome-firefox" class="text-sm text-amber-600 hidden mt-2">Your browser doesn't support the File System API.<br>Use <strong>Scratchpad</strong> to edit markdown and download as a file.</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
|
||||
<h3>Getting Started</h3>
|
||||
<ol>
|
||||
<li>Click <strong>Select Directory</strong> to open a folder. The file tree on the left will populate with all files in that folder.</li>
|
||||
<li>Click <strong>Add Local Directory</strong> to open a folder. The file tree on the left will populate with all files in that folder.</li>
|
||||
<li>Click any Markdown file (<code>.md</code>) in the tree to open it in the editor.</li>
|
||||
<li>Use the <strong>Scratchpad</strong> entry (always visible at the top of the tree) for temporary notes without saving to disk.</li>
|
||||
</ol>
|
||||
|
|
|
|||
|
|
@ -210,6 +210,24 @@ a:hover {
|
|||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
/* Subdued / de-emphasized variant.
|
||||
Used on the "Add Local Directory" button when a tool is operating
|
||||
in server (online) mode — the local-dir affordance is still
|
||||
available but visually quieter, since the typical user already
|
||||
has the directory loaded from the server. */
|
||||
.btn.btn--subtle {
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
border-color: var(--border);
|
||||
box-shadow: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.btn.btn--subtle:not(:disabled):hover {
|
||||
color: var(--text);
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: var(--success);
|
||||
color: var(--text-light);
|
||||
|
|
|
|||
|
|
@ -372,37 +372,6 @@
|
|||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.app-header__spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.app-header__icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.header-icon-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 0.25rem;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
transition: color 0.15s, background 0.15s;
|
||||
}
|
||||
|
||||
.header-icon-btn:hover {
|
||||
color: var(--primary-hover);
|
||||
background: var(--primary-light);
|
||||
}
|
||||
|
||||
/* ── Fixed footer status bar at viewport bottom ───────── */
|
||||
.page-footer {
|
||||
position: fixed;
|
||||
|
|
|
|||
|
|
@ -27,13 +27,8 @@ conventions at https://codeberg.org/VARASYS/ZDDC#file-naming-convention.
|
|||
</head>
|
||||
|
||||
<body class="font-sans text-gray-900">
|
||||
<div class="app-header print:hidden" data-no-disable="true">
|
||||
<div class="split-button" id="bottom-menu" hidden>
|
||||
<button id="bottom-toggle" type="button" class="btn btn-primary split-button__toggle" data-no-disable="true" aria-haspopup="true" aria-expanded="false">▾</button>
|
||||
<button id="bottom-primary" type="button" class="btn btn-primary" data-no-disable="true">Publish</button>
|
||||
<div class="dropdown-menu hidden" role="menu" id="bottom-dropdown"></div>
|
||||
</div>
|
||||
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
|
||||
<header class="app-header print:hidden" data-no-disable="true">
|
||||
<div class="header-left">
|
||||
<svg class="app-header__logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
|
||||
<rect width="64" height="64" rx="12" fill="#1e3a5f"/>
|
||||
<g fill="#fff">
|
||||
|
|
@ -46,12 +41,20 @@ conventions at https://codeberg.org/VARASYS/ZDDC#file-naming-convention.
|
|||
<span class="app-header__title">ZDDC Transmittal</span>
|
||||
<span class="build-timestamp">{{BUILD_LABEL}}</span>
|
||||
</div>
|
||||
<div class="app-header__spacer"></div>
|
||||
<div class="app-header__icons">
|
||||
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
|
||||
<!-- Publish split-button (Transmittal-specific primary action;
|
||||
other tools have "Add Local Directory" here instead) -->
|
||||
<div class="split-button" id="bottom-menu" hidden>
|
||||
<button id="bottom-toggle" type="button" class="btn btn-primary split-button__toggle" data-no-disable="true" aria-haspopup="true" aria-expanded="false">▾</button>
|
||||
<button id="bottom-primary" type="button" class="btn btn-primary" data-no-disable="true">Publish</button>
|
||||
<div class="dropdown-menu hidden" role="menu" id="bottom-dropdown"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button type="button" id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
<button type="button" id="help-btn" class="btn btn-secondary" aria-label="Help" title="Help">?</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="page-container">
|
||||
<form id="transmittal-form">
|
||||
<input type="hidden" id="mode" value="edit">
|
||||
|
|
|
|||
Loading…
Reference in a new issue