@lemoncat7/dsh-knowledge 2.3.3 → 2.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +1 -1
  2. package/docs/ui-maintenance.md +97 -0
  3. package/lib/client.d.ts.map +1 -1
  4. package/lib/client.js +356 -205
  5. package/lib/client.js.map +4 -4
  6. package/lib/design-tokens.d.ts +12 -0
  7. package/lib/design-tokens.d.ts.map +1 -0
  8. package/lib/design-tokens.js +58 -0
  9. package/lib/design-tokens.js.map +1 -0
  10. package/lib/knowledge-activity-controller.d.ts +3 -8
  11. package/lib/knowledge-activity-controller.d.ts.map +1 -1
  12. package/lib/knowledge-activity-controller.js +19 -7
  13. package/lib/knowledge-activity-controller.js.map +1 -1
  14. package/lib/knowledge-activity-notes.d.ts.map +1 -1
  15. package/lib/knowledge-activity-notes.js +19 -10
  16. package/lib/knowledge-activity-notes.js.map +1 -1
  17. package/lib/knowledge-activity-panel.d.ts.map +1 -1
  18. package/lib/knowledge-activity-panel.js +32 -20
  19. package/lib/knowledge-activity-panel.js.map +1 -1
  20. package/lib/knowledge-activity-presentation.d.ts +14 -0
  21. package/lib/knowledge-activity-presentation.d.ts.map +1 -0
  22. package/lib/knowledge-activity-presentation.js +77 -0
  23. package/lib/knowledge-activity-presentation.js.map +1 -0
  24. package/lib/knowledge-activity-state.d.ts +17 -0
  25. package/lib/knowledge-activity-state.d.ts.map +1 -0
  26. package/lib/knowledge-activity-state.js +14 -0
  27. package/lib/knowledge-activity-state.js.map +1 -0
  28. package/lib/latest-request.d.ts +7 -0
  29. package/lib/latest-request.d.ts.map +1 -0
  30. package/lib/latest-request.js +14 -0
  31. package/lib/latest-request.js.map +1 -0
  32. package/lib/local-provider.d.ts +0 -2
  33. package/lib/local-provider.d.ts.map +1 -1
  34. package/lib/local-provider.js +2 -323
  35. package/lib/local-provider.js.map +1 -1
  36. package/lib/notes/share-page-styles.d.ts +2 -0
  37. package/lib/notes/share-page-styles.d.ts.map +1 -0
  38. package/lib/notes/share-page-styles.js +11 -0
  39. package/lib/notes/share-page-styles.js.map +1 -0
  40. package/lib/notes/share-page.d.ts.map +1 -1
  41. package/lib/notes/share-page.js +1 -8
  42. package/lib/notes/share-page.js.map +1 -1
  43. package/lib/storage/migrations.d.ts +5 -0
  44. package/lib/storage/migrations.d.ts.map +1 -0
  45. package/lib/storage/migrations.js +325 -0
  46. package/lib/storage/migrations.js.map +1 -0
  47. package/lib/theme-bridge.d.ts +9 -7
  48. package/lib/theme-bridge.d.ts.map +1 -1
  49. package/lib/theme-bridge.js +3 -23
  50. package/lib/theme-bridge.js.map +1 -1
  51. package/lib/web-note-editor-selection.d.ts.map +1 -1
  52. package/lib/web-note-editor-selection.js +50 -15
  53. package/lib/web-note-editor-selection.js.map +1 -1
  54. package/lib/web-note-editor.d.ts.map +1 -1
  55. package/lib/web-note-editor.js +15 -1
  56. package/lib/web-note-editor.js.map +1 -1
  57. package/lib/web.d.ts.map +1 -1
  58. package/lib/web.js +4 -0
  59. package/lib/web.js.map +1 -1
  60. package/package.json +1 -1
  61. package/web/app.js +78 -176
  62. package/web/design-tokens.css +1 -0
  63. package/web/dialogs.js +94 -0
  64. package/web/document-actions.js +68 -0
  65. package/web/index.html +1 -0
  66. package/web/model-catalog.js +22 -0
  67. package/web/note-editor.js +57 -57
  68. package/web/select-control.js +193 -0
  69. package/web/styles.css +93 -185
  70. package/web/ui-primitives.js +5 -0
@@ -1,4 +1,4 @@
1
- import { Editor } from '@tiptap/core';
1
+ import { Editor, isNodeSelection } from '@tiptap/core';
2
2
  import Document from '@tiptap/extension-document';
3
3
  import Image from '@tiptap/extension-image';
4
4
  import Paragraph from '@tiptap/extension-paragraph';
@@ -11,6 +11,18 @@ import { Markdown } from '@tiptap/markdown';
11
11
  import StarterKit from '@tiptap/starter-kit';
12
12
  import { createNoteEditorChrome } from './web-note-editor-chrome.js';
13
13
  import { NoteSearch } from './web-note-editor-search.js';
14
+ /** Selecting text must never turn into an accidental move/copy gesture.
15
+ * Clipboard input and incoming drops retain the editor's normal handling.
16
+ * Shared by Markdown and plain-text documents, including knowledge documents.
17
+ */
18
+ const bodyEditorEvents = {
19
+ dragstart: (view, event) => {
20
+ if (view.state.selection.empty || isNodeSelection(view.state.selection))
21
+ return false;
22
+ event.preventDefault();
23
+ return true;
24
+ },
25
+ };
14
26
  /**
15
27
  * Mount a Markdown-native rich text editor into the notes workspace.
16
28
  *
@@ -41,6 +53,7 @@ export function createMarkdownEditor(options) {
41
53
  TaskItem.configure({ nested: true }),
42
54
  ],
43
55
  editorProps: {
56
+ handleDOMEvents: bodyEditorEvents,
44
57
  attributes: {
45
58
  class: 'notes-live-editor-surface',
46
59
  role: 'textbox',
@@ -111,6 +124,7 @@ export function createPlainTextEditor(options) {
111
124
  UndoRedo,
112
125
  ],
113
126
  editorProps: {
127
+ handleDOMEvents: bodyEditorEvents,
114
128
  attributes: {
115
129
  class: 'notes-plain-editor-surface',
116
130
  role: 'textbox',
@@ -1 +1 @@
1
- {"version":3,"file":"web-note-editor.js","sourceRoot":"","sources":["../src/web-note-editor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-note-editor.js","sourceRoot":"","sources":["../src/web-note-editor.ts"],"names":[],"mappings":"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"}
package/lib/web.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAqBtD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,kBAAkB,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,QAAQ,GAAG,aAAwB,EAC7C,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,IAAI,CAeZ"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAyBtD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,kBAAkB,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,QAAQ,GAAG,aAAwB,EAC7C,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,IAAI,CAeZ"}
package/lib/web.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { createHash, timingSafeEqual } from 'node:crypto';
3
3
  const STATIC_ASSETS = new Map([
4
+ ...['model-catalog', 'dialogs', 'select-control', 'document-actions'].map(name => [
5
+ `${name}.js`, loadAsset(`../web/${name}.js`, 'text/javascript; charset=utf-8'),
6
+ ]),
4
7
  ['app.js', loadAsset('../web/app.js', 'text/javascript; charset=utf-8')],
5
8
  ['api-client.js', loadAsset('../web/api-client.js', 'text/javascript; charset=utf-8')],
6
9
  ['change-review.js', loadAsset('../web/change-review.js', 'text/javascript; charset=utf-8')],
@@ -9,6 +12,7 @@ const STATIC_ASSETS = new Map([
9
12
  ['note-editor.js', loadAsset('../web/note-editor.js', 'text/javascript; charset=utf-8')],
10
13
  ['note-history.js', loadAsset('../web/note-history.js', 'text/javascript; charset=utf-8')],
11
14
  ['ui-primitives.js', loadAsset('../web/ui-primitives.js', 'text/javascript; charset=utf-8')],
15
+ ['design-tokens.css', loadAsset('../web/design-tokens.css', 'text/css; charset=utf-8')],
12
16
  ['styles.css', loadAsset('../web/styles.css', 'text/css; charset=utf-8')],
13
17
  ]);
14
18
  const ASSET_VERSION = assetVersion(STATIC_ASSETS.values());
package/lib/web.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lemoncat7/dsh-knowledge",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "Local and remote knowledge bases for DeepSeek Harness, with scoped recall, controlled write-back, and a Web management console",
5
5
  "keywords": [
6
6
  "deepseek-harness",
package/web/app.js CHANGED
@@ -3,14 +3,20 @@ const AUTH_MODE = document.querySelector('meta[name="dsh-knowledge-auth-mode"]')
3
3
  const WEB_PATH = document.querySelector('meta[name="dsh-knowledge-web"]')?.content || '/knowledge'
4
4
  const ASSET_VERSION = document.querySelector('meta[name="dsh-knowledge-asset-version"]')?.content || ''
5
5
  const moduleUrl = name => `./${name}.js${ASSET_VERSION ? `?v=${encodeURIComponent(ASSET_VERSION)}` : ''}`
6
- const [apiModule, themeModule, uiModule] = await Promise.all([
6
+ const [apiModule, themeModule, uiModule, modelCatalogModule, dialogModule, selectModule, documentActionsModule] = await Promise.all([
7
7
  import(moduleUrl('api-client')),
8
8
  import(moduleUrl('host-theme')),
9
9
  import(moduleUrl('ui-primitives')),
10
+ import(moduleUrl('model-catalog')),
11
+ import(moduleUrl('dialogs')),
12
+ import(moduleUrl('select-control')),
13
+ import(moduleUrl('document-actions')),
10
14
  ])
11
15
  const { createApiClient } = apiModule
12
16
  const { installHostThemeBridge } = themeModule
13
17
  const { actionButton, badge, createToastPresenter, element, interfaceIcon, paneToggleButton } = uiModule
18
+ const { renderMenu: renderDocumentMenu, closeMenus: closeDocumentMenus } = documentActionsModule.createDocumentMenuPresenter(uiModule)
19
+ const readModelCatalog = modelCatalogModule.createModelCatalogLoader()
14
20
  const TOKEN_KEY = 'dsh-knowledge.session-token'
15
21
  const TYPES = ['preference', 'fact', 'decision', 'procedure', 'lesson']
16
22
  const TYPE_LABELS = { preference: '偏好', fact: '事实', decision: '决策', procedure: '流程', lesson: '经验' }
@@ -35,6 +41,8 @@ const mountContext = {
35
41
  const app = document.querySelector('#app')
36
42
  const toastRegion = document.querySelector('#toast-region')
37
43
  const showToast = createToastPresenter(toastRegion)
44
+ const { openConfirm, openSheet, openModal } = dialogModule.createDialogPresenter({ element, actionButton, interfaceIcon, showToast, friendlyError })
45
+ selectModule.installSelectControls()
38
46
  const savedDocumentLayout = readDocumentLayout()
39
47
 
40
48
  function createDocumentViewState(overrides = {}) {
@@ -335,7 +343,10 @@ function updateLoadingPhase(request, label, progress) {
335
343
  if (request !== navigationRequest || !state.loading) return
336
344
  state.loadingPhase = label
337
345
  state.loadingProgress = Math.max(0, Math.min(1, progress))
338
- renderShell()
346
+ const progressNode = document.querySelector('.route-progress')
347
+ progressNode?.setAttribute('aria-label', label)
348
+ progressNode?.setAttribute('aria-valuenow', String(Math.round(state.loadingProgress * 100)))
349
+ progressNode?.firstElementChild?.style.setProperty('--route-progress', String(state.loadingProgress))
339
350
  }
340
351
 
341
352
  async function saveBeforeNavigation() {
@@ -939,6 +950,7 @@ async function loadTokens(signal) {
939
950
  }
940
951
 
941
952
  function renderShell() {
953
+ closeDocumentMenus()
942
954
  releaseNoteEditors()
943
955
  captureScrollPosition()
944
956
  const titles = {
@@ -962,15 +974,15 @@ function renderShell() {
962
974
  },
963
975
  renderSidebar(),
964
976
  renderAppSidebarResizer(),
965
- state.menuOpen ? element('button', {
966
- type: 'button', class: 'app-sidebar-scrim',
977
+ element('button', {
978
+ type: 'button', class: 'app-sidebar-scrim', hidden: !state.menuOpen,
967
979
  'aria-label': '关闭导航菜单',
968
- onClick: () => { state.menuOpen = false; renderShell() },
969
- }) : null,
980
+ onClick: () => setMenuOpen(false),
981
+ }),
970
982
  element('main', { class: 'main' },
971
983
  element('header', { class: 'topbar' },
972
984
  element('div', { class: 'topbar-title' },
973
- actionButton('☰', () => { state.menuOpen = !state.menuOpen; renderShell() }, 'ghost mobile-menu', {
985
+ actionButton(interfaceIcon('menu'), () => setMenuOpen(!state.menuOpen), 'ghost mobile-menu', {
974
986
  'aria-label': state.menuOpen ? '关闭导航菜单' : '打开导航菜单',
975
987
  'aria-expanded': String(state.menuOpen),
976
988
  }),
@@ -1031,24 +1043,38 @@ function startSidebarResize(event, minimum, maximum) {
1031
1043
  if (!shell) return
1032
1044
  const startX = event.clientX
1033
1045
  const startWidth = state.documentView.sidebarWidth
1046
+ let pendingWidth = startWidth
1047
+ let frame = 0
1034
1048
  handle.setPointerCapture?.(event.pointerId)
1035
1049
  handle.classList.add('is-dragging')
1036
1050
  document.body.classList.add('is-resizing-columns')
1037
1051
  const move = moveEvent => {
1038
- const width = clampNumber(startWidth + moveEvent.clientX - startX, minimum, maximum, startWidth)
1039
- setSidebarWidth(width, shell, handle)
1052
+ if (moveEvent.pointerId !== event.pointerId) return
1053
+ pendingWidth = clampNumber(startWidth + moveEvent.clientX - startX, minimum, maximum, startWidth)
1054
+ if (!frame) frame = window.requestAnimationFrame(() => {
1055
+ frame = 0
1056
+ if (shell.isConnected) setSidebarWidth(pendingWidth, shell, handle)
1057
+ })
1040
1058
  }
1041
- const finish = () => {
1059
+ const finish = endEvent => {
1060
+ if (endEvent.pointerId !== event.pointerId) return
1061
+ if (frame) window.cancelAnimationFrame(frame)
1062
+ frame = 0
1063
+ if (endEvent.type === 'pointerup') pendingWidth = clampNumber(startWidth + endEvent.clientX - startX, minimum, maximum, startWidth)
1064
+ if (shell.isConnected) setSidebarWidth(pendingWidth, shell, handle)
1042
1065
  handle.classList.remove('is-dragging')
1043
1066
  document.body.classList.remove('is-resizing-columns')
1044
1067
  handle.removeEventListener('pointermove', move)
1045
1068
  handle.removeEventListener('pointerup', finish)
1046
1069
  handle.removeEventListener('pointercancel', finish)
1070
+ handle.removeEventListener('lostpointercapture', finish)
1071
+ if (handle.hasPointerCapture?.(event.pointerId)) handle.releasePointerCapture(event.pointerId)
1047
1072
  saveDocumentLayout()
1048
1073
  }
1049
1074
  handle.addEventListener('pointermove', move)
1050
1075
  handle.addEventListener('pointerup', finish)
1051
1076
  handle.addEventListener('pointercancel', finish)
1077
+ handle.addEventListener('lostpointercapture', finish)
1052
1078
  }
1053
1079
 
1054
1080
  function resizeSidebarWithKeyboard(event, minimum, maximum) {
@@ -1068,6 +1094,18 @@ function setSidebarWidth(width, shell, handle) {
1068
1094
  handle?.setAttribute('aria-valuenow', String(width))
1069
1095
  }
1070
1096
 
1097
+ function setMenuOpen(open) {
1098
+ state.menuOpen = open
1099
+ const shell = app.querySelector('.app-shell')
1100
+ if (!shell) return
1101
+ shell.dataset.menuOpen = String(open)
1102
+ shell.querySelector('.app-sidebar-scrim')?.toggleAttribute('hidden', !open)
1103
+ const toggle = shell.querySelector('.mobile-menu')
1104
+ toggle?.setAttribute('aria-expanded', String(open))
1105
+ toggle?.setAttribute('aria-label', open ? '关闭导航菜单' : '打开导航菜单')
1106
+ applySidebarVisibility(shell, state.documentView.sidebarHidden)
1107
+ }
1108
+
1071
1109
  function setSidebarHidden(hidden) {
1072
1110
  state.documentView.sidebarHidden = hidden
1073
1111
  saveDocumentLayout()
@@ -1734,13 +1772,16 @@ function renderNoteEditor(workspace, editor, base) {
1734
1772
  element('div', { class: 'note-editor-actions' },
1735
1773
  finalized ? badge(DOCUMENT_STATE_LABELS[editor.documentState] || '已结束', 'success') : readOnly ? badge('只读') : null,
1736
1774
  element('span', { class: 'editor-save-status', role: 'status' }, editor.saveState),
1737
- !readOnly && !editor.isNew && documentWorkspaceBases(workspace).some(item => item.id !== editor.knowledgeBaseId)
1738
- ? actionButton('移动到…', () => openMoveKnowledgeDocument(workspace, editor), 'ghost small')
1739
- : null,
1740
1775
  finalized && !readOnly ? actionButton('重新打开', () => reopenDocument(workspace, editor), 'small') : null,
1741
- !readOnly && !editor.isNew && !finalized ? actionButton('标记结束', () => openFinalizeDocument(workspace, editor), 'small') : null,
1742
- !readOnly && !editor.isNew && !finalized ? actionButton('删除', () => confirmDeleteDocument(workspace, editor), 'ghost small') : null,
1743
1776
  !readOnly && !finalized ? actionButton(editor.isNew ? '创建文档' : '保存', () => { void saveDocumentEditor(workspace).then(saved => { if (saved) renderShell() }) }, 'primary small') : null,
1777
+ !readOnly && !editor.isNew ? renderDocumentMenu(editor.title || '知识文档', [
1778
+ [
1779
+ ...(documentWorkspaceBases(workspace).some(item => item.id !== editor.knowledgeBaseId)
1780
+ ? [{ label: '移动到…', icon: 'move', run: () => openMoveKnowledgeDocument(workspace, editor) }] : []),
1781
+ ...(!finalized ? [{ label: '标记结束', icon: 'check', run: () => openFinalizeDocument(workspace, editor) }] : []),
1782
+ ],
1783
+ !finalized ? [{ label: '删除文档', icon: 'trash', danger: true, run: () => confirmDeleteDocument(workspace, editor) }] : [],
1784
+ ]) : null,
1744
1785
  ),
1745
1786
  ),
1746
1787
  element('div', { class: 'note-editor-scroll', 'data-scroll-key': 'note-editor' },
@@ -2660,86 +2701,34 @@ function renderNoteFile(node) {
2660
2701
 
2661
2702
  function renderNoteFileToolbar(node, options = {}) {
2662
2703
  return element('header', { class: 'notes-document-toolbar' },
2663
- element('div', { class: 'notes-toolbar-leading' },
2664
- renderNoteDocumentBreadcrumb(node),
2665
- ),
2704
+ element('div', { class: 'notes-toolbar-leading' }, renderNoteDocumentBreadcrumb(node)),
2666
2705
  element('div', { class: 'notes-document-actions' },
2667
2706
  options.editable ? element('span', { class: 'notes-save-state', role: 'status', 'data-note-save-state': '', 'data-dirty': String(state.notes.dirty) }, state.notes.dirty ? '未保存' : '已保存') : null,
2668
- options.enhanced ? actionButton('查找', () => markdownEditorHandle?.openFind(), 'ghost small', { 'data-note-find': '', 'data-note-mobile-overflow': '', 'aria-keyshortcuts': 'Control+F Meta+F', 'aria-pressed': 'false' }) : null,
2669
2707
  options.enhanced ? actionButton([
2670
- interfaceIcon('outline', 'notes-toolbar-action-icon'),
2671
- element('span', {}, '大纲'),
2672
- ], () => markdownEditorHandle?.toggleOutline(), 'ghost small notes-outline-action', { 'data-note-outline': '', 'aria-label': '打开标题大纲', 'aria-controls': 'dsh-note-outline', 'aria-expanded': 'false', 'aria-pressed': 'false' }) : null,
2673
- options.editable ? actionButton('历史', () => { void openNoteHistory(node) }, 'ghost small', { 'data-note-history': '', 'data-note-mobile-overflow': '' }) : null,
2674
- noteDownloadButton(node, 'ghost small', '下载', { 'data-note-mobile-overflow': '' }),
2675
- actionButton(noteShareForNode(node.id) ? '分享中' : '分享', () => { void openNoteShare(node) }, 'ghost small', { 'data-note-mobile-overflow': '' }),
2676
- actionButton('复制引用', () => { void copyNoteReference(node) }, 'ghost small', { 'data-note-mobile-overflow': '' }),
2677
- actionButton('重命名', () => openRenameNoteNode(node), 'ghost small', { 'data-note-mobile-overflow': '' }),
2678
- options.editable ? actionButton('保存', () => { void saveNoteDocument() }, 'primary small', { 'data-note-save': '', 'data-note-mobile-overflow': '', disabled: !state.notes.dirty }) : null,
2708
+ interfaceIcon('outline', 'notes-toolbar-action-icon'), element('span', {}, '大纲'),
2709
+ ], () => markdownEditorHandle?.toggleOutline(), 'ghost small notes-outline-action', { 'data-note-outline': '', 'aria-label': '打开标题大纲', title: '标题大纲', 'aria-controls': 'dsh-note-outline', 'aria-expanded': 'false', 'aria-pressed': 'false' }) : null,
2710
+ options.editable ? actionButton('保存', () => { void saveNoteDocument() }, 'primary small', { 'data-note-save': '', disabled: !state.notes.dirty, 'aria-keyshortcuts': 'Control+S Meta+S' }) : null,
2679
2711
  renderNoteFileOverflowMenu(node, options),
2680
2712
  ),
2681
2713
  )
2682
2714
  }
2683
2715
 
2684
2716
  function renderNoteFileOverflowMenu(node, options) {
2685
- const details = element('details', {
2686
- class: 'notes-document-more',
2687
- onKeyDown: event => {
2688
- if (event.key !== 'Escape') return
2689
- event.preventDefault()
2690
- details.open = false
2691
- summary.focus()
2692
- },
2693
- onFocusOut: () => {
2694
- window.setTimeout(() => {
2695
- if (!details.contains(document.activeElement)) details.open = false
2696
- }, 0)
2697
- },
2698
- })
2699
- const summary = element('summary', { class: 'button ghost small', title: '更多操作', 'aria-label': `打开 ${node.name} 的更多操作` },
2700
- interfaceIcon('more', 'notes-document-more-icon'),
2701
- )
2702
- details.addEventListener('toggle', () => {
2703
- summary.setAttribute('aria-expanded', String(details.open))
2704
- summary.setAttribute('aria-label', `${details.open ? '关闭' : '打开'} ${node.name} 的更多操作`)
2705
- })
2706
- const closeThen = action => event => {
2707
- details.open = false
2708
- action(event)
2709
- }
2710
- const menuItems = []
2711
- if (options.editable && state.notes.dirty) {
2712
- menuItems.push(noteMenuAction('保存修改', 'save', closeThen(() => { void saveNoteDocument() })))
2713
- menuItems.push(noteMenuDivider())
2714
- }
2715
- if (options.enhanced) {
2716
- menuItems.push(noteMenuAction('查找', 'search', closeThen(() => markdownEditorHandle?.openFind())))
2717
- }
2718
- if (options.editable) menuItems.push(noteMenuAction('页面历史', 'history', closeThen(() => { void openNoteHistory(node) })))
2719
- if (options.enhanced || options.editable) menuItems.push(noteMenuDivider())
2720
- menuItems.push(
2721
- noteMenuAction('下载', 'download', closeThen(event => { void downloadNoteFile(node, event.currentTarget) })),
2722
- noteMenuAction(noteShareForNode(node.id) ? '管理分享' : '创建分享', 'link', closeThen(() => { void openNoteShare(node) })),
2723
- noteMenuAction('复制引用', 'link', closeThen(() => { void copyNoteReference(node) })),
2724
- noteMenuAction('重命名', 'rename', closeThen(() => openRenameNoteNode(node))),
2725
- noteMenuDivider(),
2726
- noteMenuAction('查看已分享', 'outline', closeThen(() => { void navigate('shares') })),
2727
- )
2728
- const menu = element('div', { class: 'notes-document-more-menu', role: 'menu', 'aria-label': `${node.name} 的更多操作` }, menuItems)
2729
- summary.setAttribute('aria-expanded', 'false')
2730
- details.append(summary, menu)
2731
- return details
2732
- }
2733
-
2734
- function noteMenuAction(label, icon, onClick, attributes = {}) {
2735
- return actionButton([
2736
- interfaceIcon(icon, 'notes-document-menu-icon'),
2737
- element('span', { class: 'notes-document-menu-label' }, label),
2738
- ], onClick, 'ghost small notes-document-menu-item', { role: 'menuitem', ...attributes })
2739
- }
2740
-
2741
- function noteMenuDivider() {
2742
- return element('div', { class: 'notes-document-menu-divider', role: 'separator' })
2717
+ return renderDocumentMenu(node.name, [
2718
+ [
2719
+ ...(options.enhanced ? [{ label: '查找', icon: 'search', run: () => markdownEditorHandle?.openFind(), attributes: { 'data-note-find': '', 'aria-keyshortcuts': 'Control+F Meta+F' } }] : []),
2720
+ ...(options.editable ? [{ label: '页面历史', icon: 'history', run: () => { void openNoteHistory(node) }, attributes: { 'data-note-history': '' } }] : []),
2721
+ ],
2722
+ [
2723
+ { label: '下载', icon: 'download', run: event => { void downloadNoteFile(node, event.currentTarget) } },
2724
+ { label: noteShareForNode(node.id) ? '管理分享' : '创建分享', icon: 'link', run: () => { void openNoteShare(node) } },
2725
+ { label: '复制引用', icon: 'link', run: () => { void copyNoteReference(node) } },
2726
+ ],
2727
+ [
2728
+ { label: '重命名', icon: 'rename', run: () => openRenameNoteNode(node) },
2729
+ { label: '查看已分享', icon: 'outline', run: () => { void navigate('shares') } },
2730
+ ],
2731
+ ])
2743
2732
  }
2744
2733
 
2745
2734
  function renderNoteFileStatusbar(node) {
@@ -4202,19 +4191,12 @@ function selectField(label, options, value) {
4202
4191
  }
4203
4192
 
4204
4193
  async function loadModelCatalog() {
4205
- if (state.modelCatalog !== null) return state.modelCatalog
4206
4194
  try {
4207
- const response = await fetch('/knowledge-control/v1/models', {
4208
- headers: { accept: 'application/json', 'x-dsh-knowledge-client': 'management-web' },
4209
- })
4210
- if (!response.ok) throw new Error(`HTTP ${response.status}`)
4211
- const payload = await response.json()
4212
- state.modelCatalog = Array.isArray(payload.providers) ? payload.providers : []
4195
+ state.modelCatalog = await readModelCatalog()
4213
4196
  } catch (error) {
4214
- state.modelCatalog = []
4215
- showToast(`无法读取当前 DSH 的模型目录:${error instanceof Error ? error.message : String(error)}`, 'error')
4197
+ showToast(`无法读取当前 DSH 的模型目录:${error.message},重新打开可重试。`, 'error')
4216
4198
  }
4217
- return state.modelCatalog
4199
+ return state.modelCatalog || []
4218
4200
  }
4219
4201
 
4220
4202
  function modelRouteFields(currentProvider, currentModel) {
@@ -4434,86 +4416,6 @@ function confirmDeleteToken(token) {
4434
4416
  } })
4435
4417
  }
4436
4418
 
4437
- function openConfirm({ title, message, confirmLabel, danger, onConfirm }) {
4438
- return openModal({ title, body: element('p', {}, message), primaryLabel: confirmLabel, primaryVariant: danger ? 'danger' : 'primary', onPrimary: async () => { await onConfirm(); return true } })
4439
- }
4440
-
4441
- function openSheet(options) {
4442
- return openModal({ ...options, presentation: 'sheet' })
4443
- }
4444
-
4445
- function openModal({ title, description = '', body, primaryLabel, primaryVariant = 'primary', onPrimary, cancelLabel = '取消', presentation = 'modal', className = '', onClose }) {
4446
- const previouslyFocused = document.activeElement
4447
- const isSheet = presentation === 'sheet'
4448
- const backdrop = element('div', { class: `dialog-backdrop${isSheet ? ' sheet-backdrop' : ''}` })
4449
- const dialog = element('section', { class: `dialog${isSheet ? ' sheet' : ''} ${primaryLabel ? '' : 'narrow'} ${className}`.trim(), role: 'dialog', 'aria-modal': 'true', 'aria-labelledby': 'dialog-title' })
4450
- let busy = false
4451
- let formDirty = false
4452
- let closed = false
4453
- const close = (explicit = false) => {
4454
- if (busy || closed) return
4455
- if (!explicit && formDirty) {
4456
- showToast('表单有未保存的修改,请先保存,或使用“取消”放弃修改。', 'error')
4457
- return
4458
- }
4459
- document.removeEventListener('keydown', onKeyDown)
4460
- closed = true
4461
- backdrop.remove()
4462
- onClose?.()
4463
- if (previouslyFocused instanceof HTMLElement) previouslyFocused.focus()
4464
- }
4465
- const closeButton = actionButton('×', () => close(), 'ghost', { 'aria-label': '关闭对话框' })
4466
- const cancel = actionButton(cancelLabel, () => close(true))
4467
- const primary = primaryLabel ? actionButton(primaryLabel, async () => {
4468
- if (busy) return
4469
- busy = true
4470
- primary.disabled = true
4471
- cancel.disabled = true
4472
- const original = primary.textContent
4473
- primary.textContent = '正在处理…'
4474
- try {
4475
- const shouldClose = await onPrimary()
4476
- busy = false
4477
- if (shouldClose !== false) close(true)
4478
- else { primary.disabled = false; cancel.disabled = false; primary.textContent = original }
4479
- } catch (error) {
4480
- busy = false
4481
- primary.disabled = false
4482
- cancel.disabled = false
4483
- primary.textContent = original
4484
- showToast(friendlyError(error), 'error')
4485
- }
4486
- }, primaryVariant) : null
4487
- const onKeyDown = (event) => {
4488
- if (event.key === 'Escape') { event.preventDefault(); close() }
4489
- if (event.key === 'Tab') trapFocus(event, dialog)
4490
- }
4491
- dialog.append(
4492
- element('header', { class: 'dialog-header' }, element('div', {}, element('h2', { id: 'dialog-title' }, title), description ? element('p', {}, description) : null), closeButton),
4493
- element('div', { class: 'dialog-body' }, body),
4494
- element('footer', { class: 'dialog-footer' }, cancel, primary),
4495
- )
4496
- backdrop.append(dialog)
4497
- backdrop.addEventListener('mousedown', (event) => { if (event.target === backdrop) close() })
4498
- if (body.matches?.('form') || body.querySelector?.('form')) {
4499
- body.addEventListener('input', () => { formDirty = true })
4500
- body.addEventListener('change', () => { formDirty = true })
4501
- }
4502
- document.body.append(backdrop)
4503
- document.addEventListener('keydown', onKeyDown)
4504
- window.setTimeout(() => (dialog.querySelector('input, textarea, select, button') || dialog).focus(), 0)
4505
- return { close, dialog }
4506
- }
4507
-
4508
- function trapFocus(event, container) {
4509
- const focusable = [...container.querySelectorAll('button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex="-1"])')]
4510
- if (!focusable.length) return
4511
- const first = focusable[0]
4512
- const last = focusable.at(-1)
4513
- if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus() }
4514
- else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus() }
4515
- }
4516
-
4517
4419
  function formatDate(value) {
4518
4420
  try { return new Intl.DateTimeFormat('zh-CN', { dateStyle: 'medium', timeStyle: 'short' }).format(new Date(value)) } catch { return value }
4519
4421
  }
@@ -0,0 +1 @@
1
+ :root{--font-ui:ui-sans-serif, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", "PingFang SC", "Noto Sans CJK SC", "Microsoft YaHei UI", Arial, sans-serif;--font-reading:var(--font-ui);--font-mono:"SFMono-Regular", "Cascadia Code", Menlo, Consolas, monospace;--bg:#ebebeb;--surface:#f4f4f4;--surface-raised:#fafafa;--surface-soft:#eeeeef;--surface-hover:rgb(118 118 128 / 9%);--dialog-surface:#f4f4f4;--menu-surface:rgb(232 234 236 / 98%);--menu-surface-solid:#e8eaec;--document-surface:rgb(218 222 226 / 32%);--selection-background:#b8c8d6;--selection-text:#17212b;--activity-surface:rgba(255, 255, 255, 0.14);--text:#1d1d1f;--text-secondary:#515154;--text-tertiary:#6e6e73;--border:rgb(60 60 67 / 14%);--border-strong:rgb(60 60 67 / 24%);--accent:#3a3a3c;--accent-hover:#1d1d1f;--accent-soft:#e2e2e5;--on-accent:#ffffff;--success:#248a3d;--success-soft:#e8f5eb;--warning:#c93400;--warning-soft:#fff1e8;--danger:#d70015;--danger-soft:#ffebed;--shadow:0 24px 64px rgb(0 0 0 / 20%);--knowledge-embedded-surface:rgba(255, 255, 255, 0.08);--knowledge-embedded-filter:saturate(.65) contrast(1.015) blur(24px);--knowledge-embedded-control:rgba(255, 255, 255, 0.27);}@media(prefers-color-scheme:dark){:root:not([data-color-scheme]){--bg:#101719;--surface:#182022;--surface-raised:#20292b;--surface-soft:rgb(184 204 205 / 6%);--surface-hover:rgb(105 182 186 / 9%);--dialog-surface:#20292b;--menu-surface:rgb(29 38 40 / 98%);--menu-surface-solid:#1d2628;--document-surface:rgb(130 138 146 / 6%);--selection-background:#455b68;--selection-text:#ffffff;--activity-surface:rgb(29 36 38 / 24%);--text:#e3eaeb;--text-secondary:#bbc9cc;--text-tertiary:#95a7ab;--border:rgb(184 204 205 / 10%);--border-strong:rgb(184 204 205 / 18%);--accent:#69b6ba;--accent-hover:#8aced0;--accent-soft:rgb(105 182 186 / 13%);--on-accent:#101819;--success:#30d158;--success-soft:rgb(48 209 88 / 13%);--warning:#ff9f0a;--warning-soft:rgb(255 159 10 / 13%);--danger:#ff453a;--danger-soft:rgb(255 69 58 / 14%);--shadow:0 28px 72px rgb(0 0 0 / 42%);--knowledge-embedded-surface:rgb(16 23 25 / 18%);--knowledge-embedded-filter:saturate(.55) contrast(1.02) blur(24px);--knowledge-embedded-control:rgb(39 50 53 / 72%);}}:root[data-color-scheme="dark"]{--bg:#101719;--surface:#182022;--surface-raised:#20292b;--surface-soft:rgb(184 204 205 / 6%);--surface-hover:rgb(105 182 186 / 9%);--dialog-surface:#20292b;--menu-surface:rgb(29 38 40 / 98%);--menu-surface-solid:#1d2628;--document-surface:rgb(130 138 146 / 6%);--selection-background:#455b68;--selection-text:#ffffff;--activity-surface:rgb(29 36 38 / 24%);--text:#e3eaeb;--text-secondary:#bbc9cc;--text-tertiary:#95a7ab;--border:rgb(184 204 205 / 10%);--border-strong:rgb(184 204 205 / 18%);--accent:#69b6ba;--accent-hover:#8aced0;--accent-soft:rgb(105 182 186 / 13%);--on-accent:#101819;--success:#30d158;--success-soft:rgb(48 209 88 / 13%);--warning:#ff9f0a;--warning-soft:rgb(255 159 10 / 13%);--danger:#ff453a;--danger-soft:rgb(255 69 58 / 14%);--shadow:0 28px 72px rgb(0 0 0 / 42%);--knowledge-embedded-surface:rgb(16 23 25 / 18%);--knowledge-embedded-filter:saturate(.55) contrast(1.02) blur(24px);--knowledge-embedded-control:rgb(39 50 53 / 72%);}
package/web/dialogs.js ADDED
@@ -0,0 +1,94 @@
1
+ /** Shared modal lifecycle, keyboard handling and dirty-form protection. */
2
+ export function createDialogPresenter({ element, actionButton, interfaceIcon, showToast, friendlyError }) {
3
+ let sequence = 0
4
+ const stack = []
5
+ function openConfirm({ title, message, confirmLabel, danger, onConfirm }) {
6
+ return openModal({ title, body: element('p', {}, message), primaryLabel: confirmLabel, primaryVariant: danger ? 'danger' : 'primary', onPrimary: async () => { await onConfirm(); return true } })
7
+ }
8
+
9
+ function openSheet(options) {
10
+ return openModal({ ...options, presentation: 'sheet' })
11
+ }
12
+
13
+ function openModal({ title, description = '', body, primaryLabel, primaryVariant = 'primary', onPrimary, cancelLabel = '取消', presentation = 'modal', className = '', onClose }) {
14
+ const previouslyFocused = document.activeElement
15
+ const isSheet = presentation === 'sheet'
16
+ const titleId = `knowledge-dialog-title-${++sequence}`
17
+ const backdrop = element('div', { class: `dialog-backdrop${isSheet ? ' sheet-backdrop' : ''}` })
18
+ const dialog = element('section', { class: `dialog${isSheet ? ' sheet' : ''} ${primaryLabel ? '' : 'narrow'} ${className}`.trim(), role: 'dialog', 'aria-modal': 'true', 'aria-labelledby': titleId, tabindex: '-1' })
19
+ let busy = false
20
+ let formDirty = false
21
+ let closed = false
22
+ const close = (explicit = false) => {
23
+ if (busy || closed) return
24
+ if (!explicit && formDirty) {
25
+ showToast('表单有未保存的修改,请先保存,或使用“取消”放弃修改。', 'error')
26
+ return
27
+ }
28
+ document.removeEventListener('keydown', onKeyDown)
29
+ closed = true
30
+ stack.splice(stack.indexOf(dialog), 1)
31
+ backdrop.remove()
32
+ onClose?.()
33
+ if (previouslyFocused instanceof HTMLElement) previouslyFocused.focus()
34
+ }
35
+ const closeButton = actionButton(interfaceIcon('close'), () => close(), 'ghost', { 'aria-label': '关闭对话框' })
36
+ const cancel = actionButton(cancelLabel, () => close(true))
37
+ const primary = primaryLabel ? actionButton(primaryLabel, async () => {
38
+ if (busy) return
39
+ busy = true
40
+ primary.disabled = true
41
+ cancel.disabled = true
42
+ const original = primary.textContent
43
+ primary.textContent = '正在处理…'
44
+ try {
45
+ const shouldClose = await onPrimary()
46
+ busy = false
47
+ if (shouldClose !== false) close(true)
48
+ else { primary.disabled = false; cancel.disabled = false; primary.textContent = original }
49
+ } catch (error) {
50
+ busy = false
51
+ primary.disabled = false
52
+ cancel.disabled = false
53
+ primary.textContent = original
54
+ showToast(friendlyError(error), 'error')
55
+ }
56
+ }, primaryVariant) : null
57
+ const onKeyDown = (event) => {
58
+ if (stack.at(-1) !== dialog || event.defaultPrevented) return
59
+ if (event.key === 'Escape') { event.preventDefault(); close() }
60
+ if (event.key === 'Tab') trapFocus(event, dialog)
61
+ }
62
+ dialog.append(
63
+ element('header', { class: 'dialog-header' }, element('div', {}, element('h2', { id: titleId }, title), description ? element('p', {}, description) : null), closeButton),
64
+ element('div', { class: 'dialog-body' }, body),
65
+ element('footer', { class: 'dialog-footer' }, cancel, primary),
66
+ )
67
+ backdrop.append(dialog)
68
+ backdrop.addEventListener('mousedown', (event) => { if (event.target === backdrop) close() })
69
+ if (body.matches?.('form') || body.querySelector?.('form')) {
70
+ body.addEventListener('input', () => { formDirty = true })
71
+ body.addEventListener('change', () => { formDirty = true })
72
+ }
73
+ document.body.append(backdrop)
74
+ stack.push(dialog)
75
+ document.addEventListener('keydown', onKeyDown)
76
+ window.setTimeout(() => { if (!closed && stack.at(-1) === dialog) (focusableElements(dialog)[0] || dialog).focus() }, 0)
77
+ return { close, dialog }
78
+ }
79
+
80
+ function trapFocus(event, container) {
81
+ const focusable = focusableElements(container)
82
+ if (!focusable.length) return
83
+ const first = focusable[0]
84
+ const last = focusable.at(-1)
85
+ if (event.shiftKey && (document.activeElement === first || !container.contains(document.activeElement))) { event.preventDefault(); last.focus() }
86
+ else if (!event.shiftKey && (document.activeElement === last || !container.contains(document.activeElement))) { event.preventDefault(); first.focus() }
87
+ }
88
+
89
+ function focusableElements(container) {
90
+ return [...container.querySelectorAll('button, input, select, textarea, a[href], [tabindex]')]
91
+ .filter(node => !node.disabled && node.tabIndex >= 0 && !node.closest('[hidden], [inert], [aria-hidden="true"]') && node.getClientRects().length > 0)
92
+ }
93
+ return { openConfirm, openSheet, openModal }
94
+ }