@hgdc/docs 0.0.0-stage → 0.1.0
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/bin/hgdc-docs.mjs +48 -0
- package/docs.schema.json +294 -0
- package/package.json +50 -4
- package/src/build/auto-import.ts +74 -0
- package/src/build/markdown.ts +114 -0
- package/src/build/outputs.ts +91 -0
- package/src/build/public-files.test.ts +29 -0
- package/src/build/public-files.ts +35 -0
- package/src/components/Accordion.astro +12 -0
- package/src/components/AccordionGroup.astro +4 -0
- package/src/components/Card.astro +15 -0
- package/src/components/CardGroup.astro +8 -0
- package/src/components/Check.astro +10 -0
- package/src/components/CodeGroup.astro +4 -0
- package/src/components/Columns.astro +8 -0
- package/src/components/Danger.astro +10 -0
- package/src/components/Frame.astro +11 -0
- package/src/components/Info.astro +10 -0
- package/src/components/Note.astro +10 -0
- package/src/components/Step.astro +11 -0
- package/src/components/Steps.astro +4 -0
- package/src/components/Tab.astro +9 -0
- package/src/components/Tabs.astro +9 -0
- package/src/components/Tip.astro +10 -0
- package/src/components/Warning.astro +10 -0
- package/src/core/answer-markdown.ts +109 -0
- package/src/core/assistant-api.ts +65 -0
- package/src/core/chunk.ts +134 -0
- package/src/core/config.ts +153 -0
- package/src/core/core.test.ts +253 -0
- package/src/core/corpus.ts +42 -0
- package/src/core/json-schema.ts +12 -0
- package/src/core/llms.ts +95 -0
- package/src/core/navigation.ts +88 -0
- package/src/core/theme.ts +111 -0
- package/src/integration.ts +229 -0
- package/src/locals.d.ts +6 -0
- package/src/overrides/Assistant.astro +72 -0
- package/src/overrides/Head.astro +12 -0
- package/src/overrides/PageFrame.astro +15 -0
- package/src/overrides/PageTitle.astro +94 -0
- package/src/overrides/Sidebar.astro +60 -0
- package/src/overrides/route-data.ts +33 -0
- package/src/styles/theme.css +773 -0
- package/src/virtual.d.ts +6 -0
- package/src/widget/client.ts +252 -0
- package/template/.astro/collections/docs.schema.json +651 -0
- package/template/.astro/content-assets.mjs +1 -0
- package/template/.astro/content-modules.mjs +18 -0
- package/template/.astro/content.d.ts +179 -0
- package/template/.astro/types.d.ts +2 -0
- package/template/.build/.well-known/llms.txt +38 -0
- package/template/.build/404.html +42 -0
- package/template/.build/_astro/Assistant.astro_astro_type_script_index_0_lang.DWgmlr85.js +4 -0
- package/template/.build/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C3fM4Kra.js +1 -0
- package/template/.build/_astro/Search.astro_astro_type_script_index_0_lang.g9hoxVJg.js +1 -0
- package/template/.build/_astro/TableOfContents.astro_astro_type_script_index_0_lang.BpJaGz7G.js +1 -0
- package/template/.build/_astro/common.8GHCkW7i.css +3 -0
- package/template/.build/_astro/ec.0vx5m.js +3 -0
- package/template/.build/_astro/ec.8nqtp.css +1 -0
- package/template/.build/_astro/geist-cyrillic-ext-wght-normal.DjL33-gN.woff2 +0 -0
- package/template/.build/_astro/geist-cyrillic-wght-normal.BEAKL7Jp.woff2 +0 -0
- package/template/.build/_astro/geist-latin-ext-wght-normal.DC-KSUi6.woff2 +0 -0
- package/template/.build/_astro/geist-latin-wght-normal.BgDaEnEv.woff2 +0 -0
- package/template/.build/_astro/geist-vietnamese-wght-normal.6IgcOCM7.woff2 +0 -0
- package/template/.build/_astro/inter-cyrillic-ext-wght-normal.BOeWTOD4.woff2 +0 -0
- package/template/.build/_astro/inter-cyrillic-wght-normal.DqGufNeO.woff2 +0 -0
- package/template/.build/_astro/inter-greek-ext-wght-normal.DlzME5K_.woff2 +0 -0
- package/template/.build/_astro/inter-greek-wght-normal.CkhJZR-_.woff2 +0 -0
- package/template/.build/_astro/inter-latin-ext-wght-normal.DO1Apj_S.woff2 +0 -0
- package/template/.build/_astro/inter-latin-wght-normal.Dx4kXJAl.woff2 +0 -0
- package/template/.build/_astro/inter-vietnamese-wght-normal.CBcvBZtf.woff2 +0 -0
- package/template/.build/_astro/logo-clair.BqNh6JNi.svg +1 -0
- package/template/.build/_astro/logo-sombre.BkgsFXxh.svg +1 -0
- package/template/.build/_astro/page.cNngjUgL.js +1 -0
- package/template/.build/_astro/print.ehPL0gv-.css +1 -0
- package/template/.build/_astro/starlight-toc.D4UDIxQL.js +1 -0
- package/template/.build/_astro/ui-core.Clh5jUUO.js +2 -0
- package/template/.build/_hgdc/corpus.json +1 -0
- package/template/.build/demarrer/premiere-doc/index.html +84 -0
- package/template/.build/demarrer/premiere-doc.md +65 -0
- package/template/.build/explications/donnees/index.html +114 -0
- package/template/.build/explications/donnees.md +28 -0
- package/template/.build/explications/fonctionnement/index.html +92 -0
- package/template/.build/explications/fonctionnement.md +32 -0
- package/template/.build/guides/agents/index.html +113 -0
- package/template/.build/guides/agents.md +40 -0
- package/template/.build/guides/assistant/index.html +117 -0
- package/template/.build/guides/assistant.md +42 -0
- package/template/.build/guides/composants/index.html +97 -0
- package/template/.build/guides/composants.md +103 -0
- package/template/.build/guides/ecrire/index.html +115 -0
- package/template/.build/guides/ecrire.md +63 -0
- package/template/.build/guides/navigation/index.html +89 -0
- package/template/.build/guides/navigation.md +63 -0
- package/template/.build/guides/publier/index.html +86 -0
- package/template/.build/guides/publier.md +65 -0
- package/template/.build/guides/theme/index.html +86 -0
- package/template/.build/guides/theme.md +33 -0
- package/template/.build/images/favicon.svg +1 -0
- package/template/.build/images/logo-clair.svg +1 -0
- package/template/.build/images/logo-sombre.svg +1 -0
- package/template/.build/index.html +87 -0
- package/template/.build/index.md +35 -0
- package/template/.build/llms-full.txt +830 -0
- package/template/.build/llms.txt +38 -0
- package/template/.build/pagefind/fragment/fr-ch_148313b.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_424fd16.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_4f8575c.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_5a4d77d.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_6c36edc.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_73d7887.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_8234ed3.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_8f8a19e.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_9f1b981.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_a19039d.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_d72cc1e.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_d732215.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_e2c46e3.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_e78d58b.pf_fragment +0 -0
- package/template/.build/pagefind/fragment/fr-ch_e92f972.pf_fragment +0 -0
- package/template/.build/pagefind/index/fr-ch_f94c95d.pf_index +0 -0
- package/template/.build/pagefind/pagefind-component-ui.css +1509 -0
- package/template/.build/pagefind/pagefind-component-ui.js +56 -0
- package/template/.build/pagefind/pagefind-entry.json +1 -0
- package/template/.build/pagefind/pagefind-highlight.js +1070 -0
- package/template/.build/pagefind/pagefind-modular-ui.css +214 -0
- package/template/.build/pagefind/pagefind-modular-ui.js +8 -0
- package/template/.build/pagefind/pagefind-ui.css +1 -0
- package/template/.build/pagefind/pagefind-ui.js +2 -0
- package/template/.build/pagefind/pagefind-worker.js +6 -0
- package/template/.build/pagefind/pagefind.fr-ch_fb78ab42961f4.pf_meta +0 -0
- package/template/.build/pagefind/pagefind.js +6 -0
- package/template/.build/pagefind/wasm.fr-ch.pagefind +0 -0
- package/template/.build/pagefind/wasm.unknown.pagefind +0 -0
- package/template/.build/reference/api-assistant/index.html +161 -0
- package/template/.build/reference/api-assistant.md +60 -0
- package/template/.build/reference/cli/index.html +153 -0
- package/template/.build/reference/cli.md +31 -0
- package/template/.build/reference/docs-json/index.html +192 -0
- package/template/.build/reference/docs-json.md +43 -0
- package/template/.build/reference/mcp/index.html +151 -0
- package/template/.build/reference/mcp.md +49 -0
- package/template/astro.config.ts +6 -0
- package/template/node_modules/.vite/deps/_metadata.json +74 -0
- package/template/node_modules/.vite/deps/astro-B3JHJyiv.js +434 -0
- package/template/node_modules/.vite/deps/astro-B3JHJyiv.js.map +1 -0
- package/template/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/template/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/template/node_modules/.vite/deps/astro_n_axobject-query.js +2705 -0
- package/template/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/template/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/template/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/template/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/template/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/template/node_modules/.vite/deps/audit-Do8QH17W.js +1543 -0
- package/template/node_modules/.vite/deps/audit-Do8QH17W.js.map +1 -0
- package/template/node_modules/.vite/deps/highlight-BLtvqtzO.js +48 -0
- package/template/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +1 -0
- package/template/node_modules/.vite/deps/icons-C92i61-2.js +42 -0
- package/template/node_modules/.vite/deps/icons-C92i61-2.js.map +1 -0
- package/template/node_modules/.vite/deps/package.json +3 -0
- package/template/node_modules/.vite/deps/rolldown-runtime-C3I60J0A.js +4 -0
- package/template/node_modules/.vite/deps/settings-BYmTKrLi.js +189 -0
- package/template/node_modules/.vite/deps/settings-BYmTKrLi.js.map +1 -0
- package/template/node_modules/.vite/deps/toolbar-CEKhukuK.js +461 -0
- package/template/node_modules/.vite/deps/toolbar-CEKhukuK.js.map +1 -0
- package/template/node_modules/.vite/deps/ui-library-BO4--ANp.js +1015 -0
- package/template/node_modules/.vite/deps/ui-library-BO4--ANp.js.map +1 -0
- package/template/node_modules/.vite/deps/window-vo3A6TMn.js +32 -0
- package/template/node_modules/.vite/deps/window-vo3A6TMn.js.map +1 -0
- package/template/node_modules/.vite/deps/xray-Lf9x6g8P.js +112 -0
- package/template/node_modules/.vite/deps/xray-Lf9x6g8P.js.map +1 -0
- package/template/src/content.config.ts +21 -0
- package/README.md +0 -3
package/src/virtual.d.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import type { AnswerSource, AskResponse } from "../core/assistant-api.ts"
|
|
2
|
+
import { parseMarkdown, type Block, type Inline } from "../core/answer-markdown.ts"
|
|
3
|
+
|
|
4
|
+
const FALLBACK_ERROR = "L'assistant ne répond pas pour l'instant. Réessaie dans un moment."
|
|
5
|
+
|
|
6
|
+
function isAnswer(value: unknown): value is AskResponse {
|
|
7
|
+
const v = value as Partial<AskResponse> | null
|
|
8
|
+
return Boolean(v && typeof v.answer === "string" && Array.isArray(v.sources) && typeof v.status === "string")
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function errorMessage(value: unknown): string | null {
|
|
12
|
+
const message = (value as { error?: { message?: unknown } } | null)?.error?.message
|
|
13
|
+
return typeof message === "string" ? message : null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function el<K extends keyof HTMLElementTagNameMap>(
|
|
17
|
+
tag: K,
|
|
18
|
+
className?: string,
|
|
19
|
+
text?: string,
|
|
20
|
+
): HTMLElementTagNameMap[K] {
|
|
21
|
+
const node = document.createElement(tag)
|
|
22
|
+
if (className) node.className = className
|
|
23
|
+
if (text !== undefined) node.textContent = text
|
|
24
|
+
return node
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function renderInline(parent: HTMLElement, nodes: Array<Inline>, sources: Map<number, AnswerSource>): void {
|
|
28
|
+
for (const node of nodes) {
|
|
29
|
+
switch (node.type) {
|
|
30
|
+
case "text":
|
|
31
|
+
parent.append(node.value)
|
|
32
|
+
break
|
|
33
|
+
case "code":
|
|
34
|
+
parent.append(el("code", undefined, node.value))
|
|
35
|
+
break
|
|
36
|
+
case "strong":
|
|
37
|
+
case "em": {
|
|
38
|
+
const child = el(node.type)
|
|
39
|
+
renderInline(child, node.children, sources)
|
|
40
|
+
parent.append(child)
|
|
41
|
+
break
|
|
42
|
+
}
|
|
43
|
+
case "link": {
|
|
44
|
+
const link = el("a")
|
|
45
|
+
link.href = node.href
|
|
46
|
+
link.rel = "noopener noreferrer"
|
|
47
|
+
renderInline(link, node.children, sources)
|
|
48
|
+
parent.append(link)
|
|
49
|
+
break
|
|
50
|
+
}
|
|
51
|
+
case "ref": {
|
|
52
|
+
const source = sources.get(node.n)
|
|
53
|
+
if (!source) break
|
|
54
|
+
const ref = el("a", "hgdc-ref", String(node.n))
|
|
55
|
+
ref.href = source.url
|
|
56
|
+
ref.title = source.section ? `${source.title} › ${source.section}` : source.title
|
|
57
|
+
ref.setAttribute("aria-label", `Source ${node.n} : ${ref.title}`)
|
|
58
|
+
parent.append(ref)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function renderBlocks(blocks: Array<Block>, sources: Map<number, AnswerSource>): DocumentFragment {
|
|
65
|
+
const fragment = document.createDocumentFragment()
|
|
66
|
+
for (const block of blocks) {
|
|
67
|
+
if (block.type === "code") {
|
|
68
|
+
const pre = el("pre")
|
|
69
|
+
pre.append(el("code", undefined, block.value))
|
|
70
|
+
fragment.append(pre)
|
|
71
|
+
} else if (block.type === "list") {
|
|
72
|
+
const list = el(block.ordered ? "ol" : "ul")
|
|
73
|
+
for (const item of block.items) {
|
|
74
|
+
const li = el("li")
|
|
75
|
+
renderInline(li, item, sources)
|
|
76
|
+
list.append(li)
|
|
77
|
+
}
|
|
78
|
+
fragment.append(list)
|
|
79
|
+
} else {
|
|
80
|
+
const node = el(block.type === "heading" ? "h3" : "p")
|
|
81
|
+
renderInline(node, block.children, sources)
|
|
82
|
+
fragment.append(node)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return fragment
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
class Assistant extends HTMLElement {
|
|
89
|
+
/** Identifiants des réponses précédentes : le serveur relit lui-même la conversation. */
|
|
90
|
+
private previous: Array<string> = []
|
|
91
|
+
private pending = false
|
|
92
|
+
private opener: HTMLElement | null = null
|
|
93
|
+
|
|
94
|
+
private get panel() {
|
|
95
|
+
return this.querySelector<HTMLElement>(".hgdc-panel")!
|
|
96
|
+
}
|
|
97
|
+
private get launcher() {
|
|
98
|
+
return this.querySelector<HTMLButtonElement>("[data-open]")!
|
|
99
|
+
}
|
|
100
|
+
private get input() {
|
|
101
|
+
return this.querySelector<HTMLTextAreaElement>("[data-input]")!
|
|
102
|
+
}
|
|
103
|
+
private get log() {
|
|
104
|
+
return this.querySelector<HTMLElement>("[data-log]")!
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
connectedCallback(): void {
|
|
108
|
+
const mac = /Mac|iPhone|iPad/.test(navigator.platform)
|
|
109
|
+
const shortcut = this.querySelector("[data-shortcut]")
|
|
110
|
+
if (shortcut) shortcut.textContent = mac ? "⌘ I" : "Ctrl I"
|
|
111
|
+
|
|
112
|
+
this.launcher.addEventListener("click", () => this.toggle(true, this.launcher))
|
|
113
|
+
this.querySelector("[data-close]")!.addEventListener("click", () => this.toggle(false))
|
|
114
|
+
this.querySelector("[data-reset]")!.addEventListener("click", () => this.reset())
|
|
115
|
+
this.querySelector("[data-form]")!.addEventListener("submit", (event) => {
|
|
116
|
+
event.preventDefault()
|
|
117
|
+
void this.ask()
|
|
118
|
+
})
|
|
119
|
+
this.input.addEventListener("keydown", (event) => {
|
|
120
|
+
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
|
|
121
|
+
event.preventDefault()
|
|
122
|
+
void this.ask()
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
this.input.addEventListener("input", () => this.autosize())
|
|
126
|
+
document.addEventListener("hgdc:assistant-open", () => this.toggle(true, document.activeElement as HTMLElement))
|
|
127
|
+
document.addEventListener("keydown", (event) => {
|
|
128
|
+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "i") {
|
|
129
|
+
event.preventDefault()
|
|
130
|
+
this.toggle(Boolean(this.panel.hidden), document.activeElement as HTMLElement)
|
|
131
|
+
} else if (event.key === "Escape" && !this.panel.hidden) this.toggle(false)
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private toggle(open: boolean, opener?: HTMLElement | null): void {
|
|
136
|
+
this.panel.hidden = !open
|
|
137
|
+
this.launcher.hidden = open
|
|
138
|
+
this.launcher.setAttribute("aria-expanded", String(open))
|
|
139
|
+
document.documentElement.toggleAttribute("data-hgdc-assistant", open)
|
|
140
|
+
// Plein écran sur téléphone : le panneau devient modal et le reste de la page inerte.
|
|
141
|
+
const fullscreen = open && matchMedia("(max-width: 50em)").matches
|
|
142
|
+
this.panel.setAttribute("aria-modal", String(fullscreen))
|
|
143
|
+
document.querySelector<HTMLElement>(".page")?.toggleAttribute("inert", fullscreen)
|
|
144
|
+
if (open) {
|
|
145
|
+
this.opener = opener ?? null
|
|
146
|
+
this.input.focus()
|
|
147
|
+
} else (this.opener ?? this.launcher).focus()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private autosize(): void {
|
|
151
|
+
this.input.style.height = "auto"
|
|
152
|
+
this.input.style.height = `${Math.min(this.input.scrollHeight, 160)}px`
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private reset(): void {
|
|
156
|
+
this.previous = []
|
|
157
|
+
this.log.replaceChildren(this.querySelector("[data-empty]") ?? "")
|
|
158
|
+
this.querySelector<HTMLElement>("[data-empty]")!.hidden = false
|
|
159
|
+
this.querySelector<HTMLElement>("[data-reset]")!.hidden = true
|
|
160
|
+
this.input.focus()
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private bubble(role: "user" | "assistant", className = ""): HTMLElement {
|
|
164
|
+
const node = el("div", `hgdc-msg hgdc-msg--${role} ${className}`.trim())
|
|
165
|
+
this.log.append(node)
|
|
166
|
+
node.scrollIntoView({
|
|
167
|
+
block: "end",
|
|
168
|
+
behavior: matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth",
|
|
169
|
+
})
|
|
170
|
+
return node
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private async ask(retry?: string): Promise<void> {
|
|
174
|
+
const question = (retry ?? this.input.value).trim()
|
|
175
|
+
if (this.pending || question.length < 2) return
|
|
176
|
+
this.pending = true
|
|
177
|
+
this.querySelector<HTMLElement>("[data-empty]")!.hidden = true
|
|
178
|
+
this.querySelector<HTMLElement>("[data-reset]")!.hidden = false
|
|
179
|
+
this.querySelector<HTMLButtonElement>("[data-send]")!.disabled = true
|
|
180
|
+
if (!retry) {
|
|
181
|
+
this.bubble("user").textContent = question
|
|
182
|
+
this.input.value = ""
|
|
183
|
+
this.autosize()
|
|
184
|
+
}
|
|
185
|
+
const thinking = this.bubble("assistant", "hgdc-msg--pending")
|
|
186
|
+
thinking.textContent = "Je cherche dans la documentation…"
|
|
187
|
+
thinking.setAttribute("aria-busy", "true")
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const response = await fetch(this.dataset.endpoint!, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: { "content-type": "application/json" },
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
project: this.dataset.project,
|
|
195
|
+
question,
|
|
196
|
+
page: location.pathname,
|
|
197
|
+
previous: this.previous.slice(-3),
|
|
198
|
+
}),
|
|
199
|
+
})
|
|
200
|
+
const body: unknown = await response.json().catch(() => null)
|
|
201
|
+
if (!response.ok || !isAnswer(body)) throw new Error(errorMessage(body) ?? FALLBACK_ERROR)
|
|
202
|
+
thinking.remove()
|
|
203
|
+
this.showAnswer(body)
|
|
204
|
+
if (body.status === "answered") this.previous.push(body.id)
|
|
205
|
+
} catch (error) {
|
|
206
|
+
thinking.remove()
|
|
207
|
+
this.showError(
|
|
208
|
+
error instanceof Error && error.message !== "Failed to fetch" ? error.message : FALLBACK_ERROR,
|
|
209
|
+
question,
|
|
210
|
+
)
|
|
211
|
+
} finally {
|
|
212
|
+
this.pending = false
|
|
213
|
+
this.querySelector<HTMLButtonElement>("[data-send]")!.disabled = false
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private showAnswer(answer: AskResponse): void {
|
|
218
|
+
const node = this.bubble("assistant", answer.status === "no_answer" ? "hgdc-msg--empty" : "")
|
|
219
|
+
const sources = new Map(answer.sources.map((source) => [source.n, source]))
|
|
220
|
+
node.append(renderBlocks(parseMarkdown(answer.answer, [location.origin]), sources))
|
|
221
|
+
if (answer.sources.length) {
|
|
222
|
+
const list = el("ol", "hgdc-sources")
|
|
223
|
+
list.setAttribute("aria-label", "Sources")
|
|
224
|
+
for (const source of answer.sources) {
|
|
225
|
+
const item = el("li")
|
|
226
|
+
const link = el("a")
|
|
227
|
+
link.href = source.url
|
|
228
|
+
link.append(el("span", "hgdc-sources__n", String(source.n)), el("span", undefined, source.title))
|
|
229
|
+
if (source.section) link.append(el("span", "hgdc-sources__section", source.section))
|
|
230
|
+
item.append(link)
|
|
231
|
+
list.append(item)
|
|
232
|
+
}
|
|
233
|
+
node.append(el("p", "hgdc-sources__label", "Sources"), list)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private showError(message: string, question: string): void {
|
|
238
|
+
const node = this.bubble("assistant", "hgdc-msg--error")
|
|
239
|
+
node.append(el("p", undefined, message))
|
|
240
|
+
const retry = el("button", "hgdc-retry", "Réessayer")
|
|
241
|
+
retry.type = "button"
|
|
242
|
+
retry.addEventListener("click", () => {
|
|
243
|
+
node.remove()
|
|
244
|
+
void this.ask(question)
|
|
245
|
+
})
|
|
246
|
+
node.append(retry)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function defineAssistant(): void {
|
|
251
|
+
if (!customElements.get("hgdc-assistant")) customElements.define("hgdc-assistant", Assistant)
|
|
252
|
+
}
|