chore(embedded): cut v0.0.17-beta
This commit is contained in:
parent
315d039880
commit
4cd39998aa
8 changed files with 358 additions and 16 deletions
|
|
@ -2267,7 +2267,7 @@ td[data-field="trackingNumber"] {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title">ZDDC Archive</span>
|
<span class="app-header__title">ZDDC Archive</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data">⟳</button>
|
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data">⟳</button>
|
||||||
|
|
|
||||||
|
|
@ -969,7 +969,7 @@ body {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title">ZDDC Browse</span>
|
<span class="app-header__title">ZDDC Browse</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</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">⟳</button>
|
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh listing" aria-label="Refresh listing">⟳</button>
|
||||||
|
|
|
||||||
|
|
@ -1486,7 +1486,7 @@ body.help-open .app-header {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title">ZDDC Classifier</span>
|
<span class="app-header__title">ZDDC Classifier</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</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>
|
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory" aria-label="Refresh" style="font-size:1.1rem;">⟳</button>
|
||||||
|
|
|
||||||
|
|
@ -995,6 +995,128 @@ body {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Project mode ──────────────────────────────────────────────────────── */
|
||||||
|
/* Activated when location.pathname is a single project segment (e.g.
|
||||||
|
/Project-1). Picker UI is hidden; this block surfaces the four
|
||||||
|
lifecycle-stage cards and MDL editing instructions. */
|
||||||
|
|
||||||
|
.project-title {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
margin: 0 0 0.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-title__subtle {
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lead {
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin: 0.25rem 0 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stages {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
gap: 0.85rem;
|
||||||
|
margin: 1rem 0 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-card {
|
||||||
|
display: block;
|
||||||
|
padding: 1rem 1.1rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text);
|
||||||
|
transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-card:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-card:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-card h3 {
|
||||||
|
margin: 0 0 0.3rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-card p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.browse-link {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.browse-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectView ol {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectView ol li {
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectView code {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
padding: 0.1em 0.35em;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.86em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectView h2 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin: 2.25rem 0 0.5rem;
|
||||||
|
padding-bottom: 0.3rem;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-list {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
margin: 0.4rem 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-list li {
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-list a {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-list a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-list-none-yet {
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -1010,7 +1132,7 @@ body {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title">ZDDC</span>
|
<span class="app-header__title">ZDDC</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
|
|
@ -1019,7 +1141,9 @@ body {
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="landing-main">
|
<main id="landingMain" class="landing-main">
|
||||||
|
<!-- Picker mode (deployment root /). Project picker + groups. -->
|
||||||
|
<div id="pickerView">
|
||||||
<!-- Welcome / hero -->
|
<!-- Welcome / hero -->
|
||||||
<section class="landing-hero">
|
<section class="landing-hero">
|
||||||
<h1>Welcome to the ZDDC Archive</h1>
|
<h1>Welcome to the ZDDC Archive</h1>
|
||||||
|
|
@ -1078,6 +1202,67 @@ body {
|
||||||
<div class="project-list-loading">Loading projects…</div>
|
<div class="project-list-loading">Loading projects…</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div><!-- /pickerView -->
|
||||||
|
|
||||||
|
<!-- Project mode (/<project>). Stage cards + MDL section. Shown
|
||||||
|
by landing.js when location.pathname is a single segment. -->
|
||||||
|
<div id="projectView" class="hidden">
|
||||||
|
<h1 id="projectTitle" class="project-title">
|
||||||
|
<span id="projectName"></span>
|
||||||
|
<span class="project-title__subtle">— project workspace</span>
|
||||||
|
</h1>
|
||||||
|
<p class="lead">Pick a lifecycle stage, or browse all files.</p>
|
||||||
|
|
||||||
|
<div class="stages">
|
||||||
|
<a class="stage-card" id="stageArchive">
|
||||||
|
<h3>Archive</h3>
|
||||||
|
<p>Permanent record of issued and received transmittals, organized by counterparty.</p>
|
||||||
|
</a>
|
||||||
|
<a class="stage-card" id="stageWorking">
|
||||||
|
<h3>Working</h3>
|
||||||
|
<p>Per-user drafting workspace. Your folder is private by default; you can grant access by editing its <code>.zddc</code> file.</p>
|
||||||
|
</a>
|
||||||
|
<a class="stage-card" id="stageStaging">
|
||||||
|
<h3>Staging</h3>
|
||||||
|
<p>Outbound transmittals being prepared for issue.</p>
|
||||||
|
</a>
|
||||||
|
<a class="stage-card" id="stageReviewing">
|
||||||
|
<h3>Reviewing</h3>
|
||||||
|
<p>Pending review responses — inbound submittals paired with their in-progress drafts.</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><a id="browseAllLink" class="browse-link">Browse all files →</a></p>
|
||||||
|
|
||||||
|
<h2>Master Deliverables List (MDL)</h2>
|
||||||
|
<p>Each counterparty in the archive has an MDL — an editable
|
||||||
|
table of expected deliverables. The default columns mirror
|
||||||
|
the ZDDC tracking-number components (<code>originator</code>,
|
||||||
|
<code>phase</code>, <code>project</code>, <code>area</code>,
|
||||||
|
<code>discipline</code>, <code>type</code>,
|
||||||
|
<code>sequence</code>, <code>suffix</code>) plus
|
||||||
|
<code>title</code>, <code>plannedRevision</code>,
|
||||||
|
<code>plannedDate</code>, <code>status</code>, and
|
||||||
|
<code>owner</code>.</p>
|
||||||
|
|
||||||
|
<p><strong>To edit the MDL for any party:</strong></p>
|
||||||
|
<ol>
|
||||||
|
<li>Open the project archive: <a id="archiveBrowseLink"></a></li>
|
||||||
|
<li>Click into a party's folder (e.g. <code>PartyA</code>)</li>
|
||||||
|
<li>Click <code>mdl</code> inside the party folder</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<div id="partyListSection">
|
||||||
|
<!-- Populated by JS when archive/ enumeration succeeds.
|
||||||
|
Either a "direct links" block with <ul.party-list> or a
|
||||||
|
"no parties yet" fallback. -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>To customize the columns or schema for a specific party, drop
|
||||||
|
a <code>table.yaml</code> and <code>form.yaml</code> into
|
||||||
|
<code>archive/<party>/mdl/</code>. Operator-supplied
|
||||||
|
files override the embedded defaults entirely.</p>
|
||||||
|
</div><!-- /projectView -->
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Help Panel -->
|
<!-- Help Panel -->
|
||||||
|
|
@ -2707,9 +2892,163 @@ body {
|
||||||
catch (e) { /* private mode / quota */ }
|
catch (e) { /* private mode / quota */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Project mode ─────────────────────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// The same landing tool serves at /<project> as the project-workspace
|
||||||
|
// page. Mode is determined from location.pathname:
|
||||||
|
//
|
||||||
|
// / → 'picker' (existing behavior)
|
||||||
|
// /<single-segment> → 'project'
|
||||||
|
// /index.html → 'picker' (file:// + standalone-served root)
|
||||||
|
// anything else → 'picker' (best-effort fallback)
|
||||||
|
//
|
||||||
|
// Project mode shows the four canonical lifecycle-stage cards, a
|
||||||
|
// "browse all files" link, and a Master Deliverables List section
|
||||||
|
// with direct links to any parties currently in archive/. The party
|
||||||
|
// list is fetched from <project>/<archive>/?json=1; failures fall
|
||||||
|
// back to the static "no parties yet" copy.
|
||||||
|
|
||||||
|
function detectMode() {
|
||||||
|
if (typeof location === 'undefined') return 'picker';
|
||||||
|
var path = location.pathname || '/';
|
||||||
|
// Strip any trailing /index.html so the deployment-root case
|
||||||
|
// matches even on file:// or behind some servers.
|
||||||
|
var trimmed = path.replace(/\/index\.html$/, '/');
|
||||||
|
if (trimmed === '' || trimmed === '/') return 'picker';
|
||||||
|
// Single non-slash, non-dot segment → project root.
|
||||||
|
var parts = trimmed.split('/').filter(Boolean);
|
||||||
|
if (parts.length === 1 && parts[0].indexOf('.') === -1) {
|
||||||
|
return 'project';
|
||||||
|
}
|
||||||
|
return 'picker';
|
||||||
|
}
|
||||||
|
|
||||||
|
function projectFromPath() {
|
||||||
|
var parts = (location.pathname || '/').split('/').filter(Boolean);
|
||||||
|
return parts[0] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the project-workspace view: title, four stage links, MDL
|
||||||
|
// section. Stage hrefs use the no-trailing-slash form so the server
|
||||||
|
// routes them to each canonical default tool (mdedit for working/,
|
||||||
|
// transmittal for staging/, etc.). Browse-all and the archive deep
|
||||||
|
// link use the slash form to land on the directory listing.
|
||||||
|
async function renderProjectMode() {
|
||||||
|
var project = projectFromPath();
|
||||||
|
if (!project) return;
|
||||||
|
|
||||||
|
// Hide picker, show project view.
|
||||||
|
var picker = document.getElementById('pickerView');
|
||||||
|
var projectView = document.getElementById('projectView');
|
||||||
|
if (picker) picker.classList.add('hidden');
|
||||||
|
if (projectView) projectView.classList.remove('hidden');
|
||||||
|
|
||||||
|
document.title = project + ' — ZDDC';
|
||||||
|
var titleEl = document.getElementById('projectName');
|
||||||
|
if (titleEl) titleEl.textContent = project;
|
||||||
|
|
||||||
|
var p = encodeURIComponent(project);
|
||||||
|
var stages = [
|
||||||
|
{ id: 'stageArchive', href: '/' + p + '/archive' },
|
||||||
|
{ id: 'stageWorking', href: '/' + p + '/working' },
|
||||||
|
{ id: 'stageStaging', href: '/' + p + '/staging' },
|
||||||
|
{ id: 'stageReviewing', href: '/' + p + '/reviewing' },
|
||||||
|
];
|
||||||
|
for (var i = 0; i < stages.length; i++) {
|
||||||
|
var a = document.getElementById(stages[i].id);
|
||||||
|
if (a) a.setAttribute('href', stages[i].href);
|
||||||
|
}
|
||||||
|
|
||||||
|
var browseAll = document.getElementById('browseAllLink');
|
||||||
|
if (browseAll) {
|
||||||
|
browseAll.setAttribute('href', '/' + p + '/');
|
||||||
|
browseAll.textContent = 'Browse all files →';
|
||||||
|
}
|
||||||
|
var archiveBrowse = document.getElementById('archiveBrowseLink');
|
||||||
|
if (archiveBrowse) {
|
||||||
|
archiveBrowse.setAttribute('href', '/' + p + '/archive/');
|
||||||
|
archiveBrowse.innerHTML = '<code>/' + escapeHtml(project) + '/archive/</code>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch party list. Best-effort — failures render the
|
||||||
|
// no-parties-yet fallback. We try /<project>/archive/ — the
|
||||||
|
// server returns the listing in either lowercase or PascalCase
|
||||||
|
// form; either yields the same JSON shape via case-insensitive
|
||||||
|
// URL canonicalization.
|
||||||
|
var partySection = document.getElementById('partyListSection');
|
||||||
|
if (!partySection) return;
|
||||||
|
|
||||||
|
var parties = await fetchParties(p);
|
||||||
|
if (parties == null) {
|
||||||
|
// Network error or unauthenticated — show neither list nor
|
||||||
|
// explicit "none" message. The page is still usable.
|
||||||
|
partySection.innerHTML = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (parties.length === 0) {
|
||||||
|
partySection.innerHTML =
|
||||||
|
'<p class="party-list-none-yet">No party folders yet. The MDL view auto-renders at any '
|
||||||
|
+ '<code>archive/<party>/mdl/</code> URL, even when the folder doesn\'t exist on '
|
||||||
|
+ 'disk — so you can start editing an MDL before any transmittals have been exchanged.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var html = '<p><strong>Direct links — parties currently in <code>archive/</code>:</strong></p>'
|
||||||
|
+ '<ul class="party-list">';
|
||||||
|
for (var j = 0; j < parties.length; j++) {
|
||||||
|
var name = parties[j].name;
|
||||||
|
var url = parties[j].url; // server-provided absolute URL
|
||||||
|
html += '<li><a href="' + url + 'mdl/">' + escapeHtml(name) + ' MDL →</a></li>';
|
||||||
|
}
|
||||||
|
html += '</ul>';
|
||||||
|
partySection.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns an array of {name, url} for each party folder in the
|
||||||
|
// project's archive/, sorted by name. Returns null if the listing
|
||||||
|
// can't be fetched (offline, 4xx, or non-JSON response). Returns
|
||||||
|
// [] if the listing succeeds but archive/ is empty / has no
|
||||||
|
// visible party folders.
|
||||||
|
async function fetchParties(projectURL) {
|
||||||
|
try {
|
||||||
|
var resp = await fetch('/' + projectURL + '/archive/', {
|
||||||
|
headers: { 'Accept': 'application/json' },
|
||||||
|
cache: 'no-cache',
|
||||||
|
credentials: 'same-origin'
|
||||||
|
});
|
||||||
|
if (!resp.ok) return null;
|
||||||
|
var ctype = resp.headers.get('Content-Type') || '';
|
||||||
|
if (!ctype.toLowerCase().includes('json')) return null;
|
||||||
|
var data = await resp.json();
|
||||||
|
if (!Array.isArray(data)) return null;
|
||||||
|
// Server emits directories with trailing "/" on the name.
|
||||||
|
// Filter to dirs only, strip the slash for display.
|
||||||
|
var out = [];
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
var e = data[i];
|
||||||
|
if (!e.is_dir) continue;
|
||||||
|
var nm = String(e.name || '').replace(/\/$/, '');
|
||||||
|
if (!nm) continue;
|
||||||
|
if (nm.charAt(0) === '.' || nm.charAt(0) === '_') continue;
|
||||||
|
out.push({ name: nm, url: e.url || ('/' + projectURL + '/archive/' + encodeURIComponent(nm) + '/') });
|
||||||
|
}
|
||||||
|
out.sort(function (a, b) { return a.name < b.name ? -1 : a.name > b.name ? 1 : 0; });
|
||||||
|
return out;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Bootstrap ────────────────────────────────────────────────────────────
|
// ── Bootstrap ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
|
if (detectMode() === 'project') {
|
||||||
|
await renderProjectMode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await initPicker();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initPicker() {
|
||||||
loadGroups();
|
loadGroups();
|
||||||
urlRestore();
|
urlRestore();
|
||||||
|
|
||||||
|
|
@ -2764,6 +3103,9 @@ body {
|
||||||
saveGroup: saveGroup,
|
saveGroup: saveGroup,
|
||||||
openSelectedVisible: openSelectedVisible,
|
openSelectedVisible: openSelectedVisible,
|
||||||
dismissWarning: dismissWarning,
|
dismissWarning: dismissWarning,
|
||||||
|
// Project-mode entry points (also tested directly).
|
||||||
|
detectMode: detectMode,
|
||||||
|
renderProjectMode: renderProjectMode,
|
||||||
// Test-only: override the navigation function (avoids the messy
|
// Test-only: override the navigation function (avoids the messy
|
||||||
// browser-locked-down state of window.location).
|
// browser-locked-down state of window.location).
|
||||||
_setNavigate: function(fn) { navigate = fn; }
|
_setNavigate: function(fn) { navigate = fn; }
|
||||||
|
|
|
||||||
|
|
@ -1925,7 +1925,7 @@ body.help-open .app-header {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title">ZDDC Markdown</span>
|
<span class="app-header__title">ZDDC Markdown</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
<button id="addDirectoryBtn" class="btn btn-primary" title="Add a local directory">Add Local 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">⟳</button>
|
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh directory" aria-label="Refresh">⟳</button>
|
||||||
|
|
|
||||||
|
|
@ -2285,7 +2285,7 @@ dialog.modal--narrow {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title">ZDDC Transmittal</span>
|
<span class="app-header__title">ZDDC Transmittal</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
|
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
|
||||||
<!-- Publish split-button (Transmittal-specific primary action;
|
<!-- Publish split-button (Transmittal-specific primary action;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
# Generated by build.sh — do not edit. One <app>=<build label> per line.
|
# Generated by build.sh — do not edit. One <app>=<build label> per line.
|
||||||
archive=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
archive=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
transmittal=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
transmittal=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
classifier=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
classifier=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
mdedit=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
mdedit=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
landing=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
landing=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
form=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
form=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
tables=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
tables=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
browse=v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal
|
browse=v0.0.17-beta · 2026-05-10 · log-citrus-hazel
|
||||||
|
|
|
||||||
|
|
@ -1092,7 +1092,7 @@ body.help-open .app-header {
|
||||||
</svg>
|
</svg>
|
||||||
<div class="header-title-group">
|
<div class="header-title-group">
|
||||||
<span class="app-header__title" id="table-title">ZDDC Table</span>
|
<span class="app-header__title" id="table-title">ZDDC Table</span>
|
||||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · iron-ribbon-crystal</span></span>
|
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · log-citrus-hazel</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue