feat(ext/popup): render custom sections in all 6 type detail views

This commit is contained in:
adlee-was-taken
2026-04-24 10:35:46 -04:00
parent 3f12543c81
commit 553d9d7ca9
7 changed files with 13 additions and 7 deletions

View File

@@ -145,8 +145,7 @@ export function renderSections(item: Item, idPrefix: string): string {
visibleFields.forEach((field, fIdx) => { visibleFields.forEach((field, fIdx) => {
if (field.value.kind === 'text') { if (field.value.kind === 'text') {
out += renderRow({ label: field.label, value: field.value.value, copyable: true }); out += renderRow({ label: field.label, value: field.value.value, copyable: true });
} else { } else if (field.value.kind === 'password' || field.value.kind === 'concealed') {
// password or concealed
out += renderConcealedRow({ out += renderConcealedRow({
id: `${idPrefix}-s${sIdx}-f${fIdx}`, id: `${idPrefix}-s${sIdx}-f${fIdx}`,
label: field.label, label: field.label,

View File

@@ -4,7 +4,7 @@
import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup'; import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup';
import type { Item, ItemId, ManifestEntry, CardKind } from '../../../shared/types'; import type { Item, ItemId, ManifestEntry, CardKind } from '../../../shared/types';
import { import {
renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderSections,
} from '../fields'; } from '../fields';
const CARD_KINDS: CardKind[] = ['credit', 'debit', 'gift', 'loyalty', 'other']; const CARD_KINDS: CardKind[] = ['credit', 'debit', 'gift', 'loyalty', 'other'];
@@ -79,6 +79,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
</div> </div>
${c.cvv ? renderConcealedRow({ id: 'card-cvv', label: 'cvv', value: c.cvv, monospace: true }) : ''} ${c.cvv ? renderConcealedRow({ id: 'card-cvv', label: 'cvv', value: c.cvv, monospace: true }) : ''}
${c.pin ? renderConcealedRow({ id: 'card-pin', label: 'pin', value: c.pin, monospace: true }) : ''} ${c.pin ? renderConcealedRow({ id: 'card-pin', label: 'pin', value: c.pin, monospace: true }) : ''}
${renderSections(item, 'card')}
<div class="form-actions" style="margin-top:14px;"> <div class="form-actions" style="margin-top:14px;">
<button class="btn" id="back-btn">back</button> <button class="btn" id="back-btn">back</button>
<button class="btn" id="edit-btn">edit</button> <button class="btn" id="edit-btn">edit</button>

View File

@@ -4,7 +4,7 @@
import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup'; import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup';
import type { Item, ItemId, ManifestEntry } from '../../../shared/types'; import type { Item, ItemId, ManifestEntry } from '../../../shared/types';
import { import {
renderRow, renderSignatureBlock, wireFieldHandlers, renderRow, renderSignatureBlock, wireFieldHandlers, renderSections,
} from '../fields'; } from '../fields';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null; let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
@@ -57,6 +57,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
${c.email ? renderRow({ label: 'email', value: c.email, copyable: true }) : ''} ${c.email ? renderRow({ label: 'email', value: c.email, copyable: true }) : ''}
${c.address ? renderRow({ label: 'address', value: c.address, multiline: true }) : ''} ${c.address ? renderRow({ label: 'address', value: c.address, multiline: true }) : ''}
${c.date_of_birth ? renderRow({ label: 'born', value: formatDate(c.date_of_birth) }) : ''} ${c.date_of_birth ? renderRow({ label: 'born', value: formatDate(c.date_of_birth) }) : ''}
${renderSections(item, 'identity')}
<div class="form-actions" style="margin-top:14px;"> <div class="form-actions" style="margin-top:14px;">
<button class="btn" id="back-btn">back</button> <button class="btn" id="back-btn">back</button>
<button class="btn" id="edit-btn">edit</button> <button class="btn" id="edit-btn">edit</button>

View File

@@ -5,7 +5,7 @@
import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup'; import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup';
import type { Item, ItemId, ManifestEntry } from '../../../shared/types'; import type { Item, ItemId, ManifestEntry } from '../../../shared/types';
import { import {
renderRow, renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderRow, renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderSections,
} from '../fields'; } from '../fields';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null; let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
@@ -42,6 +42,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
${c.label ? renderRow({ label: 'label', value: c.label }) : ''} ${c.label ? renderRow({ label: 'label', value: c.label }) : ''}
${c.algorithm ? renderRow({ label: 'algorithm', value: c.algorithm }) : ''} ${c.algorithm ? renderRow({ label: 'algorithm', value: c.algorithm }) : ''}
${c.public_key ? renderRow({ label: 'public', value: c.public_key, multiline: true, monospace: true, copyable: true }) : ''} ${c.public_key ? renderRow({ label: 'public', value: c.public_key, multiline: true, monospace: true, copyable: true }) : ''}
${renderSections(item, 'key')}
<div class="form-actions" style="margin-top:14px;"> <div class="form-actions" style="margin-top:14px;">
<button class="btn" id="back-btn">back</button> <button class="btn" id="back-btn">back</button>
<button class="btn" id="edit-btn">edit</button> <button class="btn" id="edit-btn">edit</button>

View File

@@ -10,6 +10,7 @@ import {
renderConcealedRow, renderConcealedRow,
renderSignatureBlock, renderSignatureBlock,
wireFieldHandlers, wireFieldHandlers,
renderSections,
} from '../fields'; } from '../fields';
/// Called by the dispatcher before each render. Stops any in-flight /// Called by the dispatcher before each render. Stops any in-flight
@@ -61,6 +62,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
</div> </div>
` : ''} ` : ''}
${item.notes ? renderRow({ label: 'notes', value: item.notes, multiline: true }) : ''} ${item.notes ? renderRow({ label: 'notes', value: item.notes, multiline: true }) : ''}
${renderSections(item, 'login')}
<div class="form-actions" style="margin-top:14px;"> <div class="form-actions" style="margin-top:14px;">
<button class="btn" id="back-btn">back</button> <button class="btn" id="back-btn">back</button>
<button class="btn" id="edit-btn">edit</button> <button class="btn" id="edit-btn">edit</button>

View File

@@ -4,7 +4,7 @@
import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup'; import { getState, setState, sendMessage, navigate, escapeHtml } from '../../popup';
import type { Item, ItemId, ManifestEntry } from '../../../shared/types'; import type { Item, ItemId, ManifestEntry } from '../../../shared/types';
import { import {
renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderSections,
} from '../fields'; } from '../fields';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null; let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
@@ -35,6 +35,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
${renderSignatureBlock({ accent: 'green', children: sigInner })} ${renderSignatureBlock({ accent: 'green', children: sigInner })}
</div> </div>
${renderConcealedRow({ id: 'note-body', label: 'body', value: body, multiline: true })} ${renderConcealedRow({ id: 'note-body', label: 'body', value: body, multiline: true })}
${renderSections(item, 'secure-note')}
<div class="form-actions" style="margin-top:14px;"> <div class="form-actions" style="margin-top:14px;">
<button class="btn" id="back-btn">back</button> <button class="btn" id="back-btn">back</button>
<button class="btn" id="edit-btn">edit</button> <button class="btn" id="edit-btn">edit</button>

View File

@@ -6,7 +6,7 @@ import { getState, setState, sendMessage, navigate, escapeHtml } from '../../pop
import type { Item, ItemId, ManifestEntry, TotpKind } from '../../../shared/types'; import type { Item, ItemId, ManifestEntry, TotpKind } from '../../../shared/types';
import { base32Decode, base32Encode } from '../../../shared/base32'; import { base32Decode, base32Encode } from '../../../shared/base32';
import { import {
renderRow, renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderRow, renderConcealedRow, renderSignatureBlock, wireFieldHandlers, renderSections,
} from '../fields'; } from '../fields';
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@@ -83,6 +83,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
${c.label ? renderRow({ label: 'label', value: c.label }) : ''} ${c.label ? renderRow({ label: 'label', value: c.label }) : ''}
${renderRow({ label: 'kind', value: isSteam ? 'Steam Guard' : 'TOTP' })} ${renderRow({ label: 'kind', value: isSteam ? 'Steam Guard' : 'TOTP' })}
${renderConcealedRow({ id: 'totp-secret', label: 'secret', value: secretB32, monospace: true })} ${renderConcealedRow({ id: 'totp-secret', label: 'secret', value: secretB32, monospace: true })}
${renderSections(item, 'totp')}
<div class="form-actions" style="margin-top:14px;"> <div class="form-actions" style="margin-top:14px;">
<button class="btn" id="back-btn">back</button> <button class="btn" id="back-btn">back</button>
<button class="btn" id="edit-btn">edit</button> <button class="btn" id="edit-btn">edit</button>