@siteping/widget 0.11.1 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunk-ISSCC4XP.js +9 -0
- package/dist/chunk-ISSCC4XP.js.map +1 -0
- package/dist/chunk-QDJDQQ6E.cjs +9 -0
- package/dist/chunk-QDJDQQ6E.cjs.map +1 -0
- package/dist/de-GCYQ3JCH.cjs +2 -0
- package/dist/de-GCYQ3JCH.cjs.map +1 -0
- package/dist/de-U3V6TPCZ.js +2 -0
- package/dist/de-U3V6TPCZ.js.map +1 -0
- package/dist/deep-link.d.cts +10 -0
- package/dist/deep-link.d.ts +10 -0
- package/dist/errors.d.cts +46 -16
- package/dist/errors.d.ts +46 -16
- package/dist/es-435K3LIV.cjs +2 -0
- package/dist/es-435K3LIV.cjs.map +1 -0
- package/dist/es-CSZUS23Z.js +2 -0
- package/dist/es-CSZUS23Z.js.map +1 -0
- package/dist/fr-DVOFE3WF.js +2 -0
- package/dist/fr-DVOFE3WF.js.map +1 -0
- package/dist/fr-RKRDGOTP.cjs +2 -0
- package/dist/fr-RKRDGOTP.cjs.map +1 -0
- package/dist/i18n.d.cts +14 -10
- package/dist/i18n.d.ts +14 -10
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -19
- package/dist/index.d.ts +26 -19
- package/dist/index.global.js +3 -3
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/it-COLRVG26.cjs +2 -0
- package/dist/it-COLRVG26.cjs.map +1 -0
- package/dist/it-ZWPEN22A.js +2 -0
- package/dist/it-ZWPEN22A.js.map +1 -0
- package/dist/ja-HLZ2GVFS.js +2 -0
- package/dist/ja-HLZ2GVFS.js.map +1 -0
- package/dist/ja-SNVDY7QP.cjs +2 -0
- package/dist/ja-SNVDY7QP.cjs.map +1 -0
- package/dist/ko-ORUCHGUZ.cjs +2 -0
- package/dist/ko-ORUCHGUZ.cjs.map +1 -0
- package/dist/ko-ZNF7AMXI.js +2 -0
- package/dist/ko-ZNF7AMXI.js.map +1 -0
- package/dist/logger.d.cts +30 -0
- package/dist/logger.d.ts +30 -0
- package/dist/panel-4CIN3Y66.js +2 -0
- package/dist/panel-4CIN3Y66.js.map +1 -0
- package/dist/panel-TD4UUEZA.cjs +2 -0
- package/dist/panel-TD4UUEZA.cjs.map +1 -0
- package/dist/pt-QQX5CA7D.cjs +2 -0
- package/dist/pt-QQX5CA7D.cjs.map +1 -0
- package/dist/pt-WGEJRQFC.js +2 -0
- package/dist/pt-WGEJRQFC.js.map +1 -0
- package/dist/react.cjs +2 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +9 -0
- package/dist/react.d.ts +9 -0
- package/dist/react.js +2 -3
- package/dist/react.js.map +1 -1
- package/dist/ru-SERDK6PQ.js +2 -0
- package/dist/ru-SERDK6PQ.js.map +1 -0
- package/dist/ru-YRXPV57R.cjs +2 -0
- package/dist/ru-YRXPV57R.cjs.map +1 -0
- package/dist/schema.d.cts +31 -0
- package/dist/schema.d.ts +31 -0
- package/dist/screenshot-storage.d.cts +14 -17
- package/dist/screenshot-storage.d.ts +14 -17
- package/dist/siteping-core.d.cts +8 -5
- package/dist/siteping-core.d.ts +8 -5
- package/dist/store-helpers.d.cts +13 -9
- package/dist/store-helpers.d.ts +13 -9
- package/dist/text.d.cts +28 -0
- package/dist/text.d.ts +28 -0
- package/dist/types.d.cts +114 -37
- package/dist/types.d.ts +114 -37
- package/dist/wire.d.cts +6 -1
- package/dist/wire.d.ts +6 -1
- package/package.json +10 -8
- package/dist/chunk-26577FDQ.js +0 -9
- package/dist/chunk-26577FDQ.js.map +0 -1
- package/dist/chunk-3EHIWTJH.js +0 -9
- package/dist/chunk-3EHIWTJH.js.map +0 -1
- package/dist/chunk-6MCFOKVG.cjs +0 -9
- package/dist/chunk-6MCFOKVG.cjs.map +0 -1
- package/dist/chunk-Q34GDCKE.cjs +0 -9
- package/dist/chunk-Q34GDCKE.cjs.map +0 -1
- package/dist/de-73CTH2E4.cjs +0 -2
- package/dist/de-73CTH2E4.cjs.map +0 -1
- package/dist/de-GUUJUHYP.js +0 -2
- package/dist/de-GUUJUHYP.js.map +0 -1
- package/dist/es-3MXMSDUC.js +0 -2
- package/dist/es-3MXMSDUC.js.map +0 -1
- package/dist/es-WJZ3XARH.cjs +0 -2
- package/dist/es-WJZ3XARH.cjs.map +0 -1
- package/dist/fr-52F3ZCLQ.js +0 -2
- package/dist/fr-52F3ZCLQ.js.map +0 -1
- package/dist/fr-ZCRIJWI3.cjs +0 -2
- package/dist/fr-ZCRIJWI3.cjs.map +0 -1
- package/dist/it-MEUT3RCC.js +0 -2
- package/dist/it-MEUT3RCC.js.map +0 -1
- package/dist/it-TGUTW6MO.cjs +0 -2
- package/dist/it-TGUTW6MO.cjs.map +0 -1
- package/dist/ja-DOS7AWLW.cjs +0 -2
- package/dist/ja-DOS7AWLW.cjs.map +0 -1
- package/dist/ja-U7NRNGPQ.js +0 -2
- package/dist/ja-U7NRNGPQ.js.map +0 -1
- package/dist/ko-U2CS6XQ4.js +0 -2
- package/dist/ko-U2CS6XQ4.js.map +0 -1
- package/dist/ko-ZUL567LW.cjs +0 -2
- package/dist/ko-ZUL567LW.cjs.map +0 -1
- package/dist/panel-3BEMZFIR.cjs +0 -2
- package/dist/panel-3BEMZFIR.cjs.map +0 -1
- package/dist/panel-HPDIAYLQ.js +0 -2
- package/dist/panel-HPDIAYLQ.js.map +0 -1
- package/dist/panel-MIWFGD7X.cjs +0 -2
- package/dist/panel-MIWFGD7X.cjs.map +0 -1
- package/dist/panel-XTNU6XHV.js +0 -2
- package/dist/panel-XTNU6XHV.js.map +0 -1
- package/dist/pt-BZRBHCYN.cjs +0 -2
- package/dist/pt-BZRBHCYN.cjs.map +0 -1
- package/dist/pt-MOS5DVOG.js +0 -2
- package/dist/pt-MOS5DVOG.js.map +0 -1
- package/dist/ru-KDNRHHNZ.cjs +0 -2
- package/dist/ru-KDNRHHNZ.cjs.map +0 -1
- package/dist/ru-VSWB5NKK.js +0 -2
- package/dist/ru-VSWB5NKK.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/segmented-control.ts","../src/panel-thread.ts","../src/panel.ts"],"names":["SegmentedControl","config","el","option","btn","isActive","iconWrap","parseSvg","labelEl","setText","e","value","buttons","visible","current","visibleValues","v","idx","nextIdx","next","m","showSending","input","send","sending","hints","buildThread","feedback","t","locale","canPost","draft","post","comments","root","list","shown","add","comment","item","head","author","badge","time","formatRelativeDate","body","COMMENT_BODY_MAX_LENGTH","foot","hint","isCoarsePointer","isMacPlatform","error","rendered","submit","newClientId","clientId","failed","isThreadFull","view","event","OPEN_FEEDBACK_STATUSES","FEEDBACK_STATUSES","s","isClosedStatus","cardList","className","label","Panel","shadowRoot","colors","bus","client","projectName","markers","options","setInert","header","title","ICON_CLOSE","ICON_TRASH","deleteAllLabel","setHidden","ExportButton","headerRight","PanelStats","filters","searchWrap","searchIcon","ICON_SEARCH","filterBar","PanelSortControls","BulkActions","ids","permission","f","DetailView","fb","newResolved","id","ann","isCompactViewport","action","normalizePanelActions","KeyboardShortcuts","dir","getFocusedCardIndex","focusCardByIndex","target","actionEl","card","feedbackId","message","isExpanded","ke","open","registerEscapeLayer","addSurfaceKeydownListener","isVisible","cur","scope","focusable","first","last","active","modal","startY","startTime","offset","dragging","release","loading","spinner","empty","text","retryBtn","tab","CLOSED_FEEDBACK_STATUSES","pages","signal","search","typeFilter","statuses","currentScope","hasContent","listIsMarkerQuery","keepThread","listRequest","feedbacks","total","page","more","controller","nextPage","loadMoreBtn","restoreBtn","setButtonLoading","markerUrl","own","found","met","seen","firstTotal","steady","capabilities","permissions","key","query","emptyText","sorted","sortFeedbacks","feedbackIds","groups","groupFeedbacksByPage","globalIndex","pagePath","groupFeedbacks","groupHeader","createPageGroupHeader","groupContent","index","remaining","loadMoreWrap","tWithParams","note","number","isResolved","typeColor","getTypeColor","getTypeLabel","getStatusLabel","bar","num","typeBg","getTypeBgColor","statusBadge","getStatusBgColor","getStatusColor","date","expandBtn","footer","resolveBtn","ICON_UNDO","ICON_CHECK","resolveBtnLabel","deleteBtn","deleteBtnLabel","closed","targets","results","i","_","failure","r","listed","resolve","backdrop","titleId","messageId","dialog","titleEl","messageEl","btnRow","cancelBtn","confirmBtn","close","result","removeKeydown","restore","ICON_LAYERS","ICON_QUESTION","ICON_CHANGE","ICON_BUG","ICON_OTHER","labelWrap","prefix","chevron","ICON_CHEVRON_DOWN","checkWrap","onClickOutside","ICON_DOT_OPEN","ICON_ARCHIVE","showTemplate","toggle","ICON_USER","selector","openDetail","escapedId","identity","record","c","replies","since","written","known","missing","a","b","fresh"],"mappings":"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","file":"panel-4CIN3Y66.js","sourcesContent":["/**\n * Accessible segmented (radiogroup) control.\n *\n * Replaces the near-identical `buildStatusSegmented` / `buildScopeSegmented`\n * pairs that previously lived inline in `panel.ts`: keyboard navigation\n * (ArrowLeft/Right, Home/End), aria-checked toggling, `tabIndex` roving,\n * and optional icon+colour decoration.\n *\n * Visibility filtering — needed by the scope control which hides the\n * \"this type\" option when there is no urlPattern — is handled by\n * `setOptionVisible(value, visible)` and is respected by keyboard\n * navigation so users can't focus a hidden option via arrow keys.\n */\n\nimport { el, parseSvg, setText } from \"../dom-utils.js\";\n\n/**\n * Visual decoration for a segmented option.\n * Both fields are optional: scope options omit them entirely.\n */\nexport interface SegmentedDecoration {\n icon?: string;\n color?: string;\n bg?: string;\n}\n\nexport interface SegmentedOption<T extends string> extends SegmentedDecoration {\n value: T;\n label: string;\n}\n\nexport interface SegmentedControlConfig<T extends string> {\n /** Options to render — order is preserved. */\n options: ReadonlyArray<SegmentedOption<T>>;\n /** Initial selected value — must appear in `options`. */\n value: T;\n /** Called whenever selection changes (click or keyboard). */\n onChange: (value: T) => void;\n /** Accessible label exposed via `aria-label` on the radiogroup. */\n ariaLabel: string;\n /** Extra CSS class appended to the wrapper (e.g. `sp-segmented--scope`). */\n extraClass?: string;\n /** dataset attribute name used per-button, e.g. `statusFilter` → `data-status-filter`. */\n datasetKey: string;\n /** Class prefix used for per-option modifier, e.g. `sp-segmented__btn--` + option.value. */\n modifierPrefix?: string;\n}\n\n/**\n * Build a segmented (radiogroup) control. Returns both the root element and\n * the imperative API for updating selection / visibility from outside —\n * Panel needs the latter when scope availability changes between SPA\n * navigations.\n */\nexport class SegmentedControl<T extends string> {\n readonly element: HTMLElement;\n private current: T;\n private readonly opts: ReadonlyArray<SegmentedOption<T>>;\n private readonly onChange: (value: T) => void;\n private readonly datasetKey: string;\n\n constructor(config: SegmentedControlConfig<T>) {\n this.opts = config.options;\n this.current = config.value;\n this.onChange = config.onChange;\n this.datasetKey = config.datasetKey;\n\n this.element = el(\"div\", {\n class: `sp-segmented${config.extraClass ? ` ${config.extraClass}` : \"\"}`,\n role: \"radiogroup\",\n });\n this.element.setAttribute(\"aria-label\", config.ariaLabel);\n\n for (const option of this.opts) {\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.className =\n config.modifierPrefix !== undefined\n ? `sp-segmented__btn ${config.modifierPrefix}${option.value}`\n : \"sp-segmented__btn\";\n btn.dataset[this.datasetKey] = option.value;\n btn.setAttribute(\"role\", \"radio\");\n const isActive = this.current === option.value;\n btn.setAttribute(\"aria-checked\", String(isActive));\n btn.tabIndex = isActive ? 0 : -1;\n if (isActive) btn.classList.add(\"sp-segmented__btn--active\");\n if (option.color) btn.style.setProperty(\"--sp-chip-color\", option.color);\n if (option.bg) btn.style.setProperty(\"--sp-chip-bg\", option.bg);\n\n if (option.icon) {\n const iconWrap = el(\"span\", { class: \"sp-segmented__icon\" });\n iconWrap.appendChild(parseSvg(option.icon));\n btn.appendChild(iconWrap);\n }\n\n const labelEl = el(\"span\", { class: \"sp-segmented__label\" });\n setText(labelEl, option.label);\n btn.appendChild(labelEl);\n\n btn.addEventListener(\"click\", () => this.select(option.value));\n btn.addEventListener(\"keydown\", (e) => this.handleKey(e, option.value));\n\n this.element.appendChild(btn);\n }\n }\n\n /** Imperatively change the selected option (also fires `onChange`). */\n select(value: T): void {\n this.current = value;\n this.syncSelection();\n this.onChange(value);\n }\n\n /** Apply selection-only DOM updates without firing `onChange`. Useful on init refresh. */\n private syncSelection(): void {\n const buttons = this.element.querySelectorAll<HTMLButtonElement>(\".sp-segmented__btn\");\n for (const btn of buttons) {\n const isActive = btn.dataset[this.datasetKey] === this.current;\n btn.classList.toggle(\"sp-segmented__btn--active\", isActive);\n btn.setAttribute(\"aria-checked\", String(isActive));\n btn.tabIndex = isActive ? 0 : -1;\n }\n }\n\n /**\n * Show / hide a specific option. Hidden options are skipped during keyboard\n * navigation. Returns true when an option was actually toggled.\n */\n setOptionVisible(value: T, visible: boolean): boolean {\n const btn = this.element.querySelector<HTMLButtonElement>(`[data-${this.kebabKey()}=\"${value}\"]`);\n if (!btn) return false;\n btn.style.display = visible ? \"\" : \"none\";\n return true;\n }\n\n /** Current selection. */\n get value(): T {\n return this.current;\n }\n\n /** Focus the button matching `value`, if it exists. */\n focusOption(value: T): void {\n const btn = this.element.querySelector<HTMLButtonElement>(`[data-${this.kebabKey()}=\"${value}\"]`);\n btn?.focus();\n }\n\n private handleKey(e: KeyboardEvent, current: T): void {\n const visibleValues = this.opts\n .map((o) => o.value)\n .filter((v) => {\n const btn = this.element.querySelector<HTMLButtonElement>(`[data-${this.kebabKey()}=\"${v}\"]`);\n return btn !== null && btn.style.display !== \"none\";\n });\n const idx = visibleValues.indexOf(current);\n if (idx < 0) return;\n\n let nextIdx: number;\n switch (e.key) {\n case \"ArrowLeft\":\n nextIdx = (idx - 1 + visibleValues.length) % visibleValues.length;\n break;\n case \"ArrowRight\":\n nextIdx = (idx + 1) % visibleValues.length;\n break;\n case \"Home\":\n nextIdx = 0;\n break;\n case \"End\":\n nextIdx = visibleValues.length - 1;\n break;\n default:\n return;\n }\n e.preventDefault();\n const next = visibleValues[nextIdx];\n if (next === undefined) return;\n this.select(next);\n this.focusOption(next);\n }\n\n /** Convert datasetKey (\"statusFilter\") to its DOM attribute form (\"status-filter\"). */\n private kebabKey(): string {\n return this.datasetKey.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n }\n}\n","/**\n * Discussion thread of the feedback detail view: the replies, oldest first,\n * and a composer when the backend takes them. Imported by the panel only, so\n * it ships in the lazily loaded panel chunk (its CSS lives in `DETAIL_CSS`).\n */\n\nimport {\n COMMENT_BODY_MAX_LENGTH,\n type CommentResponse,\n type FeedbackResponse,\n isThreadFull,\n newClientId,\n} from \"@siteping/core\";\nimport { el, formatRelativeDate, isMacPlatform, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { isCoarsePointer } from \"./viewport.js\";\n\n/**\n * A feedback's composer, kept by the panel across renders of its thread: a\n * list reload or a panel action's `refresh()` draws the detail view again,\n * and the draft, a reply in flight and its clientId must outlive that.\n */\nexport interface ThreadDraft {\n text: string;\n /**\n * The text last sent and its clientId, kept across its resends: the server\n * answers a resend of a reply that did land with the stored one instead of\n * adding it twice. An edited draft is another reply — under the first\n * one's id, that landed first text would come back in its place.\n */\n sent?: { body: string; clientId: string } | undefined;\n sending?: boolean | undefined;\n /** The render on screen, which a reply that lands goes to — whichever render sent it. */\n view?: ThreadView | undefined;\n}\n\ninterface ThreadView {\n add(comment: CommentResponse): void;\n input: HTMLTextAreaElement;\n send: HTMLButtonElement;\n error: HTMLElement;\n}\n\n/**\n * Show a send in flight on a render: the field read-only, Send busy (a CSS\n * spinner). Read-only and `aria-disabled` rather than disabled: a disabled\n * control drops the keyboard focus, and the identity prompt could not hand\n * it back on close.\n */\nfunction showSending({ input, send }: ThreadView, sending: boolean): void {\n input.readOnly = sending;\n send.setAttribute(\"aria-busy\", String(sending));\n send.setAttribute(\"aria-disabled\", String(sending));\n}\n\nexport interface ThreadOptions {\n t: TFunction;\n locale: string;\n /** Whether the backend takes replies — the list response's `capabilities.comments`. */\n canPost: boolean;\n /** This feedback's composer state. */\n draft: ThreadDraft;\n /** Post a reply; `null` when the visitor dismissed the identity prompt. Rejects when it failed. */\n post: (body: string, clientId: string) => Promise<CommentResponse | null>;\n}\n\n/** Numbers the composer hints, whose ids the fields point at. */\nlet hints = 0;\n\n/** The thread under the message — `null` when there is nothing to read and no way to reply. */\nexport function buildThread(\n feedback: FeedbackResponse,\n { t, locale, canPost, draft, post }: ThreadOptions,\n): HTMLElement | null {\n // A server that predates threads sends no `comments` at all.\n const comments = feedback.comments ?? [];\n if (!canPost && comments.length === 0) return null;\n\n const root = el(\"div\");\n // A labelled list: a screen reader hears where the replies start, and how\n // many there are (`role` too: WebKit drops it from an unstyled list).\n // Polite: a reply that lands is read out, not just drawn.\n const list = el(\"ol\", {\n class: \"sp-thread-list\",\n role: \"list\",\n \"aria-label\": t(\"comments.title\"),\n \"aria-live\": \"polite\",\n });\n const shown = new Set<string>();\n const add = (comment: CommentResponse): void => {\n // A reload may have brought the reply in before its own answer did.\n if (shown.has(comment.id)) return;\n shown.add(comment.id);\n const item = el(\"li\", { class: \"sp-detail-message sp-comment\", \"data-role\": comment.authorRole });\n const head = el(\"div\", { class: \"sp-comment-head\" });\n const author = el(\"span\");\n setText(author, comment.authorName);\n head.appendChild(author);\n if (comment.authorRole === \"team\") {\n const badge = el(\"span\", { class: \"sp-badge\" });\n setText(badge, t(\"comments.team\"));\n head.appendChild(badge);\n }\n const time = el(\"time\", { datetime: comment.createdAt });\n setText(time, formatRelativeDate(comment.createdAt, locale));\n head.appendChild(time);\n const body = el(\"div\");\n setText(body, comment.body);\n item.append(head, body);\n list.appendChild(item);\n };\n for (const comment of comments) add(comment);\n root.appendChild(list);\n if (!canPost) return root;\n\n const input = document.createElement(\"textarea\");\n input.className = \"sp-input sp-thread-input\";\n input.rows = 3;\n input.maxLength = COMMENT_BODY_MAX_LENGTH;\n input.placeholder = t(\"comments.placeholder\");\n input.setAttribute(\"aria-label\", input.placeholder);\n input.value = draft.text;\n input.addEventListener(\"input\", () => {\n draft.text = input.value;\n });\n\n const foot = el(\"div\", { class: \"sp-thread-foot\" });\n // Left empty on touch screens, like the feedback form's hint: no hardware\n // keyboard to press the shortcut with. The span keeps Send on the right.\n const hint = el(\"span\", { id: `sp-thread-hint-${++hints}` });\n if (!isCoarsePointer()) {\n setText(hint, t(isMacPlatform() ? \"popup.submitHintMac\" : \"popup.submitHintOther\"));\n input.setAttribute(\"aria-describedby\", hint.id);\n input.setAttribute(\"aria-keyshortcuts\", \"Control+Enter Meta+Enter\");\n }\n const send = document.createElement(\"button\");\n send.type = \"button\";\n send.className = \"sp-btn-primary\";\n setText(send, t(\"popup.submit\"));\n foot.append(hint, send);\n // Filled on failure: an alert is announced when its text changes.\n const error = el(\"div\", { class: \"sp-thread-error\", role: \"alert\" });\n root.append(input, foot, error);\n const rendered = { add, input, send, error };\n draft.view = rendered;\n showSending(rendered, draft.sending === true);\n\n const submit = async (): Promise<void> => {\n draft.text = input.value;\n const body = draft.text.trim();\n if (draft.sending || !body) return;\n if (draft.sent?.body !== body) draft.sent = { body, clientId: newClientId() };\n const { clientId } = draft.sent;\n draft.sending = true;\n setText(error, \"\");\n showSending(rendered, true);\n let failed = \"\";\n let comment: CommentResponse | null = null;\n try {\n comment = await post(body, clientId);\n } catch (error) {\n // Retrying won't help a full thread.\n failed = t(isThreadFull(error) ? \"comments.full\" : \"comments.error\");\n }\n draft.sending = false;\n // The thread may have been drawn again meanwhile: settle the one on screen.\n const view = draft.view ?? rendered;\n showSending(view, false);\n // On failure the text stays in the field for another try.\n setText(view.error, failed);\n if (comment) {\n view.add(comment);\n view.input.value = draft.text = \"\";\n draft.sent = undefined;\n }\n };\n send.addEventListener(\"click\", () => void submit());\n // Same shortcut as the feedback popup — Enter alone starts a new line.\n input.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n void submit();\n }\n });\n return root;\n}\n","import {\n CLOSED_FEEDBACK_STATUSES,\n type CommentResponse,\n FEEDBACK_STATUSES,\n type FeedbackResponse,\n type FeedbackResponseList,\n type FeedbackStatus,\n type FeedbackType,\n isClosedStatus,\n MAX_PAGE_LIMIT,\n type PageScope,\n type SitepingIdentity,\n type SitepingPanelAction,\n} from \"@siteping/core\";\nimport type { GetFeedbacksOptions, WidgetClient } from \"./api-client.js\";\nimport { SegmentedControl } from \"./components/segmented-control.js\";\nimport { PAGE_SIZE } from \"./constants.js\";\nimport {\n el,\n formatRelativeDate,\n onClickOutside,\n parseSvg,\n setButtonLoading,\n setHidden,\n setInert,\n setText,\n} from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport { ExportButton } from \"./export-utils.js\";\nimport { addSurfaceKeydownListener, registerEscapeLayer } from \"./host-isolation.js\";\nimport { getStatusLabel, getTypeLabel, type TFunction, tWithParams } from \"./i18n/index.js\";\nimport {\n ICON_ARCHIVE,\n ICON_BUG,\n ICON_CHANGE,\n ICON_CHECK,\n ICON_CHEVRON_DOWN,\n ICON_CLOSE,\n ICON_DOT_OPEN,\n ICON_LAYERS,\n ICON_OTHER,\n ICON_QUESTION,\n ICON_SEARCH,\n ICON_TRASH,\n ICON_UNDO,\n ICON_USER,\n} from \"./icons.js\";\nimport type { MarkerManager } from \"./markers.js\";\nimport type { OwnFeedback } from \"./own-feedback.js\";\nimport { normalizePanelActions } from \"./panel-actions.js\";\nimport { BulkActions, type TriagePermission } from \"./panel-bulk.js\";\nimport { DetailView } from \"./panel-detail.js\";\nimport { createPageGroupHeader, groupFeedbacksByPage, PanelSortControls, sortFeedbacks } from \"./panel-sort.js\";\nimport { PanelStats } from \"./panel-stats.js\";\nimport { buildThread, type ThreadDraft } from \"./panel-thread.js\";\nimport { focusCardByIndex, getFocusedCardIndex, KeyboardShortcuts } from \"./shortcuts.js\";\nimport { getStatusBgColor, getStatusColor, getTypeBgColor, getTypeColor, type ThemeColors } from \"./styles/theme.js\";\nimport { isCoarsePointer, isCompactViewport } from \"./viewport.js\";\n\n/** Non-terminal statuses — complement of `CLOSED_FEEDBACK_STATUSES`; backs the panel's \"Open\" tab bucket. */\nconst OPEN_FEEDBACK_STATUSES: readonly FeedbackStatus[] = FEEDBACK_STATUSES.filter((s) => !isClosedStatus(s));\n\n/** An ARIA list for cards (each card is its `listitem`), named `label`. */\nfunction cardList(className: string, label: string): HTMLElement {\n const list = el(\"div\", { class: className });\n list.setAttribute(\"role\", \"list\");\n list.setAttribute(\"aria-label\", label);\n return list;\n}\n\n/**\n * Side panel (400px) with feedback history, filters, search, stats,\n * sort/group, bulk actions, export, detail view, and keyboard shortcuts.\n * On phones it is a bottom sheet over a scrim — swipe its header down to close.\n *\n * Lives inside the Shadow DOM.\n * Glassmorphism: glass background, staggered card animations,\n * loading states, resolve feedback with disabled state.\n */\nexport class Panel {\n private root: HTMLElement;\n private scrim: HTMLElement;\n private listContainer: HTMLElement;\n private searchInput: HTMLInputElement;\n private closeBtn: HTMLButtonElement;\n private deleteAllBtn: HTMLButtonElement;\n private activeFilters = new Set<string>([\"all\"]);\n private typeDropdownBtn!: HTMLButtonElement;\n private typeDropdownContainer!: HTMLElement;\n private typeDropdownMenu: HTMLElement | null = null;\n private removeTypeDropdownOutsideClick: (() => void) | null = null;\n private statusSegmented!: SegmentedControl<\"all\" | FeedbackStatus>;\n private typeOptions!: ReadonlyArray<{ value: string; label: string; icon: string; color: string; bg: string }>;\n private feedbacks: FeedbackResponse[] = [];\n private currentPage = 1;\n private totalFeedbacks = 0;\n private isLoadingMore = false;\n private isOpen = false;\n private searchTimeout: ReturnType<typeof setTimeout> | null = null;\n private loadController: AbortController | null = null;\n /** True while `loadFeedbacks()` waits for the list it will render. */\n private isLoading = false;\n /**\n * Feedback a marker click asked to reveal while the list was loading (a\n * marker click on a closed panel opens it first): scrolled to and flashed\n * once that load renders, dropped if the panel closes meanwhile.\n */\n private pendingScrollId: string | null = null;\n /** Whether the pending scroll also opens the card's detail view (see `showFeedback`). */\n private pendingDetail = false;\n /** Tracks feedback IDs with in-flight mutations to prevent spam-click race conditions */\n private pendingMutations = new Set<string>();\n /** Whether the backend takes replies — advertised by the last list response. */\n private canComment = false;\n /** Each feedback's composer state, by id — see `ThreadDraft`. */\n private readonly threadDrafts = new Map<string, ThreadDraft>();\n /**\n * Every reply that lands takes the next number, and its feedback keeps the\n * replies posted from here (#420): a list requested before the last of\n * them may have been read before the server stored it — see `keepThreads`.\n */\n private threadWriteCount = 0;\n private readonly threadWrites = new Map<string, { seq: number; replies: CommentResponse[] }>();\n /** Reviewer mode (`config.readOnly`): no triage action, whatever the server allows. */\n private readonly readOnly: boolean;\n /** The visitor a reply is posted as — `null` when they dismiss the identity prompt. */\n private readonly resolveIdentity: () => Promise<SitepingIdentity | null>;\n\n // New feature modules\n private readonly stats: PanelStats;\n private readonly sortControls: PanelSortControls;\n private readonly bulk: BulkActions;\n private readonly exportBtn: ExportButton;\n private readonly shortcuts: KeyboardShortcuts;\n private readonly detail: DetailView;\n private readonly shadowRoot: ShadowRoot;\n\n // i18n: t is shared with all submodules.\n\n // Page scope — supplied by launcher so the panel can scope its results to\n // the current page (or template) and filter markers accordingly.\n private readonly getScope: () => PageScope;\n private readonly scopeAnnotationsByUrl: boolean;\n /** \"this\" = current url, \"template\" = url pattern, \"all\" = no scope filter */\n private scopeSegmented!: SegmentedControl<\"this\" | \"template\" | \"all\">;\n /** Cached initial scope value — applied after construction in `buildScopeSegmented`. */\n private readonly initialScopeFilter: \"this\" | \"template\" | \"all\" = \"this\";\n /** \"Mine\" filter: only the feedback sent from this browser, whose ids the launcher remembers. */\n private mineOnly = false;\n private readonly ownFeedback: Pick<OwnFeedback, \"ids\" | \"remove\">;\n\n constructor(\n shadowRoot: ShadowRoot,\n private readonly colors: ThemeColors,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly client: WidgetClient,\n private readonly projectName: string,\n private readonly markers: MarkerManager,\n private readonly t: TFunction,\n private readonly locale: string,\n options?: {\n getScope: () => PageScope;\n scopeAnnotationsByUrl: boolean;\n panelActions?: readonly SitepingPanelAction[] | undefined;\n ownFeedback?: Pick<OwnFeedback, \"ids\" | \"remove\"> | undefined;\n resolveIdentity?: () => Promise<SitepingIdentity | null>;\n readOnly?: boolean | undefined;\n },\n ) {\n this.shadowRoot = shadowRoot;\n this.readOnly = !!options?.readOnly;\n this.resolveIdentity = options?.resolveIdentity ?? (async () => null);\n this.getScope = options?.getScope ?? (() => ({ url: window.location.pathname, urlPattern: null }));\n this.scopeAnnotationsByUrl = options?.scopeAnnotationsByUrl ?? true;\n this.ownFeedback = options?.ownFeedback ?? { ids: () => new Set(), remove: () => {} };\n\n // Phone layout: dims the page behind the sheet; a tap on it closes the panel.\n this.scrim = el(\"div\", { class: \"sp-scrim\" });\n this.scrim.addEventListener(\"click\", () => this.close());\n\n this.root = el(\"div\", { class: \"sp-panel\" });\n this.root.setAttribute(\"role\", \"complementary\");\n this.root.setAttribute(\"aria-label\", this.t(\"panel.ariaLabel\"));\n this.root.setAttribute(\"aria-hidden\", \"true\");\n // Slid off-screen while closed, but still rendered: out of the tab order.\n setInert(this.root, true);\n\n // --- Header ---\n const header = el(\"div\", { class: \"sp-panel-header\" });\n const title = el(\"span\", { class: \"sp-panel-title\" });\n setText(title, this.t(\"panel.title\"));\n\n this.closeBtn = document.createElement(\"button\");\n this.closeBtn.className = \"sp-panel-close\";\n this.closeBtn.setAttribute(\"aria-label\", this.t(\"panel.close\"));\n this.closeBtn.appendChild(parseSvg(ICON_CLOSE));\n this.closeBtn.addEventListener(\"click\", () => this.close());\n\n this.deleteAllBtn = document.createElement(\"button\");\n this.deleteAllBtn.className = \"sp-btn-delete-all\";\n this.deleteAllBtn.setAttribute(\"aria-label\", this.t(\"panel.deleteAll\"));\n this.deleteAllBtn.appendChild(parseSvg(ICON_TRASH));\n const deleteAllLabel = document.createElement(\"span\");\n setText(deleteAllLabel, ` ${this.t(\"panel.deleteAll\")}`);\n this.deleteAllBtn.appendChild(deleteAllLabel);\n this.deleteAllBtn.addEventListener(\"click\", () => this.confirmDeleteAll());\n // Until a list says whether this visitor may use it.\n setHidden(this.deleteAllBtn, true);\n\n // Export button\n this.exportBtn = new ExportButton(colors, () => this.feedbacks, this.t);\n\n const headerRight = el(\"div\", { class: \"sp-panel-header-right\" });\n headerRight.appendChild(this.exportBtn.element);\n headerRight.appendChild(this.deleteAllBtn);\n headerRight.appendChild(this.closeBtn);\n\n header.appendChild(title);\n header.appendChild(headerRight);\n\n // --- Stats ---\n this.stats = new PanelStats(this.t);\n\n // --- Filters ---\n const filters = el(\"div\", { class: \"sp-filters\" });\n\n // Search\n const searchWrap = el(\"div\", { class: \"sp-search-wrap\" });\n const searchIcon = parseSvg(ICON_SEARCH);\n searchIcon.setAttribute(\"class\", \"sp-search-icon\");\n this.searchInput = document.createElement(\"input\");\n this.searchInput.type = \"text\";\n this.searchInput.className = \"sp-search\";\n this.searchInput.placeholder = this.t(\"panel.search\");\n this.searchInput.setAttribute(\"aria-label\", this.t(\"panel.searchAria\"));\n this.searchInput.addEventListener(\"input\", () => {\n if (this.searchTimeout) clearTimeout(this.searchTimeout);\n this.searchTimeout = setTimeout(() => this.loadFeedbacks().catch(() => {}), 200);\n });\n searchWrap.appendChild(searchIcon);\n searchWrap.appendChild(this.searchInput);\n\n // Filter bar (type dropdown + status segmented + scope segmented + \"Mine\").\n // The scope control gives users a fast way to widen results to \"this type\n // of page\" or \"all pages\" when the host provides a route template.\n const filterBar = el(\"div\", { class: \"sp-filter-bar\" });\n filterBar.appendChild(this.buildTypeDropdown());\n filterBar.appendChild(this.buildStatusSegmented());\n filterBar.appendChild(this.buildScopeSegmented());\n filterBar.appendChild(this.buildMineToggle());\n\n // Sort controls\n this.sortControls = new PanelSortControls(() => this.renderList(), this.t);\n\n filters.appendChild(searchWrap);\n filters.appendChild(filterBar);\n filters.appendChild(this.sortControls.element);\n\n // --- List ---\n // The scroll container. The ARIA list is the cards' own wrapper, rendered\n // with them: a list may own list items only, and the select-all bar, the\n // page-group headers and \"Load more\" sit beside the cards in here.\n this.listContainer = el(\"div\", { class: \"sp-list\" });\n\n // --- Bulk Actions ---\n this.bulk = new BulkActions(\n colors,\n {\n onResolve: (ids) => this.bulkResolve(ids),\n onDelete: (ids) => this.bulkDelete(ids),\n permits: (ids, permission) => this.feedbacks.every((f) => !ids.includes(f.id) || this.can(f, permission)),\n },\n this.t,\n );\n this.bulk.setListContainer(this.listContainer);\n\n // --- Detail View ---\n this.detail = new DetailView(\n colors,\n {\n onBack: () => this.detail.hide(),\n onResolve: async (fb) => {\n try {\n // Client-facing binary action: closed statuses (resolved, wont_fix)\n // reopen, everything else (open, in_progress) resolves.\n const newResolved = !isClosedStatus(fb.status);\n await this.client.resolveFeedback(fb.id, newResolved);\n await this.loadFeedbacks();\n this.hideDetailOf(fb.id);\n } catch (error) {\n // Surface the failure to the host (config.onError) like the list\n // and bulk paths do, then rethrow so DetailView restores its\n // buttons and stays open.\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n },\n onDelete: async (fb) => {\n try {\n await this.client.deleteFeedback(fb.id);\n this.bus.emit(\"feedback:deleted\", fb.id);\n await this.loadFeedbacks();\n this.hideDetailOf(fb.id);\n } catch (error) {\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n },\n // Same rule as the page markers: another page's scroll offset and\n // anchor mean nothing here (reachable via the \"all pages\" scope).\n canGoToAnnotation: (fb) => !this.scopeAnnotationsByUrl || fb.url === this.getScope().url,\n lostNote: (id) => this.lostNote(id),\n onGoToAnnotation: (fb) => {\n if (fb.annotations.length > 0) {\n const ann = fb.annotations[0];\n if (!ann) return;\n // Follow the live pin: the stored offsets come from the author's\n // layout and miss on another screen size. They remain the fallback\n // when no pin is on screen (anchor lost, or markers hidden).\n if (!this.markers.revealPin(fb.id)) {\n window.scrollTo({ left: ann.scrollX, top: ann.scrollY, behavior: \"smooth\" });\n this.markers.pinHighlight(fb);\n }\n // The phone sheet covers the page it just scrolled — get out of the way.\n if (isCompactViewport()) this.close();\n }\n },\n onCustomAction: async (action, fb) => {\n try {\n await action.onAction(fb, { refresh: () => this.refreshDetail(fb.id), close: () => this.close() });\n } catch (error) {\n this.reportActionError(error);\n }\n },\n onCustomActionError: (error) => this.reportActionError(error),\n permits: (fb, permission) => this.can(fb, permission),\n buildThread: (fb) =>\n buildThread(fb, {\n t: this.t,\n locale,\n canPost: this.canComment && fb.permissions?.canComment !== false,\n draft: this.draftOf(fb.id),\n post: (body, clientId) => this.postComment(fb, body, clientId),\n }),\n },\n this.t,\n locale,\n normalizePanelActions(options?.panelActions),\n );\n\n // --- Keyboard Shortcuts ---\n this.shortcuts = new KeyboardShortcuts(\n colors,\n {\n onNavigate: (dir) => {\n const idx = getFocusedCardIndex(this.listContainer);\n focusCardByIndex(this.listContainer, dir === \"down\" ? idx + 1 : idx - 1);\n },\n onResolve: () => this.pressInFocusedCard('[data-action=\"resolve\"]'),\n onDelete: () => this.pressInFocusedCard('[data-action=\"delete\"]'),\n onFocusSearch: () => this.searchInput.focus(),\n onToggleSelect: () => this.pressInFocusedCard(\".sp-bulk-checkbox\"),\n // The detail view covers the whole list (and would hide the help overlay).\n isSuspended: () => this.detail.isVisible,\n },\n this.t,\n );\n\n // --- Assemble DOM ---\n this.root.appendChild(header);\n this.root.appendChild(this.stats.element);\n this.root.appendChild(filters);\n this.root.appendChild(this.listContainer);\n this.root.appendChild(this.bulk.barElement);\n this.root.appendChild(this.detail.element);\n this.root.appendChild(this.shortcuts.helpOverlay);\n this.root.appendChild(this.shortcuts.hintButton);\n shadowRoot.appendChild(this.scrim);\n shadowRoot.appendChild(this.root);\n this.attachSheetDrag();\n\n // --- Event delegation on listContainer ---\n\n this.onListClick = (e: Event) => {\n const target = e.target as Element;\n\n // Bulk checkbox clicks are handled by BulkActions, skip\n if (target.closest(\".sp-bulk-checkbox\")) return;\n\n // Action buttons (expand, resolve, delete)\n const actionEl = target.closest<HTMLElement>(\"[data-action]\");\n if (actionEl) {\n e.stopPropagation();\n const card = actionEl.closest<HTMLElement>(\".sp-card\");\n if (!card) return;\n const feedbackId = card.dataset.feedbackId;\n const feedback = this.feedbacks.find((f) => f.id === feedbackId);\n if (!feedback) return;\n\n const action = actionEl.dataset.action;\n if (action === \"expand\") {\n const message = card.querySelector<HTMLElement>(\".sp-card-message\");\n if (!message) return;\n const isExpanded = message.classList.toggle(\"sp-card-message--expanded\");\n setText(actionEl, isExpanded ? this.t(\"panel.showLess\") : this.t(\"panel.showMore\"));\n actionEl.setAttribute(\"aria-expanded\", String(isExpanded));\n } else if (action === \"resolve\") {\n if (this.pendingMutations.has(feedback.id)) return;\n const btn = actionEl as HTMLButtonElement;\n this.toggleResolve(feedback, btn).catch(() => {});\n } else if (action === \"delete\") {\n if (this.pendingMutations.has(feedback.id)) return;\n const btn = actionEl as HTMLButtonElement;\n this.deleteFeedback(feedback, btn).catch(() => {});\n }\n return;\n }\n\n // Card click → open detail view\n const card = target.closest<HTMLElement>(\".sp-card\");\n if (card) {\n const feedbackId = card.dataset.feedbackId;\n const feedback = this.feedbacks.find((f) => f.id === feedbackId);\n if (feedback) this.detail.show(feedback, Number(card.dataset.number));\n }\n };\n this.listContainer.addEventListener(\"click\", this.onListClick);\n\n this.onListKeydown = (e: Event) => {\n const ke = e as KeyboardEvent;\n if (ke.key !== \"Enter\" && ke.key !== \" \") return;\n const target = ke.target as Element;\n const card = target.closest<HTMLElement>(\".sp-card\");\n // Only activate if the card itself is focused, not a button inside it\n if (!card || target !== card) return;\n ke.preventDefault();\n const feedbackId = card.dataset.feedbackId;\n const feedback = this.feedbacks.find((f) => f.id === feedbackId);\n if (feedback) this.detail.show(feedback, Number(card.dataset.number));\n };\n this.listContainer.addEventListener(\"keydown\", this.onListKeydown);\n\n // mouseover/mouseout bubble (unlike mouseenter/mouseleave), enabling delegation\n this.onListMouseover = (e: Event) => {\n const target = (e as MouseEvent).target as Element;\n const card = target.closest<HTMLElement>(\".sp-card\");\n if (!card) return;\n const feedbackId = card.dataset.feedbackId;\n if (feedbackId) this.markers.highlight(feedbackId);\n };\n this.listContainer.addEventListener(\"mouseover\", this.onListMouseover);\n\n this.onListMouseout = (e: Event) => {\n const target = (e as MouseEvent).relatedTarget as Element | null;\n // Only clear highlight when leaving all cards (relatedTarget is outside listContainer)\n if (target && this.listContainer.contains(target)) return;\n this.markers.highlight(\"\");\n };\n this.listContainer.addEventListener(\"mouseout\", this.onListMouseout);\n\n // Events\n this.bus.on(\"markers:placed\", () => this.syncLostNotes());\n this.bus.on(\"panel:toggle\", (open) => {\n open ? this.open() : this.close();\n });\n\n // Keyboard handling: Escape to close + focus trap. Nested layers (menus,\n // confirm dialog) stop Escape before it bubbles here; the help overlay's\n // handler sits on this same shadow root but runs later, so defer to it.\n registerEscapeLayer(shadowRoot, () => this.isOpen);\n addSurfaceKeydownListener(shadowRoot, (ke) => {\n if (ke.key === \"Escape\" && this.isOpen) {\n if (this.shortcuts.isHelpVisible) return;\n // If detail view is open, close it instead\n if (this.detail.isVisible) {\n this.detail.hide();\n return;\n }\n this.close();\n return;\n }\n if (ke.key === \"Tab\" && this.isOpen) {\n // Filter out non-tabbable elements: those hidden via `display: none`\n // (either on themselves or any ancestor up to this.root) and elements\n // explicitly disabled. Without this filter, the trap can jump to a\n // button inside a closed detail view and effectively swallow the Tab\n // key. We walk the computed display rather than `offsetParent`\n // because the latter is unreliable in jsdom (always null without\n // layout) and breaks unit tests. Computed, not inline: the touch layer\n // hides the trailing shortcuts button from its stylesheet, and a\n // hidden `last` let Tab walk out of the sheet onto the page.\n const isVisible = (el: HTMLElement): boolean => {\n let cur: HTMLElement | null = el;\n while (cur && cur !== this.root) {\n if (getComputedStyle(cur).display === \"none\") return false;\n cur = cur.parentElement;\n }\n return true;\n };\n // The topmost open layer covers the rest of the panel, so Tab cycles\n // inside it: the help overlay, else the detail view, else the panel.\n // Closed layers are `inert` (the browser skips them; the walk below\n // must too, or `first`/`last` land on a control Tab never reaches).\n const scope = this.shortcuts.isHelpVisible\n ? this.shortcuts.helpOverlay\n : this.detail.isVisible\n ? this.detail.element\n : this.root;\n const focusable = Array.from(\n scope.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((el) => isVisible(el) && !el.hasAttribute(\"disabled\") && !el.closest(\"[inert]\"));\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (!first || !last) return;\n const active = (shadowRoot as ShadowRoot).activeElement;\n if (!active || !scope.contains(active)) {\n // Focus behind the open layer (or nowhere) re-enters it.\n ke.preventDefault();\n (ke.shiftKey ? last : first).focus();\n } else if (ke.shiftKey && active === first) {\n ke.preventDefault();\n last.focus();\n } else if (!ke.shiftKey && active === last) {\n ke.preventDefault();\n first.focus();\n }\n }\n });\n\n // Listen for marker clicks\n this.onMarkerClick = ((e: CustomEvent) => {\n this.scrollToFeedback(e.detail.feedbackId);\n }) as EventListener;\n document.addEventListener(\"sp-marker-click\", this.onMarkerClick);\n }\n\n private onMarkerClick: EventListener;\n private onListClick: (e: Event) => void;\n private onListKeydown: (e: Event) => void;\n private onListMouseover: (e: Event) => void;\n private onListMouseout: (e: Event) => void;\n\n async open(): Promise<void> {\n if (this.isOpen) return;\n this.isOpen = true;\n // Phones: a sheet over a scrim is a modal dialog, and says so to screen\n // readers (VoiceOver then keeps to it); elsewhere the panel sits beside the page.\n const modal = isCompactViewport();\n this.root.setAttribute(\"role\", modal ? \"dialog\" : \"complementary\");\n modal ? this.root.setAttribute(\"aria-modal\", \"true\") : this.root.removeAttribute(\"aria-modal\");\n this.root.classList.add(\"sp-panel--open\");\n this.scrim.classList.add(\"sp-scrim--open\");\n this.root.setAttribute(\"aria-hidden\", \"false\");\n setInert(this.root, false);\n this.bus.emit(\"open\");\n this.shortcuts.enable(this.shadowRoot);\n await this.loadFeedbacks();\n // Move focus into the panel. Touch: the close button — focusing the\n // search field would throw the keyboard over the list.\n requestAnimationFrame(() => {\n (isCoarsePointer() ? this.closeBtn : this.searchInput).focus();\n });\n }\n\n close(): void {\n if (!this.isOpen) return;\n this.isOpen = false;\n this.root.classList.remove(\"sp-panel--open\");\n this.scrim.classList.remove(\"sp-scrim--open\");\n this.root.setAttribute(\"aria-hidden\", \"true\");\n setInert(this.root, true);\n this.bus.emit(\"close\");\n this.shortcuts.disable();\n this.detail.hide();\n this.pendingScrollId = null;\n this.pendingDetail = false;\n // Restore focus to the FAB\n const fab = (this.root.getRootNode() as ShadowRoot).querySelector<HTMLButtonElement>(\".sp-fab\");\n fab?.focus();\n }\n\n /**\n * Swipe-down-to-close for the phone sheet. Only the headers (panel and\n * detail) are drag handles, so scrolling the list never dismisses it.\n */\n private attachSheetDrag(): void {\n let startY = 0;\n let startTime = 0;\n let offset = 0;\n let dragging = false;\n this.root.addEventListener(\"pointerdown\", (e) => {\n const target = e.target as Element;\n if (\n e.pointerType === \"mouse\" ||\n !isCompactViewport() ||\n target.closest(\"button\") ||\n !target.closest(\".sp-panel-header, .sp-detail-header\")\n )\n return;\n dragging = true;\n startY = e.clientY;\n startTime = e.timeStamp;\n offset = 0;\n this.root.style.transition = \"none\";\n this.root.setPointerCapture?.(e.pointerId);\n });\n this.root.addEventListener(\"pointermove\", (e) => {\n if (!dragging) return;\n offset = Math.max(0, e.clientY - startY);\n this.root.style.transform = `translateY(${offset}px)`;\n });\n const release = (e: PointerEvent) => {\n if (!dragging) return;\n dragging = false;\n // Hand the transform back to the stylesheet: the sheet animates from\n // where the finger left it, to closed or back to open.\n this.root.style.transition = \"\";\n this.root.style.transform = \"\";\n const flick = offset > 40 && offset / Math.max(1, e.timeStamp - startTime) > 0.5;\n if (flick || offset > this.root.offsetHeight / 4) this.close();\n };\n this.root.addEventListener(\"pointerup\", release);\n this.root.addEventListener(\"pointercancel\", release);\n }\n\n private showLoading(): void {\n this.listContainer.replaceChildren();\n const loading = el(\"div\", { class: \"sp-loading\" });\n loading.setAttribute(\"role\", \"status\");\n loading.setAttribute(\"aria-live\", \"polite\");\n loading.setAttribute(\"aria-label\", this.t(\"panel.loading\"));\n const spinner = el(\"div\", { class: \"sp-spinner\" });\n loading.appendChild(spinner);\n this.listContainer.appendChild(loading);\n }\n\n private showError(): void {\n this.listContainer.replaceChildren();\n const empty = el(\"div\", { class: \"sp-empty\" });\n empty.setAttribute(\"role\", \"status\");\n empty.setAttribute(\"aria-live\", \"polite\");\n const text = el(\"div\", { class: \"sp-empty-text\" });\n setText(text, this.t(\"panel.loadError\"));\n const retryBtn = document.createElement(\"button\");\n retryBtn.className = \"sp-btn-ghost\";\n retryBtn.style.marginTop = \"8px\";\n setText(retryBtn, this.t(\"panel.retry\"));\n retryBtn.addEventListener(\"click\", () => this.loadFeedbacks().catch(() => {}));\n empty.appendChild(text);\n empty.appendChild(retryBtn);\n this.listContainer.appendChild(empty);\n }\n\n /**\n * Map a status tab value to the bucket of statuses it represents. The panel's\n * binary tabs use bucket semantics (matching markers / FAB badge / stats):\n * \"open\" covers open + in_progress, \"resolved\" covers resolved + wont_fix,\n * and \"all\" applies no status filter. Returns `undefined` when unfiltered.\n */\n private statusBucket(tab: \"all\" | FeedbackStatus): readonly FeedbackStatus[] | undefined {\n if (tab === \"all\") return undefined;\n return isClosedStatus(tab) ? CLOSED_FEEDBACK_STATUSES : OPEN_FEEDBACK_STATUSES;\n }\n\n /**\n * Load the list from page 1. `pages` > 1 re-fetches that many pages before\n * rendering, so a panel action's `refresh()` keeps what \"Load more\" added.\n */\n private async loadFeedbacks(pages = 1): Promise<void> {\n // Cancel any in-flight request to prevent stale responses from overwriting newer results\n this.loadController?.abort();\n this.loadController = new AbortController();\n const { signal } = this.loadController;\n\n // Reset to page 1 on fresh load (filter/search change)\n this.currentPage = 1;\n\n const search = this.searchInput.value.trim() || undefined;\n const typeFilter = this.activeFilters.has(\"all\") ? undefined : (Array.from(this.activeFilters)[0] as FeedbackType);\n const statuses = this.statusBucket(this.statusSegmented.value);\n\n const scope = this.getScope();\n // Refresh scope-filter button visibility based on current scope (SPA nav).\n this.syncScopeAvailability();\n const currentScope = this.scopeSegmented.value;\n const options: GetFeedbacksOptions & { page: number; limit: number } = {\n page: 1,\n limit: PAGE_SIZE,\n };\n if (typeFilter) options.type = typeFilter;\n if (statuses) options.statuses = statuses;\n if (search) options.search = search;\n if (currentScope === \"this\") {\n options.url = scope.url;\n } else if (currentScope === \"template\" && scope.urlPattern) {\n options.urlPattern = scope.urlPattern;\n }\n\n // Only show spinner on first load (empty list) — otherwise keep current content visible\n const hasContent = this.feedbacks.length > 0;\n if (!hasContent) this.showLoading();\n\n // Page markers, and the FAB badge counted from them, show the page's\n // feedbacks whatever the list's filters or scope: a \"Resolved\" tab must\n // not wipe the open markers. The list result serves them when its query\n // is theirs; otherwise their query runs alongside the list's.\n const listIsMarkerQuery = !this.mineOnly && this.isMarkerQuery(options, scope);\n const keepThread = this.keepThreads();\n this.isLoading = true;\n try {\n const listRequest = this.mineOnly\n ? this.fetchOwnFeedbacks(options, signal)\n : this.client.getFeedbacks(this.projectName, options);\n if (!listIsMarkerQuery) void this.loadPageMarkers(scope, signal);\n const first = await listRequest;\n let { feedbacks, total } = first;\n let page = 1;\n while (page < pages && feedbacks.length < total && !signal.aborted) {\n page++;\n const more = await this.client.getFeedbacks(this.projectName, { ...options, page });\n feedbacks = [...feedbacks, ...more.feedbacks];\n total = more.total;\n }\n if (signal.aborted) return; // Stale response — a newer request superseded this one\n this.currentPage = page;\n this.feedbacks = feedbacks.map(keepThread);\n this.totalFeedbacks = total;\n // Absent from a server that predates threads — which then has none.\n this.canComment = first.capabilities?.comments === true;\n setHidden(this.deleteAllBtn, this.readOnly || first.permissions?.canDeleteAll === false);\n this.stats.update(feedbacks, total);\n this.bulk.reset();\n this.renderList();\n if (this.pendingScrollId) this.flashCard(this.pendingScrollId, this.pendingDetail);\n if (listIsMarkerQuery) this.renderPageMarkers(feedbacks, scope);\n } catch (error) {\n if (signal.aborted) return; // Expected abort, not a real error\n if (!hasContent) this.showError();\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n } finally {\n // An aborted load leaves both to the load that superseded it\n if (!signal.aborted) {\n this.isLoading = false;\n this.pendingScrollId = null;\n this.pendingDetail = false;\n }\n }\n }\n\n private async loadMoreFeedbacks(): Promise<void> {\n if (this.isLoadingMore) return;\n this.isLoadingMore = true;\n\n // Capture current controller — if loadFeedbacks() runs while we're in-flight,\n // it replaces the controller, signaling that our results are stale.\n const controller = this.loadController;\n\n const nextPage = this.currentPage + 1;\n const search = this.searchInput.value.trim() || undefined;\n const typeFilter = this.activeFilters.has(\"all\") ? undefined : (Array.from(this.activeFilters)[0] as FeedbackType);\n const statuses = this.statusBucket(this.statusSegmented.value);\n\n const scope = this.getScope();\n const currentScope = this.scopeSegmented.value;\n const options: GetFeedbacksOptions & { page: number; limit: number } = {\n page: nextPage,\n limit: PAGE_SIZE,\n };\n if (typeFilter) options.type = typeFilter;\n if (statuses) options.statuses = statuses;\n if (search) options.search = search;\n if (currentScope === \"this\") {\n options.url = scope.url;\n } else if (currentScope === \"template\" && scope.urlPattern) {\n options.urlPattern = scope.urlPattern;\n }\n\n // Show spinner on the \"Load more\" button\n const loadMoreBtn = this.listContainer.querySelector<HTMLButtonElement>(\".sp-btn-load-more\");\n let restoreBtn: (() => void) | undefined;\n if (loadMoreBtn) restoreBtn = setButtonLoading(loadMoreBtn);\n\n const keepThread = this.keepThreads();\n try {\n const { feedbacks, total } = await this.client.getFeedbacks(this.projectName, options);\n if (controller !== this.loadController) return; // Filter/search changed — discard stale page\n this.currentPage = nextPage;\n this.totalFeedbacks = total;\n this.feedbacks = [...this.feedbacks, ...feedbacks.map(keepThread)];\n this.stats.update(this.feedbacks, total);\n this.renderList();\n // Under a filter, the markers keep the page query's result\n if (this.isMarkerQuery(options, scope)) this.renderPageMarkers(this.feedbacks, scope);\n } catch (error) {\n if (restoreBtn) restoreBtn();\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n } finally {\n this.isLoadingMore = false;\n }\n }\n\n /** Whether a list query returns the page markers' feedbacks too: no filter, and the markers' URL scope. */\n private isMarkerQuery(options: GetFeedbacksOptions, scope: PageScope): boolean {\n const markerUrl = this.scopeAnnotationsByUrl ? scope.url : undefined;\n return !options.type && !options.statuses && !options.search && !options.urlPattern && options.url === markerUrl;\n }\n\n /**\n * The \"Mine\" list: the feedback of the list query that this browser sent,\n * all of it at once. The server cannot filter by sender (see\n * own-feedback.ts), so the query's pages are walked until every\n * remembered id has turned up or none are left.\n */\n private async fetchOwnFeedbacks(options: GetFeedbacksOptions, signal: AbortSignal): Promise<FeedbackResponseList> {\n const own = this.ownFeedback.ids();\n // By id: a feedback created mid-walk shifts the pages, so one can come twice\n const found = new Map<string, FeedbackResponse>();\n const met = new Set<string>();\n let seen = 0;\n let firstTotal: number | undefined;\n let steady = true; // The total never changed: no page shifted under the walk\n // What the server takes (replies) and allows (Delete all), as the plain list reports it\n let capabilities: FeedbackResponseList[\"capabilities\"];\n let permissions: FeedbackResponseList[\"permissions\"];\n for (let page = 1; found.size < own.size && !signal.aborted; page++) {\n const list = await this.client.getFeedbacks(this.projectName, {\n ...options,\n page,\n limit: MAX_PAGE_LIMIT,\n });\n const { feedbacks, total } = list;\n capabilities = list.capabilities;\n permissions = list.permissions;\n firstTotal ??= total;\n steady &&= total === firstTotal;\n for (const feedback of feedbacks) {\n met.add(feedback.id);\n if (own.has(feedback.id)) found.set(feedback.id, feedback);\n }\n seen += feedbacks.length;\n if (feedbacks.length === 0 || seen >= total) break;\n }\n // A steady walk that met every feedback of the project (no filter: only\n // `page` and `limit` set) proves the remembered ids it missed deleted,\n // from the dashboard say. Forgetting them lets the next walk stop early.\n const wholeProject = Object.keys(options).every((key) => key === \"page\" || key === \"limit\");\n if (wholeProject && steady && met.size === firstTotal) {\n this.ownFeedback.remove(...[...own].filter((id) => !found.has(id)));\n }\n return { feedbacks: [...found.values()], total: found.size, capabilities, permissions };\n }\n\n /** Fetch the page markers' own query (the launcher's) when the list shows a filtered or wider one. */\n private async loadPageMarkers(scope: PageScope, signal: AbortSignal): Promise<void> {\n const query = this.scopeAnnotationsByUrl ? { limit: PAGE_SIZE, url: scope.url } : { limit: PAGE_SIZE };\n try {\n const { feedbacks } = await this.client.getFeedbacks(this.projectName, query);\n if (!signal.aborted) this.renderPageMarkers(feedbacks, scope); // Else a newer load owns the markers\n } catch {\n // Non-critical: the current markers stay\n }\n }\n\n /**\n * Markers render only the current-URL slice, even when the panel shows a\n * wider scope, so the user never sees out-of-context dots on the page. The\n * filter is defensive: a backend may ignore the `url` query.\n */\n private renderPageMarkers(feedbacks: FeedbackResponse[], scope: PageScope): void {\n this.markers.render(this.scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === scope.url) : feedbacks);\n }\n\n private renderList(): void {\n this.listContainer.replaceChildren();\n\n if (this.feedbacks.length === 0) {\n const empty = el(\"div\", { class: \"sp-empty\" });\n empty.setAttribute(\"role\", \"status\");\n empty.setAttribute(\"aria-live\", \"polite\");\n const emptyText = el(\"div\", { class: \"sp-empty-text\" });\n setText(emptyText, this.t(\"panel.empty\"));\n empty.appendChild(emptyText);\n this.listContainer.appendChild(empty);\n return;\n }\n\n // Apply sorting\n const sorted = sortFeedbacks(this.feedbacks, this.sortControls.sortMode);\n\n // Select all bar — over the feedbacks a bulk action can reach\n const feedbackIds = sorted.filter((f) => this.selectable(f)).map((f) => f.id);\n if (feedbackIds.length > 0) {\n this.listContainer.appendChild(this.bulk.createSelectAllBar(feedbackIds, this.t(\"bulk.selectAll\")));\n }\n\n if (this.sortControls.groupByPage) {\n // Group by page rendering\n const groups = groupFeedbacksByPage(sorted);\n let globalIndex = 0;\n for (const [pagePath, groupFeedbacks] of groups) {\n const groupHeader = createPageGroupHeader(pagePath, groupFeedbacks.length);\n this.listContainer.appendChild(groupHeader);\n\n const groupContent = cardList(\"sp-group-content\", pagePath);\n for (const feedback of groupFeedbacks) {\n const card = this.createCard(feedback, globalIndex + 1);\n card.style.setProperty(\"--sp-card-i\", String(globalIndex));\n groupContent.appendChild(card);\n globalIndex++;\n }\n this.listContainer.appendChild(groupContent);\n }\n } else {\n // Flat list rendering\n const list = cardList(\"sp-cards\", this.t(\"panel.feedbackList\"));\n sorted.forEach((feedback, index) => {\n const card = this.createCard(feedback, index + 1);\n card.style.setProperty(\"--sp-card-i\", String(index));\n list.appendChild(card);\n });\n this.listContainer.appendChild(list);\n }\n\n // \"Load more\" button when there are remaining feedbacks\n const remaining = this.totalFeedbacks - this.feedbacks.length;\n if (remaining > 0) {\n const loadMoreWrap = el(\"div\", { class: \"sp-load-more-wrap\" });\n const loadMoreBtn = document.createElement(\"button\");\n loadMoreBtn.className = \"sp-btn-ghost sp-btn-load-more\";\n setText(loadMoreBtn, tWithParams(this.t, \"panel.loadMore\", { remaining }));\n loadMoreBtn.addEventListener(\"click\", () => this.loadMoreFeedbacks().catch(() => {}));\n loadMoreWrap.appendChild(loadMoreBtn);\n this.listContainer.appendChild(loadMoreWrap);\n }\n }\n\n /**\n * \"Not visible on this page\", shown while the feedback has no pin here —\n * its element is gone or hidden (#304). `syncLostNotes` keeps it current\n * as pins are placed and lost.\n */\n private lostNote(feedbackId: string): HTMLElement {\n const note = el(\"div\", { class: \"sp-lost\" });\n note.dataset.lostFor = feedbackId;\n setText(note, this.t(\"panel.notOnPage\"));\n note.hidden = !this.markers.isLost(feedbackId);\n return note;\n }\n\n private syncLostNotes(): void {\n for (const note of this.root.querySelectorAll<HTMLElement>(\"[data-lost-for]\")) {\n note.hidden = !this.markers.isLost(note.dataset.lostFor ?? \"\");\n }\n }\n\n private createCard(feedback: FeedbackResponse, number: number): HTMLElement {\n // Closed = terminal (resolved, wont_fix): muted card + \"Reopen\" action.\n const isResolved = isClosedStatus(feedback.status);\n const typeColor = getTypeColor(feedback.type, this.colors);\n\n const card = el(\"div\", {\n class: `sp-card ${isResolved ? \"sp-card--resolved\" : \"\"}`,\n });\n card.classList.toggle(\"sp-card--selected\", this.bulk.isSelected(feedback.id));\n card.setAttribute(\"role\", \"listitem\");\n card.setAttribute(\"tabindex\", \"0\");\n // Same accessible name as the feedback's pin, status included.\n const label = tWithParams(this.t, \"marker.aria\", {\n number,\n type: getTypeLabel(feedback.type, this.t),\n status: getStatusLabel(feedback.status, this.t),\n message: feedback.message.slice(0, 80),\n });\n card.setAttribute(\"aria-label\", label);\n card.dataset.feedbackId = feedback.id;\n // Display (sort-order) number — the detail title must match the card's #.\n card.dataset.number = String(number);\n\n // Color bar\n const bar = el(\"div\", { class: \"sp-card-bar\" });\n bar.style.background = isResolved ? \"#9ca3af\" : typeColor;\n\n // Body\n const body = el(\"div\", { class: \"sp-card-body\" });\n\n // Header: checkbox + #number + badge + date\n const header = el(\"div\", { class: \"sp-card-header\" });\n\n // Bulk checkbox — inline in the header row, when a bulk action can reach the card\n if (this.selectable(feedback)) header.appendChild(this.bulk.createCheckbox(feedback.id, label));\n\n const num = el(\"span\", { class: \"sp-card-number\" });\n setText(num, `#${number}`);\n\n const badge = el(\"span\", { class: \"sp-badge\" });\n const typeBg = getTypeBgColor(feedback.type, this.colors);\n badge.style.background = typeBg;\n badge.style.color = typeColor;\n setText(badge, getTypeLabel(feedback.type, this.t));\n\n // Status badge — renders the record's actual status (open, in_progress,\n // resolved, wont_fix) even though panel actions stay binary.\n const statusBadge = el(\"span\", { class: \"sp-badge sp-badge--status\" });\n statusBadge.dataset.status = feedback.status;\n statusBadge.style.background = getStatusBgColor(feedback.status, this.colors);\n statusBadge.style.color = getStatusColor(feedback.status, this.colors);\n setText(statusBadge, getStatusLabel(feedback.status, this.t));\n\n const date = el(\"span\", { class: \"sp-card-date\" });\n setText(date, formatRelativeDate(feedback.createdAt, this.locale));\n\n header.appendChild(num);\n header.appendChild(badge);\n header.appendChild(statusBadge);\n header.appendChild(date);\n\n // Message\n const message = el(\"div\", { class: \"sp-card-message\" });\n setText(message, feedback.message);\n\n // Expand button\n const expandBtn = document.createElement(\"button\");\n expandBtn.className = \"sp-card-expand\";\n expandBtn.dataset.action = \"expand\";\n setText(expandBtn, this.t(\"panel.showMore\"));\n expandBtn.style.display = \"none\";\n expandBtn.setAttribute(\"aria-expanded\", \"false\");\n\n // Check if text is clamped (after render)\n requestAnimationFrame(() => {\n if (message.scrollHeight > message.clientHeight) {\n expandBtn.style.display = \"block\";\n }\n });\n\n // Footer: resolve button\n const footer = el(\"div\", { class: \"sp-card-footer\" });\n\n const resolveBtn = document.createElement(\"button\");\n resolveBtn.className = \"sp-btn-resolve\";\n resolveBtn.dataset.action = \"resolve\";\n resolveBtn.appendChild(parseSvg(isResolved ? ICON_UNDO : ICON_CHECK));\n const resolveBtnLabel = document.createElement(\"span\");\n setText(resolveBtnLabel, ` ${this.t(isResolved ? \"panel.reopen\" : \"panel.resolve\")}`);\n resolveBtn.appendChild(resolveBtnLabel);\n\n const deleteBtn = document.createElement(\"button\");\n deleteBtn.className = \"sp-btn-delete\";\n deleteBtn.dataset.action = \"delete\";\n deleteBtn.appendChild(parseSvg(ICON_TRASH));\n const deleteBtnLabel = document.createElement(\"span\");\n setText(deleteBtnLabel, ` ${this.t(\"panel.delete\")}`);\n deleteBtn.appendChild(deleteBtnLabel);\n\n if (this.can(feedback, \"canChangeStatus\")) footer.appendChild(resolveBtn);\n if (this.can(feedback, \"canDelete\")) footer.appendChild(deleteBtn);\n\n body.appendChild(header);\n body.appendChild(message);\n body.appendChild(expandBtn);\n body.appendChild(this.lostNote(feedback.id));\n if (footer.hasChildNodes()) body.appendChild(footer);\n\n card.appendChild(bar);\n card.appendChild(body);\n\n return card;\n }\n\n /** Whether the visitor may triage `feedback` this way: never in reviewer mode, else unless the server refuses. */\n private can(feedback: FeedbackResponse, permission: TriagePermission): boolean {\n return !this.readOnly && feedback.permissions?.[permission] !== false;\n }\n\n /** Whether a bulk action can reach `feedback` — else it gets no checkbox. */\n private selectable(feedback: FeedbackResponse): boolean {\n return this.can(feedback, \"canChangeStatus\") || this.can(feedback, \"canDelete\");\n }\n\n // ---------------------------------------------------------------------------\n // Bulk operations\n // ---------------------------------------------------------------------------\n\n private async bulkResolve(ids: string[]): Promise<void> {\n // Skip closed items: resolving would turn a wont_fix into resolved and\n // overwrite a resolved item's closure timestamp.\n const closed = new Set(this.feedbacks.filter((f) => isClosedStatus(f.status)).map((f) => f.id));\n const targets = ids.filter((id) => !closed.has(id));\n const results = await Promise.allSettled(targets.map((id) => this.client.resolveFeedback(id, true)));\n await this.settleBulk(targets, results);\n }\n\n private async bulkDelete(ids: string[]): Promise<void> {\n const results = await Promise.allSettled(ids.map((id) => this.client.deleteFeedback(id)));\n ids.forEach((id, i) => {\n if (results[i]?.status === \"fulfilled\") this.bus.emit(\"feedback:deleted\", id);\n });\n await this.settleBulk(ids, results);\n }\n\n /**\n * Finish a bulk action. Reload when any item succeeded — it must leave the\n * list (and its markers the page) even when another item failed. When every\n * item failed nothing changed, so skip the reload: during an outage it would\n * only fail again and report a second error. Then re-select the failed items\n * still listed, so the user can retry them, and surface the first failure,\n * rethrown so BulkActions restores its buttons.\n */\n private async settleBulk(ids: string[], results: PromiseSettledResult<unknown>[]): Promise<void> {\n const failed = ids.filter((_, i) => results[i]?.status === \"rejected\");\n if (failed.length < ids.length) await this.loadFeedbacks();\n const failure = results.find((r): r is PromiseRejectedResult => r.status === \"rejected\");\n if (!failure) return;\n const listed = new Set(this.feedbacks.map((f) => f.id));\n this.bulk.selectAll(failed.filter((id) => listed.has(id)));\n const error = failure.reason instanceof Error ? failure.reason : new Error(String(failure.reason));\n this.bus.emit(\"feedback:error\", error);\n throw error;\n }\n\n // ---------------------------------------------------------------------------\n // Existing methods (preserved)\n // ---------------------------------------------------------------------------\n\n private async confirmDeleteAll(): Promise<void> {\n const confirmed = await this.showConfirmDialog(\n this.t(\"panel.deleteAllConfirmTitle\"),\n this.t(\"panel.deleteAllConfirmMessage\"),\n );\n if (!confirmed) return;\n\n this.deleteAllBtn.disabled = true;\n try {\n await this.client.deleteAllFeedbacks(this.projectName);\n this.bus.emit(\"feedback:all-deleted\");\n await this.loadFeedbacks();\n } catch (error) {\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n // A timeout says nothing of the server's side, which may have deleted\n // some or all of it (#413): reload, so the list shows what is left.\n await this.loadFeedbacks().catch(() => {});\n } finally {\n this.deleteAllBtn.disabled = false;\n }\n }\n\n private showConfirmDialog(title: string, message: string): Promise<boolean> {\n return new Promise((resolve) => {\n const backdrop = el(\"div\", { class: \"sp-confirm-backdrop\" });\n\n const titleId = `sp-confirm-title-${Date.now()}`;\n const messageId = `sp-confirm-msg-${Date.now()}`;\n\n const dialog = el(\"div\", { class: \"sp-confirm-dialog\" });\n dialog.setAttribute(\"role\", \"alertdialog\");\n dialog.setAttribute(\"aria-modal\", \"true\");\n dialog.setAttribute(\"aria-labelledby\", titleId);\n dialog.setAttribute(\"aria-describedby\", messageId);\n\n const titleEl = el(\"div\", { class: \"sp-confirm-title\" });\n titleEl.id = titleId;\n setText(titleEl, title);\n\n const messageEl = el(\"div\", { class: \"sp-confirm-message\" });\n messageEl.id = messageId;\n setText(messageEl, message);\n\n const btnRow = el(\"div\", { class: \"sp-confirm-actions\" });\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.type = \"button\";\n cancelBtn.className = \"sp-btn-ghost\";\n setText(cancelBtn, this.t(\"panel.cancel\"));\n\n const confirmBtn = document.createElement(\"button\");\n confirmBtn.type = \"button\";\n confirmBtn.className = \"sp-btn-danger\";\n setText(confirmBtn, this.t(\"panel.confirmDelete\"));\n\n let closed = false;\n const close = (result: boolean) => {\n if (closed) return;\n closed = true;\n removeKeydown();\n backdrop.style.opacity = \"0\";\n dialog.style.transform = \"translateY(8px) scale(0.97)\";\n setTimeout(() => {\n backdrop.remove();\n resolve(result);\n }, 200);\n };\n\n // Focus trap: Tab cycles between cancel and confirm\n const onKeydown = (ke: KeyboardEvent) => {\n if (ke.key === \"Escape\") {\n ke.stopPropagation(); // Cancel the dialog only, not the panel\n close(false);\n return;\n }\n if (ke.key === \"Tab\") {\n ke.preventDefault();\n const active = (backdrop.getRootNode() as ShadowRoot).activeElement;\n if (active === cancelBtn) {\n confirmBtn.focus();\n } else {\n cancelBtn.focus();\n }\n }\n };\n const removeKeydown = addSurfaceKeydownListener(backdrop, onKeydown);\n\n cancelBtn.addEventListener(\"click\", () => close(false));\n confirmBtn.addEventListener(\"click\", () => close(true));\n backdrop.addEventListener(\"click\", (e) => {\n if (e.target === backdrop) close(false);\n });\n\n btnRow.appendChild(cancelBtn);\n btnRow.appendChild(confirmBtn);\n dialog.appendChild(titleEl);\n dialog.appendChild(messageEl);\n dialog.appendChild(btnRow);\n backdrop.appendChild(dialog);\n\n this.root.getRootNode() instanceof ShadowRoot\n ? (this.root.getRootNode() as ShadowRoot).appendChild(backdrop)\n : this.root.appendChild(backdrop);\n\n requestAnimationFrame(() => {\n backdrop.style.opacity = \"1\";\n dialog.style.transform = \"translateY(0) scale(1)\";\n cancelBtn.focus();\n });\n });\n }\n\n private async deleteFeedback(feedback: FeedbackResponse, btn: HTMLButtonElement): Promise<void> {\n this.pendingMutations.add(feedback.id);\n const restore = setButtonLoading(btn);\n try {\n await this.client.deleteFeedback(feedback.id);\n this.bus.emit(\"feedback:deleted\", feedback.id);\n await this.loadFeedbacks();\n } catch (error) {\n restore();\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n } finally {\n this.pendingMutations.delete(feedback.id);\n }\n }\n\n private async toggleResolve(feedback: FeedbackResponse, btn: HTMLButtonElement): Promise<void> {\n this.pendingMutations.add(feedback.id);\n const restore = setButtonLoading(btn);\n try {\n // Closed statuses (resolved, wont_fix) reopen; open/in_progress resolve.\n const newResolved = !isClosedStatus(feedback.status);\n await this.client.resolveFeedback(feedback.id, newResolved);\n await this.loadFeedbacks();\n } catch (error) {\n restore();\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n } finally {\n this.pendingMutations.delete(feedback.id);\n }\n }\n\n private buildTypeDropdown(): HTMLElement {\n this.typeOptions = [\n {\n value: \"all\",\n label: this.t(\"panel.filterAll\"),\n icon: ICON_LAYERS,\n color: \"var(--sp-accent-text)\",\n bg: \"var(--sp-accent-light)\",\n },\n {\n value: \"question\",\n label: this.t(\"type.question\"),\n icon: ICON_QUESTION,\n color: \"var(--sp-type-question)\",\n bg: \"var(--sp-type-question-bg)\",\n },\n {\n value: \"change\",\n label: this.t(\"type.change\"),\n icon: ICON_CHANGE,\n color: \"var(--sp-type-change)\",\n bg: \"var(--sp-type-change-bg)\",\n },\n {\n value: \"bug\",\n label: this.t(\"type.bug\"),\n icon: ICON_BUG,\n color: \"var(--sp-type-bug)\",\n bg: \"var(--sp-type-bug-bg)\",\n },\n {\n value: \"other\",\n label: this.t(\"type.other\"),\n icon: ICON_OTHER,\n color: \"var(--sp-type-other)\",\n bg: \"var(--sp-type-other-bg)\",\n },\n ];\n\n this.typeDropdownContainer = el(\"div\", { class: \"sp-filter-dropdown\" });\n\n this.typeDropdownBtn = document.createElement(\"button\");\n this.typeDropdownBtn.type = \"button\";\n this.typeDropdownBtn.className = \"sp-filter-dropdown-btn\";\n this.typeDropdownBtn.setAttribute(\"aria-haspopup\", \"listbox\");\n this.typeDropdownBtn.setAttribute(\"aria-expanded\", \"false\");\n this.renderTypeDropdownTrigger();\n\n this.typeDropdownBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (this.typeDropdownMenu) this.closeTypeDropdown();\n else this.openTypeDropdown();\n });\n\n // Escape from the trigger too: a click leaves focus there, not in the menu.\n this.typeDropdownContainer.addEventListener(\"keydown\", (e) => {\n if (e.key !== \"Escape\" || !this.typeDropdownMenu) return;\n e.stopPropagation(); // Close the menu only, not the panel\n this.closeTypeDropdown();\n this.typeDropdownBtn.focus();\n });\n\n this.typeDropdownContainer.appendChild(this.typeDropdownBtn);\n return this.typeDropdownContainer;\n }\n\n private renderTypeDropdownTrigger(): void {\n const active = this.typeOptions.find((o) => this.activeFilters.has(o.value)) ?? this.typeOptions[0];\n if (!active) return;\n\n this.typeDropdownBtn.replaceChildren();\n this.typeDropdownBtn.style.setProperty(\"--sp-chip-color\", active.color);\n this.typeDropdownBtn.style.setProperty(\"--sp-chip-bg\", active.bg);\n this.typeDropdownBtn.dataset.filter = active.value;\n this.typeDropdownBtn.classList.toggle(\"sp-filter-dropdown-btn--filtered\", active.value !== \"all\");\n this.typeDropdownBtn.setAttribute(\"aria-label\", `${this.t(\"type.label\")}: ${active.label}`);\n\n const iconWrap = el(\"span\", { class: \"sp-filter-dropdown-btn__icon\" });\n iconWrap.appendChild(parseSvg(active.icon));\n this.typeDropdownBtn.appendChild(iconWrap);\n\n const labelWrap = el(\"span\", { class: \"sp-filter-dropdown-btn__label\" });\n const prefix = el(\"span\", { class: \"sp-filter-dropdown-btn__prefix\" });\n setText(prefix, this.t(\"type.label\"));\n const value = el(\"span\", { class: \"sp-filter-dropdown-btn__value\" });\n setText(value, active.label);\n // The space renders nothing in the flex row (its `gap` spaces the two) but\n // keeps the text \"Type All\", which the accessible name must contain: run\n // together, \"TypeAll\" is not in \"Type: All\" (WCAG 2.5.3).\n labelWrap.append(prefix, \" \", value);\n this.typeDropdownBtn.appendChild(labelWrap);\n\n const chevron = el(\"span\", { class: \"sp-filter-dropdown-btn__chevron\" });\n chevron.appendChild(parseSvg(ICON_CHEVRON_DOWN));\n this.typeDropdownBtn.appendChild(chevron);\n }\n\n private openTypeDropdown(): void {\n this.typeDropdownMenu = el(\"div\", { class: \"sp-filter-dropdown-menu\" });\n this.typeDropdownMenu.setAttribute(\"role\", \"listbox\");\n this.typeDropdownMenu.setAttribute(\"aria-label\", this.t(\"type.label\"));\n this.typeDropdownBtn.setAttribute(\"aria-expanded\", \"true\");\n\n for (const option of this.typeOptions) {\n const item = document.createElement(\"button\");\n item.type = \"button\";\n const isActive = this.activeFilters.has(option.value);\n item.className = `sp-filter-dropdown-option${isActive ? \" sp-filter-dropdown-option--active\" : \"\"}`;\n item.style.setProperty(\"--sp-chip-color\", option.color);\n item.style.setProperty(\"--sp-chip-bg\", option.bg);\n item.dataset.filter = option.value;\n item.setAttribute(\"role\", \"option\");\n item.setAttribute(\"aria-selected\", String(isActive));\n\n const iconWrap = el(\"span\", { class: \"sp-filter-dropdown-option__icon\" });\n iconWrap.appendChild(parseSvg(option.icon));\n item.appendChild(iconWrap);\n\n const labelEl = el(\"span\", { class: \"sp-filter-dropdown-option__label\" });\n setText(labelEl, option.label);\n item.appendChild(labelEl);\n\n if (isActive) {\n const checkWrap = el(\"span\", { class: \"sp-filter-dropdown-option__check\" });\n checkWrap.appendChild(parseSvg(ICON_CHECK));\n item.appendChild(checkWrap);\n }\n\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.selectTypeFilter(option.value);\n });\n\n this.typeDropdownMenu.appendChild(item);\n }\n\n this.typeDropdownContainer.appendChild(this.typeDropdownMenu);\n\n // Armed now (see PanelSortControls.openMenu): a frame could outlive the menu.\n this.removeTypeDropdownOutsideClick = onClickOutside(this.typeDropdownContainer, () => this.closeTypeDropdown());\n }\n\n private closeTypeDropdown(): void {\n if (this.typeDropdownMenu) {\n this.typeDropdownMenu.remove();\n this.typeDropdownMenu = null;\n }\n this.typeDropdownBtn.setAttribute(\"aria-expanded\", \"false\");\n this.removeTypeDropdownOutsideClick?.();\n this.removeTypeDropdownOutsideClick = null;\n }\n\n private selectTypeFilter(value: string): void {\n this.activeFilters.clear();\n this.activeFilters.add(value);\n this.renderTypeDropdownTrigger();\n this.closeTypeDropdown();\n this.loadFeedbacks().catch(() => {});\n }\n\n private buildStatusSegmented(): HTMLElement {\n this.statusSegmented = new SegmentedControl<\"all\" | FeedbackStatus>({\n options: [\n {\n value: \"all\",\n label: this.t(\"panel.statusAll\"),\n icon: ICON_LAYERS,\n color: \"var(--sp-accent-text)\",\n bg: \"var(--sp-accent-light)\",\n },\n {\n value: \"open\",\n label: this.t(\"panel.statusOpen\"),\n icon: ICON_DOT_OPEN,\n color: \"var(--sp-status-open)\",\n bg: \"var(--sp-status-open-bg)\",\n },\n {\n // Filters the closed bucket (resolved + wont_fix): labelled \"Closed\".\n value: \"resolved\",\n label: this.t(\"panel.statusClosed\"),\n icon: ICON_ARCHIVE,\n color: \"var(--sp-status-resolved)\",\n bg: \"var(--sp-status-resolved-bg)\",\n },\n ],\n value: \"all\",\n onChange: () => {\n this.loadFeedbacks().catch(() => {});\n },\n ariaLabel: this.t(\"status.label\"),\n datasetKey: \"statusFilter\",\n modifierPrefix: \"sp-segmented__btn--\",\n });\n\n return this.statusSegmented.element;\n }\n\n /**\n * Build the page-scope segmented control: \"this page / this type / all\".\n * The \"this type\" button is hidden when the current scope has no urlPattern\n * (host did not provide one for this route). Visibility is refreshed on\n * every `loadFeedbacks` so SPA navigation stays consistent.\n */\n private buildScopeSegmented(): HTMLElement {\n this.scopeSegmented = new SegmentedControl<\"this\" | \"template\" | \"all\">({\n options: [\n { value: \"this\", label: this.t(\"scope.thisPage\") },\n { value: \"template\", label: this.t(\"scope.thisType\") },\n { value: \"all\", label: this.t(\"scope.all\") },\n ],\n value: this.initialScopeFilter,\n onChange: () => {\n this.loadFeedbacks().catch(() => {});\n },\n ariaLabel: this.t(\"scope.label\"),\n datasetKey: \"scopeFilter\",\n modifierPrefix: \"sp-segmented__btn--scope-\",\n extraClass: \"sp-segmented--scope\",\n });\n\n // Initial visibility — \"this type\" only meaningful when scope has urlPattern\n this.syncScopeAvailability();\n return this.scopeSegmented.element;\n }\n\n /**\n * Hide the \"this type\" button when the current scope has no urlPattern, and\n * fall back to \"this page\" if it was the active selection. Called on every\n * `loadFeedbacks` so SPA navigation stays consistent.\n */\n private syncScopeAvailability(): void {\n if (!this.scopeSegmented) return;\n const scope = this.getScope();\n const showTemplate = !!scope.urlPattern;\n this.scopeSegmented.setOptionVisible(\"template\", showTemplate);\n if (!showTemplate && this.scopeSegmented.value === \"template\") {\n this.scopeSegmented.select(\"this\");\n }\n }\n\n /** \"Mine\" toggle: narrows the list to the feedback sent from this browser. */\n private buildMineToggle(): HTMLButtonElement {\n const toggle = document.createElement(\"button\");\n toggle.type = \"button\";\n toggle.className = \"sp-mine-toggle\";\n toggle.title = this.t(\"panel.filterMineHint\");\n toggle.setAttribute(\"aria-pressed\", \"false\");\n toggle.append(parseSvg(ICON_USER), this.t(\"panel.filterMine\"));\n toggle.addEventListener(\"click\", () => {\n this.mineOnly = !this.mineOnly;\n toggle.classList.toggle(\"sp-mine-toggle--active\", this.mineOnly);\n toggle.setAttribute(\"aria-pressed\", String(this.mineOnly));\n this.loadFeedbacks().catch(() => {});\n });\n return toggle;\n }\n\n /**\n * Click a control of the focused card, as the visitor would: a shortcut\n * does nothing on a card without it — one the visitor may not triage.\n */\n private pressInFocusedCard(selector: string): void {\n const card = this.listContainer.querySelectorAll(\".sp-card\")[getFocusedCardIndex(this.listContainer)];\n card?.querySelector<HTMLElement>(selector)?.click();\n }\n\n scrollToFeedback(feedbackId: string, openDetail = false): void {\n // The rendered cards are about to be replaced (or not rendered yet, when\n // the marker click opened the panel): wait for the load to render them.\n if (this.isLoading) {\n this.pendingScrollId = feedbackId;\n this.pendingDetail = openDetail;\n return;\n }\n this.flashCard(feedbackId, openDetail);\n }\n\n /**\n * Scroll to a feedback's card and open its detail view, where its thread\n * is — what a deep link to it asks for (#381). Does nothing when the card\n * isn't in the list the panel shows.\n */\n showFeedback(feedbackId: string): void {\n this.scrollToFeedback(feedbackId, true);\n }\n\n private flashCard(feedbackId: string, openDetail: boolean): void {\n const escapedId = CSS.escape(feedbackId);\n const card = this.listContainer.querySelector<HTMLElement>(`[data-feedback-id=\"${escapedId}\"]`);\n if (card) {\n card.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n card.classList.add(\"sp-anim-flash\");\n card.addEventListener(\n \"animationend\",\n () => {\n card.classList.remove(\"sp-anim-flash\");\n },\n { once: true },\n );\n // Phones: the sheet hides the pin that was tapped — open its details\n // rather than leaving the user to find the card in the list.\n const feedback = this.feedbacks.find((f) => f.id === feedbackId);\n if (feedback && (openDetail || isCompactViewport())) this.detail.show(feedback, Number(card.dataset.number));\n }\n }\n\n /** A feedback's composer state, which outlives each render of its thread. */\n private draftOf(feedbackId: string): ThreadDraft {\n const draft = this.threadDrafts.get(feedbackId) ?? { text: \"\" };\n this.threadDrafts.set(feedbackId, draft);\n return draft;\n }\n\n /**\n * Post a reply as the visitor and add it to the cached feedback, so the\n * thread still holds it when the visitor comes back to this feedback.\n * Resolves `null` when they dismissed the identity prompt — nothing was\n * sent, and nothing went wrong.\n */\n private async postComment(\n feedback: FeedbackResponse,\n body: string,\n clientId: string,\n ): Promise<CommentResponse | null> {\n const identity = await this.resolveIdentity();\n if (!identity) return null;\n try {\n const comment = await this.client.addComment(feedback.id, {\n body,\n clientId,\n authorName: identity.name,\n authorEmail: identity.email,\n authorRole: \"client\",\n });\n // The list may have been reloaded meanwhile: the reply goes on the record\n // it holds now, as well as on the one the thread was drawn from.\n for (const record of new Set([feedback, this.feedbacks.find((f) => f.id === feedback.id)])) {\n if (record && !record.comments?.some((c) => c.id === comment.id)) {\n record.comments = [...(record.comments ?? []), comment];\n }\n }\n const replies = this.threadWrites.get(feedback.id)?.replies ?? [];\n this.threadWrites.set(feedback.id, { seq: ++this.threadWriteCount, replies: [...replies, comment] });\n this.bus.emit(\"comment:added\", comment);\n return comment;\n } catch (error) {\n this.bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n\n /**\n * Call when a list request starts; pass each record it brings back to the\n * function returned. A reply posted after the request started may be\n * missing from it — the server read the list before storing the reply —\n * so the replies posted here since are merged back in, by id and in date\n * order. A list requested after the last reply is taken whole (#420).\n */\n private keepThreads(): (record: FeedbackResponse) => FeedbackResponse {\n const since = this.threadWriteCount;\n return (record) => {\n const written = this.threadWrites.get(record.id);\n if (!written || written.seq <= since) return record;\n const known = new Set(record.comments?.map((c) => c.id));\n const missing = written.replies.filter((c) => !known.has(c.id));\n if (missing.length === 0) return record;\n const comments = [...(record.comments ?? []), ...missing];\n comments.sort((a, b) => (a.createdAt < b.createdAt ? -1 : a.createdAt > b.createdAt ? 1 : 0));\n return { ...record, comments };\n };\n }\n\n /**\n * Host `panelActions` failures go to `config.onError` through their own\n * event — never `feedback:error`, which settles a pending popup submission.\n */\n private reportActionError(error: unknown): void {\n this.bus.emit(\"panel:action-error\", error instanceof Error ? error : new Error(String(error)));\n }\n\n /**\n * Close the detail view after a built-in Resolve/Delete of `feedbackId`\n * succeeds — unless the user has opened another feedback meanwhile, which\n * stays on screen (#399), as `refreshDetail` leaves it for host actions.\n */\n private hideDetailOf(feedbackId: string): void {\n if (this.detail.feedbackId === feedbackId) this.detail.hide();\n }\n\n /**\n * `refresh()` handed to panel actions: reload the list (every page loaded\n * so far) and markers, then re-render the detail view with the updated\n * record — or go back to the list when it no longer matches the filters.\n * Leaves the view alone when the user has already moved on to another\n * feedback.\n */\n private async refreshDetail(feedbackId: string): Promise<void> {\n if (this.isOpen) await this.loadFeedbacks(this.currentPage);\n if (this.detail.feedbackId !== feedbackId) return;\n const index = this.feedbacks.findIndex((f) => f.id === feedbackId);\n const fresh = this.feedbacks[index];\n if (fresh) this.detail.show(fresh, index + 1);\n else this.detail.hide();\n }\n\n /** Refresh the panel after a new feedback is submitted */\n async refresh(): Promise<void> {\n if (this.isOpen) {\n await this.loadFeedbacks();\n }\n }\n\n /** Whether the panel is currently open — used by the launcher to coordinate marker refreshes. */\n get isCurrentlyOpen(): boolean {\n return this.isOpen;\n }\n\n destroy(): void {\n // A panel action's context can outlive the widget: its refresh() and\n // close() only act on an open panel.\n this.isOpen = false;\n this.loadController?.abort();\n if (this.searchTimeout) clearTimeout(this.searchTimeout);\n this.listContainer.removeEventListener(\"click\", this.onListClick);\n this.listContainer.removeEventListener(\"keydown\", this.onListKeydown);\n this.listContainer.removeEventListener(\"mouseover\", this.onListMouseover);\n this.listContainer.removeEventListener(\"mouseout\", this.onListMouseout);\n document.removeEventListener(\"sp-marker-click\", this.onMarkerClick);\n this.closeTypeDropdown();\n this.sortControls.destroy();\n this.bulk.destroy();\n this.exportBtn.destroy();\n this.shortcuts.destroy();\n this.detail.destroy();\n this.scrim.remove();\n this.root.remove();\n }\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunkQDJDQQ6E_cjs=require('./chunk-QDJDQQ6E.cjs');var P=class{element;current;opts;onChange;datasetKey;constructor(e){this.opts=e.options,this.current=e.value,this.onChange=e.onChange,this.datasetKey=e.datasetKey,this.element=chunkQDJDQQ6E_cjs.A("div",{class:`sp-segmented${e.extraClass?` ${e.extraClass}`:""}`,role:"radiogroup"}),this.element.setAttribute("aria-label",e.ariaLabel);for(let t of this.opts){let i=document.createElement("button");i.type="button",i.className=e.modifierPrefix!==void 0?`sp-segmented__btn ${e.modifierPrefix}${t.value}`:"sp-segmented__btn",i.dataset[this.datasetKey]=t.value,i.setAttribute("role","radio");let s=this.current===t.value;if(i.setAttribute("aria-checked",String(s)),i.tabIndex=s?0:-1,s&&i.classList.add("sp-segmented__btn--active"),t.color&&i.style.setProperty("--sp-chip-color",t.color),t.bg&&i.style.setProperty("--sp-chip-bg",t.bg),t.icon){let r=chunkQDJDQQ6E_cjs.A("span",{class:"sp-segmented__icon"});r.appendChild(chunkQDJDQQ6E_cjs.z(t.icon)),i.appendChild(r);}let a=chunkQDJDQQ6E_cjs.A("span",{class:"sp-segmented__label"});chunkQDJDQQ6E_cjs.B(a,t.label),i.appendChild(a),i.addEventListener("click",()=>this.select(t.value)),i.addEventListener("keydown",r=>this.handleKey(r,t.value)),this.element.appendChild(i);}}select(e){this.current=e,this.syncSelection(),this.onChange(e);}syncSelection(){let e=this.element.querySelectorAll(".sp-segmented__btn");for(let t of e){let i=t.dataset[this.datasetKey]===this.current;t.classList.toggle("sp-segmented__btn--active",i),t.setAttribute("aria-checked",String(i)),t.tabIndex=i?0:-1;}}setOptionVisible(e,t){let i=this.element.querySelector(`[data-${this.kebabKey()}="${e}"]`);return i?(i.style.display=t?"":"none",true):false}get value(){return this.current}focusOption(e){this.element.querySelector(`[data-${this.kebabKey()}="${e}"]`)?.focus();}handleKey(e,t){let i=this.opts.map(o=>o.value).filter(o=>{let d=this.element.querySelector(`[data-${this.kebabKey()}="${o}"]`);return d!==null&&d.style.display!=="none"}),s=i.indexOf(t);if(s<0)return;let a;switch(e.key){case "ArrowLeft":a=(s-1+i.length)%i.length;break;case "ArrowRight":a=(s+1)%i.length;break;case "Home":a=0;break;case "End":a=i.length-1;break;default:return}e.preventDefault();let r=i[a];r!==void 0&&(this.select(r),this.focusOption(r));}kebabKey(){return this.datasetKey.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}};function U({input:F,send:e},t){F.readOnly=t,e.setAttribute("aria-busy",String(t)),e.setAttribute("aria-disabled",String(t));}var Pe=0;function Me(F,{t:e,locale:t,canPost:i,draft:s,post:a}){let r=F.comments??[];if(!i&&r.length===0)return null;let o=chunkQDJDQQ6E_cjs.A("div"),d=chunkQDJDQQ6E_cjs.A("ol",{class:"sp-thread-list",role:"list","aria-label":e("comments.title"),"aria-live":"polite"}),b=new Set,C=n=>{if(b.has(n.id))return;b.add(n.id);let c=chunkQDJDQQ6E_cjs.A("li",{class:"sp-detail-message sp-comment","data-role":n.authorRole}),h=chunkQDJDQQ6E_cjs.A("div",{class:"sp-comment-head"}),y=chunkQDJDQQ6E_cjs.A("span");if(chunkQDJDQQ6E_cjs.B(y,n.authorName),h.appendChild(y),n.authorRole==="team"){let T=chunkQDJDQQ6E_cjs.A("span",{class:"sp-badge"});chunkQDJDQQ6E_cjs.B(T,e("comments.team")),h.appendChild(T);}let E=chunkQDJDQQ6E_cjs.A("time",{datetime:n.createdAt});chunkQDJDQQ6E_cjs.B(E,chunkQDJDQQ6E_cjs.H(n.createdAt,t)),h.appendChild(E);let S=chunkQDJDQQ6E_cjs.A("div");chunkQDJDQQ6E_cjs.B(S,n.body),c.append(h,S),d.appendChild(c);};for(let n of r)C(n);if(o.appendChild(d),!i)return o;let p=document.createElement("textarea");p.className="sp-input sp-thread-input",p.rows=3,p.maxLength=chunkQDJDQQ6E_cjs.m,p.placeholder=e("comments.placeholder"),p.setAttribute("aria-label",p.placeholder),p.value=s.text,p.addEventListener("input",()=>{s.text=p.value;});let m=chunkQDJDQQ6E_cjs.A("div",{class:"sp-thread-foot"}),f=chunkQDJDQQ6E_cjs.A("span",{id:`sp-thread-hint-${++Pe}`});chunkQDJDQQ6E_cjs.ma()||(chunkQDJDQQ6E_cjs.B(f,e(chunkQDJDQQ6E_cjs.G()?"popup.submitHintMac":"popup.submitHintOther")),p.setAttribute("aria-describedby",f.id),p.setAttribute("aria-keyshortcuts","Control+Enter Meta+Enter"));let v=document.createElement("button");v.type="button",v.className="sp-btn-primary",chunkQDJDQQ6E_cjs.B(v,e("popup.submit")),m.append(f,v);let w=chunkQDJDQQ6E_cjs.A("div",{class:"sp-thread-error",role:"alert"});o.append(p,m,w);let g={add:C,input:p,send:v,error:w};s.view=g,U(g,s.sending===true);let k=async()=>{s.text=p.value;let n=s.text.trim();if(s.sending||!n)return;s.sent?.body!==n&&(s.sent={body:n,clientId:chunkQDJDQQ6E_cjs.r()});let{clientId:c}=s.sent;s.sending=true,chunkQDJDQQ6E_cjs.B(w,""),U(g,true);let h="",y=null;try{y=await a(n,c);}catch(S){h=e(chunkQDJDQQ6E_cjs.w(S)?"comments.full":"comments.error");}s.sending=false;let E=s.view??g;U(E,false),chunkQDJDQQ6E_cjs.B(E.error,h),y&&(E.add(y),E.input.value=s.text="",s.sent=void 0);};return v.addEventListener("click",()=>{k();}),p.addEventListener("keydown",n=>{n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),k());}),o}var xe=chunkQDJDQQ6E_cjs.i.filter(F=>!chunkQDJDQQ6E_cjs.k(F));function De(F,e){let t=chunkQDJDQQ6E_cjs.A("div",{class:F});return t.setAttribute("role","list"),t.setAttribute("aria-label",e),t}var Be=class{constructor(e,t,i,s,a,r,o,d,b){this.colors=t;this.bus=i;this.client=s;this.projectName=a;this.markers=r;this.t=o;this.locale=d;this.shadowRoot=e,this.readOnly=!!b?.readOnly,this.resolveIdentity=b?.resolveIdentity??(async()=>null),this.getScope=b?.getScope??(()=>({url:window.location.pathname,urlPattern:null})),this.scopeAnnotationsByUrl=b?.scopeAnnotationsByUrl??true,this.ownFeedback=b?.ownFeedback??{ids:()=>new Set,remove:()=>{}},this.scrim=chunkQDJDQQ6E_cjs.A("div",{class:"sp-scrim"}),this.scrim.addEventListener("click",()=>this.close()),this.root=chunkQDJDQQ6E_cjs.A("div",{class:"sp-panel"}),this.root.setAttribute("role","complementary"),this.root.setAttribute("aria-label",this.t("panel.ariaLabel")),this.root.setAttribute("aria-hidden","true"),chunkQDJDQQ6E_cjs.E(this.root,true);let C=chunkQDJDQQ6E_cjs.A("div",{class:"sp-panel-header"}),p=chunkQDJDQQ6E_cjs.A("span",{class:"sp-panel-title"});chunkQDJDQQ6E_cjs.B(p,this.t("panel.title")),this.closeBtn=document.createElement("button"),this.closeBtn.className="sp-panel-close",this.closeBtn.setAttribute("aria-label",this.t("panel.close")),this.closeBtn.appendChild(chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs.Q)),this.closeBtn.addEventListener("click",()=>this.close()),this.deleteAllBtn=document.createElement("button"),this.deleteAllBtn.className="sp-btn-delete-all",this.deleteAllBtn.setAttribute("aria-label",this.t("panel.deleteAll")),this.deleteAllBtn.appendChild(chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs.aa));let m=document.createElement("span");chunkQDJDQQ6E_cjs.B(m,` ${this.t("panel.deleteAll")}`),this.deleteAllBtn.appendChild(m),this.deleteAllBtn.addEventListener("click",()=>this.confirmDeleteAll()),chunkQDJDQQ6E_cjs.D(this.deleteAllBtn,true),this.exportBtn=new chunkQDJDQQ6E_cjs.wa(t,()=>this.feedbacks,this.t);let f=chunkQDJDQQ6E_cjs.A("div",{class:"sp-panel-header-right"});f.appendChild(this.exportBtn.element),f.appendChild(this.deleteAllBtn),f.appendChild(this.closeBtn),C.appendChild(p),C.appendChild(f),this.stats=new chunkQDJDQQ6E_cjs.Ia(this.t);let v=chunkQDJDQQ6E_cjs.A("div",{class:"sp-filters"}),w=chunkQDJDQQ6E_cjs.A("div",{class:"sp-search-wrap"}),g=chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs.R);g.setAttribute("class","sp-search-icon"),this.searchInput=document.createElement("input"),this.searchInput.type="text",this.searchInput.className="sp-search",this.searchInput.placeholder=this.t("panel.search"),this.searchInput.setAttribute("aria-label",this.t("panel.searchAria")),this.searchInput.addEventListener("input",()=>{this.searchTimeout&&clearTimeout(this.searchTimeout),this.searchTimeout=setTimeout(()=>this.loadFeedbacks().catch(()=>{}),200);}),w.appendChild(g),w.appendChild(this.searchInput);let k=chunkQDJDQQ6E_cjs.A("div",{class:"sp-filter-bar"});k.appendChild(this.buildTypeDropdown()),k.appendChild(this.buildStatusSegmented()),k.appendChild(this.buildScopeSegmented()),k.appendChild(this.buildMineToggle()),this.sortControls=new chunkQDJDQQ6E_cjs.Fa(()=>this.renderList(),this.t),v.appendChild(w),v.appendChild(k),v.appendChild(this.sortControls.element),this.listContainer=chunkQDJDQQ6E_cjs.A("div",{class:"sp-list"}),this.bulk=new chunkQDJDQQ6E_cjs.ya(t,{onResolve:n=>this.bulkResolve(n),onDelete:n=>this.bulkDelete(n),permits:(n,c)=>this.feedbacks.every(h=>!n.includes(h.id)||this.can(h,c))},this.t),this.bulk.setListContainer(this.listContainer),this.detail=new chunkQDJDQQ6E_cjs.Ba(t,{onBack:()=>this.detail.hide(),onResolve:async n=>{try{let c=!chunkQDJDQQ6E_cjs.k(n.status);await this.client.resolveFeedback(n.id,c),await this.loadFeedbacks(),this.hideDetailOf(n.id);}catch(c){throw this.bus.emit("feedback:error",c instanceof Error?c:new Error(String(c))),c}},onDelete:async n=>{try{await this.client.deleteFeedback(n.id),this.bus.emit("feedback:deleted",n.id),await this.loadFeedbacks(),this.hideDetailOf(n.id);}catch(c){throw this.bus.emit("feedback:error",c instanceof Error?c:new Error(String(c))),c}},canGoToAnnotation:n=>!this.scopeAnnotationsByUrl||n.url===this.getScope().url,lostNote:n=>this.lostNote(n),onGoToAnnotation:n=>{if(n.annotations.length>0){let c=n.annotations[0];if(!c)return;this.markers.revealPin(n.id)||(window.scrollTo({left:c.scrollX,top:c.scrollY,behavior:"smooth"}),this.markers.pinHighlight(n)),chunkQDJDQQ6E_cjs.la()&&this.close();}},onCustomAction:async(n,c)=>{try{await n.onAction(c,{refresh:()=>this.refreshDetail(c.id),close:()=>this.close()});}catch(h){this.reportActionError(h);}},onCustomActionError:n=>this.reportActionError(n),permits:(n,c)=>this.can(n,c),buildThread:n=>Me(n,{t:this.t,locale:d,canPost:this.canComment&&n.permissions?.canComment!==false,draft:this.draftOf(n.id),post:(c,h)=>this.postComment(n,c,h)})},this.t,d,chunkQDJDQQ6E_cjs.za(b?.panelActions)),this.shortcuts=new chunkQDJDQQ6E_cjs.Ma(t,{onNavigate:n=>{let c=chunkQDJDQQ6E_cjs.Ja(this.listContainer);chunkQDJDQQ6E_cjs.Ka(this.listContainer,n==="down"?c+1:c-1);},onResolve:()=>this.pressInFocusedCard('[data-action="resolve"]'),onDelete:()=>this.pressInFocusedCard('[data-action="delete"]'),onFocusSearch:()=>this.searchInput.focus(),onToggleSelect:()=>this.pressInFocusedCard(".sp-bulk-checkbox"),isSuspended:()=>this.detail.isVisible},this.t),this.root.appendChild(C),this.root.appendChild(this.stats.element),this.root.appendChild(v),this.root.appendChild(this.listContainer),this.root.appendChild(this.bulk.barElement),this.root.appendChild(this.detail.element),this.root.appendChild(this.shortcuts.helpOverlay),this.root.appendChild(this.shortcuts.hintButton),e.appendChild(this.scrim),e.appendChild(this.root),this.attachSheetDrag(),this.onListClick=n=>{let c=n.target;if(c.closest(".sp-bulk-checkbox"))return;let h=c.closest("[data-action]");if(h){n.stopPropagation();let E=h.closest(".sp-card");if(!E)return;let S=E.dataset.feedbackId,T=this.feedbacks.find(L=>L.id===S);if(!T)return;let M=h.dataset.action;if(M==="expand"){let L=E.querySelector(".sp-card-message");if(!L)return;let Y=L.classList.toggle("sp-card-message--expanded");chunkQDJDQQ6E_cjs.B(h,Y?this.t("panel.showLess"):this.t("panel.showMore")),h.setAttribute("aria-expanded",String(Y));}else if(M==="resolve"){if(this.pendingMutations.has(T.id))return;let L=h;this.toggleResolve(T,L).catch(()=>{});}else if(M==="delete"){if(this.pendingMutations.has(T.id))return;let L=h;this.deleteFeedback(T,L).catch(()=>{});}return}let y=c.closest(".sp-card");if(y){let E=y.dataset.feedbackId,S=this.feedbacks.find(T=>T.id===E);S&&this.detail.show(S,Number(y.dataset.number));}},this.listContainer.addEventListener("click",this.onListClick),this.onListKeydown=n=>{let c=n;if(c.key!=="Enter"&&c.key!==" ")return;let h=c.target,y=h.closest(".sp-card");if(!y||h!==y)return;c.preventDefault();let E=y.dataset.feedbackId,S=this.feedbacks.find(T=>T.id===E);S&&this.detail.show(S,Number(y.dataset.number));},this.listContainer.addEventListener("keydown",this.onListKeydown),this.onListMouseover=n=>{let h=n.target.closest(".sp-card");if(!h)return;let y=h.dataset.feedbackId;y&&this.markers.highlight(y);},this.listContainer.addEventListener("mouseover",this.onListMouseover),this.onListMouseout=n=>{let c=n.relatedTarget;c&&this.listContainer.contains(c)||this.markers.highlight("");},this.listContainer.addEventListener("mouseout",this.onListMouseout),this.bus.on("markers:placed",()=>this.syncLostNotes()),this.bus.on("panel:toggle",n=>{n?this.open():this.close();}),chunkQDJDQQ6E_cjs.K(e,()=>this.isOpen),chunkQDJDQQ6E_cjs.L(e,n=>{if(n.key==="Escape"&&this.isOpen){if(this.shortcuts.isHelpVisible)return;if(this.detail.isVisible){this.detail.hide();return}this.close();return}if(n.key==="Tab"&&this.isOpen){let c=M=>{let L=M;for(;L&&L!==this.root;){if(getComputedStyle(L).display==="none")return false;L=L.parentElement;}return true},h=this.shortcuts.isHelpVisible?this.shortcuts.helpOverlay:this.detail.isVisible?this.detail.element:this.root,y=Array.from(h.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')).filter(M=>c(M)&&!M.hasAttribute("disabled")&&!M.closest("[inert]"));if(y.length===0)return;let E=y[0],S=y[y.length-1];if(!E||!S)return;let T=e.activeElement;!T||!h.contains(T)?(n.preventDefault(),(n.shiftKey?S:E).focus()):n.shiftKey&&T===E?(n.preventDefault(),S.focus()):!n.shiftKey&&T===S&&(n.preventDefault(),E.focus());}}),this.onMarkerClick=(n=>{this.scrollToFeedback(n.detail.feedbackId);}),document.addEventListener("sp-marker-click",this.onMarkerClick);}colors;bus;client;projectName;markers;t;locale;root;scrim;listContainer;searchInput;closeBtn;deleteAllBtn;activeFilters=new Set(["all"]);typeDropdownBtn;typeDropdownContainer;typeDropdownMenu=null;removeTypeDropdownOutsideClick=null;statusSegmented;typeOptions;feedbacks=[];currentPage=1;totalFeedbacks=0;isLoadingMore=false;isOpen=false;searchTimeout=null;loadController=null;isLoading=false;pendingScrollId=null;pendingDetail=false;pendingMutations=new Set;canComment=false;threadDrafts=new Map;threadWriteCount=0;threadWrites=new Map;readOnly;resolveIdentity;stats;sortControls;bulk;exportBtn;shortcuts;detail;shadowRoot;getScope;scopeAnnotationsByUrl;scopeSegmented;initialScopeFilter="this";mineOnly=false;ownFeedback;onMarkerClick;onListClick;onListKeydown;onListMouseover;onListMouseout;async open(){if(this.isOpen)return;this.isOpen=true;let e=chunkQDJDQQ6E_cjs.la();this.root.setAttribute("role",e?"dialog":"complementary"),e?this.root.setAttribute("aria-modal","true"):this.root.removeAttribute("aria-modal"),this.root.classList.add("sp-panel--open"),this.scrim.classList.add("sp-scrim--open"),this.root.setAttribute("aria-hidden","false"),chunkQDJDQQ6E_cjs.E(this.root,false),this.bus.emit("open"),this.shortcuts.enable(this.shadowRoot),await this.loadFeedbacks(),requestAnimationFrame(()=>{(chunkQDJDQQ6E_cjs.ma()?this.closeBtn:this.searchInput).focus();});}close(){if(!this.isOpen)return;this.isOpen=false,this.root.classList.remove("sp-panel--open"),this.scrim.classList.remove("sp-scrim--open"),this.root.setAttribute("aria-hidden","true"),chunkQDJDQQ6E_cjs.E(this.root,true),this.bus.emit("close"),this.shortcuts.disable(),this.detail.hide(),this.pendingScrollId=null,this.pendingDetail=false,this.root.getRootNode().querySelector(".sp-fab")?.focus();}attachSheetDrag(){let e=0,t=0,i=0,s=false;this.root.addEventListener("pointerdown",r=>{let o=r.target;r.pointerType==="mouse"||!chunkQDJDQQ6E_cjs.la()||o.closest("button")||!o.closest(".sp-panel-header, .sp-detail-header")||(s=true,e=r.clientY,t=r.timeStamp,i=0,this.root.style.transition="none",this.root.setPointerCapture?.(r.pointerId));}),this.root.addEventListener("pointermove",r=>{s&&(i=Math.max(0,r.clientY-e),this.root.style.transform=`translateY(${i}px)`);});let a=r=>{if(!s)return;s=false,this.root.style.transition="",this.root.style.transform="",(i>40&&i/Math.max(1,r.timeStamp-t)>.5||i>this.root.offsetHeight/4)&&this.close();};this.root.addEventListener("pointerup",a),this.root.addEventListener("pointercancel",a);}showLoading(){this.listContainer.replaceChildren();let e=chunkQDJDQQ6E_cjs.A("div",{class:"sp-loading"});e.setAttribute("role","status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-label",this.t("panel.loading"));let t=chunkQDJDQQ6E_cjs.A("div",{class:"sp-spinner"});e.appendChild(t),this.listContainer.appendChild(e);}showError(){this.listContainer.replaceChildren();let e=chunkQDJDQQ6E_cjs.A("div",{class:"sp-empty"});e.setAttribute("role","status"),e.setAttribute("aria-live","polite");let t=chunkQDJDQQ6E_cjs.A("div",{class:"sp-empty-text"});chunkQDJDQQ6E_cjs.B(t,this.t("panel.loadError"));let i=document.createElement("button");i.className="sp-btn-ghost",i.style.marginTop="8px",chunkQDJDQQ6E_cjs.B(i,this.t("panel.retry")),i.addEventListener("click",()=>this.loadFeedbacks().catch(()=>{})),e.appendChild(t),e.appendChild(i),this.listContainer.appendChild(e);}statusBucket(e){if(e!=="all")return chunkQDJDQQ6E_cjs.k(e)?chunkQDJDQQ6E_cjs.j:xe}async loadFeedbacks(e=1){this.loadController?.abort(),this.loadController=new AbortController;let{signal:t}=this.loadController;this.currentPage=1;let i=this.searchInput.value.trim()||void 0,s=this.activeFilters.has("all")?void 0:Array.from(this.activeFilters)[0],a=this.statusBucket(this.statusSegmented.value),r=this.getScope();this.syncScopeAvailability();let o=this.scopeSegmented.value,d={page:1,limit:20};s&&(d.type=s),a&&(d.statuses=a),i&&(d.search=i),o==="this"?d.url=r.url:o==="template"&&r.urlPattern&&(d.urlPattern=r.urlPattern);let b=this.feedbacks.length>0;b||this.showLoading();let C=!this.mineOnly&&this.isMarkerQuery(d,r),p=this.keepThreads();this.isLoading=true;try{let m=this.mineOnly?this.fetchOwnFeedbacks(d,t):this.client.getFeedbacks(this.projectName,d);C||this.loadPageMarkers(r,t);let f=await m,{feedbacks:v,total:w}=f,g=1;for(;g<e&&v.length<w&&!t.aborted;){g++;let k=await this.client.getFeedbacks(this.projectName,{...d,page:g});v=[...v,...k.feedbacks],w=k.total;}if(t.aborted)return;this.currentPage=g,this.feedbacks=v.map(p),this.totalFeedbacks=w,this.canComment=f.capabilities?.comments===!0,chunkQDJDQQ6E_cjs.D(this.deleteAllBtn,this.readOnly||f.permissions?.canDeleteAll===!1),this.stats.update(v,w),this.bulk.reset(),this.renderList(),this.pendingScrollId&&this.flashCard(this.pendingScrollId,this.pendingDetail),C&&this.renderPageMarkers(v,r);}catch(m){if(t.aborted)return;b||this.showError(),this.bus.emit("feedback:error",m instanceof Error?m:new Error(String(m)));}finally{t.aborted||(this.isLoading=false,this.pendingScrollId=null,this.pendingDetail=false);}}async loadMoreFeedbacks(){if(this.isLoadingMore)return;this.isLoadingMore=true;let e=this.loadController,t=this.currentPage+1,i=this.searchInput.value.trim()||void 0,s=this.activeFilters.has("all")?void 0:Array.from(this.activeFilters)[0],a=this.statusBucket(this.statusSegmented.value),r=this.getScope(),o=this.scopeSegmented.value,d={page:t,limit:20};s&&(d.type=s),a&&(d.statuses=a),i&&(d.search=i),o==="this"?d.url=r.url:o==="template"&&r.urlPattern&&(d.urlPattern=r.urlPattern);let b=this.listContainer.querySelector(".sp-btn-load-more"),C;b&&(C=chunkQDJDQQ6E_cjs.F(b));let p=this.keepThreads();try{let{feedbacks:m,total:f}=await this.client.getFeedbacks(this.projectName,d);if(e!==this.loadController)return;this.currentPage=t,this.totalFeedbacks=f,this.feedbacks=[...this.feedbacks,...m.map(p)],this.stats.update(this.feedbacks,f),this.renderList(),this.isMarkerQuery(d,r)&&this.renderPageMarkers(this.feedbacks,r);}catch(m){C&&C(),this.bus.emit("feedback:error",m instanceof Error?m:new Error(String(m)));}finally{this.isLoadingMore=false;}}isMarkerQuery(e,t){let i=this.scopeAnnotationsByUrl?t.url:void 0;return !e.type&&!e.statuses&&!e.search&&!e.urlPattern&&e.url===i}async fetchOwnFeedbacks(e,t){let i=this.ownFeedback.ids(),s=new Map,a=new Set,r=0,o,d=true,b,C;for(let m=1;s.size<i.size&&!t.aborted;m++){let f=await this.client.getFeedbacks(this.projectName,{...e,page:m,limit:100}),{feedbacks:v,total:w}=f;b=f.capabilities,C=f.permissions,o??=w,d&&=w===o;for(let g of v)a.add(g.id),i.has(g.id)&&s.set(g.id,g);if(r+=v.length,v.length===0||r>=w)break}return Object.keys(e).every(m=>m==="page"||m==="limit")&&d&&a.size===o&&this.ownFeedback.remove(...[...i].filter(m=>!s.has(m))),{feedbacks:[...s.values()],total:s.size,capabilities:b,permissions:C}}async loadPageMarkers(e,t){let i=this.scopeAnnotationsByUrl?{limit:20,url:e.url}:{limit:20};try{let{feedbacks:s}=await this.client.getFeedbacks(this.projectName,i);t.aborted||this.renderPageMarkers(s,e);}catch{}}renderPageMarkers(e,t){this.markers.render(this.scopeAnnotationsByUrl?e.filter(i=>i.url===t.url):e);}renderList(){if(this.listContainer.replaceChildren(),this.feedbacks.length===0){let s=chunkQDJDQQ6E_cjs.A("div",{class:"sp-empty"});s.setAttribute("role","status"),s.setAttribute("aria-live","polite");let a=chunkQDJDQQ6E_cjs.A("div",{class:"sp-empty-text"});chunkQDJDQQ6E_cjs.B(a,this.t("panel.empty")),s.appendChild(a),this.listContainer.appendChild(s);return}let e=chunkQDJDQQ6E_cjs.Ca(this.feedbacks,this.sortControls.sortMode),t=e.filter(s=>this.selectable(s)).map(s=>s.id);if(t.length>0&&this.listContainer.appendChild(this.bulk.createSelectAllBar(t,this.t("bulk.selectAll"))),this.sortControls.groupByPage){let s=chunkQDJDQQ6E_cjs.Da(e),a=0;for(let[r,o]of s){let d=chunkQDJDQQ6E_cjs.Ea(r,o.length);this.listContainer.appendChild(d);let b=De("sp-group-content",r);for(let C of o){let p=this.createCard(C,a+1);p.style.setProperty("--sp-card-i",String(a)),b.appendChild(p),a++;}this.listContainer.appendChild(b);}}else {let s=De("sp-cards",this.t("panel.feedbackList"));e.forEach((a,r)=>{let o=this.createCard(a,r+1);o.style.setProperty("--sp-card-i",String(r)),s.appendChild(o);}),this.listContainer.appendChild(s);}let i=this.totalFeedbacks-this.feedbacks.length;if(i>0){let s=chunkQDJDQQ6E_cjs.A("div",{class:"sp-load-more-wrap"}),a=document.createElement("button");a.className="sp-btn-ghost sp-btn-load-more",chunkQDJDQQ6E_cjs.B(a,chunkQDJDQQ6E_cjs.sa(this.t,"panel.loadMore",{remaining:i})),a.addEventListener("click",()=>this.loadMoreFeedbacks().catch(()=>{})),s.appendChild(a),this.listContainer.appendChild(s);}}lostNote(e){let t=chunkQDJDQQ6E_cjs.A("div",{class:"sp-lost"});return t.dataset.lostFor=e,chunkQDJDQQ6E_cjs.B(t,this.t("panel.notOnPage")),t.hidden=!this.markers.isLost(e),t}syncLostNotes(){for(let e of this.root.querySelectorAll("[data-lost-for]"))e.hidden=!this.markers.isLost(e.dataset.lostFor??"");}createCard(e,t){let i=chunkQDJDQQ6E_cjs.k(e.status),s=chunkQDJDQQ6E_cjs.ga(e.type,this.colors),a=chunkQDJDQQ6E_cjs.A("div",{class:`sp-card ${i?"sp-card--resolved":""}`});a.classList.toggle("sp-card--selected",this.bulk.isSelected(e.id)),a.setAttribute("role","listitem"),a.setAttribute("tabindex","0");let r=chunkQDJDQQ6E_cjs.sa(this.t,"marker.aria",{number:t,type:chunkQDJDQQ6E_cjs.ta(e.type,this.t),status:chunkQDJDQQ6E_cjs.ua(e.status,this.t),message:e.message.slice(0,80)});a.setAttribute("aria-label",r),a.dataset.feedbackId=e.id,a.dataset.number=String(t);let o=chunkQDJDQQ6E_cjs.A("div",{class:"sp-card-bar"});o.style.background=i?"#9ca3af":s;let d=chunkQDJDQQ6E_cjs.A("div",{class:"sp-card-body"}),b=chunkQDJDQQ6E_cjs.A("div",{class:"sp-card-header"});this.selectable(e)&&b.appendChild(this.bulk.createCheckbox(e.id,r));let C=chunkQDJDQQ6E_cjs.A("span",{class:"sp-card-number"});chunkQDJDQQ6E_cjs.B(C,`#${t}`);let p=chunkQDJDQQ6E_cjs.A("span",{class:"sp-badge"}),m=chunkQDJDQQ6E_cjs.ja(e.type,this.colors);p.style.background=m,p.style.color=s,chunkQDJDQQ6E_cjs.B(p,chunkQDJDQQ6E_cjs.ta(e.type,this.t));let f=chunkQDJDQQ6E_cjs.A("span",{class:"sp-badge sp-badge--status"});f.dataset.status=e.status,f.style.background=chunkQDJDQQ6E_cjs.ia(e.status,this.colors),f.style.color=chunkQDJDQQ6E_cjs.ha(e.status,this.colors),chunkQDJDQQ6E_cjs.B(f,chunkQDJDQQ6E_cjs.ua(e.status,this.t));let v=chunkQDJDQQ6E_cjs.A("span",{class:"sp-card-date"});chunkQDJDQQ6E_cjs.B(v,chunkQDJDQQ6E_cjs.H(e.createdAt,this.locale)),b.appendChild(C),b.appendChild(p),b.appendChild(f),b.appendChild(v);let w=chunkQDJDQQ6E_cjs.A("div",{class:"sp-card-message"});chunkQDJDQQ6E_cjs.B(w,e.message);let g=document.createElement("button");g.className="sp-card-expand",g.dataset.action="expand",chunkQDJDQQ6E_cjs.B(g,this.t("panel.showMore")),g.style.display="none",g.setAttribute("aria-expanded","false"),requestAnimationFrame(()=>{w.scrollHeight>w.clientHeight&&(g.style.display="block");});let k=chunkQDJDQQ6E_cjs.A("div",{class:"sp-card-footer"}),n=document.createElement("button");n.className="sp-btn-resolve",n.dataset.action="resolve",n.appendChild(chunkQDJDQQ6E_cjs.z(i?chunkQDJDQQ6E_cjs.$:chunkQDJDQQ6E_cjs.S));let c=document.createElement("span");chunkQDJDQQ6E_cjs.B(c,` ${this.t(i?"panel.reopen":"panel.resolve")}`),n.appendChild(c);let h=document.createElement("button");h.className="sp-btn-delete",h.dataset.action="delete",h.appendChild(chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs.aa));let y=document.createElement("span");return chunkQDJDQQ6E_cjs.B(y,` ${this.t("panel.delete")}`),h.appendChild(y),this.can(e,"canChangeStatus")&&k.appendChild(n),this.can(e,"canDelete")&&k.appendChild(h),d.appendChild(b),d.appendChild(w),d.appendChild(g),d.appendChild(this.lostNote(e.id)),k.hasChildNodes()&&d.appendChild(k),a.appendChild(o),a.appendChild(d),a}can(e,t){return !this.readOnly&&e.permissions?.[t]!==false}selectable(e){return this.can(e,"canChangeStatus")||this.can(e,"canDelete")}async bulkResolve(e){let t=new Set(this.feedbacks.filter(a=>chunkQDJDQQ6E_cjs.k(a.status)).map(a=>a.id)),i=e.filter(a=>!t.has(a)),s=await Promise.allSettled(i.map(a=>this.client.resolveFeedback(a,true)));await this.settleBulk(i,s);}async bulkDelete(e){let t=await Promise.allSettled(e.map(i=>this.client.deleteFeedback(i)));e.forEach((i,s)=>{t[s]?.status==="fulfilled"&&this.bus.emit("feedback:deleted",i);}),await this.settleBulk(e,t);}async settleBulk(e,t){let i=e.filter((o,d)=>t[d]?.status==="rejected");i.length<e.length&&await this.loadFeedbacks();let s=t.find(o=>o.status==="rejected");if(!s)return;let a=new Set(this.feedbacks.map(o=>o.id));this.bulk.selectAll(i.filter(o=>a.has(o)));let r=s.reason instanceof Error?s.reason:new Error(String(s.reason));throw this.bus.emit("feedback:error",r),r}async confirmDeleteAll(){if(await this.showConfirmDialog(this.t("panel.deleteAllConfirmTitle"),this.t("panel.deleteAllConfirmMessage"))){this.deleteAllBtn.disabled=true;try{await this.client.deleteAllFeedbacks(this.projectName),this.bus.emit("feedback:all-deleted"),await this.loadFeedbacks();}catch(t){this.bus.emit("feedback:error",t instanceof Error?t:new Error(String(t))),await this.loadFeedbacks().catch(()=>{});}finally{this.deleteAllBtn.disabled=false;}}}showConfirmDialog(e,t){return new Promise(i=>{let s=chunkQDJDQQ6E_cjs.A("div",{class:"sp-confirm-backdrop"}),a=`sp-confirm-title-${Date.now()}`,r=`sp-confirm-msg-${Date.now()}`,o=chunkQDJDQQ6E_cjs.A("div",{class:"sp-confirm-dialog"});o.setAttribute("role","alertdialog"),o.setAttribute("aria-modal","true"),o.setAttribute("aria-labelledby",a),o.setAttribute("aria-describedby",r);let d=chunkQDJDQQ6E_cjs.A("div",{class:"sp-confirm-title"});d.id=a,chunkQDJDQQ6E_cjs.B(d,e);let b=chunkQDJDQQ6E_cjs.A("div",{class:"sp-confirm-message"});b.id=r,chunkQDJDQQ6E_cjs.B(b,t);let C=chunkQDJDQQ6E_cjs.A("div",{class:"sp-confirm-actions"}),p=document.createElement("button");p.type="button",p.className="sp-btn-ghost",chunkQDJDQQ6E_cjs.B(p,this.t("panel.cancel"));let m=document.createElement("button");m.type="button",m.className="sp-btn-danger",chunkQDJDQQ6E_cjs.B(m,this.t("panel.confirmDelete"));let f=false,v=k=>{f||(f=true,g(),s.style.opacity="0",o.style.transform="translateY(8px) scale(0.97)",setTimeout(()=>{s.remove(),i(k);},200));},g=chunkQDJDQQ6E_cjs.L(s,k=>{if(k.key==="Escape"){k.stopPropagation(),v(false);return}k.key==="Tab"&&(k.preventDefault(),s.getRootNode().activeElement===p?m.focus():p.focus());});p.addEventListener("click",()=>v(false)),m.addEventListener("click",()=>v(true)),s.addEventListener("click",k=>{k.target===s&&v(false);}),C.appendChild(p),C.appendChild(m),o.appendChild(d),o.appendChild(b),o.appendChild(C),s.appendChild(o),this.root.getRootNode()instanceof ShadowRoot?this.root.getRootNode().appendChild(s):this.root.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",o.style.transform="translateY(0) scale(1)",p.focus();});})}async deleteFeedback(e,t){this.pendingMutations.add(e.id);let i=chunkQDJDQQ6E_cjs.F(t);try{await this.client.deleteFeedback(e.id),this.bus.emit("feedback:deleted",e.id),await this.loadFeedbacks();}catch(s){i(),this.bus.emit("feedback:error",s instanceof Error?s:new Error(String(s)));}finally{this.pendingMutations.delete(e.id);}}async toggleResolve(e,t){this.pendingMutations.add(e.id);let i=chunkQDJDQQ6E_cjs.F(t);try{let s=!chunkQDJDQQ6E_cjs.k(e.status);await this.client.resolveFeedback(e.id,s),await this.loadFeedbacks();}catch(s){i(),this.bus.emit("feedback:error",s instanceof Error?s:new Error(String(s)));}finally{this.pendingMutations.delete(e.id);}}buildTypeDropdown(){return this.typeOptions=[{value:"all",label:this.t("panel.filterAll"),icon:chunkQDJDQQ6E_cjs.Y,color:"var(--sp-accent-text)",bg:"var(--sp-accent-light)"},{value:"question",label:this.t("type.question"),icon:chunkQDJDQQ6E_cjs.U,color:"var(--sp-type-question)",bg:"var(--sp-type-question-bg)"},{value:"change",label:this.t("type.change"),icon:chunkQDJDQQ6E_cjs.V,color:"var(--sp-type-change)",bg:"var(--sp-type-change-bg)"},{value:"bug",label:this.t("type.bug"),icon:chunkQDJDQQ6E_cjs.W,color:"var(--sp-type-bug)",bg:"var(--sp-type-bug-bg)"},{value:"other",label:this.t("type.other"),icon:chunkQDJDQQ6E_cjs.X,color:"var(--sp-type-other)",bg:"var(--sp-type-other-bg)"}],this.typeDropdownContainer=chunkQDJDQQ6E_cjs.A("div",{class:"sp-filter-dropdown"}),this.typeDropdownBtn=document.createElement("button"),this.typeDropdownBtn.type="button",this.typeDropdownBtn.className="sp-filter-dropdown-btn",this.typeDropdownBtn.setAttribute("aria-haspopup","listbox"),this.typeDropdownBtn.setAttribute("aria-expanded","false"),this.renderTypeDropdownTrigger(),this.typeDropdownBtn.addEventListener("click",e=>{e.stopPropagation(),this.typeDropdownMenu?this.closeTypeDropdown():this.openTypeDropdown();}),this.typeDropdownContainer.addEventListener("keydown",e=>{e.key!=="Escape"||!this.typeDropdownMenu||(e.stopPropagation(),this.closeTypeDropdown(),this.typeDropdownBtn.focus());}),this.typeDropdownContainer.appendChild(this.typeDropdownBtn),this.typeDropdownContainer}renderTypeDropdownTrigger(){let e=this.typeOptions.find(o=>this.activeFilters.has(o.value))??this.typeOptions[0];if(!e)return;this.typeDropdownBtn.replaceChildren(),this.typeDropdownBtn.style.setProperty("--sp-chip-color",e.color),this.typeDropdownBtn.style.setProperty("--sp-chip-bg",e.bg),this.typeDropdownBtn.dataset.filter=e.value,this.typeDropdownBtn.classList.toggle("sp-filter-dropdown-btn--filtered",e.value!=="all"),this.typeDropdownBtn.setAttribute("aria-label",`${this.t("type.label")}: ${e.label}`);let t=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-btn__icon"});t.appendChild(chunkQDJDQQ6E_cjs.z(e.icon)),this.typeDropdownBtn.appendChild(t);let i=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-btn__label"}),s=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-btn__prefix"});chunkQDJDQQ6E_cjs.B(s,this.t("type.label"));let a=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-btn__value"});chunkQDJDQQ6E_cjs.B(a,e.label),i.append(s," ",a),this.typeDropdownBtn.appendChild(i);let r=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-btn__chevron"});r.appendChild(chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs._)),this.typeDropdownBtn.appendChild(r);}openTypeDropdown(){this.typeDropdownMenu=chunkQDJDQQ6E_cjs.A("div",{class:"sp-filter-dropdown-menu"}),this.typeDropdownMenu.setAttribute("role","listbox"),this.typeDropdownMenu.setAttribute("aria-label",this.t("type.label")),this.typeDropdownBtn.setAttribute("aria-expanded","true");for(let e of this.typeOptions){let t=document.createElement("button");t.type="button";let i=this.activeFilters.has(e.value);t.className=`sp-filter-dropdown-option${i?" sp-filter-dropdown-option--active":""}`,t.style.setProperty("--sp-chip-color",e.color),t.style.setProperty("--sp-chip-bg",e.bg),t.dataset.filter=e.value,t.setAttribute("role","option"),t.setAttribute("aria-selected",String(i));let s=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-option__icon"});s.appendChild(chunkQDJDQQ6E_cjs.z(e.icon)),t.appendChild(s);let a=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-option__label"});if(chunkQDJDQQ6E_cjs.B(a,e.label),t.appendChild(a),i){let r=chunkQDJDQQ6E_cjs.A("span",{class:"sp-filter-dropdown-option__check"});r.appendChild(chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs.S)),t.appendChild(r);}t.addEventListener("click",r=>{r.stopPropagation(),this.selectTypeFilter(e.value);}),this.typeDropdownMenu.appendChild(t);}this.typeDropdownContainer.appendChild(this.typeDropdownMenu),this.removeTypeDropdownOutsideClick=chunkQDJDQQ6E_cjs.C(this.typeDropdownContainer,()=>this.closeTypeDropdown());}closeTypeDropdown(){this.typeDropdownMenu&&(this.typeDropdownMenu.remove(),this.typeDropdownMenu=null),this.typeDropdownBtn.setAttribute("aria-expanded","false"),this.removeTypeDropdownOutsideClick?.(),this.removeTypeDropdownOutsideClick=null;}selectTypeFilter(e){this.activeFilters.clear(),this.activeFilters.add(e),this.renderTypeDropdownTrigger(),this.closeTypeDropdown(),this.loadFeedbacks().catch(()=>{});}buildStatusSegmented(){return this.statusSegmented=new P({options:[{value:"all",label:this.t("panel.statusAll"),icon:chunkQDJDQQ6E_cjs.Y,color:"var(--sp-accent-text)",bg:"var(--sp-accent-light)"},{value:"open",label:this.t("panel.statusOpen"),icon:chunkQDJDQQ6E_cjs.Z,color:"var(--sp-status-open)",bg:"var(--sp-status-open-bg)"},{value:"resolved",label:this.t("panel.statusClosed"),icon:chunkQDJDQQ6E_cjs.T,color:"var(--sp-status-resolved)",bg:"var(--sp-status-resolved-bg)"}],value:"all",onChange:()=>{this.loadFeedbacks().catch(()=>{});},ariaLabel:this.t("status.label"),datasetKey:"statusFilter",modifierPrefix:"sp-segmented__btn--"}),this.statusSegmented.element}buildScopeSegmented(){return this.scopeSegmented=new P({options:[{value:"this",label:this.t("scope.thisPage")},{value:"template",label:this.t("scope.thisType")},{value:"all",label:this.t("scope.all")}],value:this.initialScopeFilter,onChange:()=>{this.loadFeedbacks().catch(()=>{});},ariaLabel:this.t("scope.label"),datasetKey:"scopeFilter",modifierPrefix:"sp-segmented__btn--scope-",extraClass:"sp-segmented--scope"}),this.syncScopeAvailability(),this.scopeSegmented.element}syncScopeAvailability(){if(!this.scopeSegmented)return;let t=!!this.getScope().urlPattern;this.scopeSegmented.setOptionVisible("template",t),!t&&this.scopeSegmented.value==="template"&&this.scopeSegmented.select("this");}buildMineToggle(){let e=document.createElement("button");return e.type="button",e.className="sp-mine-toggle",e.title=this.t("panel.filterMineHint"),e.setAttribute("aria-pressed","false"),e.append(chunkQDJDQQ6E_cjs.z(chunkQDJDQQ6E_cjs.ba),this.t("panel.filterMine")),e.addEventListener("click",()=>{this.mineOnly=!this.mineOnly,e.classList.toggle("sp-mine-toggle--active",this.mineOnly),e.setAttribute("aria-pressed",String(this.mineOnly)),this.loadFeedbacks().catch(()=>{});}),e}pressInFocusedCard(e){this.listContainer.querySelectorAll(".sp-card")[chunkQDJDQQ6E_cjs.Ja(this.listContainer)]?.querySelector(e)?.click();}scrollToFeedback(e,t=false){if(this.isLoading){this.pendingScrollId=e,this.pendingDetail=t;return}this.flashCard(e,t);}showFeedback(e){this.scrollToFeedback(e,true);}flashCard(e,t){let i=CSS.escape(e),s=this.listContainer.querySelector(`[data-feedback-id="${i}"]`);if(s){s.scrollIntoView({behavior:"smooth",block:"center"}),s.classList.add("sp-anim-flash"),s.addEventListener("animationend",()=>{s.classList.remove("sp-anim-flash");},{once:true});let a=this.feedbacks.find(r=>r.id===e);a&&(t||chunkQDJDQQ6E_cjs.la())&&this.detail.show(a,Number(s.dataset.number));}}draftOf(e){let t=this.threadDrafts.get(e)??{text:""};return this.threadDrafts.set(e,t),t}async postComment(e,t,i){let s=await this.resolveIdentity();if(!s)return null;try{let a=await this.client.addComment(e.id,{body:t,clientId:i,authorName:s.name,authorEmail:s.email,authorRole:"client"});for(let o of new Set([e,this.feedbacks.find(d=>d.id===e.id)]))o&&!o.comments?.some(d=>d.id===a.id)&&(o.comments=[...o.comments??[],a]);let r=this.threadWrites.get(e.id)?.replies??[];return this.threadWrites.set(e.id,{seq:++this.threadWriteCount,replies:[...r,a]}),this.bus.emit("comment:added",a),a}catch(a){throw this.bus.emit("feedback:error",a instanceof Error?a:new Error(String(a))),a}}keepThreads(){let e=this.threadWriteCount;return t=>{let i=this.threadWrites.get(t.id);if(!i||i.seq<=e)return t;let s=new Set(t.comments?.map(o=>o.id)),a=i.replies.filter(o=>!s.has(o.id));if(a.length===0)return t;let r=[...t.comments??[],...a];return r.sort((o,d)=>o.createdAt<d.createdAt?-1:o.createdAt>d.createdAt?1:0),{...t,comments:r}}}reportActionError(e){this.bus.emit("panel:action-error",e instanceof Error?e:new Error(String(e)));}hideDetailOf(e){this.detail.feedbackId===e&&this.detail.hide();}async refreshDetail(e){if(this.isOpen&&await this.loadFeedbacks(this.currentPage),this.detail.feedbackId!==e)return;let t=this.feedbacks.findIndex(s=>s.id===e),i=this.feedbacks[t];i?this.detail.show(i,t+1):this.detail.hide();}async refresh(){this.isOpen&&await this.loadFeedbacks();}get isCurrentlyOpen(){return this.isOpen}destroy(){this.isOpen=false,this.loadController?.abort(),this.searchTimeout&&clearTimeout(this.searchTimeout),this.listContainer.removeEventListener("click",this.onListClick),this.listContainer.removeEventListener("keydown",this.onListKeydown),this.listContainer.removeEventListener("mouseover",this.onListMouseover),this.listContainer.removeEventListener("mouseout",this.onListMouseout),document.removeEventListener("sp-marker-click",this.onMarkerClick),this.closeTypeDropdown(),this.sortControls.destroy(),this.bulk.destroy(),this.exportBtn.destroy(),this.shortcuts.destroy(),this.detail.destroy(),this.scrim.remove(),this.root.remove();}};exports.Panel=Be;//# sourceMappingURL=panel-TD4UUEZA.cjs.map
|
|
2
|
+
//# sourceMappingURL=panel-TD4UUEZA.cjs.map
|