Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions frontend/src/lib/features/items/ItemDetail.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<script module>
// Site title from index.html, captured once so nested item views (e.g. a modal
// over an item page) don't stack item titles on top of each other.
const siteTitle = typeof document !== 'undefined' ? document.title : '';
</script>

<script>
import { onMount, onDestroy, untrack } from 'svelte';
import { copyToClipboard } from '../../utils/clipboard.js';
Expand Down Expand Up @@ -67,6 +73,19 @@ import NativeSelect from '../../components/NativeSelect.svelte';
let item = $derived(itemDetailStore.item);
let workspace = $derived(itemDetailStore.workspace);

// Show "KEY-123 Title - <site title>" in the browser tab while the item is open;
// restore the previous title when the detail view closes.
const previousDocumentTitle = document.title;
$effect(() => {
if (!item?.workspace_item_number) return;
const k = item.workspace_key || workspace?.key;
const itemKey = k ? `${k}-${item.workspace_item_number}` : `ITEM-${item.workspace_item_number}`;
document.title = `${itemKey} ${item.title || ''}`.trim() + ` - ${siteTitle}`;
});
onDestroy(() => {
document.title = previousDocumentTitle;
});

// A reconcile request that arrives while the detail is loading must not be
// dropped: queue it and run once the in-flight load settles.
let reconcilePending = $state(false);
Expand Down
Loading