@burdenoff/microfe-vibecontrols 2026.709.2 → 2026.710.1

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.
Files changed (45) hide show
  1. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js +87 -85
  2. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js.map +1 -1
  3. package/dist/components/ai/InstructionFilesManager.js +138 -136
  4. package/dist/components/ai/InstructionFilesManager.js.map +1 -1
  5. package/dist/components/ai/PluginHarnessPicker.js +70 -64
  6. package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
  7. package/dist/components/docs/DocsEditPanel.js +1 -1
  8. package/dist/components/docs/DocsEditPanel.js.map +1 -1
  9. package/dist/components/docs/DocsPageTree.js +1 -1
  10. package/dist/components/docs/DocsPageTree.js.map +1 -1
  11. package/dist/components/docs/DocsTabPanel.js +108 -106
  12. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  13. package/dist/components/notes/NotesTabPanel.js +99 -99
  14. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  15. package/dist/components/scorecard/ScorecardPanel.js +309 -308
  16. package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
  17. package/dist/components/sessions/SessionPublicLinkPanel.js +104 -102
  18. package/dist/components/sessions/SessionPublicLinkPanel.js.map +1 -1
  19. package/dist/components/settings/AdvancedSection.js +92 -90
  20. package/dist/components/settings/AdvancedSection.js.map +1 -1
  21. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +104 -102
  22. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
  23. package/dist/constants/permissions.js +7 -0
  24. package/dist/constants/permissions.js.map +1 -1
  25. package/dist/pages/ActionsPage.js +303 -303
  26. package/dist/pages/ActionsPage.js.map +1 -1
  27. package/dist/pages/AgentDetailsPage.js +520 -516
  28. package/dist/pages/AgentDetailsPage.js.map +1 -1
  29. package/dist/pages/AgentsPage.js +287 -283
  30. package/dist/pages/AgentsPage.js.map +1 -1
  31. package/dist/pages/TargetsPage.js +554 -549
  32. package/dist/pages/TargetsPage.js.map +1 -1
  33. package/dist/pages/VibeAuditPage.js +2 -2
  34. package/dist/pages/VibeAuditPage.js.map +1 -1
  35. package/dist/pages/VibeDeckPage.js +257 -257
  36. package/dist/pages/VibeDeckPage.js.map +1 -1
  37. package/dist/pages/VibeDetailsPage.js +688 -693
  38. package/dist/pages/VibeDetailsPage.js.map +1 -1
  39. package/dist/pages/VibesPage.js +49 -41
  40. package/dist/pages/VibesPage.js.map +1 -1
  41. package/dist/pages/WebhooksPage.js +162 -138
  42. package/dist/pages/WebhooksPage.js.map +1 -1
  43. package/dist/pages/tunnels/DomainsTab.js +54 -47
  44. package/dist/pages/tunnels/DomainsTab.js.map +1 -1
  45. package/package.json +1 -1
@@ -28,7 +28,7 @@ import { AccessDenied as Oe, PermissionButton as ke } from "@burdenoff/fe-libs/s
28
28
  import { MotionItem as Ae, MotionList as je } from "@burdenoff/fe-libs/shared/motion";
29
29
  //#region src/components/notes/NotesTabPanel.tsx
30
30
  function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
31
- let { t: Me } = he(), Ne = Ce(), y = we(), { hasPermission: b, isLoading: x, permissions: Pe } = Te(), S = b(c.NOTE_LIST), Fe = b(c.NOTE_CREATE), Ie = De(l.note.featureFlag, l.note.defaultEnabled), Le = b(l.note.permission), Re = Ie && Le, [C, w] = d(null), [T, ze] = d(""), [E, Be] = d("all"), [D, Ve] = d("all"), [O, k] = d("all"), [A, He] = d(!1), [j, M] = d("grid"), [Ue, N] = d(!1), [We, P] = d(null), [Ge, F] = d(!1), I = (e) => {
31
+ let { t: Me } = he(), Ne = Ce(), y = we(), { hasPermission: b, isLoading: x, permissions: Pe } = Te(), S = b(c.NOTE_LIST), Fe = b(c.NOTE_CREATE), C = b(c.NOTE_DELETE), Ie = De(l.note.featureFlag, l.note.defaultEnabled), Le = b(l.note.permission), Re = Ie && Le, [w, T] = d(null), [E, ze] = d(""), [D, Be] = d("all"), [O, Ve] = d("all"), [k, A] = d("all"), [j, He] = d(!1), [M, N] = d("grid"), [Ue, P] = d(!1), [We, F] = d(null), [Ge, I] = d(!1), L = (e) => {
32
32
  y.cache.evict({
33
33
  id: "ROOT_QUERY",
34
34
  fieldName: "notes"
@@ -48,41 +48,41 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
48
48
  }), [Xe] = ie({
49
49
  refetchQueries: [e],
50
50
  awaitRefetchQueries: !0
51
- }), [L] = te({
51
+ }), [R] = te({
52
52
  refetchQueries: [e],
53
53
  awaitRefetchQueries: !0
54
54
  }), [Ze] = ne({
55
55
  refetchQueries: [e],
56
56
  awaitRefetchQueries: !0
57
- }), R = x || !S, { data: z } = t({ skip: R }), { data: B, loading: V, error: H, refetch: U } = i({
57
+ }), z = x || !S, { data: B } = t({ skip: z }), { data: V, loading: H, error: U, refetch: W } = i({
58
58
  variables: {
59
59
  filter: u(() => {
60
- let e = O === "all" ? void 0 : O;
60
+ let e = k === "all" ? void 0 : k;
61
61
  return h === "session" && _ ? {
62
62
  sessionId: _,
63
- isPinned: A ? !0 : void 0,
63
+ isPinned: j ? !0 : void 0,
64
64
  visibility: e
65
65
  } : h === "vibe" && g ? {
66
66
  vibeId: g,
67
- isPinned: A ? !0 : void 0,
67
+ isPinned: j ? !0 : void 0,
68
68
  visibility: e
69
69
  } : {
70
- vibeId: E === "none" ? null : E === "all" ? void 0 : E,
71
- isPinned: A ? !0 : void 0,
70
+ vibeId: D === "none" ? null : D === "all" ? void 0 : D,
71
+ isPinned: j ? !0 : void 0,
72
72
  visibility: e
73
73
  };
74
74
  }, [
75
75
  h,
76
76
  g,
77
77
  _,
78
- E,
79
- A,
80
- O
78
+ D,
79
+ j,
80
+ k
81
81
  ]),
82
82
  pagination: { limit: 50 }
83
83
  },
84
84
  fetchPolicy: "cache-and-network",
85
- skip: R
85
+ skip: z
86
86
  }), Qe = u(() => h === "agent" ? [
87
87
  {
88
88
  value: "all",
@@ -96,11 +96,11 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
96
96
  value: e.id,
97
97
  label: e.name
98
98
  }))
99
- ] : [], [h, v]), W = u(() => {
100
- let e = z?.availableNoteTags ?? [];
99
+ ] : [], [h, v]), G = u(() => {
100
+ let e = B?.availableNoteTags ?? [];
101
101
  return new Map(e.map((e) => [e.id, e]));
102
- }, [z?.availableNoteTags]), G = u(() => {
103
- let e = (B?.notes?.items ?? []).map((e) => ({
102
+ }, [B?.availableNoteTags]), K = u(() => {
103
+ let e = (V?.notes?.items ?? []).map((e) => ({
104
104
  id: e.id,
105
105
  workspaceId: e.workspaceId,
106
106
  vibeId: e.vibeId || null,
@@ -113,11 +113,11 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
113
113
  label: e.tag.label,
114
114
  key: e.tag.key,
115
115
  color: e.tag.color
116
- } : W.has(e.tagId) ? {
116
+ } : G.has(e.tagId) ? {
117
117
  id: e.tagId,
118
- label: W.get(e.tagId).label,
119
- key: W.get(e.tagId).key,
120
- color: W.get(e.tagId).color ?? null
118
+ label: G.get(e.tagId).label,
119
+ key: G.get(e.tagId).key,
120
+ color: G.get(e.tagId).color ?? null
121
121
  } : void 0;
122
122
  return {
123
123
  id: e.id,
@@ -147,45 +147,45 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
147
147
  }
148
148
  return e;
149
149
  }, [
150
- B?.notes?.items,
150
+ V?.notes?.items,
151
151
  h,
152
152
  v,
153
- W
153
+ G
154
154
  ]), $e = u(() => [{
155
155
  value: "all",
156
156
  label: "All Tags"
157
- }, ...(z?.availableNoteTags ?? []).map((e) => ({
157
+ }, ...(B?.availableNoteTags ?? []).map((e) => ({
158
158
  value: e.id,
159
159
  label: e.label
160
- }))], [z?.availableNoteTags]), K = u(() => G.filter((e) => {
161
- if (T) {
162
- let t = T.toLowerCase();
160
+ }))], [B?.availableNoteTags]), q = u(() => K.filter((e) => {
161
+ if (E) {
162
+ let t = E.toLowerCase();
163
163
  if (!(e.title.toLowerCase().includes(t) || e.content.toLowerCase().includes(t) || e.tagAssignments?.some((e) => e.tag?.label?.toLowerCase().includes(t)))) return !1;
164
164
  }
165
- return !(D !== "all" && !e.tagAssignments?.some((e) => e.tagId === D));
165
+ return !(O !== "all" && !e.tagAssignments?.some((e) => e.tagId === O));
166
166
  }), [
167
- G,
168
- T,
169
- D
170
- ]), q = u(() => [...K].sort((e, t) => e.isPinned && !t.isPinned ? -1 : !e.isPinned && t.isPinned ? 1 : new Date(t.updatedAt).getTime() - new Date(e.updatedAt).getTime()), [K]), J = (e) => {
171
- P(e), N(!0);
172
- }, Y = () => {
173
- P(null), N(!0);
174
- }, X = async (e) => {
167
+ K,
168
+ E,
169
+ O
170
+ ]), J = u(() => [...q].sort((e, t) => e.isPinned && !t.isPinned ? -1 : !e.isPinned && t.isPinned ? 1 : new Date(t.updatedAt).getTime() - new Date(e.updatedAt).getTime()), [q]), Y = (e) => {
171
+ F(e), P(!0);
172
+ }, X = () => {
173
+ F(null), P(!0);
174
+ }, Z = async (e) => {
175
175
  try {
176
- e.isPinned ? await qe({ variables: { id: e.id } }) : await Ke({ variables: { id: e.id } }), I(U);
176
+ e.isPinned ? await qe({ variables: { id: e.id } }) : await Ke({ variables: { id: e.id } }), L(W);
177
177
  } catch (e) {
178
178
  console.error("Failed to toggle pin for note:", e);
179
179
  }
180
180
  }, et = async (e) => {
181
181
  try {
182
- await Je({ variables: { id: e.id } }), I(U);
182
+ await Je({ variables: { id: e.id } }), L(W);
183
183
  } catch (e) {
184
184
  console.error("Failed to delete note:", e);
185
185
  }
186
186
  }, tt = async (e) => {
187
187
  let t = () => {
188
- N(!1), P(null), oe(), F(!0);
188
+ P(!1), F(null), oe(), I(!0);
189
189
  };
190
190
  try {
191
191
  let n, r = h === "vibe" ? g : e.vibeId;
@@ -227,13 +227,13 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
227
227
  }
228
228
  n = i.data?.createNote?.id;
229
229
  }
230
- n && e.selectedTagIds && e.selectedTagIds.length > 0 ? await L({ variables: { input: {
230
+ n && e.selectedTagIds && e.selectedTagIds.length > 0 ? await R({ variables: { input: {
231
231
  noteId: n,
232
232
  tagIds: e.selectedTagIds
233
- } } }) : n && e.selectedTagIds?.length === 0 && e.id && await L({ variables: { input: {
233
+ } } }) : n && e.selectedTagIds?.length === 0 && e.id && await R({ variables: { input: {
234
234
  noteId: n,
235
235
  tagIds: []
236
- } } }), N(!1), I(U);
236
+ } } }), P(!1), L(W);
237
237
  } catch (e) {
238
238
  console.error("Failed to save note:", e);
239
239
  }
@@ -243,26 +243,26 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
243
243
  await Ze({ variables: {
244
244
  id: e.id,
245
245
  visibility: t
246
- } }), I(U);
246
+ } }), L(W);
247
247
  } catch (e) {
248
248
  console.error("Failed to toggle note visibility:", e);
249
249
  }
250
- }, Z = Re ? (e) => w(e) : void 0, Q = {
251
- total: G.length,
252
- pinned: G.filter((e) => e.isPinned).length
253
- }, rt = u(() => h === "vibe" ? [] : v, [h, v]);
250
+ }, rt = Re ? (e) => T(e) : void 0, Q = {
251
+ total: K.length,
252
+ pinned: K.filter((e) => e.isPinned).length
253
+ }, it = u(() => h === "vibe" ? [] : v, [h, v]);
254
254
  if (!x && Pe && !S) return /* @__PURE__ */ p(Oe, {
255
255
  title: "Access Denied",
256
256
  description: "You don't have permission to view notes.",
257
257
  details: "Required permission: note:list"
258
258
  });
259
- if (V && G.length === 0) return /* @__PURE__ */ p(se, { message: "Loading notes..." });
260
- if (H && G.length === 0) return /* @__PURE__ */ p(ce, {
259
+ if (H && K.length === 0) return /* @__PURE__ */ p(se, { message: "Loading notes..." });
260
+ if (U && K.length === 0) return /* @__PURE__ */ p(ce, {
261
261
  title: "Failed to load notes",
262
- message: H.message,
263
- onRetry: () => U()
262
+ message: U.message,
263
+ onRetry: () => W()
264
264
  });
265
- let $ = T || h === "agent" && E !== "all" || D !== "all" || A;
265
+ let $ = E || h === "agent" && D !== "all" || O !== "all" || j;
266
266
  return /* @__PURE__ */ m("div", {
267
267
  className: "space-y-4",
268
268
  children: [
@@ -285,16 +285,16 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
285
285
  className: "flex items-center gap-2",
286
286
  children: [/* @__PURE__ */ p("button", {
287
287
  type: "button",
288
- onClick: () => U(),
289
- disabled: V,
288
+ onClick: () => W(),
289
+ disabled: H,
290
290
  className: "flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50",
291
291
  title: "Refresh notes",
292
- children: /* @__PURE__ */ p(Se, { className: `size-4 ${V ? "animate-spin" : ""}` })
292
+ children: /* @__PURE__ */ p(Se, { className: `size-4 ${H ? "animate-spin" : ""}` })
293
293
  }), /* @__PURE__ */ p(ke, {
294
294
  permission: c.NOTE_CREATE,
295
295
  children: /* @__PURE__ */ m("button", {
296
296
  type: "button",
297
- onClick: Y,
297
+ onClick: X,
298
298
  className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors",
299
299
  children: [/* @__PURE__ */ p(f, { className: "size-4" }), "New Note"]
300
300
  })
@@ -306,7 +306,7 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
306
306
  children: [/* @__PURE__ */ m("div", {
307
307
  className: "flex items-center gap-2",
308
308
  children: [/* @__PURE__ */ p(ue, {
309
- value: T,
309
+ value: E,
310
310
  onChange: ze,
311
311
  placeholder: "Search notes...",
312
312
  className: "flex-1 sm:w-64 sm:flex-none"
@@ -314,14 +314,14 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
314
314
  className: "flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0",
315
315
  children: [/* @__PURE__ */ p("button", {
316
316
  type: "button",
317
- onClick: () => M("grid"),
318
- className: `p-1.5 sm:p-2 rounded ${j === "grid" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
317
+ onClick: () => N("grid"),
318
+ className: `p-1.5 sm:p-2 rounded ${M === "grid" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
319
319
  title: "Grid view",
320
320
  children: /* @__PURE__ */ p(ve, { className: "size-4 text-text-secondary" })
321
321
  }), /* @__PURE__ */ p("button", {
322
322
  type: "button",
323
- onClick: () => M("list"),
324
- className: `p-1.5 sm:p-2 rounded ${j === "list" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
323
+ onClick: () => N("list"),
324
+ className: `p-1.5 sm:p-2 rounded ${M === "list" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
325
325
  title: "List view",
326
326
  children: /* @__PURE__ */ p(ye, { className: "size-4 text-text-secondary" })
327
327
  })]
@@ -331,13 +331,13 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
331
331
  children: [
332
332
  h === "agent" && /* @__PURE__ */ p(s, {
333
333
  label: "Vibe",
334
- value: E,
334
+ value: D,
335
335
  options: Qe,
336
336
  onChange: Be
337
337
  }),
338
338
  /* @__PURE__ */ p(s, {
339
339
  label: "Tag",
340
- value: D,
340
+ value: O,
341
341
  options: $e,
342
342
  onChange: Ve
343
343
  }),
@@ -346,20 +346,20 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
346
346
  children: [
347
347
  /* @__PURE__ */ p("button", {
348
348
  type: "button",
349
- onClick: () => k("all"),
350
- className: `px-2.5 py-1 text-xs rounded transition-colors ${O === "all" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-secondary"}`,
349
+ onClick: () => A("all"),
350
+ className: `px-2.5 py-1 text-xs rounded transition-colors ${k === "all" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-secondary"}`,
351
351
  children: "All"
352
352
  }),
353
353
  /* @__PURE__ */ m("button", {
354
354
  type: "button",
355
- onClick: () => k("WORKSPACE"),
356
- className: `flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${O === "WORKSPACE" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-secondary"}`,
355
+ onClick: () => A("WORKSPACE"),
356
+ className: `flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${k === "WORKSPACE" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-secondary"}`,
357
357
  children: [/* @__PURE__ */ p(_e, { className: "size-3" }), "Shared"]
358
358
  }),
359
359
  /* @__PURE__ */ m("button", {
360
360
  type: "button",
361
- onClick: () => k("PRIVATE"),
362
- className: `flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${O === "PRIVATE" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-secondary"}`,
361
+ onClick: () => A("PRIVATE"),
362
+ className: `flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${k === "PRIVATE" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-secondary"}`,
363
363
  children: [/* @__PURE__ */ p(be, { className: "size-3" }), "Private"]
364
364
  })
365
365
  ]
@@ -371,8 +371,8 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
371
371
  className: "flex items-center gap-2",
372
372
  children: /* @__PURE__ */ m("button", {
373
373
  type: "button",
374
- onClick: () => He(!A),
375
- className: `flex items-center gap-2 px-3 py-1.5 text-sm rounded-full transition-colors ${A ? "bg-status-warning-bg-subtle text-status-warning-text" : "bg-bg-sunken text-text-secondary hover:bg-bg-sunken/80"}`,
374
+ onClick: () => He(!j),
375
+ className: `flex items-center gap-2 px-3 py-1.5 text-sm rounded-full transition-colors ${j ? "bg-status-warning-bg-subtle text-status-warning-text" : "bg-bg-sunken text-text-secondary hover:bg-bg-sunken/80"}`,
376
376
  children: [
377
377
  /* @__PURE__ */ p(xe, { className: "size-3" }),
378
378
  "Pinned (",
@@ -385,11 +385,11 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
385
385
  className: "text-sm text-text-secondary",
386
386
  children: [
387
387
  "Showing ",
388
- q.length,
388
+ J.length,
389
389
  " of ",
390
- G.length,
390
+ K.length,
391
391
  " notes",
392
- V && /* @__PURE__ */ p("span", {
392
+ H && /* @__PURE__ */ p("span", {
393
393
  className: "ml-2 text-text-muted",
394
394
  children: "(refreshing…)"
395
395
  })
@@ -397,35 +397,35 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
397
397
  }) : null,
398
398
  /* @__PURE__ */ p(Ee, {
399
399
  mode: "wait",
400
- children: q.length > 0 ? j === "grid" ? /* @__PURE__ */ p(je, {
400
+ children: J.length > 0 ? M === "grid" ? /* @__PURE__ */ p(je, {
401
401
  stagger: .04,
402
402
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
403
- children: q.map((e) => /* @__PURE__ */ p(Ae, { children: /* @__PURE__ */ p(fe, {
403
+ children: J.map((e) => /* @__PURE__ */ p(Ae, { children: /* @__PURE__ */ p(fe, {
404
404
  note: e,
405
- onOpen: J,
406
- onEdit: J,
407
- onPin: X,
408
- onUnpin: X,
409
- onDelete: et,
405
+ onOpen: Y,
406
+ onEdit: Y,
407
+ onPin: Z,
408
+ onUnpin: Z,
409
+ onDelete: C ? et : void 0,
410
410
  onShare: nt,
411
- onShareAccess: Z
411
+ onShareAccess: rt
412
412
  }) }, e.id))
413
413
  }, "grid") : /* @__PURE__ */ p(pe, {
414
- notes: q,
415
- onOpen: J,
416
- onEdit: J,
417
- onPin: X,
418
- onUnpin: X,
419
- onDelete: et,
414
+ notes: J,
415
+ onOpen: Y,
416
+ onEdit: Y,
417
+ onPin: Z,
418
+ onUnpin: Z,
419
+ onDelete: C ? et : void 0,
420
420
  onShare: nt,
421
- onShareAccess: Z
421
+ onShareAccess: rt
422
422
  }, "list") : /* @__PURE__ */ p(le, {
423
423
  icon: /* @__PURE__ */ p(ge, { className: "size-8 text-text-secondary" }),
424
424
  title: $ ? "No notes found" : "No notes yet",
425
425
  description: $ ? "Try adjusting your search or filters" : "Create your first note to start documenting your work",
426
426
  action: !$ && Fe ? /* @__PURE__ */ m("button", {
427
427
  type: "button",
428
- onClick: Y,
428
+ onClick: X,
429
429
  className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors",
430
430
  children: [/* @__PURE__ */ p(f, { className: "size-4" }), "New Note"]
431
431
  }) : void 0
@@ -433,30 +433,30 @@ function h({ context: h, vibeId: g, sessionId: _, agentVibes: v = [] }) {
433
433
  }),
434
434
  Ue && /* @__PURE__ */ p(me, {
435
435
  note: We || void 0,
436
- vibeOptions: rt,
436
+ vibeOptions: it,
437
437
  defaultVibeId: h === "vibe" ? g : void 0,
438
438
  hideVibeSelect: h === "vibe",
439
439
  onSubmit: tt,
440
- onCancel: () => N(!1)
440
+ onCancel: () => P(!1)
441
441
  }),
442
442
  /* @__PURE__ */ p(ae, {
443
443
  isOpen: Ge,
444
- onClose: () => F(!1),
444
+ onClose: () => I(!1),
445
445
  onConfirm: () => {
446
- F(!1), Ne("/billing/plans");
446
+ I(!1), Ne("/billing/plans");
447
447
  },
448
448
  title: "Note Quota Reached",
449
449
  message: "You've used all available note quota on your current plan. Upgrade your plan to create or update more notes."
450
450
  }),
451
- C && /* @__PURE__ */ p(de, {
451
+ w && /* @__PURE__ */ p(de, {
452
452
  note: {
453
- id: C.id,
454
- title: C.title,
455
- vibeId: C.vibeId
453
+ id: w.id,
454
+ title: w.title,
455
+ vibeId: w.vibeId
456
456
  },
457
- open: !!C,
457
+ open: !!w,
458
458
  onOpenChange: (e) => {
459
- e || w(null);
459
+ e || T(null);
460
460
  }
461
461
  })
462
462
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"NotesTabPanel.js","names":[],"sources":["../../../src/components/notes/NotesTabPanel.tsx"],"sourcesContent":["import { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useState, useMemo } from 'react';\nimport { Plus, FileText, Grid, List, Pin, RefreshCw, Lock, Globe } from 'lucide-react';\nimport { AnimatePresence } from 'framer-motion';\nimport { useNavigate } from 'react-router-dom';\nimport { useApolloClient } from '@apollo/client/react';\nimport { MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\nimport { NoteCard } from './NoteCard';\nimport { NoteList } from './NoteList';\nimport { NoteEditor } from './NoteEditor';\nimport type { Note, NoteVisibility } from './types';\nimport type { NoteEditorSubmitData } from './NoteEditor';\nimport {\n SearchInput,\n FilterDropdown,\n EmptyState,\n LoadingState,\n ErrorState,\n QuotaExhaustedDialog,\n} from '@/components/shared';\nimport {\n useListNotesQuery,\n usePinNoteMutation,\n useUnpinNoteMutation,\n useDeleteNoteMutation,\n useCreateNoteMutation,\n useUpdateNoteMutation,\n useReplaceNoteTagsMutation,\n useAvailableNoteTagsQuery,\n useShareNoteMutation,\n ListNotesDocument,\n} from '@/generated/wspace-operations';\nimport { NoteVisibility as GqlNoteVisibility } from '@/generated/wspace-types';\nimport { PermissionButton, AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useFeatureFlag } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { isQuotaExhaustedError, markQuotaHandledLocally } from '@/utils/quotaUtils';\nimport { NoteShareDialog, SHARE_REGISTRY } from '@/components/sharing';\n\ntype ViewMode = 'grid' | 'list';\n\ninterface NotesTabPanelProps {\n /**\n * 'vibe' = single vibe context; 'agent' = multi-vibe agent context;\n * 'session' = notes authored against a single terminal session (F1).\n */\n context: 'vibe' | 'agent' | 'session';\n /** For vibe context: the single vibeId to scope notes to */\n vibeId?: string;\n /** For session context: the single sessionId to scope notes to */\n sessionId?: string;\n /** For agent context: the vibes belonging to the agent */\n agentVibes?: { id: string; name: string }[];\n}\n\n/**\n * Reusable notes panel for embedding as a tab in detail pages.\n * Supports vibe-scoped, agent-scoped, and session-scoped contexts.\n */\nexport function NotesTabPanel({ context, vibeId, sessionId, agentVibes = [] }: NotesTabPanelProps) {\n const { t } = useI18n();\n const navigate = useNavigate();\n const apolloClient = useApolloClient();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n\n const canListNotes = hasPermission(VIBE_PERMISSIONS.NOTE_LIST);\n const canCreateNote = hasPermission(VIBE_PERMISSIONS.NOTE_CREATE);\n\n // Generic note sharing (full users/link/vibe dialog). Gated by the\n // `vibecontrols.sharing.note` flag (default ON) + note share permission.\n // Distinct from the legacy `onShare` visibility toggle, which stays as-is.\n const noteSharingFlagEnabled = useFeatureFlag(\n SHARE_REGISTRY.note.featureFlag,\n SHARE_REGISTRY.note.defaultEnabled\n );\n const canShareNote = hasPermission(SHARE_REGISTRY.note.permission);\n const noteSharingEnabled = noteSharingFlagEnabled && canShareNote;\n const [genericShareNote, setGenericShareNote] = useState<Note | null>(null);\n\n const [searchQuery, setSearchQuery] = useState('');\n const [vibeFilter, setVibeFilter] = useState('all');\n const [tagFilter, setTagFilter] = useState('all');\n const [visibilityFilter, setVisibilityFilter] = useState<'all' | 'PRIVATE' | 'WORKSPACE'>('all');\n const [showPinnedOnly, setShowPinnedOnly] = useState(false);\n const [viewMode, setViewMode] = useState<ViewMode>('grid');\n const [showEditor, setShowEditor] = useState(false);\n const [selectedNote, setSelectedNote] = useState<Note | null>(null);\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n\n // Evict cached notes list and refetch — bypasses stale cache-and-network data\n const evictAndRefetch = (refetch: () => void) => {\n apolloClient.cache.evict({ id: 'ROOT_QUERY', fieldName: 'notes' });\n apolloClient.cache.gc();\n refetch();\n };\n\n const [pinNote] = usePinNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [unpinNote] = useUnpinNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [deleteNote] = useDeleteNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [createNote] = useCreateNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [updateNote] = useUpdateNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [replaceNoteTags] = useReplaceNoteTagsMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [shareNote] = useShareNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n\n const shouldSkipQueries = permissionsLoading || !canListNotes;\n\n const { data: availableTagsData } = useAvailableNoteTagsQuery({ skip: shouldSkipQueries });\n\n // Build query filter based on context\n const queryFilter = useMemo(() => {\n const visibilityVal =\n visibilityFilter !== 'all' ? (visibilityFilter as GqlNoteVisibility) : undefined;\n\n if (context === 'session' && sessionId) {\n return {\n sessionId,\n isPinned: showPinnedOnly ? true : undefined,\n visibility: visibilityVal,\n };\n }\n if (context === 'vibe' && vibeId) {\n return {\n vibeId,\n isPinned: showPinnedOnly ? true : undefined,\n visibility: visibilityVal,\n };\n }\n // Agent context: fetch all notes, filter client-side\n return {\n vibeId: vibeFilter === 'none' ? null : vibeFilter !== 'all' ? vibeFilter : undefined,\n isPinned: showPinnedOnly ? true : undefined,\n visibility: visibilityVal,\n };\n }, [context, vibeId, sessionId, vibeFilter, showPinnedOnly, visibilityFilter]);\n\n const { data, loading, error, refetch } = useListNotesQuery({\n variables: { filter: queryFilter, pagination: { limit: 50 } },\n fetchPolicy: 'cache-and-network',\n skip: shouldSkipQueries,\n });\n\n // Vibe filter options (agent context only)\n const vibeOptions = useMemo(() => {\n if (context !== 'agent') return [];\n return [\n { value: 'all', label: 'All Vibes' },\n { value: 'none', label: 'No Vibe (General)' },\n ...agentVibes.map((v) => ({ value: v.id, label: v.name })),\n ];\n }, [context, agentVibes]);\n\n // Tag label lookup by ID — used when federation doesn't return nested tag object\n type AvailableTag = { id: string; key: string; label: string; color?: string | null };\n const tagLabelMap = useMemo((): Map<string, AvailableTag> => {\n const tags = (availableTagsData?.availableNoteTags ?? []) as AvailableTag[];\n return new Map(tags.map((tag) => [tag.id, tag]));\n }, [availableTagsData?.availableNoteTags]);\n\n // Map GraphQL response to Note type\n const notes: Note[] = useMemo(() => {\n const rawNotes = data?.notes?.items ?? [];\n const mapped = rawNotes.map((note: NonNullable<typeof rawNotes>[number]) => ({\n id: note.id,\n workspaceId: note.workspaceId,\n vibeId: note.vibeId || null,\n title: note.title,\n content: note.content,\n tags: note.tags || [],\n tagAssignments:\n note.tagAssignments?.map((a: NonNullable<typeof note.tagAssignments>[number]) => {\n // `a.tag` may be null when federation doesn't resolve the tag entity.\n // Fall back to the availableNoteTags lookup so the label always shows.\n const resolvedTag = a.tag\n ? { id: a.tag.id, label: a.tag.label, key: a.tag.key, color: a.tag.color }\n : tagLabelMap.has(a.tagId)\n ? {\n id: a.tagId,\n label: tagLabelMap.get(a.tagId)!.label,\n key: tagLabelMap.get(a.tagId)!.key,\n color: tagLabelMap.get(a.tagId)!.color ?? null,\n }\n : undefined;\n return {\n id: a.id,\n tagId: a.tagId,\n tag: resolvedTag,\n entityType: a.entityType,\n entityId: a.entityId,\n source: a.source,\n assignedBy: a.assignedBy,\n assignedAt: a.assignedAt,\n };\n }) || [],\n isPinned: note.isPinned,\n visibility: (note.visibility ?? 'WORKSPACE') as NoteVisibility,\n createdBy: note.createdBy ?? '',\n metadata: (note.metadata as Record<string, unknown>) || {},\n createdAt: note.createdAt,\n updatedAt: note.updatedAt,\n vibe: note.vibe ? { id: note.vibe.id, name: note.vibe.name } : undefined,\n }));\n\n // Agent context: client-side filter to only agent's vibes\n if (context === 'agent' && agentVibes.length > 0) {\n const vibeIdSet = new Set(agentVibes.map((v) => v.id));\n return mapped.filter((n: Note) => n.vibeId && vibeIdSet.has(n.vibeId));\n }\n\n return mapped;\n }, [data?.notes?.items, context, agentVibes, tagLabelMap]);\n\n // Tag filter options\n const tagOptions = useMemo(() => {\n const tags = availableTagsData?.availableNoteTags ?? [];\n return [\n { value: 'all', label: 'All Tags' },\n ...tags.map((tag: AvailableTag) => ({\n value: tag.id,\n label: tag.label,\n })),\n ];\n }, [availableTagsData?.availableNoteTags]);\n\n // Client-side search and tag filtering\n const filteredNotes = useMemo(() => {\n return notes.filter((note) => {\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n const matchesSearch =\n note.title.toLowerCase().includes(query) ||\n note.content.toLowerCase().includes(query) ||\n note.tagAssignments?.some((a) => a.tag?.label?.toLowerCase().includes(query));\n if (!matchesSearch) return false;\n }\n if (tagFilter !== 'all') {\n const hasTag = note.tagAssignments?.some((a) => a.tagId === tagFilter);\n if (!hasTag) return false;\n }\n return true;\n });\n }, [notes, searchQuery, tagFilter]);\n\n // Sort: pinned first, then by updatedAt\n const sortedNotes = useMemo(() => {\n return [...filteredNotes].sort((a, b) => {\n if (a.isPinned && !b.isPinned) return -1;\n if (!a.isPinned && b.isPinned) return 1;\n return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();\n });\n }, [filteredNotes]);\n\n const handleNoteSelect = (note: Note) => {\n setSelectedNote(note);\n setShowEditor(true);\n };\n\n const handleCreateNote = () => {\n setSelectedNote(null);\n setShowEditor(true);\n };\n\n const handlePinNote = async (note: Note) => {\n try {\n if (note.isPinned) {\n await unpinNote({ variables: { id: note.id } });\n } else {\n await pinNote({ variables: { id: note.id } });\n }\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to toggle pin for note:', err);\n }\n };\n\n const handleDeleteNote = async (note: Note) => {\n try {\n await deleteNote({ variables: { id: note.id } });\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to delete note:', err);\n }\n };\n\n const handleSaveNote = async (noteData: NoteEditorSubmitData) => {\n const closeEditorForQuota = () => {\n setShowEditor(false);\n setSelectedNote(null);\n markQuotaHandledLocally();\n setShowQuotaExhausted(true);\n };\n\n try {\n let noteId: string | undefined;\n\n // In vibe context, always force the vibeId\n const effectiveVibeId = context === 'vibe' ? vibeId : noteData.vibeId;\n\n if (noteData.id) {\n let result;\n try {\n result = await updateNote({\n variables: {\n id: noteData.id,\n input: {\n title: noteData.title,\n content: noteData.content,\n visibility: noteData.visibility\n ? (noteData.visibility as GqlNoteVisibility)\n : undefined,\n },\n },\n });\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n closeEditorForQuota();\n return;\n }\n\n throw err;\n }\n noteId = result.data?.updateNote?.id;\n } else {\n let result;\n try {\n result = await createNote({\n variables: {\n input: {\n title: noteData.title || '',\n content: noteData.content || '',\n vibeId: effectiveVibeId,\n // F1 — stamp the session so the note shows in this session's\n // drawer; it stays workspace-reusable everywhere else.\n sessionId: context === 'session' ? sessionId : undefined,\n visibility: noteData.visibility\n ? (noteData.visibility as GqlNoteVisibility)\n : GqlNoteVisibility.Workspace,\n },\n },\n });\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n closeEditorForQuota();\n return;\n }\n\n throw err;\n }\n noteId = result.data?.createNote?.id;\n }\n\n // Assign tags\n if (noteId && noteData.selectedTagIds && noteData.selectedTagIds.length > 0) {\n await replaceNoteTags({\n variables: { input: { noteId, tagIds: noteData.selectedTagIds } },\n });\n } else if (noteId && noteData.selectedTagIds?.length === 0 && noteData.id) {\n await replaceNoteTags({\n variables: { input: { noteId, tagIds: [] } },\n });\n }\n\n setShowEditor(false);\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to save note:', err);\n }\n };\n\n const handleShareNote = async (note: Note) => {\n const newVisibility =\n note.visibility === 'PRIVATE' ? GqlNoteVisibility.Workspace : GqlNoteVisibility.Private;\n try {\n await shareNote({ variables: { id: note.id, visibility: newVisibility } });\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to toggle note visibility:', err);\n }\n };\n\n // Opens the generic Share dialog for a note (users / link / vibe).\n const handleShareNoteAccess = noteSharingEnabled\n ? (note: Note) => setGenericShareNote(note)\n : undefined;\n\n // Stats\n const stats = {\n total: notes.length,\n pinned: notes.filter((n) => n.isPinned).length,\n };\n\n // Vibe options for editor\n const vibeOptionsForEditor = useMemo(() => {\n if (context === 'vibe') return [];\n return agentVibes;\n }, [context, agentVibes]);\n\n // Permission guard\n if (!permissionsLoading && permissions && !canListNotes) {\n return (\n <AccessDenied\n title=\"Access Denied\"\n description=\"You don't have permission to view notes.\"\n details=\"Required permission: note:list\"\n />\n );\n }\n\n if (loading && notes.length === 0) {\n return <LoadingState message=\"Loading notes...\" />;\n }\n\n if (error && notes.length === 0) {\n return (\n <ErrorState title=\"Failed to load notes\" message={error.message} onRetry={() => refetch()} />\n );\n }\n\n const isFiltered =\n searchQuery ||\n (context === 'agent' && vibeFilter !== 'all') ||\n tagFilter !== 'all' ||\n showPinnedOnly;\n\n return (\n <div className=\"space-y-4\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">Notes</h3>\n <p className=\"text-sm text-text-secondary\">\n {stats.total} {stats.total === 1 ? 'note' : 'notes'}, {stats.pinned} pinned\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n title=\"Refresh notes\"\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <PermissionButton permission={VIBE_PERMISSIONS.NOTE_CREATE}>\n <button\n type=\"button\"\n onClick={handleCreateNote}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n New Note\n </button>\n </PermissionButton>\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder=\"Search notes...\"\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n <div className=\"flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0\">\n <button\n type=\"button\"\n onClick={() => setViewMode('grid')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'grid' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title=\"Grid view\"\n >\n <Grid className=\"size-4 text-text-secondary\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setViewMode('list')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'list' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title=\"List view\"\n >\n <List className=\"size-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 sm:gap-3 flex-wrap\">\n {context === 'agent' && (\n <FilterDropdown\n label=\"Vibe\"\n value={vibeFilter}\n options={vibeOptions}\n onChange={setVibeFilter}\n />\n )}\n <FilterDropdown\n label=\"Tag\"\n value={tagFilter}\n options={tagOptions}\n onChange={setTagFilter}\n />\n {/* Visibility filter */}\n <div className=\"flex items-center gap-1 bg-bg-sunken rounded-md p-0.5\">\n <button\n type=\"button\"\n onClick={() => setVisibilityFilter('all')}\n className={`px-2.5 py-1 text-xs rounded transition-colors ${visibilityFilter === 'all' ? 'bg-bg-surface text-text-primary shadow-sm' : 'text-text-muted hover:text-text-secondary'}`}\n >\n All\n </button>\n <button\n type=\"button\"\n onClick={() => setVisibilityFilter('WORKSPACE')}\n className={`flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${visibilityFilter === 'WORKSPACE' ? 'bg-bg-surface text-text-primary shadow-sm' : 'text-text-muted hover:text-text-secondary'}`}\n >\n <Globe className=\"size-3\" />\n Shared\n </button>\n <button\n type=\"button\"\n onClick={() => setVisibilityFilter('PRIVATE')}\n className={`flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${visibilityFilter === 'PRIVATE' ? 'bg-bg-surface text-text-primary shadow-sm' : 'text-text-muted hover:text-text-secondary'}`}\n >\n <Lock className=\"size-3\" />\n Private\n </button>\n </div>\n </div>\n </div>\n\n {/* Pinned toggle */}\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setShowPinnedOnly(!showPinnedOnly)}\n className={`flex items-center gap-2 px-3 py-1.5 text-sm rounded-full transition-colors ${\n showPinnedOnly\n ? 'bg-status-warning-bg-subtle text-status-warning-text'\n : 'bg-bg-sunken text-text-secondary hover:bg-bg-sunken/80'\n }`}\n >\n <Pin className=\"size-3\" />\n Pinned ({stats.pinned})\n </button>\n </div>\n\n {/* Results count */}\n {isFiltered ? (\n <p className=\"text-sm text-text-secondary\">\n Showing {sortedNotes.length} of {notes.length} notes\n {loading && <span className=\"ml-2 text-text-muted\">(refreshing…)</span>}\n </p>\n ) : null}\n\n {/* Notes display */}\n <AnimatePresence mode=\"wait\">\n {sortedNotes.length > 0 ? (\n viewMode === 'grid' ? (\n <MotionList\n key=\"grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {sortedNotes.map((note) => (\n <MotionItem key={note.id}>\n <NoteCard\n note={note}\n onOpen={handleNoteSelect}\n onEdit={handleNoteSelect}\n onPin={handlePinNote}\n onUnpin={handlePinNote}\n onDelete={handleDeleteNote}\n onShare={handleShareNote}\n onShareAccess={handleShareNoteAccess}\n />\n </MotionItem>\n ))}\n </MotionList>\n ) : (\n <NoteList\n key=\"list\"\n notes={sortedNotes}\n onOpen={handleNoteSelect}\n onEdit={handleNoteSelect}\n onPin={handlePinNote}\n onUnpin={handlePinNote}\n onDelete={handleDeleteNote}\n onShare={handleShareNote}\n onShareAccess={handleShareNoteAccess}\n />\n )\n ) : (\n <EmptyState\n icon={<FileText className=\"size-8 text-text-secondary\" />}\n title={isFiltered ? 'No notes found' : 'No notes yet'}\n description={\n isFiltered\n ? 'Try adjusting your search or filters'\n : 'Create your first note to start documenting your work'\n }\n action={\n !isFiltered && canCreateNote ? (\n <button\n type=\"button\"\n onClick={handleCreateNote}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n New Note\n </button>\n ) : undefined\n }\n />\n )}\n </AnimatePresence>\n\n {/* Note Editor Modal */}\n {showEditor && (\n <NoteEditor\n note={selectedNote || undefined}\n vibeOptions={vibeOptionsForEditor}\n defaultVibeId={context === 'vibe' ? vibeId : undefined}\n hideVibeSelect={context === 'vibe'}\n onSubmit={handleSaveNote}\n onCancel={() => setShowEditor(false)}\n />\n )}\n\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Note Quota Reached\"\n message=\"You've used all available note quota on your current plan. Upgrade your plan to create or update more notes.\"\n />\n\n {/* Generic note sharing dialog (users / link / vibe) */}\n {genericShareNote && (\n <NoteShareDialog\n note={{\n id: genericShareNote.id,\n title: genericShareNote.title,\n vibeId: genericShareNote.vibeId,\n }}\n open={Boolean(genericShareNote)}\n onOpenChange={(next) => {\n if (!next) setGenericShareNote(null);\n }}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"NotesTabPanel.js","names":[],"sources":["../../../src/components/notes/NotesTabPanel.tsx"],"sourcesContent":["import { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useState, useMemo } from 'react';\nimport { Plus, FileText, Grid, List, Pin, RefreshCw, Lock, Globe } from 'lucide-react';\nimport { AnimatePresence } from 'framer-motion';\nimport { useNavigate } from 'react-router-dom';\nimport { useApolloClient } from '@apollo/client/react';\nimport { MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\nimport { NoteCard } from './NoteCard';\nimport { NoteList } from './NoteList';\nimport { NoteEditor } from './NoteEditor';\nimport type { Note, NoteVisibility } from './types';\nimport type { NoteEditorSubmitData } from './NoteEditor';\nimport {\n SearchInput,\n FilterDropdown,\n EmptyState,\n LoadingState,\n ErrorState,\n QuotaExhaustedDialog,\n} from '@/components/shared';\nimport {\n useListNotesQuery,\n usePinNoteMutation,\n useUnpinNoteMutation,\n useDeleteNoteMutation,\n useCreateNoteMutation,\n useUpdateNoteMutation,\n useReplaceNoteTagsMutation,\n useAvailableNoteTagsQuery,\n useShareNoteMutation,\n ListNotesDocument,\n} from '@/generated/wspace-operations';\nimport { NoteVisibility as GqlNoteVisibility } from '@/generated/wspace-types';\nimport { PermissionButton, AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useFeatureFlag } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { isQuotaExhaustedError, markQuotaHandledLocally } from '@/utils/quotaUtils';\nimport { NoteShareDialog, SHARE_REGISTRY } from '@/components/sharing';\n\ntype ViewMode = 'grid' | 'list';\n\ninterface NotesTabPanelProps {\n /**\n * 'vibe' = single vibe context; 'agent' = multi-vibe agent context;\n * 'session' = notes authored against a single terminal session (F1).\n */\n context: 'vibe' | 'agent' | 'session';\n /** For vibe context: the single vibeId to scope notes to */\n vibeId?: string;\n /** For session context: the single sessionId to scope notes to */\n sessionId?: string;\n /** For agent context: the vibes belonging to the agent */\n agentVibes?: { id: string; name: string }[];\n}\n\n/**\n * Reusable notes panel for embedding as a tab in detail pages.\n * Supports vibe-scoped, agent-scoped, and session-scoped contexts.\n */\nexport function NotesTabPanel({ context, vibeId, sessionId, agentVibes = [] }: NotesTabPanelProps) {\n const { t } = useI18n();\n const navigate = useNavigate();\n const apolloClient = useApolloClient();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n\n const canListNotes = hasPermission(VIBE_PERMISSIONS.NOTE_LIST);\n const canCreateNote = hasPermission(VIBE_PERMISSIONS.NOTE_CREATE);\n const canDeleteNote = hasPermission(VIBE_PERMISSIONS.NOTE_DELETE);\n\n // Generic note sharing (full users/link/vibe dialog). Gated by the\n // `vibecontrols.sharing.note` flag (default ON) + note share permission.\n // Distinct from the legacy `onShare` visibility toggle, which stays as-is.\n const noteSharingFlagEnabled = useFeatureFlag(\n SHARE_REGISTRY.note.featureFlag,\n SHARE_REGISTRY.note.defaultEnabled\n );\n const canShareNote = hasPermission(SHARE_REGISTRY.note.permission);\n const noteSharingEnabled = noteSharingFlagEnabled && canShareNote;\n const [genericShareNote, setGenericShareNote] = useState<Note | null>(null);\n\n const [searchQuery, setSearchQuery] = useState('');\n const [vibeFilter, setVibeFilter] = useState('all');\n const [tagFilter, setTagFilter] = useState('all');\n const [visibilityFilter, setVisibilityFilter] = useState<'all' | 'PRIVATE' | 'WORKSPACE'>('all');\n const [showPinnedOnly, setShowPinnedOnly] = useState(false);\n const [viewMode, setViewMode] = useState<ViewMode>('grid');\n const [showEditor, setShowEditor] = useState(false);\n const [selectedNote, setSelectedNote] = useState<Note | null>(null);\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n\n // Evict cached notes list and refetch — bypasses stale cache-and-network data\n const evictAndRefetch = (refetch: () => void) => {\n apolloClient.cache.evict({ id: 'ROOT_QUERY', fieldName: 'notes' });\n apolloClient.cache.gc();\n refetch();\n };\n\n const [pinNote] = usePinNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [unpinNote] = useUnpinNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [deleteNote] = useDeleteNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [createNote] = useCreateNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [updateNote] = useUpdateNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [replaceNoteTags] = useReplaceNoteTagsMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n const [shareNote] = useShareNoteMutation({\n refetchQueries: [ListNotesDocument],\n awaitRefetchQueries: true,\n });\n\n const shouldSkipQueries = permissionsLoading || !canListNotes;\n\n const { data: availableTagsData } = useAvailableNoteTagsQuery({ skip: shouldSkipQueries });\n\n // Build query filter based on context\n const queryFilter = useMemo(() => {\n const visibilityVal =\n visibilityFilter !== 'all' ? (visibilityFilter as GqlNoteVisibility) : undefined;\n\n if (context === 'session' && sessionId) {\n return {\n sessionId,\n isPinned: showPinnedOnly ? true : undefined,\n visibility: visibilityVal,\n };\n }\n if (context === 'vibe' && vibeId) {\n return {\n vibeId,\n isPinned: showPinnedOnly ? true : undefined,\n visibility: visibilityVal,\n };\n }\n // Agent context: fetch all notes, filter client-side\n return {\n vibeId: vibeFilter === 'none' ? null : vibeFilter !== 'all' ? vibeFilter : undefined,\n isPinned: showPinnedOnly ? true : undefined,\n visibility: visibilityVal,\n };\n }, [context, vibeId, sessionId, vibeFilter, showPinnedOnly, visibilityFilter]);\n\n const { data, loading, error, refetch } = useListNotesQuery({\n variables: { filter: queryFilter, pagination: { limit: 50 } },\n fetchPolicy: 'cache-and-network',\n skip: shouldSkipQueries,\n });\n\n // Vibe filter options (agent context only)\n const vibeOptions = useMemo(() => {\n if (context !== 'agent') return [];\n return [\n { value: 'all', label: 'All Vibes' },\n { value: 'none', label: 'No Vibe (General)' },\n ...agentVibes.map((v) => ({ value: v.id, label: v.name })),\n ];\n }, [context, agentVibes]);\n\n // Tag label lookup by ID — used when federation doesn't return nested tag object\n type AvailableTag = { id: string; key: string; label: string; color?: string | null };\n const tagLabelMap = useMemo((): Map<string, AvailableTag> => {\n const tags = (availableTagsData?.availableNoteTags ?? []) as AvailableTag[];\n return new Map(tags.map((tag) => [tag.id, tag]));\n }, [availableTagsData?.availableNoteTags]);\n\n // Map GraphQL response to Note type\n const notes: Note[] = useMemo(() => {\n const rawNotes = data?.notes?.items ?? [];\n const mapped = rawNotes.map((note: NonNullable<typeof rawNotes>[number]) => ({\n id: note.id,\n workspaceId: note.workspaceId,\n vibeId: note.vibeId || null,\n title: note.title,\n content: note.content,\n tags: note.tags || [],\n tagAssignments:\n note.tagAssignments?.map((a: NonNullable<typeof note.tagAssignments>[number]) => {\n // `a.tag` may be null when federation doesn't resolve the tag entity.\n // Fall back to the availableNoteTags lookup so the label always shows.\n const resolvedTag = a.tag\n ? { id: a.tag.id, label: a.tag.label, key: a.tag.key, color: a.tag.color }\n : tagLabelMap.has(a.tagId)\n ? {\n id: a.tagId,\n label: tagLabelMap.get(a.tagId)!.label,\n key: tagLabelMap.get(a.tagId)!.key,\n color: tagLabelMap.get(a.tagId)!.color ?? null,\n }\n : undefined;\n return {\n id: a.id,\n tagId: a.tagId,\n tag: resolvedTag,\n entityType: a.entityType,\n entityId: a.entityId,\n source: a.source,\n assignedBy: a.assignedBy,\n assignedAt: a.assignedAt,\n };\n }) || [],\n isPinned: note.isPinned,\n visibility: (note.visibility ?? 'WORKSPACE') as NoteVisibility,\n createdBy: note.createdBy ?? '',\n metadata: (note.metadata as Record<string, unknown>) || {},\n createdAt: note.createdAt,\n updatedAt: note.updatedAt,\n vibe: note.vibe ? { id: note.vibe.id, name: note.vibe.name } : undefined,\n }));\n\n // Agent context: client-side filter to only agent's vibes\n if (context === 'agent' && agentVibes.length > 0) {\n const vibeIdSet = new Set(agentVibes.map((v) => v.id));\n return mapped.filter((n: Note) => n.vibeId && vibeIdSet.has(n.vibeId));\n }\n\n return mapped;\n }, [data?.notes?.items, context, agentVibes, tagLabelMap]);\n\n // Tag filter options\n const tagOptions = useMemo(() => {\n const tags = availableTagsData?.availableNoteTags ?? [];\n return [\n { value: 'all', label: 'All Tags' },\n ...tags.map((tag: AvailableTag) => ({\n value: tag.id,\n label: tag.label,\n })),\n ];\n }, [availableTagsData?.availableNoteTags]);\n\n // Client-side search and tag filtering\n const filteredNotes = useMemo(() => {\n return notes.filter((note) => {\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n const matchesSearch =\n note.title.toLowerCase().includes(query) ||\n note.content.toLowerCase().includes(query) ||\n note.tagAssignments?.some((a) => a.tag?.label?.toLowerCase().includes(query));\n if (!matchesSearch) return false;\n }\n if (tagFilter !== 'all') {\n const hasTag = note.tagAssignments?.some((a) => a.tagId === tagFilter);\n if (!hasTag) return false;\n }\n return true;\n });\n }, [notes, searchQuery, tagFilter]);\n\n // Sort: pinned first, then by updatedAt\n const sortedNotes = useMemo(() => {\n return [...filteredNotes].sort((a, b) => {\n if (a.isPinned && !b.isPinned) return -1;\n if (!a.isPinned && b.isPinned) return 1;\n return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();\n });\n }, [filteredNotes]);\n\n const handleNoteSelect = (note: Note) => {\n setSelectedNote(note);\n setShowEditor(true);\n };\n\n const handleCreateNote = () => {\n setSelectedNote(null);\n setShowEditor(true);\n };\n\n const handlePinNote = async (note: Note) => {\n try {\n if (note.isPinned) {\n await unpinNote({ variables: { id: note.id } });\n } else {\n await pinNote({ variables: { id: note.id } });\n }\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to toggle pin for note:', err);\n }\n };\n\n const handleDeleteNote = async (note: Note) => {\n try {\n await deleteNote({ variables: { id: note.id } });\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to delete note:', err);\n }\n };\n\n const handleSaveNote = async (noteData: NoteEditorSubmitData) => {\n const closeEditorForQuota = () => {\n setShowEditor(false);\n setSelectedNote(null);\n markQuotaHandledLocally();\n setShowQuotaExhausted(true);\n };\n\n try {\n let noteId: string | undefined;\n\n // In vibe context, always force the vibeId\n const effectiveVibeId = context === 'vibe' ? vibeId : noteData.vibeId;\n\n if (noteData.id) {\n let result;\n try {\n result = await updateNote({\n variables: {\n id: noteData.id,\n input: {\n title: noteData.title,\n content: noteData.content,\n visibility: noteData.visibility\n ? (noteData.visibility as GqlNoteVisibility)\n : undefined,\n },\n },\n });\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n closeEditorForQuota();\n return;\n }\n\n throw err;\n }\n noteId = result.data?.updateNote?.id;\n } else {\n let result;\n try {\n result = await createNote({\n variables: {\n input: {\n title: noteData.title || '',\n content: noteData.content || '',\n vibeId: effectiveVibeId,\n // F1 — stamp the session so the note shows in this session's\n // drawer; it stays workspace-reusable everywhere else.\n sessionId: context === 'session' ? sessionId : undefined,\n visibility: noteData.visibility\n ? (noteData.visibility as GqlNoteVisibility)\n : GqlNoteVisibility.Workspace,\n },\n },\n });\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n closeEditorForQuota();\n return;\n }\n\n throw err;\n }\n noteId = result.data?.createNote?.id;\n }\n\n // Assign tags\n if (noteId && noteData.selectedTagIds && noteData.selectedTagIds.length > 0) {\n await replaceNoteTags({\n variables: { input: { noteId, tagIds: noteData.selectedTagIds } },\n });\n } else if (noteId && noteData.selectedTagIds?.length === 0 && noteData.id) {\n await replaceNoteTags({\n variables: { input: { noteId, tagIds: [] } },\n });\n }\n\n setShowEditor(false);\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to save note:', err);\n }\n };\n\n const handleShareNote = async (note: Note) => {\n const newVisibility =\n note.visibility === 'PRIVATE' ? GqlNoteVisibility.Workspace : GqlNoteVisibility.Private;\n try {\n await shareNote({ variables: { id: note.id, visibility: newVisibility } });\n evictAndRefetch(refetch);\n } catch (err) {\n console.error('Failed to toggle note visibility:', err);\n }\n };\n\n // Opens the generic Share dialog for a note (users / link / vibe).\n const handleShareNoteAccess = noteSharingEnabled\n ? (note: Note) => setGenericShareNote(note)\n : undefined;\n\n // Stats\n const stats = {\n total: notes.length,\n pinned: notes.filter((n) => n.isPinned).length,\n };\n\n // Vibe options for editor\n const vibeOptionsForEditor = useMemo(() => {\n if (context === 'vibe') return [];\n return agentVibes;\n }, [context, agentVibes]);\n\n // Permission guard\n if (!permissionsLoading && permissions && !canListNotes) {\n return (\n <AccessDenied\n title=\"Access Denied\"\n description=\"You don't have permission to view notes.\"\n details=\"Required permission: note:list\"\n />\n );\n }\n\n if (loading && notes.length === 0) {\n return <LoadingState message=\"Loading notes...\" />;\n }\n\n if (error && notes.length === 0) {\n return (\n <ErrorState title=\"Failed to load notes\" message={error.message} onRetry={() => refetch()} />\n );\n }\n\n const isFiltered =\n searchQuery ||\n (context === 'agent' && vibeFilter !== 'all') ||\n tagFilter !== 'all' ||\n showPinnedOnly;\n\n return (\n <div className=\"space-y-4\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">Notes</h3>\n <p className=\"text-sm text-text-secondary\">\n {stats.total} {stats.total === 1 ? 'note' : 'notes'}, {stats.pinned} pinned\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n title=\"Refresh notes\"\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <PermissionButton permission={VIBE_PERMISSIONS.NOTE_CREATE}>\n <button\n type=\"button\"\n onClick={handleCreateNote}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n New Note\n </button>\n </PermissionButton>\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder=\"Search notes...\"\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n <div className=\"flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0\">\n <button\n type=\"button\"\n onClick={() => setViewMode('grid')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'grid' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title=\"Grid view\"\n >\n <Grid className=\"size-4 text-text-secondary\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setViewMode('list')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'list' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title=\"List view\"\n >\n <List className=\"size-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 sm:gap-3 flex-wrap\">\n {context === 'agent' && (\n <FilterDropdown\n label=\"Vibe\"\n value={vibeFilter}\n options={vibeOptions}\n onChange={setVibeFilter}\n />\n )}\n <FilterDropdown\n label=\"Tag\"\n value={tagFilter}\n options={tagOptions}\n onChange={setTagFilter}\n />\n {/* Visibility filter */}\n <div className=\"flex items-center gap-1 bg-bg-sunken rounded-md p-0.5\">\n <button\n type=\"button\"\n onClick={() => setVisibilityFilter('all')}\n className={`px-2.5 py-1 text-xs rounded transition-colors ${visibilityFilter === 'all' ? 'bg-bg-surface text-text-primary shadow-sm' : 'text-text-muted hover:text-text-secondary'}`}\n >\n All\n </button>\n <button\n type=\"button\"\n onClick={() => setVisibilityFilter('WORKSPACE')}\n className={`flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${visibilityFilter === 'WORKSPACE' ? 'bg-bg-surface text-text-primary shadow-sm' : 'text-text-muted hover:text-text-secondary'}`}\n >\n <Globe className=\"size-3\" />\n Shared\n </button>\n <button\n type=\"button\"\n onClick={() => setVisibilityFilter('PRIVATE')}\n className={`flex items-center gap-1 px-2.5 py-1 text-xs rounded transition-colors ${visibilityFilter === 'PRIVATE' ? 'bg-bg-surface text-text-primary shadow-sm' : 'text-text-muted hover:text-text-secondary'}`}\n >\n <Lock className=\"size-3\" />\n Private\n </button>\n </div>\n </div>\n </div>\n\n {/* Pinned toggle */}\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setShowPinnedOnly(!showPinnedOnly)}\n className={`flex items-center gap-2 px-3 py-1.5 text-sm rounded-full transition-colors ${\n showPinnedOnly\n ? 'bg-status-warning-bg-subtle text-status-warning-text'\n : 'bg-bg-sunken text-text-secondary hover:bg-bg-sunken/80'\n }`}\n >\n <Pin className=\"size-3\" />\n Pinned ({stats.pinned})\n </button>\n </div>\n\n {/* Results count */}\n {isFiltered ? (\n <p className=\"text-sm text-text-secondary\">\n Showing {sortedNotes.length} of {notes.length} notes\n {loading && <span className=\"ml-2 text-text-muted\">(refreshing…)</span>}\n </p>\n ) : null}\n\n {/* Notes display */}\n <AnimatePresence mode=\"wait\">\n {sortedNotes.length > 0 ? (\n viewMode === 'grid' ? (\n <MotionList\n key=\"grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {sortedNotes.map((note) => (\n <MotionItem key={note.id}>\n <NoteCard\n note={note}\n onOpen={handleNoteSelect}\n onEdit={handleNoteSelect}\n onPin={handlePinNote}\n onUnpin={handlePinNote}\n onDelete={canDeleteNote ? handleDeleteNote : undefined}\n onShare={handleShareNote}\n onShareAccess={handleShareNoteAccess}\n />\n </MotionItem>\n ))}\n </MotionList>\n ) : (\n <NoteList\n key=\"list\"\n notes={sortedNotes}\n onOpen={handleNoteSelect}\n onEdit={handleNoteSelect}\n onPin={handlePinNote}\n onUnpin={handlePinNote}\n onDelete={canDeleteNote ? handleDeleteNote : undefined}\n onShare={handleShareNote}\n onShareAccess={handleShareNoteAccess}\n />\n )\n ) : (\n <EmptyState\n icon={<FileText className=\"size-8 text-text-secondary\" />}\n title={isFiltered ? 'No notes found' : 'No notes yet'}\n description={\n isFiltered\n ? 'Try adjusting your search or filters'\n : 'Create your first note to start documenting your work'\n }\n action={\n !isFiltered && canCreateNote ? (\n <button\n type=\"button\"\n onClick={handleCreateNote}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n New Note\n </button>\n ) : undefined\n }\n />\n )}\n </AnimatePresence>\n\n {/* Note Editor Modal */}\n {showEditor && (\n <NoteEditor\n note={selectedNote || undefined}\n vibeOptions={vibeOptionsForEditor}\n defaultVibeId={context === 'vibe' ? vibeId : undefined}\n hideVibeSelect={context === 'vibe'}\n onSubmit={handleSaveNote}\n onCancel={() => setShowEditor(false)}\n />\n )}\n\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Note Quota Reached\"\n message=\"You've used all available note quota on your current plan. Upgrade your plan to create or update more notes.\"\n />\n\n {/* Generic note sharing dialog (users / link / vibe) */}\n {genericShareNote && (\n <NoteShareDialog\n note={{\n id: genericShareNote.id,\n title: genericShareNote.title,\n vibeId: genericShareNote.vibeId,\n }}\n open={Boolean(genericShareNote)}\n onOpenChange={(next) => {\n if (!next) setGenericShareNote(null);\n }}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}