@unbrained/pm-web 2026.8.10 → 2026.8.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/app.d.ts +16 -0
- package/dist/app.js +16 -0
- package/dist/app.js.map +1 -1
- package/dist/auth.d.ts +5 -0
- package/dist/auth.js.map +1 -1
- package/dist/board.d.ts +53 -0
- package/dist/board.js +48 -0
- package/dist/board.js.map +1 -1
- package/dist/crypto.d.ts +23 -0
- package/dist/crypto.js +32 -0
- package/dist/crypto.js.map +1 -1
- package/dist/db.d.ts +19 -0
- package/dist/db.js +19 -0
- package/dist/db.js.map +1 -1
- package/dist/ical.d.ts +72 -0
- package/dist/ical.js +73 -0
- package/dist/ical.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.js +52 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/auth.d.ts +8 -0
- package/dist/middleware/auth.js.map +1 -1
- package/dist/oidc.d.ts +87 -0
- package/dist/oidc.js +113 -0
- package/dist/oidc.js.map +1 -1
- package/dist/routes/admin.js +15 -0
- package/dist/routes/admin.js.map +1 -1
- package/dist/routes/extensions.js +10 -0
- package/dist/routes/extensions.js.map +1 -1
- package/dist/routes/github.js +13 -0
- package/dist/routes/github.js.map +1 -1
- package/dist/routes/oidc.d.ts +10 -0
- package/dist/routes/oidc.js +51 -0
- package/dist/routes/oidc.js.map +1 -1
- package/dist/routes/pm.js +132 -1
- package/dist/routes/pm.js.map +1 -1
- package/dist/routes/sharing.js +8 -0
- package/dist/routes/sharing.js.map +1 -1
- package/dist/services/mutation-event-watcher.js +13 -0
- package/dist/services/mutation-event-watcher.js.map +1 -1
- package/dist/services/package-catalog.d.ts +24 -0
- package/dist/services/package-catalog.js +22 -2
- package/dist/services/package-catalog.js.map +1 -1
- package/dist/services/pm-runner.d.ts +82 -0
- package/dist/services/pm-runner.js +121 -0
- package/dist/services/pm-runner.js.map +1 -1
- package/dist/services/project-watcher.d.ts +22 -0
- package/dist/services/project-watcher.js +51 -0
- package/dist/services/project-watcher.js.map +1 -1
- package/dist/services/realtime-bus.d.ts +46 -0
- package/dist/services/realtime-bus.js +59 -0
- package/dist/services/realtime-bus.js.map +1 -1
- package/dist/services/sse.d.ts +134 -0
- package/dist/services/sse.js +145 -0
- package/dist/services/sse.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +5 -3
- package/public/src/app.js +44 -1
- package/public/src/app.js.map +1 -1
- package/public/src/app.ts +44 -1
- package/public/src/components/modals.js +11 -0
- package/public/src/components/modals.js.map +1 -1
- package/public/src/components/modals.ts +11 -0
- package/public/src/components/toast.js +2 -0
- package/public/src/components/toast.js.map +1 -1
- package/public/src/components/toast.ts +2 -0
- package/public/src/constants.js +21 -4
- package/public/src/constants.js.map +1 -1
- package/public/src/constants.ts +21 -4
- package/public/src/filters.js +10 -7
- package/public/src/filters.js.map +1 -1
- package/public/src/filters.ts +10 -7
- package/public/src/i18n/de.json +3 -1
- package/public/src/i18n/en.json +3 -1
- package/public/src/i18n/es.json +3 -1
- package/public/src/i18n/zh.json +3 -1
- package/public/src/i18n.js +11 -1
- package/public/src/i18n.js.map +1 -1
- package/public/src/i18n.ts +13 -1
- package/public/src/state.js +3 -0
- package/public/src/state.js.map +1 -1
- package/public/src/state.ts +3 -0
- package/public/src/sw.ts +71 -7
- package/public/src/theme.js +13 -1
- package/public/src/theme.js.map +1 -1
- package/public/src/theme.ts +15 -1
- package/public/src/types.ts +2 -0
- package/public/src/utils.js +26 -1
- package/public/src/utils.js.map +1 -1
- package/public/src/utils.ts +26 -1
- package/public/src/views/activity.js +1 -0
- package/public/src/views/activity.js.map +1 -1
- package/public/src/views/activity.ts +1 -0
- package/public/src/views/admin.js +134 -0
- package/public/src/views/admin.js.map +1 -1
- package/public/src/views/admin.ts +134 -0
- package/public/src/views/auth.js +31 -0
- package/public/src/views/auth.js.map +1 -1
- package/public/src/views/auth.ts +31 -0
- package/public/src/views/calendar.js +3 -0
- package/public/src/views/calendar.js.map +1 -1
- package/public/src/views/calendar.ts +3 -0
- package/public/src/views/comments-audit.js +1 -0
- package/public/src/views/comments-audit.js.map +1 -1
- package/public/src/views/comments-audit.ts +1 -0
- package/public/src/views/config.js +67 -0
- package/public/src/views/config.js.map +1 -1
- package/public/src/views/config.ts +67 -0
- package/public/src/views/context.js +2 -0
- package/public/src/views/context.js.map +1 -1
- package/public/src/views/context.ts +2 -0
- package/public/src/views/create.js +3 -0
- package/public/src/views/create.js.map +1 -1
- package/public/src/views/create.ts +3 -0
- package/public/src/views/dedupe.js +1 -0
- package/public/src/views/dedupe.js.map +1 -1
- package/public/src/views/dedupe.ts +1 -0
- package/public/src/views/export.js +6 -0
- package/public/src/views/export.js.map +1 -1
- package/public/src/views/export.ts +6 -0
- package/public/src/views/github.js +58 -0
- package/public/src/views/github.js.map +1 -1
- package/public/src/views/github.ts +58 -0
- package/public/src/views/graph-canvas.js +18 -0
- package/public/src/views/graph-canvas.js.map +1 -1
- package/public/src/views/graph-canvas.ts +20 -0
- package/public/src/views/graph.js +41 -0
- package/public/src/views/graph.js.map +1 -1
- package/public/src/views/graph.ts +42 -1
- package/public/src/views/groups.js +45 -0
- package/public/src/views/groups.js.map +1 -1
- package/public/src/views/groups.ts +45 -0
- package/public/src/views/guide.js +3 -0
- package/public/src/views/guide.js.map +1 -1
- package/public/src/views/guide.ts +3 -0
- package/public/src/views/health.js +3 -0
- package/public/src/views/health.js.map +1 -1
- package/public/src/views/health.ts +3 -0
- package/public/src/views/items.js +196 -6
- package/public/src/views/items.js.map +1 -1
- package/public/src/views/items.ts +196 -6
- package/public/src/views/normalize.js +2 -0
- package/public/src/views/normalize.js.map +1 -1
- package/public/src/views/normalize.ts +2 -0
- package/public/src/views/packages.js +67 -5
- package/public/src/views/packages.js.map +1 -1
- package/public/src/views/packages.ts +74 -5
- package/public/src/views/plan-execution.js +6 -0
- package/public/src/views/plan-execution.js.map +1 -1
- package/public/src/views/plan-execution.ts +8 -0
- package/public/src/views/plan.js +145 -0
- package/public/src/views/plan.js.map +1 -1
- package/public/src/views/plan.ts +146 -1
- package/public/src/views/projects.js +60 -0
- package/public/src/views/projects.js.map +1 -1
- package/public/src/views/projects.ts +60 -0
- package/public/src/views/router.js +43 -0
- package/public/src/views/router.js.map +1 -1
- package/public/src/views/router.ts +43 -0
- package/public/src/views/search.js +5 -0
- package/public/src/views/search.js.map +1 -1
- package/public/src/views/search.ts +5 -0
- package/public/src/views/settings.js +36 -0
- package/public/src/views/settings.js.map +1 -1
- package/public/src/views/settings.ts +36 -0
- package/public/src/views/shared.js +1 -0
- package/public/src/views/shared.js.map +1 -1
- package/public/src/views/shared.ts +1 -0
- package/public/src/views/sharing.js +32 -0
- package/public/src/views/sharing.js.map +1 -1
- package/public/src/views/sharing.ts +32 -0
- package/public/src/views/stats.js +1 -0
- package/public/src/views/stats.js.map +1 -1
- package/public/src/views/stats.ts +1 -0
- package/public/src/views/templates.js +4 -0
- package/public/src/views/templates.js.map +1 -1
- package/public/src/views/templates.ts +4 -0
- package/public/src/views/validate.js +1 -0
- package/public/src/views/validate.js.map +1 -1
- package/public/src/views/validate.ts +1 -0
- package/public/sw.js +60 -5
package/public/src/app.ts
CHANGED
|
@@ -15,7 +15,8 @@ import { renderCalendarView, calNav, showDayItems } from './views/calendar.js';
|
|
|
15
15
|
import { renderContextView } from './views/context.js';
|
|
16
16
|
import { renderGraphView } from './views/graph.js';
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
/** Switch to the graph view, wait for it to mount, render it, then focus the
|
|
19
|
+
* node with the given id by invoking the graph view's select-node hook. */
|
|
19
20
|
async function openGraphAt(nodeId: string): Promise<void> {
|
|
20
21
|
showView('graph');
|
|
21
22
|
// Give the graph view time to mount, then set selected node
|
|
@@ -56,6 +57,9 @@ initTheme();
|
|
|
56
57
|
// Global search modal
|
|
57
58
|
let globalSearchTimer: ReturnType<typeof setTimeout>;
|
|
58
59
|
|
|
60
|
+
/** Build (without showing) the global-search modal: a search input wired to
|
|
61
|
+
* the debounced search handler and a results container with an initial
|
|
62
|
+
* prompt. */
|
|
59
63
|
function buildSearchModal(): void {
|
|
60
64
|
createModal('global-search-modal','Search',`
|
|
61
65
|
<div class="search-box-wrap" style="margin-bottom:12px">
|
|
@@ -124,6 +128,9 @@ const mobileCommandGroups: Array<{ title: string; commands: MobileCommand[] }> =
|
|
|
124
128
|
},
|
|
125
129
|
];
|
|
126
130
|
|
|
131
|
+
/** Build (without showing) the mobile command-sheet modal listing every
|
|
132
|
+
* navigation command grouped by section, disabling project-scoped commands
|
|
133
|
+
* when no project is selected and hiding the admin command for non-admins. */
|
|
127
134
|
function buildMobileCommandSheet(): void {
|
|
128
135
|
const hasProject = !!state.currentProject;
|
|
129
136
|
const projectName = state.currentProject?.name || 'No project selected';
|
|
@@ -177,6 +184,9 @@ function globalSearchDebounced(): void {
|
|
|
177
184
|
globalSearchTimer = setTimeout(doGlobalSearch, 300);
|
|
178
185
|
}
|
|
179
186
|
|
|
187
|
+
/** Read the global-search input, POST the query to the project search
|
|
188
|
+
* endpoint, and render matching items into the results pane (or an
|
|
189
|
+
* empty/error state). No-op when the query or current project is missing. */
|
|
180
190
|
async function doGlobalSearch(): Promise<void> {
|
|
181
191
|
const query = (document.getElementById('global-search-input') as HTMLInputElement | null)?.value?.trim();
|
|
182
192
|
if (!query || !state.currentProject) return;
|
|
@@ -453,6 +463,8 @@ interface PresenceUser {
|
|
|
453
463
|
connectedAt: string;
|
|
454
464
|
}
|
|
455
465
|
|
|
466
|
+
/** Derive up to two uppercase initials from a display name by splitting on
|
|
467
|
+
* common delimiters and taking the first character of the leading tokens. */
|
|
456
468
|
function userInitials(displayName: string): string {
|
|
457
469
|
return displayName
|
|
458
470
|
.split(/[\s@._-]+/)
|
|
@@ -462,6 +474,9 @@ function userInitials(displayName: string): string {
|
|
|
462
474
|
.join('');
|
|
463
475
|
}
|
|
464
476
|
|
|
477
|
+
/** Render the presence bar showing up to five other currently-viewing users
|
|
478
|
+
* as colored initial chips (plus an overflow count), or hide the bar when only
|
|
479
|
+
* the current user is present. */
|
|
465
480
|
function renderPresenceBar(users: PresenceUser[]): void {
|
|
466
481
|
const bar = document.getElementById('presence-bar');
|
|
467
482
|
if (!bar) return;
|
|
@@ -493,6 +508,9 @@ function renderPresenceBar(users: PresenceUser[]): void {
|
|
|
493
508
|
bar.innerHTML = `<span class="presence-label">Viewing:</span>${chips}${extraChip}`;
|
|
494
509
|
}
|
|
495
510
|
|
|
511
|
+
/** Update the real-time-sync indicator element to reflect `connected`,
|
|
512
|
+
* `reconnecting`, or `disconnected` state, and clear the presence bar on
|
|
513
|
+
* disconnect. */
|
|
496
514
|
function setSseStatus(status: 'connected' | 'disconnected' | 'reconnecting'): void {
|
|
497
515
|
const el = document.getElementById('sse-indicator');
|
|
498
516
|
if (!el) return;
|
|
@@ -511,6 +529,9 @@ function setSseStatus(status: 'connected' | 'disconnected' | 'reconnecting'): vo
|
|
|
511
529
|
}
|
|
512
530
|
}
|
|
513
531
|
|
|
532
|
+
/** Tear down the current SSE connection: cancel pending reconnect and refresh
|
|
533
|
+
* timers, close the event source, clear the tracked project/client ids, and
|
|
534
|
+
* mark sync as disconnected. */
|
|
514
535
|
function disconnectSSE(): void {
|
|
515
536
|
if (sseReconnectTimer) { clearTimeout(sseReconnectTimer); sseReconnectTimer = null; }
|
|
516
537
|
if (sseRefreshTimer) { clearTimeout(sseRefreshTimer); sseRefreshTimer = null; }
|
|
@@ -520,6 +541,9 @@ function disconnectSSE(): void {
|
|
|
520
541
|
setSseStatus('disconnected');
|
|
521
542
|
}
|
|
522
543
|
|
|
544
|
+
/** Fire-and-forget PATCH to the server updating which view the current client
|
|
545
|
+
* is looking at, so other users see accurate presence. No-op when not
|
|
546
|
+
* connected. */
|
|
523
547
|
function notifyPresenceView(view: string): void {
|
|
524
548
|
if (!sseClientId || !sseCurrentProjectId) return;
|
|
525
549
|
// Fire-and-forget: update current view on server
|
|
@@ -530,6 +554,10 @@ function notifyPresenceView(view: string): void {
|
|
|
530
554
|
}).catch(() => undefined);
|
|
531
555
|
}
|
|
532
556
|
|
|
557
|
+
/** Open an SSE stream for the given project (reusing an existing connection
|
|
558
|
+
* when already live), wire handlers for connection, presence, item, graph,
|
|
559
|
+
* and package events that refresh the active view, and reconnect with
|
|
560
|
+
* exponential backoff on error. */
|
|
533
561
|
function connectSSE(projectId: string, attempt = 0): void {
|
|
534
562
|
if (sseCurrentProjectId === projectId && sseSource && sseSource.readyState !== EventSource.CLOSED) return;
|
|
535
563
|
disconnectSSE();
|
|
@@ -674,6 +702,9 @@ export { connectSSE, disconnectSSE, notifyPresenceView };
|
|
|
674
702
|
// ═══════════════════════════════════════════════════════════════
|
|
675
703
|
// BOOT
|
|
676
704
|
// ═══════════════════════════════════════════════════════════════
|
|
705
|
+
/** Reveal the main app shell, populate the signed-in user's avatar/name and
|
|
706
|
+
* admin-gated controls, build the project/search/mobile modals, register the
|
|
707
|
+
* presence view-change hook, then load projects and run the launch action. */
|
|
677
708
|
export async function bootApp(): Promise<void> {
|
|
678
709
|
const authScreen = document.getElementById('auth-screen');
|
|
679
710
|
const mainApp = document.getElementById('main-app');
|
|
@@ -701,6 +732,9 @@ export async function bootApp(): Promise<void> {
|
|
|
701
732
|
await handleLaunchAction();
|
|
702
733
|
}
|
|
703
734
|
|
|
735
|
+
/** Act on the `?action=` query param or URL path to deep-link into a view
|
|
736
|
+
* (new-project, new-item, search, or a restored bookmarked view), selecting a
|
|
737
|
+
* default project and showing toasts when a required project is missing. */
|
|
704
738
|
async function handleLaunchAction(): Promise<void> {
|
|
705
739
|
const action = new URLSearchParams(window.location.search).get('action');
|
|
706
740
|
|
|
@@ -756,6 +790,9 @@ async function handleLaunchAction(): Promise<void> {
|
|
|
756
790
|
// ═══════════════════════════════════════════════════════════════
|
|
757
791
|
// GLOBAL ERROR BOUNDARY
|
|
758
792
|
// ═══════════════════════════════════════════════════════════════
|
|
793
|
+
/** Replace the app shell with a full-screen error screen showing the message
|
|
794
|
+
* and (when available) a collapsible stack trace, with reload, login, and
|
|
795
|
+
* copy-details actions. Hides the auth and main screens. */
|
|
759
796
|
function showGlobalError(errorMsg: string, error?: unknown): void {
|
|
760
797
|
const appEl = document.getElementById('app');
|
|
761
798
|
if (!appEl) return;
|
|
@@ -817,6 +854,8 @@ window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent) =>
|
|
|
817
854
|
// Apply the persisted locale + catalog BEFORE the auth screen or main app
|
|
818
855
|
// is shown so package-owned strings render in the right language on first
|
|
819
856
|
// paint (after the inline <html lang> hint in index.html).
|
|
857
|
+
/** Entry point: initialize i18n, probe the session via `/auth/me`, and either
|
|
858
|
+
* boot the app on success or show the auth screen on failure. */
|
|
820
859
|
async function init(): Promise<void> {
|
|
821
860
|
await initI18n();
|
|
822
861
|
try {
|
|
@@ -842,6 +881,8 @@ async function changeLanguage(locale: string): Promise<void> {
|
|
|
842
881
|
let lastKeyTime = 0;
|
|
843
882
|
let lastKey = '';
|
|
844
883
|
|
|
884
|
+
/** Build and show the keyboard-shortcuts reference modal as a two-column
|
|
885
|
+
* key/description table. */
|
|
845
886
|
function openShortcutsHelp(): void {
|
|
846
887
|
createModal('shortcuts-help-modal', 'Keyboard Shortcuts', `
|
|
847
888
|
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
|
@@ -938,6 +979,8 @@ window.dismissInstallBanner = function(): void {
|
|
|
938
979
|
// ═══════════════════════════════════════════════════════════════
|
|
939
980
|
// OFFLINE / ONLINE STATUS BANNER
|
|
940
981
|
// ═══════════════════════════════════════════════════════════════
|
|
982
|
+
/** Toggle the offline status banner's visibility to match the browser's
|
|
983
|
+
* current connectivity (`navigator.onLine`). */
|
|
941
984
|
function updateOfflineBanner(): void {
|
|
942
985
|
const banner = document.getElementById('offline-banner');
|
|
943
986
|
if (!banner) return;
|
|
@@ -2,21 +2,28 @@
|
|
|
2
2
|
// MODALS
|
|
3
3
|
// ═══════════════════════════════════════════════════════════════
|
|
4
4
|
import { escHtml } from '../utils.js';
|
|
5
|
+
/** Display the modal with the given id by setting its display style to flex. */
|
|
5
6
|
export function showModal(id) {
|
|
6
7
|
const modal = document.getElementById(id);
|
|
7
8
|
if (modal)
|
|
8
9
|
modal.style.display = 'flex';
|
|
9
10
|
}
|
|
11
|
+
/** Hide the modal with the given id by setting its display style to none. */
|
|
10
12
|
export function hideModal(id) {
|
|
11
13
|
const modal = document.getElementById(id);
|
|
12
14
|
if (modal)
|
|
13
15
|
modal.style.display = 'none';
|
|
14
16
|
}
|
|
17
|
+
/** Hide every modal backdrop element in the document by setting each to
|
|
18
|
+
* display none. */
|
|
15
19
|
export function closeAllModals() {
|
|
16
20
|
document.querySelectorAll('.modal-backdrop').forEach(m => {
|
|
17
21
|
m.style.display = 'none';
|
|
18
22
|
});
|
|
19
23
|
}
|
|
24
|
+
/** Build (or rebuild) a modal element with the given id, title, body, and
|
|
25
|
+
* optional footer markup, append it under `#modal-container`, and wire its
|
|
26
|
+
* backdrop-click-to-close behavior. Returns the created modal element. */
|
|
20
27
|
export function createModal(id, title, bodyHtml, footerHtml, wide = false) {
|
|
21
28
|
let existing = document.getElementById(id);
|
|
22
29
|
if (existing)
|
|
@@ -41,6 +48,10 @@ export function createModal(id, title, bodyHtml, footerHtml, wide = false) {
|
|
|
41
48
|
container.appendChild(el);
|
|
42
49
|
return el;
|
|
43
50
|
}
|
|
51
|
+
/** Open a confirmation modal with a title and description; when the user
|
|
52
|
+
* clicks the confirm button the modal closes and `onConfirm` runs. The
|
|
53
|
+
* `danger` flag switches the styling and default labels to a destructive
|
|
54
|
+
* action, and `labels` overrides the button text. */
|
|
44
55
|
export function confirmDialog(title, desc, onConfirm, danger = false, labels) {
|
|
45
56
|
const id = 'confirm-dialog-' + Date.now();
|
|
46
57
|
const cancelLabel = labels?.cancel ?? 'Cancel';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modals.js","sourceRoot":"","sources":["modals.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"modals.js","sourceRoot":"","sources":["modals.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,22 +3,29 @@
|
|
|
3
3
|
// ═══════════════════════════════════════════════════════════════
|
|
4
4
|
import { escHtml } from '../utils.js';
|
|
5
5
|
|
|
6
|
+
/** Display the modal with the given id by setting its display style to flex. */
|
|
6
7
|
export function showModal(id: string): void {
|
|
7
8
|
const modal = document.getElementById(id);
|
|
8
9
|
if (modal) modal.style.display = 'flex';
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
/** Hide the modal with the given id by setting its display style to none. */
|
|
11
13
|
export function hideModal(id: string): void {
|
|
12
14
|
const modal = document.getElementById(id);
|
|
13
15
|
if (modal) modal.style.display = 'none';
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
/** Hide every modal backdrop element in the document by setting each to
|
|
19
|
+
* display none. */
|
|
16
20
|
export function closeAllModals(): void {
|
|
17
21
|
document.querySelectorAll('.modal-backdrop').forEach(m => {
|
|
18
22
|
(m as HTMLElement).style.display = 'none';
|
|
19
23
|
});
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
/** Build (or rebuild) a modal element with the given id, title, body, and
|
|
27
|
+
* optional footer markup, append it under `#modal-container`, and wire its
|
|
28
|
+
* backdrop-click-to-close behavior. Returns the created modal element. */
|
|
22
29
|
export function createModal(
|
|
23
30
|
id: string,
|
|
24
31
|
title: string,
|
|
@@ -47,6 +54,10 @@ export function createModal(
|
|
|
47
54
|
return el;
|
|
48
55
|
}
|
|
49
56
|
|
|
57
|
+
/** Open a confirmation modal with a title and description; when the user
|
|
58
|
+
* clicks the confirm button the modal closes and `onConfirm` runs. The
|
|
59
|
+
* `danger` flag switches the styling and default labels to a destructive
|
|
60
|
+
* action, and `labels` overrides the button text. */
|
|
50
61
|
export function confirmDialog(
|
|
51
62
|
title: string,
|
|
52
63
|
desc: string,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.js","sourceRoot":"","sources":["toast.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,IAAI,GAAc,MAAM;IACzD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,EAAE,CAAC,SAAS,GAAG,eAAe,IAAI,EAAE,CAAC;IACrC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IACrB,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC7D,IAAI,SAAS;QAAE,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACzC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
|
|
1
|
+
{"version":3,"file":"toast.js","sourceRoot":"","sources":["toast.ts"],"names":[],"mappings":"AAKA;wDACwD;AACxD,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,IAAI,GAAc,MAAM;IACzD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,EAAE,CAAC,SAAS,GAAG,eAAe,IAAI,EAAE,CAAC;IACrC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IACrB,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC7D,IAAI,SAAS;QAAE,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACzC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// ═══════════════════════════════════════════════════════════════
|
|
4
4
|
import type { ToastType } from '../types.js';
|
|
5
5
|
|
|
6
|
+
/** Show a transient toast notification of the given type, appending it to the
|
|
7
|
+
* toast container and removing it after 3.5 seconds. */
|
|
6
8
|
export function toast(msg: string, type: ToastType = 'info'): void {
|
|
7
9
|
const el = document.createElement('div');
|
|
8
10
|
el.className = `toast toast-${type}`;
|
package/public/src/constants.js
CHANGED
|
@@ -1,26 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/** Item-type names kept in sync with the pm CLI builtins, used as the
|
|
2
|
+
* offline fallback when the live project schema is unavailable. Prefer
|
|
3
|
+
* `getTypes()` everywhere so the fetched schema wins when present. */
|
|
4
4
|
export const FALLBACK_TYPES = [
|
|
5
5
|
'Task', 'Feature', 'Issue', 'Epic', 'Milestone', 'Decision', 'Chore', 'Event', 'Meeting', 'Reminder', 'Plan'
|
|
6
6
|
];
|
|
7
|
+
/** Lifecycle status names kept in sync with the pm CLI builtins, used as the
|
|
8
|
+
* offline fallback when the live project schema is unavailable. Prefer
|
|
9
|
+
* `getStatuses()` everywhere so the fetched schema wins when present. */
|
|
7
10
|
export const FALLBACK_STATUSES = ['draft', 'open', 'in_progress', 'blocked', 'closed', 'canceled'];
|
|
8
|
-
|
|
11
|
+
/** Back-compat alias for `FALLBACK_TYPES`, retained to avoid a widespread
|
|
12
|
+
* refactor; new code should call `getTypes()` instead. */
|
|
9
13
|
export const TYPES = FALLBACK_TYPES;
|
|
14
|
+
/** Back-compat alias for `FALLBACK_STATUSES`, retained to avoid a widespread
|
|
15
|
+
* refactor; new code should call `getStatuses()` instead. */
|
|
10
16
|
export const STATUSES = FALLBACK_STATUSES;
|
|
17
|
+
/** Return the item types for a project, preferring the live `schema.types`
|
|
18
|
+
* when non-empty and falling back to the built-in `FALLBACK_TYPES`. */
|
|
11
19
|
export function getTypes(schema) {
|
|
12
20
|
return schema?.types?.length ? schema.types : [...FALLBACK_TYPES];
|
|
13
21
|
}
|
|
22
|
+
/** Return the lifecycle statuses for a project, preferring the live
|
|
23
|
+
* `schema.statuses` when non-empty and falling back to the built-in
|
|
24
|
+
* `FALLBACK_STATUSES`. */
|
|
14
25
|
export function getStatuses(schema) {
|
|
15
26
|
return schema?.statuses?.length ? schema.statuses : [...FALLBACK_STATUSES];
|
|
16
27
|
}
|
|
28
|
+
/** Map of item-type name to the single-character glyph shown in the UI for
|
|
29
|
+
* that type. */
|
|
17
30
|
export const TYPE_ICONS = {
|
|
18
31
|
Task: '✓', Feature: '★', Issue: '⚠', Epic: '◈',
|
|
19
32
|
Milestone: '⚑', Decision: '⚖', Chore: '⚙', Event: '◷', Meeting: '◉', Reminder: '◉', Plan: '◧'
|
|
20
33
|
};
|
|
34
|
+
/** Map of numeric priority (0–4) to its human-readable label, used for
|
|
35
|
+
* tooltips and accessibility text on priority indicators. */
|
|
21
36
|
export const PRIORITY_LABELS = {
|
|
22
37
|
0: 'Critical', 1: 'High', 2: 'Medium', 3: 'Low', 4: 'Minimal'
|
|
23
38
|
};
|
|
39
|
+
/** Fixed list of navigation view identifiers in display order; mirrors the
|
|
40
|
+
* routing keys accepted by the SPA router. */
|
|
24
41
|
export const VIEW_NAMES = [
|
|
25
42
|
'projects', 'items', 'create', 'activity', 'search', 'stats', 'calendar',
|
|
26
43
|
'context', 'graph', 'sharing', 'groups', 'health', 'dedupe', 'validate', 'settings',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["constants.ts"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["constants.ts"],"names":[],"mappings":"AAKA;;sEAEsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,EAAC,WAAW,EAAC,UAAU,EAAC,OAAO,EAAC,OAAO,EAAC,SAAS,EAAC,UAAU,EAAC,MAAM;CAC1F,CAAC;AAEX;;yEAEyE;AACzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAC,MAAM,EAAC,aAAa,EAAC,SAAS,EAAC,QAAQ,EAAC,UAAU,CAAU,CAAC;AAEvG;0DAC0D;AAC1D,MAAM,CAAC,MAAM,KAAK,GAAG,cAAc,CAAC;AACpC;6DAC6D;AAC7D,MAAM,CAAC,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAE1C;uEACuE;AACvE,MAAM,UAAU,QAAQ,CAAC,MAA6B;IACpD,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;AACpE,CAAC;AAED;;0BAE0B;AAC1B,MAAM,UAAU,WAAW,CAAC,MAA6B;IACvD,OAAO,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;AAC7E,CAAC;AAED;gBACgB;AAChB,MAAM,CAAC,MAAM,UAAU,GAA2B;IAChD,IAAI,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,IAAI,EAAC,GAAG;IAC1C,SAAS,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,EAAE,IAAI,EAAC,GAAG;CACvF,CAAC;AAEF;6DAC6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,CAAC,EAAC,UAAU,EAAE,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,QAAQ,EAAE,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,SAAS;CACzD,CAAC;AAEF;8CAC8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU,EAAC,OAAO,EAAC,QAAQ,EAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAC,UAAU;IAClE,SAAS,EAAC,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,EAAC,UAAU,EAAC,UAAU;IAC5E,QAAQ,EAAC,QAAQ,EAAC,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAC,UAAU,EAAC,gBAAgB,EAAC,QAAQ,EAAC,OAAO;IAC/F,OAAO,EAAC,MAAM;CACN,CAAC"}
|
package/public/src/constants.ts
CHANGED
|
@@ -3,36 +3,53 @@
|
|
|
3
3
|
// ═══════════════════════════════════════════════════════════════
|
|
4
4
|
import type { ProjectSchema } from './types.js';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
/** Item-type names kept in sync with the pm CLI builtins, used as the
|
|
7
|
+
* offline fallback when the live project schema is unavailable. Prefer
|
|
8
|
+
* `getTypes()` everywhere so the fetched schema wins when present. */
|
|
9
9
|
export const FALLBACK_TYPES = [
|
|
10
10
|
'Task','Feature','Issue','Epic','Milestone','Decision','Chore','Event','Meeting','Reminder','Plan'
|
|
11
11
|
] as const;
|
|
12
12
|
|
|
13
|
+
/** Lifecycle status names kept in sync with the pm CLI builtins, used as the
|
|
14
|
+
* offline fallback when the live project schema is unavailable. Prefer
|
|
15
|
+
* `getStatuses()` everywhere so the fetched schema wins when present. */
|
|
13
16
|
export const FALLBACK_STATUSES = ['draft','open','in_progress','blocked','closed','canceled'] as const;
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
/** Back-compat alias for `FALLBACK_TYPES`, retained to avoid a widespread
|
|
19
|
+
* refactor; new code should call `getTypes()` instead. */
|
|
16
20
|
export const TYPES = FALLBACK_TYPES;
|
|
21
|
+
/** Back-compat alias for `FALLBACK_STATUSES`, retained to avoid a widespread
|
|
22
|
+
* refactor; new code should call `getStatuses()` instead. */
|
|
17
23
|
export const STATUSES = FALLBACK_STATUSES;
|
|
18
24
|
|
|
25
|
+
/** Return the item types for a project, preferring the live `schema.types`
|
|
26
|
+
* when non-empty and falling back to the built-in `FALLBACK_TYPES`. */
|
|
19
27
|
export function getTypes(schema?: ProjectSchema | null): string[] {
|
|
20
28
|
return schema?.types?.length ? schema.types : [...FALLBACK_TYPES];
|
|
21
29
|
}
|
|
22
30
|
|
|
31
|
+
/** Return the lifecycle statuses for a project, preferring the live
|
|
32
|
+
* `schema.statuses` when non-empty and falling back to the built-in
|
|
33
|
+
* `FALLBACK_STATUSES`. */
|
|
23
34
|
export function getStatuses(schema?: ProjectSchema | null): string[] {
|
|
24
35
|
return schema?.statuses?.length ? schema.statuses : [...FALLBACK_STATUSES];
|
|
25
36
|
}
|
|
26
37
|
|
|
38
|
+
/** Map of item-type name to the single-character glyph shown in the UI for
|
|
39
|
+
* that type. */
|
|
27
40
|
export const TYPE_ICONS: Record<string, string> = {
|
|
28
41
|
Task:'✓', Feature:'★', Issue:'⚠', Epic:'◈',
|
|
29
42
|
Milestone:'⚑', Decision:'⚖', Chore:'⚙', Event:'◷', Meeting:'◉', Reminder:'◉', Plan:'◧'
|
|
30
43
|
};
|
|
31
44
|
|
|
45
|
+
/** Map of numeric priority (0–4) to its human-readable label, used for
|
|
46
|
+
* tooltips and accessibility text on priority indicators. */
|
|
32
47
|
export const PRIORITY_LABELS: Record<number, string> = {
|
|
33
48
|
0:'Critical', 1:'High', 2:'Medium', 3:'Low', 4:'Minimal'
|
|
34
49
|
};
|
|
35
50
|
|
|
51
|
+
/** Fixed list of navigation view identifiers in display order; mirrors the
|
|
52
|
+
* routing keys accepted by the SPA router. */
|
|
36
53
|
export const VIEW_NAMES = [
|
|
37
54
|
'projects','items','create','activity','search','stats','calendar',
|
|
38
55
|
'context','graph','sharing','groups','health','dedupe','validate','settings',
|
package/public/src/filters.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Item filter state with every dimension empty, used as the base value when
|
|
2
|
+
* resetting or parsing filters. */
|
|
1
3
|
export const EMPTY_FILTERS = {
|
|
2
4
|
status: '', type: '', priority: '', sprint: '', release: '', assignee: '', tag: '',
|
|
3
5
|
};
|
|
@@ -5,8 +7,8 @@ export const EMPTY_FILTERS = {
|
|
|
5
7
|
const FILTER_KEYS = [
|
|
6
8
|
'status', 'type', 'priority', 'sprint', 'release', 'assignee', 'tag',
|
|
7
9
|
];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
/** Serialize the active (non-empty) filter dimensions into a `URLSearchParams`
|
|
11
|
+
* in a stable key order, omitting empty values so generated URLs stay clean. */
|
|
10
12
|
export function filtersToSearchParams(f) {
|
|
11
13
|
const params = new URLSearchParams();
|
|
12
14
|
for (const key of FILTER_KEYS) {
|
|
@@ -16,13 +18,13 @@ export function filtersToSearchParams(f) {
|
|
|
16
18
|
}
|
|
17
19
|
return params;
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
/** Serialize filters to a URL query string without the leading `?`, returning
|
|
22
|
+
* an empty string when no dimensions are active. */
|
|
21
23
|
export function filtersToQueryString(f) {
|
|
22
24
|
return filtersToSearchParams(f).toString();
|
|
23
25
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
/** Parse filter dimensions back out of a `URLSearchParams` or query string,
|
|
27
|
+
* defaulting missing known keys to empty strings and ignoring unknown keys. */
|
|
26
28
|
export function filtersFromSearchParams(input) {
|
|
27
29
|
const params = typeof input === 'string' ? new URLSearchParams(input) : input;
|
|
28
30
|
const result = { ...EMPTY_FILTERS };
|
|
@@ -33,7 +35,8 @@ export function filtersFromSearchParams(input) {
|
|
|
33
35
|
}
|
|
34
36
|
return result;
|
|
35
37
|
}
|
|
36
|
-
|
|
38
|
+
/** Return true when at least one filter dimension has a non-empty trimmed
|
|
39
|
+
* value. */
|
|
37
40
|
export function hasActiveFilters(f) {
|
|
38
41
|
return FILTER_KEYS.some((key) => (f[key] ?? '').trim() !== '');
|
|
39
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filters.js","sourceRoot":"","sources":["filters.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;CACnF,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,GAA0B;IACzC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK;CACrE,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"filters.js","sourceRoot":"","sources":["filters.ts"],"names":[],"mappings":"AAUA;mCACmC;AACnC,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;CACnF,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,GAA0B;IACzC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK;CACrE,CAAC;AAEF;gFACgF;AAChF,MAAM,UAAU,qBAAqB,CAAC,CAAc;IAClD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;oDACoD;AACpD,MAAM,UAAU,oBAAoB,CAAC,CAAc;IACjD,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC7C,CAAC;AAED;+EAC+E;AAC/E,MAAM,UAAU,uBAAuB,CAAC,KAA+B;IACrE,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9E,MAAM,MAAM,GAAgB,EAAE,GAAG,aAAa,EAAE,CAAC;IACjD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;YACY;AACZ,MAAM,UAAU,gBAAgB,CAAC,CAAc;IAC7C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjE,CAAC"}
|
package/public/src/filters.ts
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
// free so they can be unit-tested without a DOM.
|
|
9
9
|
import type { ItemFilters } from './types.js';
|
|
10
10
|
|
|
11
|
+
/** Item filter state with every dimension empty, used as the base value when
|
|
12
|
+
* resetting or parsing filters. */
|
|
11
13
|
export const EMPTY_FILTERS: ItemFilters = {
|
|
12
14
|
status: '', type: '', priority: '', sprint: '', release: '', assignee: '', tag: '',
|
|
13
15
|
};
|
|
@@ -17,8 +19,8 @@ const FILTER_KEYS: (keyof ItemFilters)[] = [
|
|
|
17
19
|
'status', 'type', 'priority', 'sprint', 'release', 'assignee', 'tag',
|
|
18
20
|
];
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
/** Serialize the active (non-empty) filter dimensions into a `URLSearchParams`
|
|
23
|
+
* in a stable key order, omitting empty values so generated URLs stay clean. */
|
|
22
24
|
export function filtersToSearchParams(f: ItemFilters): URLSearchParams {
|
|
23
25
|
const params = new URLSearchParams();
|
|
24
26
|
for (const key of FILTER_KEYS) {
|
|
@@ -28,14 +30,14 @@ export function filtersToSearchParams(f: ItemFilters): URLSearchParams {
|
|
|
28
30
|
return params;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
/** Serialize filters to a URL query string without the leading `?`, returning
|
|
34
|
+
* an empty string when no dimensions are active. */
|
|
33
35
|
export function filtersToQueryString(f: ItemFilters): string {
|
|
34
36
|
return filtersToSearchParams(f).toString();
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
/** Parse filter dimensions back out of a `URLSearchParams` or query string,
|
|
40
|
+
* defaulting missing known keys to empty strings and ignoring unknown keys. */
|
|
39
41
|
export function filtersFromSearchParams(input: URLSearchParams | string): ItemFilters {
|
|
40
42
|
const params = typeof input === 'string' ? new URLSearchParams(input) : input;
|
|
41
43
|
const result: ItemFilters = { ...EMPTY_FILTERS };
|
|
@@ -46,7 +48,8 @@ export function filtersFromSearchParams(input: URLSearchParams | string): ItemFi
|
|
|
46
48
|
return result;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
/** Return true when at least one filter dimension has a non-empty trimmed
|
|
52
|
+
* value. */
|
|
50
53
|
export function hasActiveFilters(f: ItemFilters): boolean {
|
|
51
54
|
return FILTER_KEYS.some((key) => (f[key] ?? '').trim() !== '');
|
|
52
55
|
}
|
package/public/src/i18n/de.json
CHANGED
|
@@ -137,5 +137,7 @@
|
|
|
137
137
|
"packages.confirmUninstall": "{name} aus diesem Projekt deinstallieren?",
|
|
138
138
|
"packages.noProject": "Kein Projekt ausgewählt",
|
|
139
139
|
"packages.changedByOther": "Paket {name} von einem anderen Benutzer {operation}",
|
|
140
|
-
"packages.templateBadge": "Vorlage"
|
|
140
|
+
"packages.templateBadge": "Vorlage",
|
|
141
|
+
"packages.unreleasedBadge": "Noch nicht veröffentlicht",
|
|
142
|
+
"packages.unreleased": "Dieses Paket wird offen entwickelt, ist aber noch nicht auf npm veröffentlicht und kann daher nicht installiert werden."
|
|
141
143
|
}
|
package/public/src/i18n/en.json
CHANGED
|
@@ -137,5 +137,7 @@
|
|
|
137
137
|
"packages.confirmUninstall": "Uninstall {name} from this project?",
|
|
138
138
|
"packages.noProject": "No project selected",
|
|
139
139
|
"packages.changedByOther": "Package {name} {operation} by another user",
|
|
140
|
-
"packages.templateBadge": "Template"
|
|
140
|
+
"packages.templateBadge": "Template",
|
|
141
|
+
"packages.unreleasedBadge": "Not yet released",
|
|
142
|
+
"packages.unreleased": "This package is developed in the open but is not published to npm yet, so it cannot be installed."
|
|
141
143
|
}
|
package/public/src/i18n/es.json
CHANGED
|
@@ -137,5 +137,7 @@
|
|
|
137
137
|
"packages.confirmUninstall": "¿Desinstalar {name} de este proyecto?",
|
|
138
138
|
"packages.noProject": "Ningún proyecto seleccionado",
|
|
139
139
|
"packages.changedByOther": "Paquete {name} {operation} por otro usuario",
|
|
140
|
-
"packages.templateBadge": "Plantilla"
|
|
140
|
+
"packages.templateBadge": "Plantilla",
|
|
141
|
+
"packages.unreleasedBadge": "Aún no publicado",
|
|
142
|
+
"packages.unreleased": "Este paquete se desarrolla de forma abierta, pero todavía no está publicado en npm, por lo que no se puede instalar."
|
|
141
143
|
}
|
package/public/src/i18n/zh.json
CHANGED
|
@@ -137,5 +137,7 @@
|
|
|
137
137
|
"packages.confirmUninstall": "是否从该项目卸载 {name}?",
|
|
138
138
|
"packages.noProject": "未选择项目",
|
|
139
139
|
"packages.changedByOther": "软件包 {name} 已被其他用户{operation}",
|
|
140
|
-
"packages.templateBadge": "模板"
|
|
140
|
+
"packages.templateBadge": "模板",
|
|
141
|
+
"packages.unreleasedBadge": "尚未发布",
|
|
142
|
+
"packages.unreleased": "该软件包公开开发,但尚未发布到 npm,因此无法安装。"
|
|
141
143
|
}
|
package/public/src/i18n.js
CHANGED
|
@@ -153,7 +153,8 @@ export async function initI18n() {
|
|
|
153
153
|
syncHtmlLang(currentLocale);
|
|
154
154
|
applyTranslations();
|
|
155
155
|
}
|
|
156
|
-
/**
|
|
156
|
+
/** Return the locale currently selected for the session, set by `initI18n` or
|
|
157
|
+
* `setLocale`. Defaults to the English fallback before initialization. */
|
|
157
158
|
export function getLocale() {
|
|
158
159
|
return currentLocale;
|
|
159
160
|
}
|
|
@@ -220,6 +221,10 @@ export function applyTranslations(root) {
|
|
|
220
221
|
bindAttr(scope, '[data-i18n-placeholder]', 'data-i18n-placeholder', (el, v) => { el.setAttribute('placeholder', v); });
|
|
221
222
|
bindAttr(scope, '[data-i18n-aria]', 'data-i18n-aria', (el, v) => { el.setAttribute('aria-label', v); });
|
|
222
223
|
}
|
|
224
|
+
/** For every element in `scope` matching `selector`, read its `attr` data
|
|
225
|
+
* key, resolve the translation (with optional `data-i18n-params`
|
|
226
|
+
* substitutions), and pass the result to `setter`. Used to bind each
|
|
227
|
+
* `data-i18n*` flavor. */
|
|
223
228
|
function bindAttr(scope, selector, attr, setter) {
|
|
224
229
|
scope.querySelectorAll(selector).forEach((el) => {
|
|
225
230
|
const key = el.getAttribute(attr);
|
|
@@ -230,6 +235,8 @@ function bindAttr(scope, selector, attr, setter) {
|
|
|
230
235
|
setter(el, t(key, params));
|
|
231
236
|
});
|
|
232
237
|
}
|
|
238
|
+
/** Parse a `data-i18n-params` JSON string into a parameter object, returning
|
|
239
|
+
* `undefined` when the JSON is missing, malformed, or not a plain object. */
|
|
233
240
|
function safeParseParams(json) {
|
|
234
241
|
try {
|
|
235
242
|
const parsed = JSON.parse(json);
|
|
@@ -257,6 +264,9 @@ export function translateError(message) {
|
|
|
257
264
|
// Lazy reverse map: English error text → catalog key. Built from enCatalog
|
|
258
265
|
// so it tracks the catalog without a hand-maintained second table.
|
|
259
266
|
let cachedErrorReverse = null;
|
|
267
|
+
/** Build and cache a reverse lookup from English error text to its catalog
|
|
268
|
+
* key (covering only `error.*` entries), so server error strings can be
|
|
269
|
+
* mapped back to translatable keys at the display layer. */
|
|
260
270
|
function errorReverseMap() {
|
|
261
271
|
if (cachedErrorReverse)
|
|
262
272
|
return cachedErrorReverse;
|
package/public/src/i18n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["i18n.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,wDAAwD;AACxD,kEAAkE;AAClE,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AACvE,gEAAgE;AAChE,EAAE;AACF,+DAA+D;AAC/D,6EAA6E;AAC7E,oEAAoE;AACpE,sEAAsE;AACtE,wCAAwC;AAExC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C,gFAAgF;AAChF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["i18n.ts"],"names":[],"mappings":"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"}
|