feat(extension): wire history sidebar slot + #history/<id> route normalization
This commit is contained in:
@@ -12,7 +12,7 @@ import { registerHost } from '../shared/state';
|
|||||||
import { lookupErrorCopy, type ErrorCta } from '../shared/error-copy';
|
import { lookupErrorCopy, type ErrorCta } from '../shared/error-copy';
|
||||||
import { relativeTime } from '../shared/relative-time';
|
import { relativeTime } from '../shared/relative-time';
|
||||||
import {
|
import {
|
||||||
GLYPH_TRASH, GLYPH_DEVICES, GLYPH_SETTINGS, GLYPH_LOCK,
|
GLYPH_TRASH, GLYPH_DEVICES, GLYPH_SETTINGS, GLYPH_LOCK, GLYPH_HISTORY,
|
||||||
GLYPH_TYPE_LOGIN, GLYPH_TYPE_SECURE_NOTE, GLYPH_TYPE_TOTP,
|
GLYPH_TYPE_LOGIN, GLYPH_TYPE_SECURE_NOTE, GLYPH_TYPE_TOTP,
|
||||||
GLYPH_TYPE_CARD, GLYPH_TYPE_IDENTITY, GLYPH_TYPE_KEY, GLYPH_TYPE_DOCUMENT,
|
GLYPH_TYPE_CARD, GLYPH_TYPE_IDENTITY, GLYPH_TYPE_KEY, GLYPH_TYPE_DOCUMENT,
|
||||||
} from '../shared/glyphs';
|
} from '../shared/glyphs';
|
||||||
@@ -23,6 +23,7 @@ import { renderDevices, teardown as teardownDevices } from '../popup/components/
|
|||||||
import { renderSettings, teardownSettings } from '../popup/components/settings';
|
import { renderSettings, teardownSettings } from '../popup/components/settings';
|
||||||
import { renderVaultSettings as renderVaultSettingsView } from '../popup/components/settings-vault';
|
import { renderVaultSettings as renderVaultSettingsView } from '../popup/components/settings-vault';
|
||||||
import { renderFieldHistory, teardown as teardownFieldHistory } from '../popup/components/field-history';
|
import { renderFieldHistory, teardown as teardownFieldHistory } from '../popup/components/field-history';
|
||||||
|
import { renderItemHistoryIndex, teardown as teardownHistoryIndex } from '../popup/components/item-history-index';
|
||||||
import { renderBackupPanel, teardown as teardownBackup } from './components/backup-panel';
|
import { renderBackupPanel, teardown as teardownBackup } from './components/backup-panel';
|
||||||
import { renderImportPanel, teardown as teardownImport } from './components/import-panel';
|
import { renderImportPanel, teardown as teardownImport } from './components/import-panel';
|
||||||
import { applyColorScheme } from '../shared/color-scheme';
|
import { applyColorScheme } from '../shared/color-scheme';
|
||||||
@@ -127,7 +128,7 @@ function typeLabel(t: ItemType): string {
|
|||||||
// Hash routing
|
// Hash routing
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
type VaultView = 'list' | 'detail' | 'add' | 'edit' | 'trash' | 'devices' | 'settings' | 'settings-vault' | 'field-history' | 'backup' | 'import';
|
type VaultView = 'list' | 'detail' | 'add' | 'edit' | 'trash' | 'devices' | 'settings' | 'settings-vault' | 'field-history' | 'history' | 'backup' | 'import';
|
||||||
|
|
||||||
interface HashRoute {
|
interface HashRoute {
|
||||||
view: VaultView;
|
view: VaultView;
|
||||||
@@ -136,9 +137,15 @@ interface HashRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseHash(): HashRoute {
|
function parseHash(): HashRoute {
|
||||||
const raw = window.location.hash.replace(/^#\/?/, '');
|
let raw = window.location.hash.replace(/^#\/?/, '');
|
||||||
if (!raw) return { view: 'list' };
|
if (!raw) return { view: 'list' };
|
||||||
|
|
||||||
|
// Normalize legacy bookmarks: #field-history/<id> → #history/<id>
|
||||||
|
if (raw.startsWith('field-history/')) {
|
||||||
|
raw = 'history/' + raw.slice('field-history/'.length);
|
||||||
|
window.location.hash = raw;
|
||||||
|
}
|
||||||
|
|
||||||
const parts = raw.split('/');
|
const parts = raw.split('/');
|
||||||
const view = parts[0] as VaultView;
|
const view = parts[0] as VaultView;
|
||||||
|
|
||||||
@@ -148,6 +155,10 @@ function parseHash(): HashRoute {
|
|||||||
return { view, id: parts[1] };
|
return { view, id: parts[1] };
|
||||||
case 'add':
|
case 'add':
|
||||||
return { view, type: parts[1] };
|
return { view, type: parts[1] };
|
||||||
|
case 'history':
|
||||||
|
return parts[1]
|
||||||
|
? { view: 'field-history', id: parts[1] }
|
||||||
|
: { view: 'history' };
|
||||||
case 'trash':
|
case 'trash':
|
||||||
case 'devices':
|
case 'devices':
|
||||||
case 'settings':
|
case 'settings':
|
||||||
@@ -317,6 +328,7 @@ function renderShell(app: HTMLElement): void {
|
|||||||
<button class="vault-sidebar__nav-item" data-nav="trash" title="Trash">${GLYPH_TRASH} <span class="vault-sidebar__nav-label">trash</span></button>
|
<button class="vault-sidebar__nav-item" data-nav="trash" title="Trash">${GLYPH_TRASH} <span class="vault-sidebar__nav-label">trash</span></button>
|
||||||
<button class="vault-sidebar__nav-item" data-nav="devices" title="Devices">${GLYPH_DEVICES} <span class="vault-sidebar__nav-label">devices</span></button>
|
<button class="vault-sidebar__nav-item" data-nav="devices" title="Devices">${GLYPH_DEVICES} <span class="vault-sidebar__nav-label">devices</span></button>
|
||||||
<button class="vault-sidebar__nav-item" data-nav="settings" title="Settings">${GLYPH_SETTINGS} <span class="vault-sidebar__nav-label">settings</span></button>
|
<button class="vault-sidebar__nav-item" data-nav="settings" title="Settings">${GLYPH_SETTINGS} <span class="vault-sidebar__nav-label">settings</span></button>
|
||||||
|
<button class="vault-sidebar__nav-item" data-nav="history" title="History">${GLYPH_HISTORY} <span class="vault-sidebar__nav-label">history</span></button>
|
||||||
<button class="vault-sidebar__nav-item" data-nav="lock" title="Lock">${GLYPH_LOCK} <span class="vault-sidebar__nav-label">lock</span></button>
|
<button class="vault-sidebar__nav-item" data-nav="lock" title="Lock">${GLYPH_LOCK} <span class="vault-sidebar__nav-label">lock</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -580,7 +592,7 @@ function wireSidebar(): void {
|
|||||||
openTypePanel();
|
openTypePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nav === 'trash' || nav === 'devices' || nav === 'settings') {
|
if (nav === 'trash' || nav === 'devices' || nav === 'settings' || nav === 'history') {
|
||||||
state.selectedId = null;
|
state.selectedId = null;
|
||||||
state.selectedItem = null;
|
state.selectedItem = null;
|
||||||
state.newType = null;
|
state.newType = null;
|
||||||
@@ -808,6 +820,7 @@ function teardownPaneComponents(): void {
|
|||||||
teardownDevices();
|
teardownDevices();
|
||||||
teardownSettings();
|
teardownSettings();
|
||||||
teardownFieldHistory();
|
teardownFieldHistory();
|
||||||
|
teardownHistoryIndex();
|
||||||
teardownBackup();
|
teardownBackup();
|
||||||
teardownImport();
|
teardownImport();
|
||||||
}
|
}
|
||||||
@@ -865,6 +878,9 @@ function renderPane(): void {
|
|||||||
case 'field-history':
|
case 'field-history':
|
||||||
renderFieldHistory(pane);
|
renderFieldHistory(pane);
|
||||||
break;
|
break;
|
||||||
|
case 'history':
|
||||||
|
renderItemHistoryIndex(pane);
|
||||||
|
break;
|
||||||
case 'backup':
|
case 'backup':
|
||||||
renderBackupPanel(pane);
|
renderBackupPanel(pane);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user