@open-mercato/ui 0.7.0 → 0.7.1-develop.7102.1.b41f7e3e51
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/.turbo/turbo-build.log +1 -1
- package/dist/ai/records/ActivityCard.js +4 -3
- package/dist/ai/records/ActivityCard.js.map +2 -2
- package/dist/ai/records/DealCard.js +4 -3
- package/dist/ai/records/DealCard.js.map +2 -2
- package/dist/ai/records/ProductCard.js +3 -2
- package/dist/ai/records/ProductCard.js.map +2 -2
- package/dist/backend/AppShell.js +129 -106
- package/dist/backend/AppShell.js.map +2 -2
- package/dist/backend/DataTable.js +20 -7
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/detail/NotesSection.js +26 -20
- package/dist/backend/detail/NotesSection.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.generated.js +4 -0
- package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
- package/dist/backend/injection/useRegisteredComponent.js +24 -6
- package/dist/backend/injection/useRegisteredComponent.js.map +2 -2
- package/dist/backend/inputs/ComboboxInput.js +8 -4
- package/dist/backend/inputs/ComboboxInput.js.map +2 -2
- package/dist/backend/inputs/LookupSelect.js +8 -8
- package/dist/backend/inputs/LookupSelect.js.map +2 -2
- package/dist/backend/sidebar/SidebarCustomizationEditor.js +36 -30
- package/dist/backend/sidebar/SidebarCustomizationEditor.js.map +2 -2
- package/dist/backend/utils/crud.js.map +2 -2
- package/dist/primitives/alert.js +1 -1
- package/dist/primitives/alert.js.map +2 -2
- package/dist/primitives/icon-button.js +20 -1
- package/dist/primitives/icon-button.js.map +2 -2
- package/dist/primitives/pagination.js +14 -9
- package/dist/primitives/pagination.js.map +2 -2
- package/dist/primitives/rich-editor.js +14 -7
- package/dist/primitives/rich-editor.js.map +2 -2
- package/dist/utils/format.js +5 -5
- package/dist/utils/format.js.map +2 -2
- package/package.json +5 -4
- package/src/ai/parts/__tests__/ConfirmationCard.test.tsx +2 -0
- package/src/ai/records/ActivityCard.tsx +4 -3
- package/src/ai/records/DealCard.tsx +4 -3
- package/src/ai/records/ProductCard.tsx +3 -2
- package/src/backend/AppShell.tsx +89 -58
- package/src/backend/DataTable.tsx +44 -10
- package/src/backend/__tests__/AppShell.test.tsx +162 -1
- package/src/backend/__tests__/DataTable.cappedPagination.test.tsx +122 -0
- package/src/backend/__tests__/DataTable.headerWrap.test.tsx +111 -0
- package/src/backend/__tests__/DataTable.render.test.tsx +37 -0
- package/src/backend/__tests__/NotesSection.test.tsx +89 -0
- package/src/backend/__tests__/useRegisteredComponent.identity.test.tsx +305 -0
- package/src/backend/detail/NotesSection.tsx +92 -67
- package/src/backend/icons/lucideRegistry.generated.tsx +4 -0
- package/src/backend/injection/useRegisteredComponent.tsx +49 -8
- package/src/backend/inputs/ComboboxInput.tsx +21 -5
- package/src/backend/inputs/LookupSelect.tsx +8 -8
- package/src/backend/inputs/__tests__/ComboboxInput.test.tsx +142 -0
- package/src/backend/inputs/__tests__/LookupSelect.test.tsx +75 -0
- package/src/backend/sidebar/SidebarCustomizationEditor.tsx +14 -11
- package/src/backend/utils/crud.ts +2 -0
- package/src/primitives/__tests__/alert.test.tsx +41 -1
- package/src/primitives/__tests__/icon-button.test.tsx +70 -0
- package/src/primitives/__tests__/notification.test.tsx +1 -1
- package/src/primitives/__tests__/pagination.test.tsx +54 -0
- package/src/primitives/__tests__/rich-editor.test.tsx +43 -0
- package/src/primitives/alert.tsx +5 -2
- package/src/primitives/icon-button.tsx +20 -1
- package/src/primitives/pagination.tsx +40 -9
- package/src/primitives/rich-editor.tsx +9 -4
- package/src/utils/__tests__/format.test.ts +27 -14
- package/src/utils/format.ts +10 -5
|
@@ -134,7 +134,10 @@ function NotesSectionImpl({
|
|
|
134
134
|
iconSuggestions,
|
|
135
135
|
readMarkdownPreference,
|
|
136
136
|
writeMarkdownPreference,
|
|
137
|
-
disableMarkdown
|
|
137
|
+
disableMarkdown,
|
|
138
|
+
forceMarkdown,
|
|
139
|
+
hideMarkdownToggle,
|
|
140
|
+
disableAppearance
|
|
138
141
|
}) {
|
|
139
142
|
const { confirm, ConfirmDialogElement } = useConfirmDialog();
|
|
140
143
|
const t = React.useMemo(() => translator ?? ((key, fallback) => fallback ?? key), [translator]);
|
|
@@ -246,13 +249,16 @@ function NotesSectionImpl({
|
|
|
246
249
|
const [draftIcon, setDraftIcon] = React.useState(null);
|
|
247
250
|
const [draftColor, setDraftColor] = React.useState(null);
|
|
248
251
|
const [isMarkdownEnabled, setIsMarkdownEnabled] = React.useState(false);
|
|
252
|
+
const isMarkdownActive = !disableMarkdown && (Boolean(forceMarkdown) || isMarkdownEnabled);
|
|
253
|
+
const showMarkdownToggle = !disableMarkdown && !forceMarkdown && !hideMarkdownToggle;
|
|
254
|
+
const showAppearanceControls = !disableAppearance;
|
|
249
255
|
const textareaRef = React.useRef(null);
|
|
250
256
|
const formRef = React.useRef(null);
|
|
251
257
|
const focusComposer = React.useCallback(() => {
|
|
252
258
|
if (!hasEntity) return;
|
|
253
259
|
setComposerOpen(true);
|
|
254
260
|
window.requestAnimationFrame(() => {
|
|
255
|
-
if (
|
|
261
|
+
if (isMarkdownActive) {
|
|
256
262
|
const markdownTextarea = formRef.current?.querySelector("textarea");
|
|
257
263
|
if (markdownTextarea instanceof HTMLTextAreaElement) {
|
|
258
264
|
markdownTextarea.focus();
|
|
@@ -265,7 +271,7 @@ function NotesSectionImpl({
|
|
|
265
271
|
element.focus();
|
|
266
272
|
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
267
273
|
});
|
|
268
|
-
}, [formRef, hasEntity,
|
|
274
|
+
}, [formRef, hasEntity, isMarkdownActive]);
|
|
269
275
|
const [appearanceDialogState, setAppearanceDialogState] = React.useState(null);
|
|
270
276
|
const [appearanceDialogSaving, setAppearanceDialogSaving] = React.useState(false);
|
|
271
277
|
const [appearanceDialogError, setAppearanceDialogError] = React.useState(null);
|
|
@@ -369,7 +375,7 @@ function NotesSectionImpl({
|
|
|
369
375
|
}, []);
|
|
370
376
|
React.useEffect(() => {
|
|
371
377
|
adjustTextareaSize(textareaRef.current);
|
|
372
|
-
}, [adjustTextareaSize, draftBody,
|
|
378
|
+
}, [adjustTextareaSize, draftBody, isMarkdownActive, composerOpen]);
|
|
373
379
|
React.useEffect(() => {
|
|
374
380
|
const preference = readMarkdownPreference ? readMarkdownPreference() : null;
|
|
375
381
|
if (preference !== null) {
|
|
@@ -731,7 +737,7 @@ function NotesSectionImpl({
|
|
|
731
737
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
732
738
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: label("addLabel") }),
|
|
733
739
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
734
|
-
/* @__PURE__ */ jsxs(
|
|
740
|
+
showAppearanceControls ? /* @__PURE__ */ jsxs(
|
|
735
741
|
Button,
|
|
736
742
|
{
|
|
737
743
|
type: "button",
|
|
@@ -747,19 +753,19 @@ function NotesSectionImpl({
|
|
|
747
753
|
/* @__PURE__ */ jsx(Palette, { className: "h-4 w-4" })
|
|
748
754
|
]
|
|
749
755
|
}
|
|
750
|
-
),
|
|
751
|
-
|
|
756
|
+
) : null,
|
|
757
|
+
showMarkdownToggle ? /* @__PURE__ */ jsx(
|
|
752
758
|
Button,
|
|
753
759
|
{
|
|
754
760
|
type: "button",
|
|
755
|
-
variant:
|
|
761
|
+
variant: isMarkdownActive ? "secondary" : "ghost",
|
|
756
762
|
size: "icon",
|
|
757
763
|
onClick: handleMarkdownToggle,
|
|
758
|
-
"aria-pressed":
|
|
764
|
+
"aria-pressed": isMarkdownActive,
|
|
759
765
|
disabled: isSubmitting || isLoading,
|
|
760
766
|
children: /* @__PURE__ */ jsx(FileCode, { className: "h-4 w-4" })
|
|
761
767
|
}
|
|
762
|
-
),
|
|
768
|
+
) : null,
|
|
763
769
|
/* @__PURE__ */ jsx(
|
|
764
770
|
Button,
|
|
765
771
|
{
|
|
@@ -829,7 +835,7 @@ function NotesSectionImpl({
|
|
|
829
835
|
{
|
|
830
836
|
value: draftBody,
|
|
831
837
|
onChange: setDraftBody,
|
|
832
|
-
isMarkdownEnabled,
|
|
838
|
+
isMarkdownEnabled: isMarkdownActive,
|
|
833
839
|
disableMarkdown,
|
|
834
840
|
rows: 1,
|
|
835
841
|
placeholder: label("placeholder"),
|
|
@@ -952,7 +958,7 @@ function NotesSectionImpl({
|
|
|
952
958
|
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
953
959
|
}
|
|
954
960
|
),
|
|
955
|
-
/* @__PURE__ */ jsx(
|
|
961
|
+
showAppearanceControls ? /* @__PURE__ */ jsx(
|
|
956
962
|
Button,
|
|
957
963
|
{
|
|
958
964
|
type: "button",
|
|
@@ -971,7 +977,7 @@ function NotesSectionImpl({
|
|
|
971
977
|
disabled: appearanceDialogSaving && editingAppearanceNoteId === note.id,
|
|
972
978
|
children: isAppearanceSaving ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Palette, { className: "h-4 w-4" })
|
|
973
979
|
}
|
|
974
|
-
),
|
|
980
|
+
) : null,
|
|
975
981
|
/* @__PURE__ */ jsx(
|
|
976
982
|
Button,
|
|
977
983
|
{
|
|
@@ -996,7 +1002,7 @@ function NotesSectionImpl({
|
|
|
996
1002
|
{
|
|
997
1003
|
value: contentEditor.value,
|
|
998
1004
|
onChange: (nextValue) => setContentEditor((prev) => ({ ...prev, value: nextValue })),
|
|
999
|
-
isMarkdownEnabled,
|
|
1005
|
+
isMarkdownEnabled: isMarkdownActive,
|
|
1000
1006
|
disableMarkdown,
|
|
1001
1007
|
rows: 3,
|
|
1002
1008
|
textareaRef: contentTextareaRef,
|
|
@@ -1012,19 +1018,19 @@ function NotesSectionImpl({
|
|
|
1012
1018
|
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
1013
1019
|
label("saving")
|
|
1014
1020
|
] }) : inlineLabel("saveShortcut") }),
|
|
1015
|
-
|
|
1021
|
+
showMarkdownToggle ? /* @__PURE__ */ jsx(
|
|
1016
1022
|
Button,
|
|
1017
1023
|
{
|
|
1018
1024
|
type: "button",
|
|
1019
1025
|
variant: "ghost",
|
|
1020
1026
|
size: "icon",
|
|
1021
1027
|
onClick: handleMarkdownToggle,
|
|
1022
|
-
"aria-pressed":
|
|
1023
|
-
className:
|
|
1028
|
+
"aria-pressed": isMarkdownActive,
|
|
1029
|
+
className: isMarkdownActive ? "text-primary" : void 0,
|
|
1024
1030
|
disabled: contentSavingId === note.id,
|
|
1025
1031
|
children: /* @__PURE__ */ jsx(FileCode, { className: "h-4 w-4" })
|
|
1026
1032
|
}
|
|
1027
|
-
),
|
|
1033
|
+
) : null,
|
|
1028
1034
|
/* @__PURE__ */ jsx(
|
|
1029
1035
|
Button,
|
|
1030
1036
|
{
|
|
@@ -1070,7 +1076,7 @@ function NotesSectionImpl({
|
|
|
1070
1076
|
),
|
|
1071
1077
|
isLoading || (pagedMode ? !hasMore : visibleCount >= notes.length) ? null : /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleLoadMore, children: loadMoreLabel }) })
|
|
1072
1078
|
] }),
|
|
1073
|
-
/* @__PURE__ */ jsx(
|
|
1079
|
+
showAppearanceControls ? /* @__PURE__ */ jsx(
|
|
1074
1080
|
AppearanceDialog,
|
|
1075
1081
|
{
|
|
1076
1082
|
open: appearanceDialogOpen,
|
|
@@ -1091,7 +1097,7 @@ function NotesSectionImpl({
|
|
|
1091
1097
|
savingLabel: appearanceDialogSavingLabel,
|
|
1092
1098
|
cancelLabel: label("appearance.cancel")
|
|
1093
1099
|
}
|
|
1094
|
-
),
|
|
1100
|
+
) : null,
|
|
1095
1101
|
ConfirmDialogElement
|
|
1096
1102
|
] });
|
|
1097
1103
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/backend/detail/NotesSection.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { PluggableList } from 'unified'\nimport type { AppearanceSelectorLabels } from '@open-mercato/core/modules/dictionaries/components/AppearanceSelector'\nimport { AppearanceDialog } from '@open-mercato/core/modules/customers/components/detail/AppearanceDialog'\nimport type { IconOption } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ArrowUpRightSquare, FileCode, Loader2, Palette, Pencil, Plus, Trash2 } from 'lucide-react'\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\nimport { hasMoreFromPage } from '@open-mercato/shared/lib/pagination/load-more'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { flash } from '../FlashMessages'\nimport { surfaceRecordConflict } from '../conflicts'\nimport { SwitchableMarkdownInput } from '../inputs/SwitchableMarkdownInput'\nimport { ErrorMessage } from './ErrorMessage'\nimport { LoadingMessage } from './LoadingMessage'\nimport { TabEmptyState } from './TabEmptyState'\nimport { useConfirmDialog } from '../confirm-dialog'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\nimport { ComponentReplacementHandles } from '@open-mercato/shared/modules/widgets/component-registry'\nimport { MarkdownPreview } from '../markdown'\nimport { useRegisteredComponent } from '../injection/useRegisteredComponent'\ntype Translator = (key: string, fallback?: string, params?: Record<string, string | number>) => string\n\nconst NOTES_PAGE_SIZE = 20\n\nconst isTestEnv =\n typeof process !== 'undefined' &&\n (process.env.NODE_ENV === 'test' || typeof process.env.JEST_WORKER_ID !== 'undefined')\n\nexport type SectionAction = {\n label: React.ReactNode\n onClick: () => void\n disabled?: boolean\n icon?: React.ReactNode\n}\n\nexport type TabEmptyStateConfig = {\n title: string\n actionLabel: string\n description?: string\n}\n\nexport type CommentSummary = {\n id: string\n body: string\n createdAt: string\n updatedAt?: string | null\n authorUserId?: string | null\n authorName?: string | null\n authorEmail?: string | null\n dealId?: string | null\n dealTitle?: string | null\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesCreatePayload = {\n entityId: string\n body: string\n appearanceIcon: string | null\n appearanceColor: string | null\n dealId?: string | null\n}\n\nexport type NotesUpdatePayload = {\n body?: string\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesDataAdapter<C = unknown> = {\n list: (params: { entityId: string | null; dealId: string | null; context?: C }) => Promise<CommentSummary[]>\n listPage?: (params: {\n entityId: string | null\n dealId: string | null\n page: number\n pageSize: number\n context?: C\n }) => Promise<{\n items: CommentSummary[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n }>\n create: (params: NotesCreatePayload & { context?: C }) => Promise<Partial<CommentSummary> | void>\n update: (params: { id: string; patch: NotesUpdatePayload; updatedAt?: string | null; context?: C }) => Promise<void>\n delete: (params: { id: string; updatedAt?: string | null; context?: C }) => Promise<void>\n}\n\ntype RenderIconFn = (icon: string, className?: string) => React.ReactNode\ntype RenderColorFn = (color: string, className?: string) => React.ReactNode\n\nlet markdownPluginsPromise: Promise<PluggableList> | null = null\n\nasync function loadMarkdownPlugins(): Promise<PluggableList> {\n if (isTestEnv) return []\n if (!markdownPluginsPromise) {\n markdownPluginsPromise = import('remark-gfm')\n .then((mod) => [mod.default ?? mod] as PluggableList)\n .catch(() => [])\n }\n return markdownPluginsPromise\n}\n\nfunction generateTempId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') return crypto.randomUUID()\n return `tmp_${Math.random().toString(36).slice(2)}`\n}\n\n\n\ntype TimelineItemHeaderProps = {\n title: React.ReactNode\n subtitle?: React.ReactNode\n timestamp?: string | Date | null\n fallbackTimestampLabel?: React.ReactNode\n icon?: string | null\n color?: string | null\n iconSize?: 'sm' | 'md'\n className?: string\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n}\n\nfunction TimelineItemHeader({\n title,\n subtitle,\n timestamp,\n fallbackTimestampLabel,\n icon,\n color,\n iconSize = 'md',\n className,\n renderIcon,\n renderColor,\n}: TimelineItemHeaderProps) {\n const wrapperSize = iconSize === 'sm' ? 'h-6 w-6' : 'h-8 w-8'\n const iconSizeClass = iconSize === 'sm' ? 'h-3.5 w-3.5' : 'h-4 w-4'\n const resolvedTimestamp = React.useMemo(() => {\n if (subtitle) return subtitle\n if (!timestamp) return fallbackTimestampLabel ?? null\n const value = typeof timestamp === 'string' ? timestamp : timestamp.toISOString()\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallbackTimestampLabel ?? null\n const now = Date.now()\n const diff = Math.abs(now - date.getTime())\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000\n const relativeLabel = diff <= THIRTY_DAYS_MS ? formatRelativeTime(value) : null\n const absoluteLabel = formatDateTime(value)\n if (relativeLabel) {\n return (\n <span title={absoluteLabel ?? undefined}>\n {relativeLabel}\n </span>\n )\n }\n return absoluteLabel ?? fallbackTimestampLabel ?? null\n }, [fallbackTimestampLabel, subtitle, timestamp])\n\n return (\n <div className={['flex items-start gap-3', className].filter(Boolean).join(' ')}>\n {icon && renderIcon ? (\n <span className={['inline-flex items-center justify-center rounded border border-border bg-muted/50', wrapperSize].join(' ')}>\n {renderIcon(icon, iconSizeClass)}\n </span>\n ) : null}\n <div className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">{title}</span>\n {color && renderColor ? renderColor(color, 'h-3 w-3 rounded-full border border-border') : null}\n </div>\n {resolvedTimestamp ? <div className=\"text-xs text-muted-foreground\">{resolvedTimestamp}</div> : null}\n </div>\n </div>\n )\n}\n\nexport type NotesSectionProps<C = unknown> = {\n entityId: string | null\n dealId?: string | null\n emptyLabel: string\n viewerUserId: string | null\n viewerName?: string | null\n viewerEmail?: string | null\n addActionLabel: string\n emptyState: TabEmptyStateConfig\n onActionChange?: (action: SectionAction | null) => void\n translator?: Translator\n labelPrefix?: string\n inlineLabelPrefix?: string\n onLoadingChange?: (isLoading: boolean) => void\n dealOptions?: Array<{ id: string; label: string }>\n entityOptions?: Array<{ id: string; label: string }>\n dataAdapter: NotesDataAdapter<C>\n dataContext?: C\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n iconSuggestions?: IconOption[]\n readMarkdownPreference?: () => boolean | null\n writeMarkdownPreference?: (value: boolean) => void\n disableMarkdown?: boolean\n}\n\nexport function sanitizeHexColor(value: string | null): string | null {\n if (!value) return null\n const trimmed = value.trim()\n return /^#([0-9a-f]{6})$/i.test(trimmed) ? trimmed.toLowerCase() : null\n}\n\nexport function mapCommentSummary(input: unknown): CommentSummary {\n const data = (typeof input === 'object' && input !== null ? input : {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : generateTempId()\n const body = typeof data.body === 'string' ? data.body : ''\n const createdAt =\n typeof data.createdAt === 'string'\n ? data.createdAt\n : typeof data.created_at === 'string'\n ? data.created_at\n : new Date().toISOString()\n const updatedAt =\n typeof data.updatedAt === 'string'\n ? data.updatedAt\n : typeof data.updated_at === 'string'\n ? data.updated_at\n : null\n const authorUserId =\n typeof data.authorUserId === 'string'\n ? data.authorUserId\n : typeof data.author_user_id === 'string'\n ? data.author_user_id\n : null\n const authorName =\n typeof data.authorName === 'string'\n ? data.authorName\n : typeof data.author_name === 'string'\n ? data.author_name\n : null\n const authorEmail =\n typeof data.authorEmail === 'string'\n ? data.authorEmail\n : typeof data.author_email === 'string'\n ? data.author_email\n : null\n const dealId =\n typeof data.dealId === 'string'\n ? data.dealId\n : typeof data.deal_id === 'string'\n ? data.deal_id\n : null\n const dealTitle =\n typeof data.dealTitle === 'string'\n ? data.dealTitle\n : typeof data.deal_title === 'string'\n ? data.deal_title\n : null\n const appearanceIcon =\n typeof data.appearanceIcon === 'string'\n ? data.appearanceIcon\n : typeof data.appearance_icon === 'string'\n ? data.appearance_icon\n : null\n const appearanceColor =\n typeof data.appearanceColor === 'string'\n ? data.appearanceColor\n : typeof data.appearance_color === 'string'\n ? data.appearance_color\n : null\n return {\n id,\n body,\n createdAt,\n updatedAt,\n authorUserId,\n authorName,\n authorEmail,\n dealId,\n dealTitle,\n appearanceIcon,\n appearanceColor,\n }\n}\n\nfunction NotesSectionImpl<C = unknown>({\n entityId,\n dealId,\n emptyLabel,\n viewerUserId,\n viewerName,\n viewerEmail,\n addActionLabel,\n emptyState,\n onActionChange,\n translator,\n labelPrefix = 'customers.people.detail.notes',\n inlineLabelPrefix = 'customers.people.detail.inline',\n onLoadingChange,\n dealOptions,\n entityOptions,\n dataAdapter,\n dataContext,\n renderIcon,\n renderColor,\n iconSuggestions,\n readMarkdownPreference,\n writeMarkdownPreference,\n disableMarkdown,\n}: NotesSectionProps<C>) {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const t = React.useMemo<Translator>(() => translator ?? ((key, fallback) => fallback ?? key), [translator])\n const label = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${labelPrefix}.${suffix}`, fallback, params),\n [labelPrefix, t],\n )\n const inlineLabel = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${inlineLabelPrefix}.${suffix}`, fallback, params),\n [inlineLabelPrefix, t],\n )\n const [markdownPlugins, setMarkdownPlugins] = React.useState<PluggableList>([])\n React.useEffect(() => {\n if (isTestEnv) return\n let mounted = true\n void loadMarkdownPlugins().then((plugins) => {\n if (!mounted) return\n setMarkdownPlugins(plugins)\n })\n return () => {\n mounted = false\n }\n }, [])\n\n const normalizedDealOptions = React.useMemo(() => {\n if (!Array.isArray(dealOptions)) return []\n const seen = new Set<string>()\n return dealOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [dealOptions])\n\n const dealLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n normalizedDealOptions.forEach((option) => {\n map.set(option.id, option.label)\n })\n return map\n }, [normalizedDealOptions])\n\n const normalizedEntityOptions = React.useMemo(() => {\n if (!Array.isArray(entityOptions)) return []\n const seen = new Set<string>()\n return entityOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [entityOptions])\n\n const [selectedDealId, setSelectedDealId] = React.useState<string>(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n return initial\n })\n React.useEffect(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n if (initial !== selectedDealId) {\n setSelectedDealId(initial)\n }\n }, [dealId, selectedDealId])\n\n const [selectedEntityId, setSelectedEntityId] = React.useState<string>(() => {\n if (normalizedEntityOptions.length) return normalizedEntityOptions[0].id\n return typeof entityId === 'string' ? entityId : ''\n })\n React.useEffect(() => {\n if (normalizedEntityOptions.length) {\n if (!normalizedEntityOptions.some((option) => option.id === selectedEntityId)) {\n setSelectedEntityId(normalizedEntityOptions[0].id)\n }\n } else {\n const initial = typeof entityId === 'string' ? entityId : ''\n if (initial !== selectedEntityId) {\n setSelectedEntityId(initial)\n }\n }\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedEntityId = React.useMemo(() => {\n if (normalizedEntityOptions.length) return selectedEntityId\n return typeof entityId === 'string' ? entityId : ''\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedDealId = React.useMemo(() => {\n const trimmed = typeof selectedDealId === 'string' ? selectedDealId.trim() : ''\n return trimmed\n }, [selectedDealId])\n\n const hasEntity = resolvedEntityId.length > 0\n\n const [notes, setNotes] = React.useState<CommentSummary[]>([])\n const [isLoading, setIsLoading] = React.useState<boolean>(() => Boolean(entityId || dealId))\n const [isSubmitting, setIsSubmitting] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const pendingCounterRef = React.useRef(0)\n\n const pushLoading = React.useCallback(() => {\n pendingCounterRef.current += 1\n if (pendingCounterRef.current === 1) {\n onLoadingChange?.(true)\n }\n }, [onLoadingChange])\n\n const popLoading = React.useCallback(() => {\n pendingCounterRef.current = Math.max(0, pendingCounterRef.current - 1)\n if (pendingCounterRef.current === 0) {\n onLoadingChange?.(false)\n }\n }, [onLoadingChange])\n\n const [composerOpen, setComposerOpen] = React.useState(false)\n const [draftBody, setDraftBody] = React.useState('')\n const [draftIcon, setDraftIcon] = React.useState<string | null>(null)\n const [draftColor, setDraftColor] = React.useState<string | null>(null)\n const [isMarkdownEnabled, setIsMarkdownEnabled] = React.useState(false)\n const textareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const formRef = React.useRef<HTMLFormElement | null>(null)\n const focusComposer = React.useCallback(() => {\n if (!hasEntity) return\n setComposerOpen(true)\n window.requestAnimationFrame(() => {\n if (isMarkdownEnabled) {\n const markdownTextarea = formRef.current?.querySelector('textarea')\n if (markdownTextarea instanceof HTMLTextAreaElement) {\n markdownTextarea.focus()\n markdownTextarea.scrollIntoView({ behavior: 'smooth', block: 'center' })\n return\n }\n }\n const element = textareaRef.current\n if (!element) return\n element.focus()\n element.scrollIntoView({ behavior: 'smooth', block: 'center' })\n })\n }, [formRef, hasEntity, isMarkdownEnabled])\n const [appearanceDialogState, setAppearanceDialogState] = React.useState<\n | { mode: 'create'; icon: string | null; color: string | null }\n | { mode: 'edit'; noteId: string; icon: string | null; color: string | null }\n | null\n >(null)\n const [appearanceDialogSaving, setAppearanceDialogSaving] = React.useState(false)\n const [appearanceDialogError, setAppearanceDialogError] = React.useState<string | null>(null)\n const [contentEditor, setContentEditor] = React.useState<{ id: string; value: string }>({ id: '', value: '' })\n const [contentSavingId, setContentSavingId] = React.useState<string | null>(null)\n const [contentError, setContentError] = React.useState<string | null>(null)\n const contentTextareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const [visibleCount, setVisibleCount] = React.useState(0)\n const [currentPage, setCurrentPage] = React.useState(1)\n // Short-page termination instead of `currentPage >= totalPages` \u2014 see\n // `hasMoreFromPage`. `/api/customers/comments` is a `makeCrudRoute` list, so\n // a page past the end comes back empty rather than clamped.\n const [hasMore, setHasMore] = React.useState(false)\n const [deletingNoteId, setDeletingNoteId] = React.useState<string | null>(null)\n const pagedMode = typeof dataAdapter.listPage === 'function'\n\n React.useEffect(() => {\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n if (!queryEntityId && !queryDealId) {\n setNotes([])\n setLoadError(null)\n setIsLoading(false)\n setCurrentPage(1)\n setHasMore(false)\n return\n }\n let cancelled = false\n setIsLoading(true)\n setLoadError(null)\n pushLoading()\n async function loadNotes() {\n try {\n if (dataAdapter.listPage) {\n const pageResult = await dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(pageResult.items)\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n return\n }\n const mapped = await dataAdapter.list({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(mapped)\n setCurrentPage(1)\n setHasMore(false)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error ? err.message : label('loadError', 'Failed to load notes.')\n setNotes([])\n setLoadError(message)\n setCurrentPage(1)\n setHasMore(false)\n flash(message, 'error')\n } finally {\n if (!cancelled) setIsLoading(false)\n popLoading()\n }\n }\n loadNotes().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [dataAdapter, dataContext, dealId, entityId, label, popLoading, pushLoading])\n\n const youLabel = label('you', 'You')\n const viewerLabel = React.useMemo(() => viewerName ?? viewerEmail ?? null, [viewerEmail, viewerName])\n\n const handleMarkdownToggle = React.useCallback(() => {\n setIsMarkdownEnabled((prev) => {\n const next = !prev\n if (writeMarkdownPreference) {\n writeMarkdownPreference(next)\n }\n return next\n })\n }, [writeMarkdownPreference])\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (!notes.length) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || isLoading || !hasEntity,\n icon: <Plus className=\"mr-2 h-4 w-4\" />,\n })\n return () => onActionChange(null)\n }, [onActionChange, addActionLabel, focusComposer, hasEntity, isLoading, isSubmitting, notes.length])\n\n const adjustTextareaSize = React.useCallback((element: HTMLTextAreaElement | null) => {\n if (!element) return\n element.style.height = 'auto'\n element.style.height = `${element.scrollHeight}px`\n }, [])\n\n React.useEffect(() => {\n adjustTextareaSize(textareaRef.current)\n }, [adjustTextareaSize, draftBody, isMarkdownEnabled, composerOpen])\n\n React.useEffect(() => {\n const preference = readMarkdownPreference ? readMarkdownPreference() : null\n if (preference !== null) {\n setIsMarkdownEnabled(preference)\n }\n }, [readMarkdownPreference])\n\n React.useEffect(() => {\n if (pagedMode) {\n setVisibleCount(notes.length)\n return\n }\n if (!notes.length) {\n setVisibleCount(0)\n return\n }\n const baseline = Math.min(5, notes.length)\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(Math.max(prev, baseline), notes.length)\n })\n }, [notes.length, pagedMode])\n\n React.useEffect(() => {\n if (hasEntity) return\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }, [hasEntity])\n\n const visibleNotes = React.useMemo(\n () => (pagedMode ? notes : notes.slice(0, visibleCount)),\n [notes, pagedMode, visibleCount],\n )\n const hasVisibleNotes = React.useMemo(\n () => (pagedMode ? notes.length > 0 : visibleCount > 0),\n [notes.length, pagedMode, visibleCount],\n )\n\n const loadMoreLabel = label('loadMore')\n\n const handleCreateNote = React.useCallback(\n async (input: { body: string; appearanceIcon: string | null; appearanceColor: string | null }) => {\n if (!hasEntity || !resolvedEntityId) {\n flash(label('entityMissing', 'Unable to determine current person.'), 'error')\n return false\n }\n const body = input.body.trim()\n const strippedBody = body\n .replace(/^[\\s#\\-*>_~`|+\\\\\\n\\r]+$/gm, '')\n .replace(/\\s+/g, '')\n if (!body || !strippedBody.length) {\n focusComposer()\n return false\n }\n const icon = input.appearanceIcon && input.appearanceIcon.trim().length ? input.appearanceIcon.trim() : null\n const color = sanitizeHexColor(input.appearanceColor)\n const targetDealId = resolvedDealId.length ? resolvedDealId : null\n const dealLabel = targetDealId ? dealLabelMap.get(targetDealId) ?? null : null\n setIsSubmitting(true)\n pushLoading()\n try {\n const responseBody =\n (await dataAdapter.create({\n entityId: resolvedEntityId,\n body,\n appearanceIcon: icon,\n appearanceColor: color,\n dealId: targetDealId,\n context: dataContext,\n })) ?? {}\n setNotes((prev) => {\n const viewerId = viewerUserId ?? null\n const resolvedAuthorId =\n typeof responseBody?.authorUserId === 'string' ? responseBody.authorUserId : viewerId ?? null\n const resolvedAuthorName = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return youLabel\n }\n return typeof responseBody?.authorName === 'string' ? responseBody.authorName : viewerLabel\n })()\n const resolvedAuthorEmail = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return viewerEmail ?? null\n }\n return typeof responseBody?.authorEmail === 'string' ? responseBody.authorEmail : null\n })()\n const newNote: CommentSummary = {\n id: typeof responseBody?.id === 'string' ? responseBody.id : generateTempId(),\n body,\n createdAt: new Date().toISOString(),\n authorUserId: resolvedAuthorId,\n authorName: resolvedAuthorName,\n authorEmail: resolvedAuthorEmail,\n dealId: targetDealId,\n dealTitle: dealLabel,\n appearanceIcon: icon,\n appearanceColor: color,\n }\n return [newNote, ...prev]\n })\n setVisibleCount((prev) => Math.max(prev, 1))\n flash(label('success'), 'success')\n return true\n } catch (err) {\n const message = err instanceof Error ? err.message : label('error')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n return false\n } finally {\n setIsSubmitting(false)\n popLoading()\n }\n },\n [dataAdapter, dataContext, dealLabelMap, focusComposer, hasEntity, popLoading, pushLoading, resolvedDealId, resolvedEntityId, t, viewerEmail, viewerLabel, viewerUserId, youLabel],\n )\n\n const handleUpdateNote = React.useCallback(\n async (noteId: string, patch: { body?: string; appearanceIcon?: string | null; appearanceColor?: string | null }) => {\n const sanitizedBody = patch.body\n const sanitizedIcon =\n patch.appearanceIcon !== undefined && patch.appearanceIcon !== null && patch.appearanceIcon.trim().length\n ? patch.appearanceIcon.trim()\n : patch.appearanceIcon === null\n ? null\n : undefined\n const sanitizedColor =\n patch.appearanceColor !== undefined ? sanitizeHexColor(patch.appearanceColor ?? null) : undefined\n const noteUpdatedAt = notes.find((comment) => comment.id === noteId)?.updatedAt ?? null\n try {\n await dataAdapter.update({\n id: noteId,\n patch: {\n body: sanitizedBody,\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n },\n updatedAt: noteUpdatedAt,\n context: dataContext,\n })\n setNotes((prev) => {\n const nextComments = prev.map((comment) => {\n if (comment.id !== noteId) return comment\n const next = { ...comment }\n if (sanitizedBody !== undefined) next.body = sanitizedBody\n if (sanitizedIcon !== undefined) next.appearanceIcon = sanitizedIcon ?? null\n if (sanitizedColor !== undefined) next.appearanceColor = sanitizedColor ?? null\n return next\n })\n return nextComments\n })\n flash(label('updateSuccess'), 'success')\n } catch (error) {\n const message = error instanceof Error ? error.message : label('updateError')\n if (!surfaceRecordConflict(error, t)) flash(message, 'error')\n throw error instanceof Error ? error : new Error(message)\n }\n },\n [dataAdapter, dataContext, notes, t],\n )\n\n const handleDeleteNote = React.useCallback(\n async (note: CommentSummary) => {\n const confirmed = await confirm({\n title: label('deleteConfirm', 'Delete this note? You can restore it using version history.'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setDeletingNoteId(note.id)\n pushLoading()\n try {\n await dataAdapter.delete({ id: note.id, updatedAt: note.updatedAt ?? null, context: dataContext })\n setNotes((prev) => prev.filter((existing) => existing.id !== note.id))\n if (pagedMode) {\n setVisibleCount((prev) => Math.max(0, prev - 1))\n }\n flash(label('deleteSuccess', 'Note deleted'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : label('deleteError', 'Failed to delete note')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n } finally {\n setDeletingNoteId(null)\n popLoading()\n }\n },\n [confirm, dataAdapter, dataContext, label, popLoading, pushLoading, t],\n )\n\n const handleSubmit = React.useCallback(\n async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const created = await handleCreateNote({\n body: draftBody,\n appearanceIcon: draftIcon,\n appearanceColor: draftColor,\n })\n if (created) {\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }\n },\n [draftBody, draftColor, draftIcon, handleCreateNote],\n )\n\n const handleLoadMore = React.useCallback(() => {\n if (pagedMode && dataAdapter.listPage) {\n if (!hasMore || isLoading) return\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n setIsLoading(true)\n pushLoading()\n void dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: currentPage + 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n .then((pageResult) => {\n setNotes((prev) => {\n const merged = new Map(prev.map((note) => [note.id, note]))\n pageResult.items.forEach((note) => merged.set(note.id, note))\n return Array.from(merged.values())\n })\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n })\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : label('loadError', 'Failed to load notes.')\n flash(message, 'error')\n })\n .finally(() => {\n setIsLoading(false)\n popLoading()\n })\n return\n }\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(prev + 5, notes.length)\n })\n }, [currentPage, dataAdapter, dataContext, dealId, entityId, flash, hasMore, isLoading, label, notes.length, pagedMode, popLoading, pushLoading])\n\n const handleAppearanceDialogSubmit = React.useCallback(async () => {\n if (!appearanceDialogState) return\n setAppearanceDialogError(null)\n const sanitizedIcon =\n appearanceDialogState.icon && appearanceDialogState.icon.trim().length\n ? appearanceDialogState.icon.trim()\n : null\n const sanitizedColor = sanitizeHexColor(appearanceDialogState.color ?? null)\n if (appearanceDialogState.mode === 'create') {\n setDraftIcon(sanitizedIcon)\n setDraftColor(sanitizedColor)\n setAppearanceDialogState(null)\n return\n }\n setAppearanceDialogSaving(true)\n try {\n await handleUpdateNote(appearanceDialogState.noteId, {\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n })\n setAppearanceDialogState(null)\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : label('appearance.error', 'Failed to update appearance.')\n setAppearanceDialogError(message)\n } finally {\n setAppearanceDialogSaving(false)\n }\n }, [appearanceDialogState, handleUpdateNote, t])\n\n const handleAppearanceDialogClose = React.useCallback(() => {\n if (appearanceDialogSaving) return\n setAppearanceDialogState(null)\n setAppearanceDialogError(null)\n }, [appearanceDialogSaving])\n\n const handleContentSave = React.useCallback(async () => {\n if (!contentEditor.id) return\n const trimmed = contentEditor.value.trim()\n if (!trimmed) {\n setContentError(label('updateError', 'Failed to update note'))\n return\n }\n setContentSavingId(contentEditor.id)\n setContentError(null)\n try {\n await handleUpdateNote(contentEditor.id, { body: trimmed })\n setContentEditor({ id: '', value: '' })\n } catch (err) {\n const message =\n err instanceof Error ? err.message : label('updateError', 'Failed to update note')\n setContentError(message)\n } finally {\n setContentSavingId(null)\n }\n }, [contentEditor, handleUpdateNote, t])\n\n const handleContentEditorKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (!contentEditor.id) return\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (!contentSavingId) void handleContentSave()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n setContentEditor({ id: '', value: '' })\n setContentError(null)\n }\n },\n [contentEditor.id, contentSavingId, handleContentSave],\n )\n\n const handleComposerKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLFormElement>) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n formRef.current?.requestSubmit()\n }\n },\n [],\n )\n\n const handleContentKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>, note: CommentSummary) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n setContentEditor({ id: note.id, value: note.body })\n }\n },\n [],\n )\n\n const noteAuthorLabel = React.useCallback(\n (note: CommentSummary) => {\n if (note.authorUserId && viewerUserId && note.authorUserId === viewerUserId) {\n return youLabel\n }\n return note.authorName ?? note.authorEmail ?? youLabel\n },\n [viewerUserId, youLabel],\n )\n\n const noteAppearanceLabels = React.useMemo<AppearanceSelectorLabels>(\n () => ({\n colorLabel: label('appearance.colorLabel'),\n colorHelp: label('appearance.colorHelp'),\n colorClearLabel: label('appearance.clearColor'),\n iconLabel: label('appearance.iconLabel'),\n iconPlaceholder: label('appearance.iconPlaceholder'),\n iconPickerTriggerLabel: label('appearance.iconPicker'),\n iconSearchPlaceholder: label('appearance.iconSearchPlaceholder'),\n iconSearchEmptyLabel: label('appearance.iconSearchEmpty'),\n iconSuggestionsLabel: label('appearance.iconSuggestions'),\n iconClearLabel: label('appearance.iconClear'),\n previewEmptyLabel: label('appearance.previewEmpty'),\n }),\n [label],\n )\n\n const composerAuthor = React.useMemo(\n () => youLabel,\n [youLabel],\n )\n const composerHasAppearance = Boolean(draftIcon) || Boolean(draftColor)\n const appearanceDialogOpen = appearanceDialogState !== null\n const editingAppearanceNoteId =\n appearanceDialogState?.mode === 'edit' ? appearanceDialogState.noteId : null\n const addNoteShortcutLabel = label('addShortcut', 'Add note \u2318\u23CE / Ctrl+Enter')\n const saveAppearanceShortcutLabel = label('appearance.saveShortcut', 'Save appearance \u2318\u23CE / Ctrl+Enter')\n const composerSubmitLabel = addNoteShortcutLabel\n const appearanceDialogPrimaryLabel = saveAppearanceShortcutLabel\n const appearanceDialogSavingLabel =\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.saving')\n : label('saving', 'Saving note\u2026')\n\n return (\n <div className=\"mt-0 space-y-2\">\n <div\n className={[\n 'overflow-hidden rounded-xl transition-all duration-300 ease-out',\n composerOpen ? 'max-h-[1200px] bg-muted/30 p-4 opacity-100' : 'pointer-events-none max-h-0 p-0 opacity-0',\n ].join(' ')}\n aria-hidden={!composerOpen}\n >\n {composerOpen ? (\n <form\n ref={formRef}\n onSubmit={handleSubmit}\n onKeyDown={handleComposerKeyDown}\n className=\"space-y-3\"\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium\">{label('addLabel')}</h3>\n <div className=\"flex flex-wrap items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setAppearanceDialogError(null)\n setAppearanceDialogState({ mode: 'create', icon: draftIcon, color: draftColor })\n }}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <span className=\"sr-only\">{label('appearance.toggleOpen', 'Customize appearance')}</span>\n <Palette className=\"h-4 w-4\" />\n </Button>\n {disableMarkdown ? null : (\n <Button\n type=\"button\"\n variant={isMarkdownEnabled ? 'secondary' : 'ghost'}\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownEnabled}\n disabled={isSubmitting || isLoading}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting || isLoading}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n {(normalizedEntityOptions.length || normalizedDealOptions.length) ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {normalizedEntityOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-entity-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.entity', 'Assign to customer')}\n </label>\n <Select\n value={selectedEntityId || undefined}\n onValueChange={(next) => setSelectedEntityId(next ?? '')}\n disabled={isSubmitting || isLoading || !normalizedEntityOptions.length}\n >\n <SelectTrigger id=\"note-entity-select\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {normalizedEntityOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {normalizedDealOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-deal-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.deal', 'Link to deal (optional)')}\n </label>\n <Select\n value={selectedDealId || undefined}\n onValueChange={(next) => setSelectedDealId(next ?? '')}\n disabled={isSubmitting || isLoading}\n >\n <SelectTrigger id=\"note-deal-select\">\n <SelectValue placeholder={label('fields.dealPlaceholder', 'No linked deal')} />\n </SelectTrigger>\n <SelectContent>\n {normalizedDealOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n </div>\n ) : null}\n <SwitchableMarkdownInput\n value={draftBody}\n onChange={setDraftBody}\n isMarkdownEnabled={isMarkdownEnabled}\n disableMarkdown={disableMarkdown}\n rows={1}\n placeholder={label('placeholder')}\n textareaRef={textareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n disabled={isSubmitting || isLoading || !hasEntity}\n remarkPlugins={markdownPlugins}\n />\n {composerHasAppearance ? (\n <div className=\"flex flex-wrap items-center justify-between gap-3 rounded-lg border border-dashed border-muted-foreground/40 px-3 py-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-sm\">\n {draftIcon && renderIcon ? (\n <span className=\"inline-flex h-7 w-7 items-center justify-center rounded border border-border bg-muted/50\">\n {renderIcon(draftIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <span className=\"font-semibold text-foreground\">{composerAuthor}</span>\n {draftColor && renderColor ? (\n <span className=\"flex items-center gap-2\">\n {renderColor(draftColor, 'h-3.5 w-3.5 rounded-full border border-border')}\n <span className=\"text-xs font-medium uppercase text-muted-foreground\">{draftColor}</span>\n </span>\n ) : null}\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting}\n >\n {label('appearance.clearAll', 'Clear')}\n </Button>\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n {isSubmitting ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {composerSubmitLabel}\n </Button>\n </div>\n </form>\n ) : null}\n </div>\n\n {loadError ? <ErrorMessage label={loadError} className=\"mt-3\" /> : null}\n\n <div className=\"space-y-3\">\n {!composerOpen && hasVisibleNotes && !onActionChange ? (\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={focusComposer}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <Plus className=\"size-4\" />\n {addActionLabel}\n </Button>\n </div>\n ) : null}\n {isLoading ? (\n <LoadingMessage\n label={label('loading', 'Loading notes\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : hasVisibleNotes ? (\n visibleNotes.map((note) => {\n const author = noteAuthorLabel(note)\n const isAppearanceSaving = appearanceDialogSaving && editingAppearanceNoteId === note.id\n const isEditingContent = contentEditor.id === note.id\n const displayIcon = note.appearanceIcon ?? null\n const displayColor = note.appearanceColor ?? null\n const timestampValue = note.createdAt\n const fallbackTimestampLabel = formatDateTime(note.createdAt) ?? emptyLabel\n return (\n <div key={note.id} className=\"group space-y-2 rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <TimelineItemHeader\n title={author}\n timestamp={timestampValue}\n fallbackTimestampLabel={fallbackTimestampLabel}\n icon={displayIcon}\n color={displayColor}\n renderIcon={renderIcon}\n renderColor={renderColor}\n />\n {note.dealId ? (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <ArrowUpRightSquare className=\"h-3.5 w-3.5\" />\n <a\n href={`/backend/customers/deals/${encodeURIComponent(note.dealId)}`}\n className=\"font-medium text-foreground hover:underline\"\n >\n {note.dealTitle && note.dealTitle.length\n ? note.dealTitle\n : label('linkedDeal', 'Linked deal')}\n </a>\n </div>\n ) : null}\n </div>\n <div\n className={`flex items-center gap-2 transition-opacity ${\n isEditingContent ? 'opacity-100' : 'opacity-100 md:opacity-0 md:group-hover:opacity-100 focus-within:opacity-100'\n }`}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n setAppearanceDialogError(null)\n setAppearanceDialogState({\n mode: 'edit',\n noteId: note.id,\n icon: note.appearanceIcon ?? null,\n color: note.appearanceColor ?? null,\n })\n }}\n disabled={appearanceDialogSaving && editingAppearanceNoteId === note.id}\n >\n {isAppearanceSaving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Palette className=\"h-4 w-4\" />}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n void handleDeleteNote(note)\n }}\n disabled={deletingNoteId === note.id}\n >\n {deletingNoteId === note.id ? (\n <span className=\"relative flex h-4 w-4 items-center justify-center text-destructive\">\n <span className=\"absolute h-4 w-4 animate-spin rounded-full border border-destructive border-t-transparent\" />\n </span>\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n {isEditingContent ? (\n <div className=\"space-y-2\" onKeyDown={handleContentEditorKeyDown}>\n <SwitchableMarkdownInput\n value={contentEditor.value}\n onChange={(nextValue) => setContentEditor((prev) => ({ ...prev, value: nextValue }))}\n isMarkdownEnabled={isMarkdownEnabled}\n disableMarkdown={disableMarkdown}\n rows={3}\n textareaRef={contentTextareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n textareaClassName=\"w-full resize-none overflow-hidden rounded-md border border-border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n editorWrapperClassName=\"w-full rounded-md border border-muted-foreground/20 bg-background p-2\"\n remarkPlugins={markdownPlugins}\n />\n {contentError ? <p className=\"text-xs text-status-error-text\">{contentError}</p> : null}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={handleContentSave} disabled={contentSavingId === note.id}>\n {contentSavingId === note.id ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {label('saving')}\n </>\n ) : (\n inlineLabel('saveShortcut')\n )}\n </Button>\n {disableMarkdown ? null : (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownEnabled}\n className={isMarkdownEnabled ? 'text-primary' : undefined}\n disabled={contentSavingId === note.id}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => setContentEditor({ id: '', value: '' })}\n disabled={contentSavingId === note.id}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n ) : (\n <div\n role=\"button\"\n tabIndex={0}\n className=\"cursor-pointer text-sm\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n onKeyDown={(event) => handleContentKeyDown(event, note)}\n >\n <MarkdownPreview\n remarkPlugins={markdownPlugins}\n className=\"break-words text-foreground [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs\"\n >\n {note.body}\n </MarkdownPreview>\n </div>\n )}\n </div>\n )\n })\n ) : composerOpen ? null : (\n <TabEmptyState\n title={emptyState.title}\n description={emptyState.description}\n action={{\n label: emptyState.actionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || !hasEntity,\n }}\n />\n )}\n {isLoading || (pagedMode ? !hasMore : visibleCount >= notes.length) ? null : (\n <div className=\"flex justify-center\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleLoadMore}>\n {loadMoreLabel}\n </Button>\n </div>\n )}\n </div>\n <AppearanceDialog\n open={appearanceDialogOpen}\n title={\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.edit')\n : label('appearance.toggleOpen', 'Customize appearance')\n }\n icon={appearanceDialogState?.icon ?? null}\n color={appearanceDialogState?.color ?? null}\n labels={noteAppearanceLabels}\n iconSuggestions={iconSuggestions}\n onIconChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, icon: value ?? null } : prev))}\n onColorChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, color: value ?? null } : prev))}\n onSubmit={() => {\n void handleAppearanceDialogSubmit()\n }}\n onClose={handleAppearanceDialogClose}\n isSaving={appearanceDialogSaving}\n errorMessage={appearanceDialogError}\n primaryLabel={appearanceDialogPrimaryLabel}\n savingLabel={appearanceDialogSavingLabel}\n cancelLabel={label('appearance.cancel')}\n />\n {ConfirmDialogElement}\n </div>\n )\n}\n\nexport function NotesSection<C = unknown>(props: NotesSectionProps<C>) {\n const handle = ComponentReplacementHandles.section('ui.detail', 'NotesSection')\n const Resolved = useRegisteredComponent<NotesSectionProps<C>>(\n handle,\n NotesSectionImpl as React.ComponentType<NotesSectionProps<C>>,\n )\n\n return (\n <div data-component-handle={handle}>\n <Resolved {...props} />\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { PluggableList } from 'unified'\nimport type { AppearanceSelectorLabels } from '@open-mercato/core/modules/dictionaries/components/AppearanceSelector'\nimport { AppearanceDialog } from '@open-mercato/core/modules/customers/components/detail/AppearanceDialog'\nimport type { IconOption } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ArrowUpRightSquare, FileCode, Loader2, Palette, Pencil, Plus, Trash2 } from 'lucide-react'\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\nimport { hasMoreFromPage } from '@open-mercato/shared/lib/pagination/load-more'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { flash } from '../FlashMessages'\nimport { surfaceRecordConflict } from '../conflicts'\nimport { SwitchableMarkdownInput } from '../inputs/SwitchableMarkdownInput'\nimport { ErrorMessage } from './ErrorMessage'\nimport { LoadingMessage } from './LoadingMessage'\nimport { TabEmptyState } from './TabEmptyState'\nimport { useConfirmDialog } from '../confirm-dialog'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\nimport { ComponentReplacementHandles } from '@open-mercato/shared/modules/widgets/component-registry'\nimport { MarkdownPreview } from '../markdown'\nimport { useRegisteredComponent } from '../injection/useRegisteredComponent'\ntype Translator = (key: string, fallback?: string, params?: Record<string, string | number>) => string\n\nconst NOTES_PAGE_SIZE = 20\n\nconst isTestEnv =\n typeof process !== 'undefined' &&\n (process.env.NODE_ENV === 'test' || typeof process.env.JEST_WORKER_ID !== 'undefined')\n\nexport type SectionAction = {\n label: React.ReactNode\n onClick: () => void\n disabled?: boolean\n icon?: React.ReactNode\n}\n\nexport type TabEmptyStateConfig = {\n title: string\n actionLabel: string\n description?: string\n}\n\nexport type CommentSummary = {\n id: string\n body: string\n createdAt: string\n updatedAt?: string | null\n authorUserId?: string | null\n authorName?: string | null\n authorEmail?: string | null\n dealId?: string | null\n dealTitle?: string | null\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesCreatePayload = {\n entityId: string\n body: string\n appearanceIcon: string | null\n appearanceColor: string | null\n dealId?: string | null\n}\n\nexport type NotesUpdatePayload = {\n body?: string\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesDataAdapter<C = unknown> = {\n list: (params: { entityId: string | null; dealId: string | null; context?: C }) => Promise<CommentSummary[]>\n listPage?: (params: {\n entityId: string | null\n dealId: string | null\n page: number\n pageSize: number\n context?: C\n }) => Promise<{\n items: CommentSummary[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n }>\n create: (params: NotesCreatePayload & { context?: C }) => Promise<Partial<CommentSummary> | void>\n update: (params: { id: string; patch: NotesUpdatePayload; updatedAt?: string | null; context?: C }) => Promise<void>\n delete: (params: { id: string; updatedAt?: string | null; context?: C }) => Promise<void>\n}\n\ntype RenderIconFn = (icon: string, className?: string) => React.ReactNode\ntype RenderColorFn = (color: string, className?: string) => React.ReactNode\n\nlet markdownPluginsPromise: Promise<PluggableList> | null = null\n\nasync function loadMarkdownPlugins(): Promise<PluggableList> {\n if (isTestEnv) return []\n if (!markdownPluginsPromise) {\n markdownPluginsPromise = import('remark-gfm')\n .then((mod) => [mod.default ?? mod] as PluggableList)\n .catch(() => [])\n }\n return markdownPluginsPromise\n}\n\nfunction generateTempId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') return crypto.randomUUID()\n return `tmp_${Math.random().toString(36).slice(2)}`\n}\n\n\n\ntype TimelineItemHeaderProps = {\n title: React.ReactNode\n subtitle?: React.ReactNode\n timestamp?: string | Date | null\n fallbackTimestampLabel?: React.ReactNode\n icon?: string | null\n color?: string | null\n iconSize?: 'sm' | 'md'\n className?: string\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n}\n\nfunction TimelineItemHeader({\n title,\n subtitle,\n timestamp,\n fallbackTimestampLabel,\n icon,\n color,\n iconSize = 'md',\n className,\n renderIcon,\n renderColor,\n}: TimelineItemHeaderProps) {\n const wrapperSize = iconSize === 'sm' ? 'h-6 w-6' : 'h-8 w-8'\n const iconSizeClass = iconSize === 'sm' ? 'h-3.5 w-3.5' : 'h-4 w-4'\n const resolvedTimestamp = React.useMemo(() => {\n if (subtitle) return subtitle\n if (!timestamp) return fallbackTimestampLabel ?? null\n const value = typeof timestamp === 'string' ? timestamp : timestamp.toISOString()\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallbackTimestampLabel ?? null\n const now = Date.now()\n const diff = Math.abs(now - date.getTime())\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000\n const relativeLabel = diff <= THIRTY_DAYS_MS ? formatRelativeTime(value) : null\n const absoluteLabel = formatDateTime(value)\n if (relativeLabel) {\n return (\n <span title={absoluteLabel ?? undefined}>\n {relativeLabel}\n </span>\n )\n }\n return absoluteLabel ?? fallbackTimestampLabel ?? null\n }, [fallbackTimestampLabel, subtitle, timestamp])\n\n return (\n <div className={['flex items-start gap-3', className].filter(Boolean).join(' ')}>\n {icon && renderIcon ? (\n <span className={['inline-flex items-center justify-center rounded border border-border bg-muted/50', wrapperSize].join(' ')}>\n {renderIcon(icon, iconSizeClass)}\n </span>\n ) : null}\n <div className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">{title}</span>\n {color && renderColor ? renderColor(color, 'h-3 w-3 rounded-full border border-border') : null}\n </div>\n {resolvedTimestamp ? <div className=\"text-xs text-muted-foreground\">{resolvedTimestamp}</div> : null}\n </div>\n </div>\n )\n}\n\nexport type NotesSectionProps<C = unknown> = {\n entityId: string | null\n dealId?: string | null\n emptyLabel: string\n viewerUserId: string | null\n viewerName?: string | null\n viewerEmail?: string | null\n addActionLabel: string\n emptyState: TabEmptyStateConfig\n onActionChange?: (action: SectionAction | null) => void\n translator?: Translator\n labelPrefix?: string\n inlineLabelPrefix?: string\n onLoadingChange?: (isLoading: boolean) => void\n dealOptions?: Array<{ id: string; label: string }>\n entityOptions?: Array<{ id: string; label: string }>\n dataAdapter: NotesDataAdapter<C>\n dataContext?: C\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n iconSuggestions?: IconOption[]\n readMarkdownPreference?: () => boolean | null\n writeMarkdownPreference?: (value: boolean) => void\n /** Force the plain textarea and hide the markdown toggle. Wins over `forceMarkdown`. */\n disableMarkdown?: boolean\n /**\n * Keep the rich markdown editor active for every note and hide the markdown toggle,\n * so the editor shape cannot be switched. Ignored when `disableMarkdown` is set.\n */\n forceMarkdown?: boolean\n /**\n * Hide the markdown toggle without changing which editor renders \u2014 the seeded\n * `readMarkdownPreference` value stays in effect. Implied by `forceMarkdown`.\n */\n hideMarkdownToggle?: boolean\n /** Hide the appearance (icon/color) affordances: the palette buttons and the appearance dialog. */\n disableAppearance?: boolean\n}\n\nexport function sanitizeHexColor(value: string | null): string | null {\n if (!value) return null\n const trimmed = value.trim()\n return /^#([0-9a-f]{6})$/i.test(trimmed) ? trimmed.toLowerCase() : null\n}\n\nexport function mapCommentSummary(input: unknown): CommentSummary {\n const data = (typeof input === 'object' && input !== null ? input : {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : generateTempId()\n const body = typeof data.body === 'string' ? data.body : ''\n const createdAt =\n typeof data.createdAt === 'string'\n ? data.createdAt\n : typeof data.created_at === 'string'\n ? data.created_at\n : new Date().toISOString()\n const updatedAt =\n typeof data.updatedAt === 'string'\n ? data.updatedAt\n : typeof data.updated_at === 'string'\n ? data.updated_at\n : null\n const authorUserId =\n typeof data.authorUserId === 'string'\n ? data.authorUserId\n : typeof data.author_user_id === 'string'\n ? data.author_user_id\n : null\n const authorName =\n typeof data.authorName === 'string'\n ? data.authorName\n : typeof data.author_name === 'string'\n ? data.author_name\n : null\n const authorEmail =\n typeof data.authorEmail === 'string'\n ? data.authorEmail\n : typeof data.author_email === 'string'\n ? data.author_email\n : null\n const dealId =\n typeof data.dealId === 'string'\n ? data.dealId\n : typeof data.deal_id === 'string'\n ? data.deal_id\n : null\n const dealTitle =\n typeof data.dealTitle === 'string'\n ? data.dealTitle\n : typeof data.deal_title === 'string'\n ? data.deal_title\n : null\n const appearanceIcon =\n typeof data.appearanceIcon === 'string'\n ? data.appearanceIcon\n : typeof data.appearance_icon === 'string'\n ? data.appearance_icon\n : null\n const appearanceColor =\n typeof data.appearanceColor === 'string'\n ? data.appearanceColor\n : typeof data.appearance_color === 'string'\n ? data.appearance_color\n : null\n return {\n id,\n body,\n createdAt,\n updatedAt,\n authorUserId,\n authorName,\n authorEmail,\n dealId,\n dealTitle,\n appearanceIcon,\n appearanceColor,\n }\n}\n\nfunction NotesSectionImpl<C = unknown>({\n entityId,\n dealId,\n emptyLabel,\n viewerUserId,\n viewerName,\n viewerEmail,\n addActionLabel,\n emptyState,\n onActionChange,\n translator,\n labelPrefix = 'customers.people.detail.notes',\n inlineLabelPrefix = 'customers.people.detail.inline',\n onLoadingChange,\n dealOptions,\n entityOptions,\n dataAdapter,\n dataContext,\n renderIcon,\n renderColor,\n iconSuggestions,\n readMarkdownPreference,\n writeMarkdownPreference,\n disableMarkdown,\n forceMarkdown,\n hideMarkdownToggle,\n disableAppearance,\n}: NotesSectionProps<C>) {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const t = React.useMemo<Translator>(() => translator ?? ((key, fallback) => fallback ?? key), [translator])\n const label = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${labelPrefix}.${suffix}`, fallback, params),\n [labelPrefix, t],\n )\n const inlineLabel = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${inlineLabelPrefix}.${suffix}`, fallback, params),\n [inlineLabelPrefix, t],\n )\n const [markdownPlugins, setMarkdownPlugins] = React.useState<PluggableList>([])\n React.useEffect(() => {\n if (isTestEnv) return\n let mounted = true\n void loadMarkdownPlugins().then((plugins) => {\n if (!mounted) return\n setMarkdownPlugins(plugins)\n })\n return () => {\n mounted = false\n }\n }, [])\n\n const normalizedDealOptions = React.useMemo(() => {\n if (!Array.isArray(dealOptions)) return []\n const seen = new Set<string>()\n return dealOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [dealOptions])\n\n const dealLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n normalizedDealOptions.forEach((option) => {\n map.set(option.id, option.label)\n })\n return map\n }, [normalizedDealOptions])\n\n const normalizedEntityOptions = React.useMemo(() => {\n if (!Array.isArray(entityOptions)) return []\n const seen = new Set<string>()\n return entityOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [entityOptions])\n\n const [selectedDealId, setSelectedDealId] = React.useState<string>(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n return initial\n })\n React.useEffect(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n if (initial !== selectedDealId) {\n setSelectedDealId(initial)\n }\n }, [dealId, selectedDealId])\n\n const [selectedEntityId, setSelectedEntityId] = React.useState<string>(() => {\n if (normalizedEntityOptions.length) return normalizedEntityOptions[0].id\n return typeof entityId === 'string' ? entityId : ''\n })\n React.useEffect(() => {\n if (normalizedEntityOptions.length) {\n if (!normalizedEntityOptions.some((option) => option.id === selectedEntityId)) {\n setSelectedEntityId(normalizedEntityOptions[0].id)\n }\n } else {\n const initial = typeof entityId === 'string' ? entityId : ''\n if (initial !== selectedEntityId) {\n setSelectedEntityId(initial)\n }\n }\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedEntityId = React.useMemo(() => {\n if (normalizedEntityOptions.length) return selectedEntityId\n return typeof entityId === 'string' ? entityId : ''\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedDealId = React.useMemo(() => {\n const trimmed = typeof selectedDealId === 'string' ? selectedDealId.trim() : ''\n return trimmed\n }, [selectedDealId])\n\n const hasEntity = resolvedEntityId.length > 0\n\n const [notes, setNotes] = React.useState<CommentSummary[]>([])\n const [isLoading, setIsLoading] = React.useState<boolean>(() => Boolean(entityId || dealId))\n const [isSubmitting, setIsSubmitting] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const pendingCounterRef = React.useRef(0)\n\n const pushLoading = React.useCallback(() => {\n pendingCounterRef.current += 1\n if (pendingCounterRef.current === 1) {\n onLoadingChange?.(true)\n }\n }, [onLoadingChange])\n\n const popLoading = React.useCallback(() => {\n pendingCounterRef.current = Math.max(0, pendingCounterRef.current - 1)\n if (pendingCounterRef.current === 0) {\n onLoadingChange?.(false)\n }\n }, [onLoadingChange])\n\n const [composerOpen, setComposerOpen] = React.useState(false)\n const [draftBody, setDraftBody] = React.useState('')\n const [draftIcon, setDraftIcon] = React.useState<string | null>(null)\n const [draftColor, setDraftColor] = React.useState<string | null>(null)\n const [isMarkdownEnabled, setIsMarkdownEnabled] = React.useState(false)\n const isMarkdownActive = !disableMarkdown && (Boolean(forceMarkdown) || isMarkdownEnabled)\n const showMarkdownToggle = !disableMarkdown && !forceMarkdown && !hideMarkdownToggle\n const showAppearanceControls = !disableAppearance\n const textareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const formRef = React.useRef<HTMLFormElement | null>(null)\n const focusComposer = React.useCallback(() => {\n if (!hasEntity) return\n setComposerOpen(true)\n window.requestAnimationFrame(() => {\n if (isMarkdownActive) {\n const markdownTextarea = formRef.current?.querySelector('textarea')\n if (markdownTextarea instanceof HTMLTextAreaElement) {\n markdownTextarea.focus()\n markdownTextarea.scrollIntoView({ behavior: 'smooth', block: 'center' })\n return\n }\n }\n const element = textareaRef.current\n if (!element) return\n element.focus()\n element.scrollIntoView({ behavior: 'smooth', block: 'center' })\n })\n }, [formRef, hasEntity, isMarkdownActive])\n const [appearanceDialogState, setAppearanceDialogState] = React.useState<\n | { mode: 'create'; icon: string | null; color: string | null }\n | { mode: 'edit'; noteId: string; icon: string | null; color: string | null }\n | null\n >(null)\n const [appearanceDialogSaving, setAppearanceDialogSaving] = React.useState(false)\n const [appearanceDialogError, setAppearanceDialogError] = React.useState<string | null>(null)\n const [contentEditor, setContentEditor] = React.useState<{ id: string; value: string }>({ id: '', value: '' })\n const [contentSavingId, setContentSavingId] = React.useState<string | null>(null)\n const [contentError, setContentError] = React.useState<string | null>(null)\n const contentTextareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const [visibleCount, setVisibleCount] = React.useState(0)\n const [currentPage, setCurrentPage] = React.useState(1)\n // Short-page termination instead of `currentPage >= totalPages` \u2014 see\n // `hasMoreFromPage`. `/api/customers/comments` is a `makeCrudRoute` list, so\n // a page past the end comes back empty rather than clamped.\n const [hasMore, setHasMore] = React.useState(false)\n const [deletingNoteId, setDeletingNoteId] = React.useState<string | null>(null)\n const pagedMode = typeof dataAdapter.listPage === 'function'\n\n React.useEffect(() => {\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n if (!queryEntityId && !queryDealId) {\n setNotes([])\n setLoadError(null)\n setIsLoading(false)\n setCurrentPage(1)\n setHasMore(false)\n return\n }\n let cancelled = false\n setIsLoading(true)\n setLoadError(null)\n pushLoading()\n async function loadNotes() {\n try {\n if (dataAdapter.listPage) {\n const pageResult = await dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(pageResult.items)\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n return\n }\n const mapped = await dataAdapter.list({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(mapped)\n setCurrentPage(1)\n setHasMore(false)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error ? err.message : label('loadError', 'Failed to load notes.')\n setNotes([])\n setLoadError(message)\n setCurrentPage(1)\n setHasMore(false)\n flash(message, 'error')\n } finally {\n if (!cancelled) setIsLoading(false)\n popLoading()\n }\n }\n loadNotes().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [dataAdapter, dataContext, dealId, entityId, label, popLoading, pushLoading])\n\n const youLabel = label('you', 'You')\n const viewerLabel = React.useMemo(() => viewerName ?? viewerEmail ?? null, [viewerEmail, viewerName])\n\n const handleMarkdownToggle = React.useCallback(() => {\n setIsMarkdownEnabled((prev) => {\n const next = !prev\n if (writeMarkdownPreference) {\n writeMarkdownPreference(next)\n }\n return next\n })\n }, [writeMarkdownPreference])\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (!notes.length) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || isLoading || !hasEntity,\n icon: <Plus className=\"mr-2 h-4 w-4\" />,\n })\n return () => onActionChange(null)\n }, [onActionChange, addActionLabel, focusComposer, hasEntity, isLoading, isSubmitting, notes.length])\n\n const adjustTextareaSize = React.useCallback((element: HTMLTextAreaElement | null) => {\n if (!element) return\n element.style.height = 'auto'\n element.style.height = `${element.scrollHeight}px`\n }, [])\n\n React.useEffect(() => {\n adjustTextareaSize(textareaRef.current)\n }, [adjustTextareaSize, draftBody, isMarkdownActive, composerOpen])\n\n React.useEffect(() => {\n const preference = readMarkdownPreference ? readMarkdownPreference() : null\n if (preference !== null) {\n setIsMarkdownEnabled(preference)\n }\n }, [readMarkdownPreference])\n\n React.useEffect(() => {\n if (pagedMode) {\n setVisibleCount(notes.length)\n return\n }\n if (!notes.length) {\n setVisibleCount(0)\n return\n }\n const baseline = Math.min(5, notes.length)\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(Math.max(prev, baseline), notes.length)\n })\n }, [notes.length, pagedMode])\n\n React.useEffect(() => {\n if (hasEntity) return\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }, [hasEntity])\n\n const visibleNotes = React.useMemo(\n () => (pagedMode ? notes : notes.slice(0, visibleCount)),\n [notes, pagedMode, visibleCount],\n )\n const hasVisibleNotes = React.useMemo(\n () => (pagedMode ? notes.length > 0 : visibleCount > 0),\n [notes.length, pagedMode, visibleCount],\n )\n\n const loadMoreLabel = label('loadMore')\n\n const handleCreateNote = React.useCallback(\n async (input: { body: string; appearanceIcon: string | null; appearanceColor: string | null }) => {\n if (!hasEntity || !resolvedEntityId) {\n flash(label('entityMissing', 'Unable to determine current person.'), 'error')\n return false\n }\n const body = input.body.trim()\n const strippedBody = body\n .replace(/^[\\s#\\-*>_~`|+\\\\\\n\\r]+$/gm, '')\n .replace(/\\s+/g, '')\n if (!body || !strippedBody.length) {\n focusComposer()\n return false\n }\n const icon = input.appearanceIcon && input.appearanceIcon.trim().length ? input.appearanceIcon.trim() : null\n const color = sanitizeHexColor(input.appearanceColor)\n const targetDealId = resolvedDealId.length ? resolvedDealId : null\n const dealLabel = targetDealId ? dealLabelMap.get(targetDealId) ?? null : null\n setIsSubmitting(true)\n pushLoading()\n try {\n const responseBody =\n (await dataAdapter.create({\n entityId: resolvedEntityId,\n body,\n appearanceIcon: icon,\n appearanceColor: color,\n dealId: targetDealId,\n context: dataContext,\n })) ?? {}\n setNotes((prev) => {\n const viewerId = viewerUserId ?? null\n const resolvedAuthorId =\n typeof responseBody?.authorUserId === 'string' ? responseBody.authorUserId : viewerId ?? null\n const resolvedAuthorName = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return youLabel\n }\n return typeof responseBody?.authorName === 'string' ? responseBody.authorName : viewerLabel\n })()\n const resolvedAuthorEmail = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return viewerEmail ?? null\n }\n return typeof responseBody?.authorEmail === 'string' ? responseBody.authorEmail : null\n })()\n const newNote: CommentSummary = {\n id: typeof responseBody?.id === 'string' ? responseBody.id : generateTempId(),\n body,\n createdAt: new Date().toISOString(),\n authorUserId: resolvedAuthorId,\n authorName: resolvedAuthorName,\n authorEmail: resolvedAuthorEmail,\n dealId: targetDealId,\n dealTitle: dealLabel,\n appearanceIcon: icon,\n appearanceColor: color,\n }\n return [newNote, ...prev]\n })\n setVisibleCount((prev) => Math.max(prev, 1))\n flash(label('success'), 'success')\n return true\n } catch (err) {\n const message = err instanceof Error ? err.message : label('error')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n return false\n } finally {\n setIsSubmitting(false)\n popLoading()\n }\n },\n [dataAdapter, dataContext, dealLabelMap, focusComposer, hasEntity, popLoading, pushLoading, resolvedDealId, resolvedEntityId, t, viewerEmail, viewerLabel, viewerUserId, youLabel],\n )\n\n const handleUpdateNote = React.useCallback(\n async (noteId: string, patch: { body?: string; appearanceIcon?: string | null; appearanceColor?: string | null }) => {\n const sanitizedBody = patch.body\n const sanitizedIcon =\n patch.appearanceIcon !== undefined && patch.appearanceIcon !== null && patch.appearanceIcon.trim().length\n ? patch.appearanceIcon.trim()\n : patch.appearanceIcon === null\n ? null\n : undefined\n const sanitizedColor =\n patch.appearanceColor !== undefined ? sanitizeHexColor(patch.appearanceColor ?? null) : undefined\n const noteUpdatedAt = notes.find((comment) => comment.id === noteId)?.updatedAt ?? null\n try {\n await dataAdapter.update({\n id: noteId,\n patch: {\n body: sanitizedBody,\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n },\n updatedAt: noteUpdatedAt,\n context: dataContext,\n })\n setNotes((prev) => {\n const nextComments = prev.map((comment) => {\n if (comment.id !== noteId) return comment\n const next = { ...comment }\n if (sanitizedBody !== undefined) next.body = sanitizedBody\n if (sanitizedIcon !== undefined) next.appearanceIcon = sanitizedIcon ?? null\n if (sanitizedColor !== undefined) next.appearanceColor = sanitizedColor ?? null\n return next\n })\n return nextComments\n })\n flash(label('updateSuccess'), 'success')\n } catch (error) {\n const message = error instanceof Error ? error.message : label('updateError')\n if (!surfaceRecordConflict(error, t)) flash(message, 'error')\n throw error instanceof Error ? error : new Error(message)\n }\n },\n [dataAdapter, dataContext, notes, t],\n )\n\n const handleDeleteNote = React.useCallback(\n async (note: CommentSummary) => {\n const confirmed = await confirm({\n title: label('deleteConfirm', 'Delete this note? You can restore it using version history.'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setDeletingNoteId(note.id)\n pushLoading()\n try {\n await dataAdapter.delete({ id: note.id, updatedAt: note.updatedAt ?? null, context: dataContext })\n setNotes((prev) => prev.filter((existing) => existing.id !== note.id))\n if (pagedMode) {\n setVisibleCount((prev) => Math.max(0, prev - 1))\n }\n flash(label('deleteSuccess', 'Note deleted'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : label('deleteError', 'Failed to delete note')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n } finally {\n setDeletingNoteId(null)\n popLoading()\n }\n },\n [confirm, dataAdapter, dataContext, label, popLoading, pushLoading, t],\n )\n\n const handleSubmit = React.useCallback(\n async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const created = await handleCreateNote({\n body: draftBody,\n appearanceIcon: draftIcon,\n appearanceColor: draftColor,\n })\n if (created) {\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }\n },\n [draftBody, draftColor, draftIcon, handleCreateNote],\n )\n\n const handleLoadMore = React.useCallback(() => {\n if (pagedMode && dataAdapter.listPage) {\n if (!hasMore || isLoading) return\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n setIsLoading(true)\n pushLoading()\n void dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: currentPage + 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n .then((pageResult) => {\n setNotes((prev) => {\n const merged = new Map(prev.map((note) => [note.id, note]))\n pageResult.items.forEach((note) => merged.set(note.id, note))\n return Array.from(merged.values())\n })\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n })\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : label('loadError', 'Failed to load notes.')\n flash(message, 'error')\n })\n .finally(() => {\n setIsLoading(false)\n popLoading()\n })\n return\n }\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(prev + 5, notes.length)\n })\n }, [currentPage, dataAdapter, dataContext, dealId, entityId, flash, hasMore, isLoading, label, notes.length, pagedMode, popLoading, pushLoading])\n\n const handleAppearanceDialogSubmit = React.useCallback(async () => {\n if (!appearanceDialogState) return\n setAppearanceDialogError(null)\n const sanitizedIcon =\n appearanceDialogState.icon && appearanceDialogState.icon.trim().length\n ? appearanceDialogState.icon.trim()\n : null\n const sanitizedColor = sanitizeHexColor(appearanceDialogState.color ?? null)\n if (appearanceDialogState.mode === 'create') {\n setDraftIcon(sanitizedIcon)\n setDraftColor(sanitizedColor)\n setAppearanceDialogState(null)\n return\n }\n setAppearanceDialogSaving(true)\n try {\n await handleUpdateNote(appearanceDialogState.noteId, {\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n })\n setAppearanceDialogState(null)\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : label('appearance.error', 'Failed to update appearance.')\n setAppearanceDialogError(message)\n } finally {\n setAppearanceDialogSaving(false)\n }\n }, [appearanceDialogState, handleUpdateNote, t])\n\n const handleAppearanceDialogClose = React.useCallback(() => {\n if (appearanceDialogSaving) return\n setAppearanceDialogState(null)\n setAppearanceDialogError(null)\n }, [appearanceDialogSaving])\n\n const handleContentSave = React.useCallback(async () => {\n if (!contentEditor.id) return\n const trimmed = contentEditor.value.trim()\n if (!trimmed) {\n setContentError(label('updateError', 'Failed to update note'))\n return\n }\n setContentSavingId(contentEditor.id)\n setContentError(null)\n try {\n await handleUpdateNote(contentEditor.id, { body: trimmed })\n setContentEditor({ id: '', value: '' })\n } catch (err) {\n const message =\n err instanceof Error ? err.message : label('updateError', 'Failed to update note')\n setContentError(message)\n } finally {\n setContentSavingId(null)\n }\n }, [contentEditor, handleUpdateNote, t])\n\n const handleContentEditorKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (!contentEditor.id) return\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (!contentSavingId) void handleContentSave()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n setContentEditor({ id: '', value: '' })\n setContentError(null)\n }\n },\n [contentEditor.id, contentSavingId, handleContentSave],\n )\n\n const handleComposerKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLFormElement>) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n formRef.current?.requestSubmit()\n }\n },\n [],\n )\n\n const handleContentKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>, note: CommentSummary) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n setContentEditor({ id: note.id, value: note.body })\n }\n },\n [],\n )\n\n const noteAuthorLabel = React.useCallback(\n (note: CommentSummary) => {\n if (note.authorUserId && viewerUserId && note.authorUserId === viewerUserId) {\n return youLabel\n }\n return note.authorName ?? note.authorEmail ?? youLabel\n },\n [viewerUserId, youLabel],\n )\n\n const noteAppearanceLabels = React.useMemo<AppearanceSelectorLabels>(\n () => ({\n colorLabel: label('appearance.colorLabel'),\n colorHelp: label('appearance.colorHelp'),\n colorClearLabel: label('appearance.clearColor'),\n iconLabel: label('appearance.iconLabel'),\n iconPlaceholder: label('appearance.iconPlaceholder'),\n iconPickerTriggerLabel: label('appearance.iconPicker'),\n iconSearchPlaceholder: label('appearance.iconSearchPlaceholder'),\n iconSearchEmptyLabel: label('appearance.iconSearchEmpty'),\n iconSuggestionsLabel: label('appearance.iconSuggestions'),\n iconClearLabel: label('appearance.iconClear'),\n previewEmptyLabel: label('appearance.previewEmpty'),\n }),\n [label],\n )\n\n const composerAuthor = React.useMemo(\n () => youLabel,\n [youLabel],\n )\n const composerHasAppearance = Boolean(draftIcon) || Boolean(draftColor)\n const appearanceDialogOpen = appearanceDialogState !== null\n const editingAppearanceNoteId =\n appearanceDialogState?.mode === 'edit' ? appearanceDialogState.noteId : null\n const addNoteShortcutLabel = label('addShortcut', 'Add note \u2318\u23CE / Ctrl+Enter')\n const saveAppearanceShortcutLabel = label('appearance.saveShortcut', 'Save appearance \u2318\u23CE / Ctrl+Enter')\n const composerSubmitLabel = addNoteShortcutLabel\n const appearanceDialogPrimaryLabel = saveAppearanceShortcutLabel\n const appearanceDialogSavingLabel =\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.saving')\n : label('saving', 'Saving note\u2026')\n\n return (\n <div className=\"mt-0 space-y-2\">\n <div\n className={[\n 'overflow-hidden rounded-xl transition-all duration-300 ease-out',\n composerOpen ? 'max-h-[1200px] bg-muted/30 p-4 opacity-100' : 'pointer-events-none max-h-0 p-0 opacity-0',\n ].join(' ')}\n aria-hidden={!composerOpen}\n >\n {composerOpen ? (\n <form\n ref={formRef}\n onSubmit={handleSubmit}\n onKeyDown={handleComposerKeyDown}\n className=\"space-y-3\"\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium\">{label('addLabel')}</h3>\n <div className=\"flex flex-wrap items-center gap-1\">\n {showAppearanceControls ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setAppearanceDialogError(null)\n setAppearanceDialogState({ mode: 'create', icon: draftIcon, color: draftColor })\n }}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <span className=\"sr-only\">{label('appearance.toggleOpen', 'Customize appearance')}</span>\n <Palette className=\"h-4 w-4\" />\n </Button>\n ) : null}\n {showMarkdownToggle ? (\n <Button\n type=\"button\"\n variant={isMarkdownActive ? 'secondary' : 'ghost'}\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownActive}\n disabled={isSubmitting || isLoading}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n ) : null}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting || isLoading}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n {(normalizedEntityOptions.length || normalizedDealOptions.length) ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {normalizedEntityOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-entity-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.entity', 'Assign to customer')}\n </label>\n <Select\n value={selectedEntityId || undefined}\n onValueChange={(next) => setSelectedEntityId(next ?? '')}\n disabled={isSubmitting || isLoading || !normalizedEntityOptions.length}\n >\n <SelectTrigger id=\"note-entity-select\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {normalizedEntityOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {normalizedDealOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-deal-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.deal', 'Link to deal (optional)')}\n </label>\n <Select\n value={selectedDealId || undefined}\n onValueChange={(next) => setSelectedDealId(next ?? '')}\n disabled={isSubmitting || isLoading}\n >\n <SelectTrigger id=\"note-deal-select\">\n <SelectValue placeholder={label('fields.dealPlaceholder', 'No linked deal')} />\n </SelectTrigger>\n <SelectContent>\n {normalizedDealOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n </div>\n ) : null}\n <SwitchableMarkdownInput\n value={draftBody}\n onChange={setDraftBody}\n isMarkdownEnabled={isMarkdownActive}\n disableMarkdown={disableMarkdown}\n rows={1}\n placeholder={label('placeholder')}\n textareaRef={textareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n disabled={isSubmitting || isLoading || !hasEntity}\n remarkPlugins={markdownPlugins}\n />\n {composerHasAppearance ? (\n <div className=\"flex flex-wrap items-center justify-between gap-3 rounded-lg border border-dashed border-muted-foreground/40 px-3 py-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-sm\">\n {draftIcon && renderIcon ? (\n <span className=\"inline-flex h-7 w-7 items-center justify-center rounded border border-border bg-muted/50\">\n {renderIcon(draftIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <span className=\"font-semibold text-foreground\">{composerAuthor}</span>\n {draftColor && renderColor ? (\n <span className=\"flex items-center gap-2\">\n {renderColor(draftColor, 'h-3.5 w-3.5 rounded-full border border-border')}\n <span className=\"text-xs font-medium uppercase text-muted-foreground\">{draftColor}</span>\n </span>\n ) : null}\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting}\n >\n {label('appearance.clearAll', 'Clear')}\n </Button>\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n {isSubmitting ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {composerSubmitLabel}\n </Button>\n </div>\n </form>\n ) : null}\n </div>\n\n {loadError ? <ErrorMessage label={loadError} className=\"mt-3\" /> : null}\n\n <div className=\"space-y-3\">\n {!composerOpen && hasVisibleNotes && !onActionChange ? (\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={focusComposer}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <Plus className=\"size-4\" />\n {addActionLabel}\n </Button>\n </div>\n ) : null}\n {isLoading ? (\n <LoadingMessage\n label={label('loading', 'Loading notes\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : hasVisibleNotes ? (\n visibleNotes.map((note) => {\n const author = noteAuthorLabel(note)\n const isAppearanceSaving = appearanceDialogSaving && editingAppearanceNoteId === note.id\n const isEditingContent = contentEditor.id === note.id\n const displayIcon = note.appearanceIcon ?? null\n const displayColor = note.appearanceColor ?? null\n const timestampValue = note.createdAt\n const fallbackTimestampLabel = formatDateTime(note.createdAt) ?? emptyLabel\n return (\n <div key={note.id} className=\"group space-y-2 rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <TimelineItemHeader\n title={author}\n timestamp={timestampValue}\n fallbackTimestampLabel={fallbackTimestampLabel}\n icon={displayIcon}\n color={displayColor}\n renderIcon={renderIcon}\n renderColor={renderColor}\n />\n {note.dealId ? (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <ArrowUpRightSquare className=\"h-3.5 w-3.5\" />\n <a\n href={`/backend/customers/deals/${encodeURIComponent(note.dealId)}`}\n className=\"font-medium text-foreground hover:underline\"\n >\n {note.dealTitle && note.dealTitle.length\n ? note.dealTitle\n : label('linkedDeal', 'Linked deal')}\n </a>\n </div>\n ) : null}\n </div>\n <div\n className={`flex items-center gap-2 transition-opacity ${\n isEditingContent ? 'opacity-100' : 'opacity-100 md:opacity-0 md:group-hover:opacity-100 focus-within:opacity-100'\n }`}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n {showAppearanceControls ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n setAppearanceDialogError(null)\n setAppearanceDialogState({\n mode: 'edit',\n noteId: note.id,\n icon: note.appearanceIcon ?? null,\n color: note.appearanceColor ?? null,\n })\n }}\n disabled={appearanceDialogSaving && editingAppearanceNoteId === note.id}\n >\n {isAppearanceSaving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Palette className=\"h-4 w-4\" />}\n </Button>\n ) : null}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n void handleDeleteNote(note)\n }}\n disabled={deletingNoteId === note.id}\n >\n {deletingNoteId === note.id ? (\n <span className=\"relative flex h-4 w-4 items-center justify-center text-destructive\">\n <span className=\"absolute h-4 w-4 animate-spin rounded-full border border-destructive border-t-transparent\" />\n </span>\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n {isEditingContent ? (\n <div className=\"space-y-2\" onKeyDown={handleContentEditorKeyDown}>\n <SwitchableMarkdownInput\n value={contentEditor.value}\n onChange={(nextValue) => setContentEditor((prev) => ({ ...prev, value: nextValue }))}\n isMarkdownEnabled={isMarkdownActive}\n disableMarkdown={disableMarkdown}\n rows={3}\n textareaRef={contentTextareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n textareaClassName=\"w-full resize-none overflow-hidden rounded-md border border-border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n editorWrapperClassName=\"w-full rounded-md border border-muted-foreground/20 bg-background p-2\"\n remarkPlugins={markdownPlugins}\n />\n {contentError ? <p className=\"text-xs text-status-error-text\">{contentError}</p> : null}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={handleContentSave} disabled={contentSavingId === note.id}>\n {contentSavingId === note.id ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {label('saving')}\n </>\n ) : (\n inlineLabel('saveShortcut')\n )}\n </Button>\n {showMarkdownToggle ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownActive}\n className={isMarkdownActive ? 'text-primary' : undefined}\n disabled={contentSavingId === note.id}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n ) : null}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => setContentEditor({ id: '', value: '' })}\n disabled={contentSavingId === note.id}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n ) : (\n <div\n role=\"button\"\n tabIndex={0}\n className=\"cursor-pointer text-sm\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n onKeyDown={(event) => handleContentKeyDown(event, note)}\n >\n <MarkdownPreview\n remarkPlugins={markdownPlugins}\n className=\"break-words text-foreground [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs\"\n >\n {note.body}\n </MarkdownPreview>\n </div>\n )}\n </div>\n )\n })\n ) : composerOpen ? null : (\n <TabEmptyState\n title={emptyState.title}\n description={emptyState.description}\n action={{\n label: emptyState.actionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || !hasEntity,\n }}\n />\n )}\n {isLoading || (pagedMode ? !hasMore : visibleCount >= notes.length) ? null : (\n <div className=\"flex justify-center\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleLoadMore}>\n {loadMoreLabel}\n </Button>\n </div>\n )}\n </div>\n {showAppearanceControls ? (\n <AppearanceDialog\n open={appearanceDialogOpen}\n title={\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.edit')\n : label('appearance.toggleOpen', 'Customize appearance')\n }\n icon={appearanceDialogState?.icon ?? null}\n color={appearanceDialogState?.color ?? null}\n labels={noteAppearanceLabels}\n iconSuggestions={iconSuggestions}\n onIconChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, icon: value ?? null } : prev))}\n onColorChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, color: value ?? null } : prev))}\n onSubmit={() => {\n void handleAppearanceDialogSubmit()\n }}\n onClose={handleAppearanceDialogClose}\n isSaving={appearanceDialogSaving}\n errorMessage={appearanceDialogError}\n primaryLabel={appearanceDialogPrimaryLabel}\n savingLabel={appearanceDialogSavingLabel}\n cancelLabel={label('appearance.cancel')}\n />\n ) : null}\n {ConfirmDialogElement}\n </div>\n )\n}\n\nexport function NotesSection<C = unknown>(props: NotesSectionProps<C>) {\n const handle = ComponentReplacementHandles.section('ui.detail', 'NotesSection')\n const Resolved = useRegisteredComponent<NotesSectionProps<C>>(\n handle,\n NotesSectionImpl as React.ComponentType<NotesSectionProps<C>>,\n )\n\n return (\n <div data-component-handle={handle}>\n <Resolved {...props} />\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["label"]
|
|
7
7
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
AlertTriangle,
|
|
7
7
|
Apple,
|
|
8
8
|
Archive,
|
|
9
|
+
AtSign,
|
|
9
10
|
Award,
|
|
10
11
|
BadgeCheck,
|
|
11
12
|
Ban,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
Bolt,
|
|
17
18
|
Book,
|
|
18
19
|
Bookmark,
|
|
20
|
+
Bot,
|
|
19
21
|
Box,
|
|
20
22
|
Boxes,
|
|
21
23
|
Briefcase,
|
|
@@ -167,6 +169,7 @@ const LUCIDE_ICON_REGISTRY = {
|
|
|
167
169
|
"alert-triangle": AlertTriangle,
|
|
168
170
|
"apple": Apple,
|
|
169
171
|
"archive": Archive,
|
|
172
|
+
"at-sign": AtSign,
|
|
170
173
|
"award": Award,
|
|
171
174
|
"badge-check": BadgeCheck,
|
|
172
175
|
"ban": Ban,
|
|
@@ -177,6 +180,7 @@ const LUCIDE_ICON_REGISTRY = {
|
|
|
177
180
|
"bolt": Bolt,
|
|
178
181
|
"book": Book,
|
|
179
182
|
"bookmark": Bookmark,
|
|
183
|
+
"bot": Bot,
|
|
180
184
|
"box": Box,
|
|
181
185
|
"boxes": Boxes,
|
|
182
186
|
"briefcase": Briefcase,
|