@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.
- package/README.md +1 -1
- package/docs/ui-maintenance.md +97 -0
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +356 -205
- package/lib/client.js.map +4 -4
- package/lib/design-tokens.d.ts +12 -0
- package/lib/design-tokens.d.ts.map +1 -0
- package/lib/design-tokens.js +58 -0
- package/lib/design-tokens.js.map +1 -0
- package/lib/knowledge-activity-controller.d.ts +3 -8
- package/lib/knowledge-activity-controller.d.ts.map +1 -1
- package/lib/knowledge-activity-controller.js +19 -7
- package/lib/knowledge-activity-controller.js.map +1 -1
- package/lib/knowledge-activity-notes.d.ts.map +1 -1
- package/lib/knowledge-activity-notes.js +19 -10
- package/lib/knowledge-activity-notes.js.map +1 -1
- package/lib/knowledge-activity-panel.d.ts.map +1 -1
- package/lib/knowledge-activity-panel.js +32 -20
- package/lib/knowledge-activity-panel.js.map +1 -1
- package/lib/knowledge-activity-presentation.d.ts +14 -0
- package/lib/knowledge-activity-presentation.d.ts.map +1 -0
- package/lib/knowledge-activity-presentation.js +77 -0
- package/lib/knowledge-activity-presentation.js.map +1 -0
- package/lib/knowledge-activity-state.d.ts +17 -0
- package/lib/knowledge-activity-state.d.ts.map +1 -0
- package/lib/knowledge-activity-state.js +14 -0
- package/lib/knowledge-activity-state.js.map +1 -0
- package/lib/latest-request.d.ts +7 -0
- package/lib/latest-request.d.ts.map +1 -0
- package/lib/latest-request.js +14 -0
- package/lib/latest-request.js.map +1 -0
- package/lib/local-provider.d.ts +0 -2
- package/lib/local-provider.d.ts.map +1 -1
- package/lib/local-provider.js +2 -323
- package/lib/local-provider.js.map +1 -1
- package/lib/notes/share-page-styles.d.ts +2 -0
- package/lib/notes/share-page-styles.d.ts.map +1 -0
- package/lib/notes/share-page-styles.js +11 -0
- package/lib/notes/share-page-styles.js.map +1 -0
- package/lib/notes/share-page.d.ts.map +1 -1
- package/lib/notes/share-page.js +1 -8
- package/lib/notes/share-page.js.map +1 -1
- package/lib/storage/migrations.d.ts +5 -0
- package/lib/storage/migrations.d.ts.map +1 -0
- package/lib/storage/migrations.js +325 -0
- package/lib/storage/migrations.js.map +1 -0
- package/lib/theme-bridge.d.ts +9 -7
- package/lib/theme-bridge.d.ts.map +1 -1
- package/lib/theme-bridge.js +3 -23
- package/lib/theme-bridge.js.map +1 -1
- package/lib/web-note-editor-selection.d.ts.map +1 -1
- package/lib/web-note-editor-selection.js +50 -15
- package/lib/web-note-editor-selection.js.map +1 -1
- package/lib/web-note-editor.d.ts.map +1 -1
- package/lib/web-note-editor.js +15 -1
- package/lib/web-note-editor.js.map +1 -1
- package/lib/web.d.ts.map +1 -1
- package/lib/web.js +4 -0
- package/lib/web.js.map +1 -1
- package/package.json +1 -1
- package/web/app.js +78 -176
- package/web/design-tokens.css +1 -0
- package/web/dialogs.js +94 -0
- package/web/document-actions.js +68 -0
- package/web/index.html +1 -0
- package/web/model-catalog.js +22 -0
- package/web/note-editor.js +57 -57
- package/web/select-control.js +193 -0
- package/web/styles.css +93 -185
- package/web/ui-primitives.js +5 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Shared document overflow: one action list and keyboard model for every width. */
|
|
2
|
+
export function createDocumentMenuPresenter({ element, actionButton, interfaceIcon }) {
|
|
3
|
+
const openMenus = new Set()
|
|
4
|
+
const closeMenus = () => { for (const close of [...openMenus]) close() }
|
|
5
|
+
function renderMenu(label, groups) {
|
|
6
|
+
const actions = groups.filter(group => group.length)
|
|
7
|
+
if (!actions.length) return null
|
|
8
|
+
let events
|
|
9
|
+
const details = element('details', { class: 'notes-document-more' })
|
|
10
|
+
const summary = element('summary', {
|
|
11
|
+
class: 'button ghost small', title: '更多操作', 'aria-label': `${label}的更多操作`,
|
|
12
|
+
'aria-haspopup': 'menu', 'aria-expanded': 'false',
|
|
13
|
+
onClick: event => { event.preventDefault(); setOpen(!details.open) },
|
|
14
|
+
}, interfaceIcon('more', 'notes-document-more-icon'))
|
|
15
|
+
const close = (restoreFocus = false) => {
|
|
16
|
+
details.open = false
|
|
17
|
+
summary.setAttribute('aria-expanded', 'false')
|
|
18
|
+
events?.abort()
|
|
19
|
+
events = undefined
|
|
20
|
+
openMenus.delete(close)
|
|
21
|
+
if (restoreFocus && summary.isConnected) summary.focus()
|
|
22
|
+
}
|
|
23
|
+
const menu = element('div', { class: 'notes-document-more-menu', role: 'menu', 'aria-label': `${label}的更多操作` },
|
|
24
|
+
actions.flatMap((group, index) => [
|
|
25
|
+
index ? element('div', { class: 'notes-document-menu-divider', role: 'separator' }) : null,
|
|
26
|
+
...group.map(action => actionButton([
|
|
27
|
+
interfaceIcon(action.icon, 'notes-document-menu-icon'),
|
|
28
|
+
element('span', { class: 'notes-document-menu-label' }, action.label),
|
|
29
|
+
], event => { close(true); action.run(event) }, `ghost small notes-document-menu-item${action.danger ? ' is-danger' : ''}`, {
|
|
30
|
+
role: 'menuitem', tabindex: '-1', ...action.attributes,
|
|
31
|
+
})),
|
|
32
|
+
]),
|
|
33
|
+
)
|
|
34
|
+
const items = () => [...menu.querySelectorAll('[role="menuitem"]:not(:disabled)')]
|
|
35
|
+
const setOpen = (open, last = false) => {
|
|
36
|
+
if (!open) return close(true)
|
|
37
|
+
closeMenus()
|
|
38
|
+
details.open = true
|
|
39
|
+
summary.setAttribute('aria-expanded', 'true')
|
|
40
|
+
openMenus.add(close)
|
|
41
|
+
const bounds = summary.getBoundingClientRect()
|
|
42
|
+
menu.style.maxHeight = `${Math.max(100, window.innerHeight - bounds.bottom - 16)}px`
|
|
43
|
+
events = new AbortController()
|
|
44
|
+
const { signal } = events
|
|
45
|
+
document.addEventListener('pointerdown', event => { if (!details.contains(event.target)) close() }, { signal })
|
|
46
|
+
window.addEventListener('resize', () => close(), { signal, once: true })
|
|
47
|
+
const choices = items()
|
|
48
|
+
choices[last ? choices.length - 1 : 0]?.focus()
|
|
49
|
+
}
|
|
50
|
+
details.addEventListener('keydown', event => {
|
|
51
|
+
if (event.key === 'Escape' && details.open) { event.preventDefault(); event.stopPropagation(); close(true); return }
|
|
52
|
+
if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return
|
|
53
|
+
event.preventDefault()
|
|
54
|
+
if (!details.open) return setOpen(true, event.key === 'ArrowUp' || event.key === 'End')
|
|
55
|
+
const choices = items()
|
|
56
|
+
const index = choices.indexOf(document.activeElement)
|
|
57
|
+
const next = event.key === 'Home' ? 0 : event.key === 'End' ? choices.length - 1
|
|
58
|
+
: (index + (event.key === 'ArrowDown' ? 1 : -1) + choices.length) % choices.length
|
|
59
|
+
choices[next]?.focus()
|
|
60
|
+
})
|
|
61
|
+
details.addEventListener('focusout', event => {
|
|
62
|
+
if (event.relatedTarget && !details.contains(event.relatedTarget)) close()
|
|
63
|
+
})
|
|
64
|
+
details.append(summary, menu)
|
|
65
|
+
return details
|
|
66
|
+
}
|
|
67
|
+
return { renderMenu, closeMenus }
|
|
68
|
+
}
|
package/web/index.html
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<meta name="dsh-knowledge-web" content="__DSH_KNOWLEDGE_WEB_PATH__">
|
|
11
11
|
<meta name="dsh-knowledge-asset-version" content="__DSH_KNOWLEDGE_ASSET_VERSION__">
|
|
12
12
|
<title>DSH 知识库</title>
|
|
13
|
+
<link rel="stylesheet" href="__DSH_KNOWLEDGE_WEB_PATH__/design-tokens.css?v=__DSH_KNOWLEDGE_ASSET_VERSION__">
|
|
13
14
|
<link rel="stylesheet" href="__DSH_KNOWLEDGE_WEB_PATH__/styles.css?v=__DSH_KNOWLEDGE_ASSET_VERSION__">
|
|
14
15
|
<script src="__DSH_KNOWLEDGE_WEB_PATH__/markdown-preview.js?v=__DSH_KNOWLEDGE_ASSET_VERSION__"></script>
|
|
15
16
|
<script src="__DSH_KNOWLEDGE_WEB_PATH__/change-review.js?v=__DSH_KNOWLEDGE_ASSET_VERSION__"></script>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Cache successful model discovery; share in-flight reads and allow retry after failure. */
|
|
2
|
+
export function createModelCatalogLoader(request = fetch, ttlMs = 60000) {
|
|
3
|
+
let cached
|
|
4
|
+
let expires = 0
|
|
5
|
+
let pending
|
|
6
|
+
return function load() {
|
|
7
|
+
if (cached !== undefined && Date.now() < expires) return Promise.resolve(cached)
|
|
8
|
+
if (pending) return pending
|
|
9
|
+
pending = (async () => {
|
|
10
|
+
const response = await request('/knowledge-control/v1/models', {
|
|
11
|
+
headers: { accept: 'application/json', 'x-dsh-knowledge-client': 'management-web' },
|
|
12
|
+
})
|
|
13
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
|
14
|
+
const payload = await response.json()
|
|
15
|
+
if (!Array.isArray(payload.providers)) throw new Error('模型目录返回了无效数据')
|
|
16
|
+
cached = payload.providers
|
|
17
|
+
expires = Date.now() + ttlMs
|
|
18
|
+
return cached
|
|
19
|
+
})().finally(() => { pending = undefined })
|
|
20
|
+
return pending
|
|
21
|
+
}
|
|
22
|
+
}
|