@alliance-droid/status-feedback-system 4.1.5 → 4.1.6

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.1.6
4
+
5
+ ### Fixed
6
+
7
+ - Board status badges: for privileged viewers (Admin / ProductOwner), **every** item now shows its real internal status (e.g. "QA / UAT"), not just the first one. Previously the list badge derived its label solely from the per-item transitions cache, which is only populated lazily (on menu open) plus a one-time privilege probe of `items[0]` — so exactly the first item showed its real status and the rest stayed on the coarse public projection ("In progress"). The badge now derives the privileged label from each item's own `status` (already present on every board item) via a new `internalStatusLabel`, so all rows resolve consistently once privilege is confirmed. Non-privileged viewers are unchanged (they still see the public status bucket).
8
+
3
9
  ## 4.1.5
4
10
 
5
11
  ### Fixed
@@ -21,7 +21,7 @@
21
21
  import { onMount } from 'svelte';
22
22
  import type { BoardItem, BoardTransition } from '../../api.js';
23
23
  import type { FeedbackBoardState } from './state.svelte.js';
24
- import { getStatusBadgeVariant, publicStatusLabel } from './utils.js';
24
+ import { getStatusBadgeVariant, publicStatusLabel, internalStatusLabel } from './utils.js';
25
25
 
26
26
  interface Props {
27
27
  board: FeedbackBoardState;
@@ -45,7 +45,15 @@
45
45
 
46
46
  // Read from the board's shared cache so detail + list reuse the same fetch.
47
47
  let txns = $derived(board.transitions[item.id] ?? null);
48
- let badgeLabel = $derived(txns?.current.display ?? publicStatusLabel(item.publicStatus));
48
+ // Label priority: the authoritative loaded transitions display (if this item's
49
+ // transitions have been fetched) → for privileged viewers, the item's own
50
+ // internal status (present on every board item, so ALL rows show their real
51
+ // status, not just the one the privilege probe happened to load) → otherwise
52
+ // the coarse public projection shown to everyone else.
53
+ let badgeLabel = $derived(
54
+ txns?.current.display ??
55
+ (board.canManageStatus ? internalStatusLabel(item.status) : publicStatusLabel(item.publicStatus))
56
+ );
49
57
  // Changes whenever the menu's content (and thus its size) changes — drives a
50
58
  // reposition so the teleported menu stays anchored after it loads/expands.
51
59
  let posKey = $derived(`${menuOpen}:${loading}:${pendingTarget?.status ?? ''}:${txns?.targets.length ?? 0}`);
@@ -3,5 +3,11 @@ export declare function timeAgo(timestamp: number): string;
3
3
  import type { PublicStatus } from '../../types.js';
4
4
  /** Human label for a public board status. */
5
5
  export declare function publicStatusLabel(status: PublicStatus): string;
6
+ /**
7
+ * Human label for an item's internal status. Falls back to a title-cased
8
+ * version of an unknown status value (e.g. a status added to the backend after
9
+ * this package was built) so the badge always shows something readable.
10
+ */
11
+ export declare function internalStatusLabel(status: string): string;
6
12
  /** Map a public board status to a badge variant. */
7
13
  export declare function getStatusBadgeVariant(status: PublicStatus): 'success' | 'neutral' | 'info' | 'warning';
@@ -30,6 +30,42 @@ const PUBLIC_STATUS_VARIANTS = {
30
30
  export function publicStatusLabel(status) {
31
31
  return PUBLIC_STATUS_LABELS[status] ?? status;
32
32
  }
33
+ /**
34
+ * Display labels for the backend's internal statuses. Mirrors `STATUS_META`
35
+ * (display) in status-feedback-admin's `status.ts`. Privileged users (who can
36
+ * manage status) see these precise labels; the public sees the coarser
37
+ * `publicStatus` bucket instead. `internalStatusLabel` degrades gracefully for
38
+ * any status not in this map, so drift only loses polish — never breaks.
39
+ */
40
+ const INTERNAL_STATUS_LABELS = {
41
+ open: 'Open',
42
+ considering: 'Considering',
43
+ accepted: 'Accepted',
44
+ investigating: 'Investigating',
45
+ waiting_on_reply: 'Waiting on reply',
46
+ ready_to_start: 'Ready to start',
47
+ in_progress: 'In progress',
48
+ technical_review: 'Technical review',
49
+ qa_uat: 'QA / UAT',
50
+ reopened: 'Reopened',
51
+ resolved: 'Resolved',
52
+ wont_do: "Won't do",
53
+ duplicate: 'Duplicate',
54
+ cannot_reproduce: "Can't reproduce"
55
+ };
56
+ /**
57
+ * Human label for an item's internal status. Falls back to a title-cased
58
+ * version of an unknown status value (e.g. a status added to the backend after
59
+ * this package was built) so the badge always shows something readable.
60
+ */
61
+ export function internalStatusLabel(status) {
62
+ if (INTERNAL_STATUS_LABELS[status])
63
+ return INTERNAL_STATUS_LABELS[status];
64
+ if (!status)
65
+ return '';
66
+ const spaced = status.replace(/_/g, ' ');
67
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
68
+ }
33
69
  /** Map a public board status to a badge variant. */
34
70
  export function getStatusBadgeVariant(status) {
35
71
  return PUBLIC_STATUS_VARIANTS[status] ?? 'neutral';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alliance-droid/status-feedback-system",
3
- "version": "4.1.5",
3
+ "version": "4.1.6",
4
4
  "type": "module",
5
5
  "description": "Drop-in system status pages and user feedback forms for SvelteKit apps",
6
6
  "svelte": "./dist/index.js",