@anchrd/intel-ui 0.37.0 → 0.38.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/src/kind-icon.ts CHANGED
@@ -1,4 +1,13 @@
1
- import { FileText, Folder, type LucideIcon, Paperclip, Table, Workflow } from "lucide-react";
1
+ import {
2
+ CircleCheck,
3
+ FileText,
4
+ Folder,
5
+ KanbanSquare,
6
+ type LucideIcon,
7
+ Paperclip,
8
+ Table,
9
+ Workflow,
10
+ } from "lucide-react";
2
11
  import type { TreeEntry } from "@/data/intel-data-provider/intel-data-provider.types.ts";
3
12
 
4
13
  /**
@@ -16,4 +25,11 @@ export const kindIcons: Record<TreeEntry["kind"], LucideIcon> = {
16
25
  attachment: Paperclip,
17
26
  table: Table,
18
27
  flow: Workflow,
28
+ // ⚠️ A board draws as a board, never as a folder, although it behaves like one in the tree. The
29
+ // icon is the ONLY thing that tells a reader the row will not open (D66, #376) — the chevron is
30
+ // absent, and an absent chevron looks exactly like an empty folder.
31
+ board: KanbanSquare,
32
+ // A task has an icon although the tree never draws one: the folder table, search results and the
33
+ // relation graph all reach a task by its own address, and each of them asks this map.
34
+ task: CircleCheck,
19
35
  };
@@ -14,13 +14,14 @@ import { ActionSlot } from "@/app/action-slot/action-slot.tsx";
14
14
  import { BlockNoteView, defaultSlashMenuItems } from "@/blocknote-view/blocknote-view.tsx";
15
15
  import { IntelRequestError } from "@/data/intel-data-provider/intel-data-provider.ts";
16
16
  import type { IntelDataProvider } from "@/data/intel-data-provider/intel-data-provider.types.ts";
17
+ import { DocumentLinkProvider, documentLinkIds } from "@/document-link/document-link.tsx";
17
18
  import {
18
- DocumentLinkProvider,
19
- documentLinkIds,
20
19
  type IntelEditor,
21
20
  type IntelEditorPartialBlock,
22
21
  intelEditorSchema,
23
- } from "@/document-link/document-link.tsx";
22
+ } from "@/editor-schema/editor-schema.ts";
23
+ import { FrontmatterProvider } from "@/frontmatter/frontmatter.tsx";
24
+ import { blocksToMarkdown, markdownToBlocks } from "@/frontmatter/frontmatter-markdown.ts";
24
25
  import type { I18n } from "@/i18n/i18n.types.ts";
25
26
  import { Modal } from "@/modal/modal.tsx";
26
27
  import { SaveButton, UnsavedChangesGuard } from "@/save-button/save-button.tsx";
@@ -135,7 +136,7 @@ export function NodeEditor({
135
136
  format: "blocknote",
136
137
  schemaVersion: 1,
137
138
  blocks,
138
- markdown: await editor.blocksToMarkdownLossy(blocks),
139
+ markdown: await blocksToMarkdown(editor, blocks),
139
140
  });
140
141
  const node = await data.saveNode({
141
142
  nodeId: document.node.id,
@@ -163,7 +164,7 @@ export function NodeEditor({
163
164
 
164
165
  useEffect(() => {
165
166
  if (!document.content || initialBlocks) return;
166
- const blocks = editor.tryParseMarkdownToBlocks(document.content);
167
+ const blocks = markdownToBlocks(editor, document.content);
167
168
  editor.replaceBlocks(editor.document, blocks);
168
169
  // ⚠️ Loading the content IS a change to the editor, and `onChange` reports it as one. This is
169
170
  // the line that keeps a document nobody has touched from asking to be saved: what was just
@@ -207,33 +208,40 @@ export function NodeEditor({
207
208
  unresolvedLabel: i18n.t("node.link.unresolved"),
208
209
  }}
209
210
  >
210
- <BlockNoteView
211
- editor={editor}
212
- onChange={() => {
213
- settle();
214
- setLinkedIds(documentLinkIds(editor.document));
211
+ <FrontmatterProvider
212
+ value={{
213
+ summary: i18n.t("node.frontmatter.summary"),
214
+ expand: i18n.t("node.frontmatter.toggle"),
215
215
  }}
216
216
  >
217
- {/* The `/` line BlockNote already has, with one item added. A second way to reach the
217
+ <BlockNoteView
218
+ editor={editor}
219
+ onChange={() => {
220
+ settle();
221
+ setLinkedIds(documentLinkIds(editor.document));
222
+ }}
223
+ >
224
+ {/* The `/` line BlockNote already has, with one item added. A second way to reach the
218
225
  same thing would be the second way #41 exists to remove. */}
219
- <SuggestionMenuController
220
- triggerCharacter="/"
221
- getItems={async (query) =>
222
- filterSuggestionItems(
223
- [
224
- ...defaultSlashMenuItems(editor),
225
- {
226
- title: i18n.t("node.link.insert"),
227
- group: i18n.t("node.link.group"),
228
- icon: <Link2 aria-hidden="true" className="size-4" />,
229
- onItemClick: () => setPicking(true),
230
- },
231
- ],
232
- query,
233
- )
234
- }
235
- />
236
- </BlockNoteView>
226
+ <SuggestionMenuController
227
+ triggerCharacter="/"
228
+ getItems={async (query) =>
229
+ filterSuggestionItems(
230
+ [
231
+ ...defaultSlashMenuItems(editor),
232
+ {
233
+ title: i18n.t("node.link.insert"),
234
+ group: i18n.t("node.link.group"),
235
+ icon: <Link2 aria-hidden="true" className="size-4" />,
236
+ onItemClick: () => setPicking(true),
237
+ },
238
+ ],
239
+ query,
240
+ )
241
+ }
242
+ />
243
+ </BlockNoteView>
244
+ </FrontmatterProvider>
237
245
  </DocumentLinkProvider>
238
246
  </TitleRowScrollArea>
239
247
  {picking ? (
@@ -5,6 +5,7 @@ import { Download, Paperclip } from "lucide-react";
5
5
  import { lazy, Suspense } from "react";
6
6
  import { treeLevelKey } from "@/app/tree-move/tree-move.tsx";
7
7
  import { ViewToggle } from "@/app/view-toggle/view-toggle.tsx";
8
+ import { BoardPanel } from "@/board/board-panel/board-panel.tsx";
8
9
  import { RefusalNotice } from "@/data/request-refusal/refusal-notice.tsx";
9
10
  import { refusalOf } from "@/data/request-refusal/request-refusal.ts";
10
11
  import { FolderContents } from "@/folder-contents/folder-contents.tsx";
@@ -160,6 +161,8 @@ export function Nodes() {
160
161
  <AttachmentPanel node={selected} />
161
162
  ) : selected.kind === "table" ? (
162
163
  <NodeTablePanel node={selected} />
164
+ ) : selected.kind === "board" ? (
165
+ <BoardPanel node={selected} />
163
166
  ) : document.data ? (
164
167
  <Suspense
165
168
  fallback={