alinea 2.0.0-preview.0 → 2.0.0-preview.2

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 (237) hide show
  1. package/dist/.init/content/pages/welcome.json +1 -1
  2. package/dist/LICENSES.md +134 -80
  3. package/dist/adapter/next/DevRemote.d.ts +3 -0
  4. package/dist/adapter/next/DevRemote.js +37 -0
  5. package/dist/adapter/next/ForwardCredentials.d.ts +1 -0
  6. package/dist/adapter/next/ForwardCredentials.js +17 -0
  7. package/dist/adapter/next/cms.js +86 -38
  8. package/dist/adapter/next/context.d.ts +1 -1
  9. package/dist/adapter/next/context.js +11 -3
  10. package/dist/adapter/next/handler.d.ts +2 -0
  11. package/dist/adapter/next/handler.js +23 -16
  12. package/dist/adapter/next/with-alinea.js +18 -16
  13. package/dist/backend/Handler.d.ts +14 -13
  14. package/dist/backend/Handler.js +70 -36
  15. package/dist/backend/resolver/ParsePreview.d.ts +8 -4
  16. package/dist/backend/resolver/ParsePreview.js +40 -43
  17. package/dist/backend/router/Router.d.ts +1 -0
  18. package/dist/backend/router/Router.js +21 -15
  19. package/dist/bundled.d.ts +369 -99
  20. package/dist/chunks/chunk-6UT4N4CO.js +919 -0
  21. package/dist/chunks/{chunk-LUBOGJCG.js → chunk-6V4TAD2N.js} +1 -1
  22. package/dist/chunks/{chunk-TL7ZW6BX.js → chunk-A3XXZBOQ.js} +2535 -2999
  23. package/dist/chunks/chunk-AC5ATYI3.js +1434 -0
  24. package/dist/chunks/{chunk-7ORQ7BYK.js → chunk-KMLLLZ6X.js} +202 -269
  25. package/dist/chunks/{chunk-IWN3T3FL.js → chunk-O7XWTMCB.js} +1 -1
  26. package/dist/chunks/{chunk-53DZYORR.js → chunk-PAYSVIYI.js} +76 -176
  27. package/dist/chunks/{chunk-YK3OSMDM.js → chunk-S4AU6SRS.js} +188 -158
  28. package/dist/chunks/{chunk-EQ3TDHYD.js → chunk-UVOEM4AH.js} +6 -3
  29. package/dist/chunks/{chunk-I7X64JTZ.js → chunk-VXZM6V4P.js} +4 -4
  30. package/dist/cli/Generate.js +3 -13
  31. package/dist/cli/Serve.js +7 -3
  32. package/dist/cli/bin.js +8 -5
  33. package/dist/cli/generate/CompileConfig.js +3 -2
  34. package/dist/cli/generate/CopyStaticFiles.js +2 -3
  35. package/dist/cli/generate/DevDB.d.ts +1 -1
  36. package/dist/cli/generate/DevDB.js +3 -5
  37. package/dist/cli/serve/CreateLocalServer.d.ts +1 -1
  38. package/dist/cli/serve/CreateLocalServer.js +3 -2
  39. package/dist/cli/serve/DevServer.d.ts +3 -2
  40. package/dist/cli/serve/DevServer.js +60 -3
  41. package/dist/cli/serve/ServeContext.d.ts +1 -0
  42. package/dist/cli/serve/StartServer.d.ts +1 -0
  43. package/dist/cli/serve/StartServer.js +6 -1
  44. package/dist/cli/util/EnsureLibs.js +2 -2
  45. package/dist/cli/util/EnsureNode.js +2 -2
  46. package/dist/cloud/CloudRemote.d.ts +2 -1
  47. package/dist/cloud/CloudRemote.js +3 -2
  48. package/dist/components/Breadcrumbs.js +8 -8
  49. package/dist/components/Button.js +6 -6
  50. package/dist/components/Calendar.js +11 -11
  51. package/dist/components/Checkbox.js +7 -7
  52. package/dist/components/CheckboxGroup.js +6 -6
  53. package/dist/components/ColorSwatch.js +6 -6
  54. package/dist/components/ColorSwatchPicker.js +6 -6
  55. package/dist/components/ComboBox.js +17 -17
  56. package/dist/components/DateField.js +9 -9
  57. package/dist/components/DatePicker.js +10 -10
  58. package/dist/components/DateRangePicker.js +14 -14
  59. package/dist/components/Dialog.js +6 -6
  60. package/dist/components/Disclosure.js +13 -13
  61. package/dist/components/DropZone.js +6 -6
  62. package/dist/components/Label.js +16 -16
  63. package/dist/components/Link.js +6 -6
  64. package/dist/components/List.js +34 -34
  65. package/dist/components/Menu.js +10 -10
  66. package/dist/components/Modal.js +8 -8
  67. package/dist/components/MultipleSelect.js +33 -33
  68. package/dist/components/NumberField.d.ts +2 -1
  69. package/dist/components/NumberField.js +21 -11
  70. package/dist/components/Popover.js +6 -6
  71. package/dist/components/ProgressCircle.js +10 -10
  72. package/dist/components/RadioGroup.js +6 -6
  73. package/dist/components/SearchField.js +11 -11
  74. package/dist/components/Select.js +13 -13
  75. package/dist/components/Surface.js +3 -3
  76. package/dist/components/Switch.js +6 -6
  77. package/dist/components/Table.js +13 -13
  78. package/dist/components/Tabs.js +8 -8
  79. package/dist/components/TagGroup.js +7 -7
  80. package/dist/components/TextField.js +10 -10
  81. package/dist/components/TimeField.js +6 -6
  82. package/dist/components/Toggle.js +6 -6
  83. package/dist/components/Toolbar.js +7 -7
  84. package/dist/components/Tooltip.js +10 -10
  85. package/dist/components/Tree.js +9 -9
  86. package/dist/core/BlobTransport.d.ts +5 -0
  87. package/dist/core/BlobTransport.js +79 -0
  88. package/dist/core/Client.d.ts +2 -1
  89. package/dist/core/Client.js +17 -12
  90. package/dist/core/Config.d.ts +4 -0
  91. package/dist/core/Config.js +6 -0
  92. package/dist/core/Connection.d.ts +4 -3
  93. package/dist/core/Connection.js +7 -0
  94. package/dist/core/Graph.d.ts +3 -4
  95. package/dist/core/ListRow.d.ts +2 -0
  96. package/dist/core/OrderBy.d.ts +7 -3
  97. package/dist/core/TextDoc.d.ts +11 -0
  98. package/dist/core/Trace.d.ts +8 -0
  99. package/dist/core/Trace.js +32 -0
  100. package/dist/core/Type.d.ts +7 -1
  101. package/dist/core/db/CommitRequest.d.ts +0 -3
  102. package/dist/core/db/CommitRequest.js +0 -9
  103. package/dist/core/db/EntryDB.js +1 -1
  104. package/dist/core/db/EntryIndex.d.ts +12 -2
  105. package/dist/core/db/EntryIndex.js +131 -22
  106. package/dist/core/db/EntryResolver.js +104 -29
  107. package/dist/core/db/EntryTransaction.d.ts +1 -2
  108. package/dist/core/db/EntryTransaction.js +29 -22
  109. package/dist/core/db/LocalDB.d.ts +5 -5
  110. package/dist/core/db/LocalDB.js +27 -12
  111. package/dist/core/field/RichTextField.d.ts +30 -3
  112. package/dist/core/field/RichTextField.js +124 -56
  113. package/dist/core/media/MediaAltField.d.ts +1 -0
  114. package/dist/core/media/MediaAltField.js +9 -1
  115. package/dist/core/media/MediaLocation.d.ts +5 -2
  116. package/dist/core/media/MediaLocation.js +6 -7
  117. package/dist/core/media/MediaTypes.js +11 -0
  118. package/dist/core/source/CombinedSource.d.ts +2 -2
  119. package/dist/core/source/CombinedSource.js +6 -3
  120. package/dist/core/source/FSSource.d.ts +4 -3
  121. package/dist/core/source/FSSource.js +59 -27
  122. package/dist/core/source/GithubSource.d.ts +2 -2
  123. package/dist/core/source/GithubSource.js +21 -9
  124. package/dist/core/source/IndexedDBSource.d.ts +2 -2
  125. package/dist/core/source/IndexedDBSource.js +3 -1
  126. package/dist/core/source/MemorySource.d.ts +2 -2
  127. package/dist/core/source/MemorySource.js +3 -1
  128. package/dist/core/source/OverlaySource.d.ts +12 -0
  129. package/dist/core/source/OverlaySource.js +50 -0
  130. package/dist/core/source/Source.d.ts +5 -2
  131. package/dist/core/source/Source.js +3 -3
  132. package/dist/core/util/Async.d.ts +8 -2
  133. package/dist/core/util/Async.js +67 -0
  134. package/dist/core/util/EntryFilenames.d.ts +2 -2
  135. package/dist/core/util/EntryFilenames.js +3 -3
  136. package/dist/dashboard/App.css +158 -0
  137. package/dist/dashboard/App.js +2 -2
  138. package/dist/dashboard/app/AccessDenied.js +3 -3
  139. package/dist/dashboard/app/ActivityStatus.js +15 -15
  140. package/dist/dashboard/app/AppShell.js +1 -1
  141. package/dist/dashboard/app/AuthView.js +11 -11
  142. package/dist/dashboard/app/CompactField.js +10 -10
  143. package/dist/dashboard/app/DashboardErrorBoundary.js +5 -5
  144. package/dist/dashboard/app/DashboardLayout.js +22 -19
  145. package/dist/dashboard/app/EntryHeader.js +12 -12
  146. package/dist/dashboard/app/EntryReferences.js +9 -9
  147. package/dist/dashboard/app/EntrySidebar.d.ts +1 -1
  148. package/dist/dashboard/app/EntrySidebar.js +17 -16
  149. package/dist/dashboard/app/EntrySidebarPreview.d.ts +1 -1
  150. package/dist/dashboard/app/EntrySidebarPreview.js +19 -14
  151. package/dist/dashboard/app/EntryTranslationBanner.js +7 -7
  152. package/dist/dashboard/app/Explorer.js +51 -43
  153. package/dist/dashboard/app/ExplorerCards.js +34 -34
  154. package/dist/dashboard/app/ExplorerFileCard.js +18 -18
  155. package/dist/dashboard/app/ExplorerList.js +13 -13
  156. package/dist/dashboard/app/ExplorerModal.js +3 -3
  157. package/dist/dashboard/app/ExplorerTable.js +76 -61
  158. package/dist/dashboard/app/ExternalLinkPicker.js +15 -4
  159. package/dist/dashboard/app/LinkPicker.js +8 -8
  160. package/dist/dashboard/app/LocaleMenu.js +12 -12
  161. package/dist/dashboard/app/SidebarLayout.d.ts +8 -0
  162. package/dist/dashboard/app/SidebarLayout.js +1169 -0
  163. package/dist/dashboard/app/SidebarTree.js +46 -46
  164. package/dist/dashboard/app/WorkspaceMenu.js +17 -17
  165. package/dist/dashboard/app/WorkspaceRoots.js +23 -23
  166. package/dist/dashboard/app/editor/FileEditor.d.ts +2 -1
  167. package/dist/dashboard/app/editor/FileEditor.js +41 -32
  168. package/dist/dashboard/app/editor/FilePreview.js +4 -4
  169. package/dist/dashboard/app/editor/MediaAltField.view.d.ts +1 -1
  170. package/dist/dashboard/app/editor/MediaAltField.view.js +6 -9
  171. package/dist/dashboard/app/modals/CreateEntry.js +4 -4
  172. package/dist/dashboard/app/pages/EntryPage.js +57 -31
  173. package/dist/dashboard/app/pages/UsersPage.js +33 -33
  174. package/dist/dashboard/app/ui/DashboardModal.js +23 -23
  175. package/dist/dashboard/app/ui/Rail.js +3 -3
  176. package/dist/dashboard/app/ui/Sidebar.js +2 -2
  177. package/dist/dashboard/atoms/auth.js +2 -0
  178. package/dist/dashboard/atoms/dashboard.d.ts +9 -0
  179. package/dist/dashboard/atoms/dashboard.js +17 -0
  180. package/dist/dashboard/atoms/editor.d.ts +7 -1
  181. package/dist/dashboard/atoms/editor.js +4 -1
  182. package/dist/dashboard/atoms/entry.d.ts +48 -2
  183. package/dist/dashboard/atoms/entry.js +222 -17
  184. package/dist/dashboard/atoms/explorer.js +4 -9
  185. package/dist/dashboard/atoms/preview.d.ts +3 -0
  186. package/dist/dashboard/atoms/preview.js +18 -1
  187. package/dist/dashboard/atoms/root.d.ts +4 -1
  188. package/dist/dashboard/atoms/root.js +96 -157
  189. package/dist/dashboard/hooks.d.ts +4 -2
  190. package/dist/dashboard/hooks.js +9 -5
  191. package/dist/dashboard/icons.d.ts +1 -0
  192. package/dist/dashboard/icons.js +10 -0
  193. package/dist/field/check/CheckField.view.js +2 -2
  194. package/dist/field/code/CodeField.view.js +12 -12
  195. package/dist/field/date/DateField.view.js +12 -2
  196. package/dist/field/link/FileLink.d.ts +2 -2
  197. package/dist/field/link/FileLink.js +5 -3
  198. package/dist/field/link/ImageLink.d.ts +1 -1
  199. package/dist/field/link/ImageLink.js +1 -1
  200. package/dist/field/link/Link.js +2 -2
  201. package/dist/field/link/LinkField.view.js +155 -128
  202. package/dist/field/list/ListField.view.js +22 -33
  203. package/dist/field/metadata/MetadataField.view.js +19 -19
  204. package/dist/field/number/NumberField.d.ts +2 -0
  205. package/dist/field/number/NumberField.view.js +4 -2
  206. package/dist/field/richtext/PickTextLink.d.ts +7 -0
  207. package/dist/field/richtext/PickTextLink.js +104 -2
  208. package/dist/field/richtext/ReferenceLink.d.ts +4 -1
  209. package/dist/field/richtext/ReferenceLink.js +18 -4
  210. package/dist/field/richtext/RichTextDocument.d.ts +7 -2
  211. package/dist/field/richtext/RichTextDocument.js +34 -5
  212. package/dist/field/richtext/RichTextExtensions.d.ts +3 -1
  213. package/dist/field/richtext/RichTextExtensions.js +2704 -7467
  214. package/dist/field/richtext/RichTextField.d.ts +4 -0
  215. package/dist/field/richtext/RichTextField.story.d.ts +4 -0
  216. package/dist/field/richtext/RichTextField.view.js +43 -20
  217. package/dist/field/richtext/RichTextInsertMenu.js +281 -495
  218. package/dist/field/richtext/RichTextToolbar.d.ts +5 -2
  219. package/dist/field/richtext/RichTextToolbar.js +38 -3
  220. package/dist/field/richtext/Toolbar.d.ts +19 -1
  221. package/dist/field/richtext/Toolbar.js +18 -13
  222. package/dist/field/richtext/extensions/Anchor.js +1 -1
  223. package/dist/field/richtext/extensions/Link.js +1 -1
  224. package/dist/field/richtext/extensions/Small.js +1 -1
  225. package/dist/field/select/SelectField.view.js +8 -6
  226. package/dist/index.css +227 -16
  227. package/dist/next.cjs +18 -16
  228. package/dist/next.d.ts +2 -1
  229. package/dist/next.edge.d.ts +2 -1
  230. package/dist/picker/entry/EntryPicker.js +9 -35
  231. package/dist/preview/PreviewPayload.js +35 -250
  232. package/dist/ui/RichText.d.ts +1 -0
  233. package/dist/ui/RichText.js +29 -2
  234. package/package.json +6 -3
  235. package/dist/cli/util/ExternalPlugin.d.ts +0 -2
  236. package/dist/cli/util/ExternalPlugin.js +0 -919
  237. package/dist/chunks/{chunk-JFROOUG6.js → chunk-NIVGVRDS.js} +17 -17
@@ -7,16 +7,19 @@ import {
7
7
  import "../../chunks/chunk-CQ52GEHY.js";
8
8
 
9
9
  // src/dashboard/atoms/root.ts
10
- import { Entry } from "alinea/core/Entry";
11
10
  import { Permission } from "alinea/core/Role";
12
11
  import { getRoot, getType, getWorkspace } from "alinea/core/Internal";
13
- import { Type } from "alinea/core/Type";
14
12
  import {
15
13
  createExplorerAtoms
16
14
  } from "alinea/dashboard/atoms/explorer";
17
15
  import { LucideFile } from "../icons.js";
18
16
  import { viewAtoms } from "./config.js";
19
17
  import { configAtom, graphAtom } from "./core.js";
18
+ import {
19
+ loadTreeChildren,
20
+ MissingEntryError,
21
+ treeEntryAtoms
22
+ } from "./entry.js";
20
23
  import { shaAtom } from "./graph.js";
21
24
  import { pageAtom } from "./nav.js";
22
25
  import { policyAtom } from "./user.js";
@@ -31,27 +34,21 @@ var emptyTreeSnapshot = {
31
34
  items: [],
32
35
  selectedKeys: /* @__PURE__ */ new Set()
33
36
  };
34
- var treeItemSelect = {
35
- id: Entry.id,
36
- title: Entry.title,
37
- type: Entry.type,
38
- status: Entry.status,
39
- main: Entry.main,
40
- locale: Entry.locale,
41
- parentId: Entry.parentId,
42
- parents: Entry.parents
43
- };
44
- function preferredLocaleEntries(items, locale) {
45
- const translated = new Set(
46
- items.filter((item) => item.locale === locale).map((item) => item.id)
47
- );
48
- const untranslated = /* @__PURE__ */ new Set();
49
- return items.filter((item) => {
50
- if (translated.has(item.id)) return item.locale === locale;
51
- if (untranslated.has(item.id)) return false;
52
- untranslated.add(item.id);
53
- return true;
54
- });
37
+ function rootTreeItem(config, entry, parentType) {
38
+ return {
39
+ id: entry.id,
40
+ title: entry.title,
41
+ type: entry.type,
42
+ status: entry.status,
43
+ main: entry.main,
44
+ locale: entry.locale,
45
+ parentId: entry.parentId,
46
+ parents: entry.parents,
47
+ hasChildren: entry.hasChildren,
48
+ dragDisabled: Boolean(
49
+ parentType && getType(config.schema[parentType]).orderChildrenBy
50
+ )
51
+ };
55
52
  }
56
53
  var TreeAtoms = class {
57
54
  expandedKeys;
@@ -70,108 +67,76 @@ var TreeAtoms = class {
70
67
  });
71
68
  }
72
69
  #source = atom(async (get) => {
73
- get(shaAtom);
74
- const data = get(this.#root.data);
75
70
  const config = get(configAtom);
76
- const graph = get(graphAtom);
77
- const policy = get(policyAtom);
78
- const visibleTypes = Object.entries(config.schema).filter(([, type]) => !Type.isHidden(type)).map(([name]) => name);
79
71
  const selectedKeys = new Set([...get(this.#selectedKeys)].map(String));
80
72
  const selectedId = [...selectedKeys][0];
81
- const requestedExpanded = get(this.expandedKeys);
82
- const metadataIds = new Set(requestedExpanded);
83
- if (selectedId) metadataIds.add(selectedId);
84
- const metadata = metadataIds.size === 0 ? [] : await graph.find({
85
- workspace: this.#root.workspace,
86
- root: this.#root.key,
87
- id: { in: [...metadataIds] },
88
- filter: { _type: { in: visibleTypes } },
89
- status: "preferDraft",
90
- select: treeItemSelect
91
- });
92
- const metadataById = new Map(
93
- preferredLocaleEntries(
94
- metadata.filter((entry) => policy.canRead(entry)),
95
- this.#locale
96
- ).map((entry) => [entry.id, entry])
97
- );
98
- const selected = selectedId ? metadataById.get(selectedId) : void 0;
73
+ const selectedModel = selectedId ? treeEntryAtoms(selectedId) : void 0;
74
+ let selected;
75
+ try {
76
+ selected = selectedModel ? await get(selectedModel.summary(this.#locale)) : void 0;
77
+ } catch (error) {
78
+ if (!(error instanceof MissingEntryError)) throw error;
79
+ selected = void 0;
80
+ }
81
+ const parents = selectedModel && selected ? await get(selectedModel.parents) : [];
82
+ const models = new Map(parents.map((parent) => [parent.id, parent]));
83
+ if (selectedModel) models.set(selectedModel.id, selectedModel);
99
84
  const collapsed = get(this.collapsedKeys);
100
85
  const collapsedKeys = collapsed.selectedId === selectedId ? collapsed.keys : /* @__PURE__ */ new Set();
101
- const expandedKeys = new Set(requestedExpanded);
86
+ const expandedKeys = new Set(get(this.expandedKeys));
102
87
  for (const parentId of selected?.parents ?? [])
103
88
  if (!collapsedKeys.has(parentId)) expandedKeys.add(parentId);
104
- const parentIds = /* @__PURE__ */ new Set([null, ...expandedKeys]);
105
- const missingParentIds = [...parentIds].filter(
106
- (id) => id !== null && !metadataById.has(id)
107
- );
108
- if (missingParentIds.length > 0) {
109
- const parents = await graph.find({
110
- workspace: this.#root.workspace,
111
- root: this.#root.key,
112
- id: { in: missingParentIds },
113
- filter: { _type: { in: visibleTypes } },
114
- status: "preferDraft",
115
- select: treeItemSelect
116
- });
117
- for (const parent of preferredLocaleEntries(
118
- parents.filter((entry) => policy.canRead(entry)),
119
- this.#locale
120
- ))
121
- metadataById.set(parent.id, parent);
122
- }
123
- const childLists = await Promise.all(
124
- [...parentIds].map(async (parentId) => {
125
- const parent = parentId === null ? void 0 : metadataById.get(parentId);
126
- const entries2 = await graph.find({
127
- workspace: this.#root.workspace,
128
- root: this.#root.key,
129
- parentId,
130
- filter: { _type: { in: visibleTypes } },
131
- status: "preferDraft",
132
- orderBy: parent ? getType(config.schema[parent.type]).orderChildrenBy : data.orderChildrenBy,
133
- select: treeItemSelect
134
- });
135
- return preferredLocaleEntries(
136
- entries2.filter((entry) => policy.canRead(entry)),
137
- this.#locale
138
- );
139
- })
89
+ const missingModels = await Promise.all(
90
+ [...expandedKeys].filter((id) => !models.has(id)).map((id) => get(treeEntryAtoms(id).ready))
140
91
  );
141
- const loadedEntries = childLists.flat();
142
- const possibleChildren = loadedEntries.length === 0 ? [] : await graph.find({
143
- workspace: this.#root.workspace,
144
- root: this.#root.key,
145
- parentId: { in: loadedEntries.map((entry) => entry.id) },
146
- filter: { _type: { in: visibleTypes } },
147
- status: "preferDraft",
148
- select: treeItemSelect
92
+ for (const model of missingModels) models.set(model.id, model);
93
+ const expandedModels = [...expandedKeys].flatMap((id) => {
94
+ const model = models.get(id);
95
+ return model ? [model] : [];
149
96
  });
150
- const entriesWithChildren = new Set(
151
- preferredLocaleEntries(
152
- possibleChildren.filter((entry) => policy.canRead(entry)),
153
- this.#locale
154
- ).flatMap((entry) => entry.parentId ? [entry.parentId] : [])
97
+ const [rootModels, childLevels, parentEntries] = await Promise.all([
98
+ get(this.#root.treeEntries(this.#locale)),
99
+ Promise.all(
100
+ expandedModels.map((model) => get(model.children(this.#locale)))
101
+ ),
102
+ Promise.all(expandedModels.map((model) => get(model.raw(this.#locale))))
103
+ ]);
104
+ const levels = [rootModels, ...childLevels];
105
+ const parentTypes = [
106
+ null,
107
+ ...parentEntries.map((entry) => entry.type)
108
+ ];
109
+ const levelItems = await Promise.all(
110
+ levels.map(
111
+ (level, index) => Promise.all(
112
+ level.map(
113
+ async (model) => rootTreeItem(
114
+ config,
115
+ await get(model.summary(this.#locale)),
116
+ parentTypes[index] ?? null
117
+ )
118
+ )
119
+ )
120
+ )
155
121
  );
156
122
  const entries = /* @__PURE__ */ new Map();
157
123
  const children = /* @__PURE__ */ new Map();
158
- for (const entry of loadedEntries) {
159
- const parent = entry.parentId ? metadataById.get(entry.parentId) : void 0;
160
- entries.set(entry.id, {
161
- ...entry,
162
- dragDisabled: Boolean(
163
- parent && getType(config.schema[parent.type]).orderChildrenBy
164
- ),
165
- hasChildren: entriesWithChildren.has(entry.id)
166
- });
167
- const ids = children.get(entry.parentId) ?? [];
168
- ids.push(entry.id);
169
- children.set(entry.parentId, ids);
124
+ const parentIds = [
125
+ null,
126
+ ...expandedModels.map((model) => model.id)
127
+ ];
128
+ for (const [index, level] of levelItems.entries()) {
129
+ const parentId = parentIds[index] ?? null;
130
+ children.set(
131
+ parentId,
132
+ level.map((entry) => entry.id)
133
+ );
134
+ for (const entry of level) entries.set(entry.id, entry);
170
135
  }
171
136
  function nested(parentId) {
172
137
  return (children.get(parentId) ?? []).map((id) => ({
173
138
  id,
174
- children: nested(id)
139
+ children: expandedKeys.has(id) ? nested(id) : []
175
140
  }));
176
141
  }
177
142
  return {
@@ -184,62 +149,24 @@ var TreeAtoms = class {
184
149
  items = atom((get) => [...get(this.#state)?.entries.values() ?? []]);
185
150
  #itemSource = dispense(
186
151
  (id) => atom(async (get) => {
187
- const loaded = (await get(this.#source)).entries.get(id);
188
- if (loaded) return loaded;
152
+ const model = treeEntryAtoms(id);
153
+ const entry = await get(model.summary(this.#locale));
189
154
  const config = get(configAtom);
190
- const graph = get(graphAtom);
191
- const policy = get(policyAtom);
192
- const visibleTypes = Object.entries(config.schema).filter(([, type]) => !Type.isHidden(type)).map(([name]) => name);
193
- const matches = await graph.find({
194
- workspace: this.#root.workspace,
195
- root: this.#root.key,
196
- id,
197
- filter: { _type: { in: visibleTypes } },
198
- status: "preferDraft",
199
- select: treeItemSelect
200
- });
201
- const entry = preferredLocaleEntries(
202
- matches.filter((match) => policy.canRead(match)),
203
- this.#locale
204
- )[0];
205
- if (!entry) throw new Error(`Tree item "${id}" not found`);
206
- const parent = entry.parentId ? await graph.first({
207
- workspace: this.#root.workspace,
208
- root: this.#root.key,
209
- id: entry.parentId,
210
- status: "preferDraft",
211
- select: { type: Entry.type }
212
- }) : void 0;
213
- const children = await graph.find({
214
- workspace: this.#root.workspace,
215
- root: this.#root.key,
216
- parentId: id,
217
- filter: { _type: { in: visibleTypes } },
218
- status: "preferDraft",
219
- select: treeItemSelect
220
- });
221
- return {
222
- ...entry,
223
- dragDisabled: Boolean(
224
- parent && getType(config.schema[parent.type]).orderChildrenBy
225
- ),
226
- hasChildren: preferredLocaleEntries(
227
- children.filter((child) => policy.canRead(child)),
228
- this.#locale
229
- ).length > 0
230
- };
155
+ const parent = entry.parentId ? await get(treeEntryAtoms(entry.parentId).raw(this.#locale)) : void 0;
156
+ return rootTreeItem(config, entry, parent?.type ?? null);
231
157
  })
232
158
  );
159
+ children = dispense((id) => treeEntryAtoms(id).children(this.#locale));
233
160
  #itemState = dispense(
234
161
  (id) => unwrap(this.#itemSource(id), (previous) => previous)
235
162
  );
236
163
  item = dispense(
237
164
  (id) => atom((get) => {
165
+ const item = get(this.#itemState(id));
166
+ if (item) return item;
238
167
  const loaded = get(this.#state)?.entries.get(id);
239
168
  if (loaded) return loaded;
240
- const item = get(this.#itemState(id));
241
- if (!item) throw get(this.#itemSource(id));
242
- return item;
169
+ throw get(this.#itemSource(id));
243
170
  })
244
171
  );
245
172
  selectedItem = atom((get) => {
@@ -251,7 +178,7 @@ var TreeAtoms = class {
251
178
  get(this.snapshot);
252
179
  const source = await get(this.#source);
253
180
  await Promise.all(
254
- [...source.entries].map(([id]) => get(this.#itemSource(id)))
181
+ [...source.entries.keys()].map((id) => get(this.#itemSource(id)))
255
182
  );
256
183
  return source.snapshot;
257
184
  });
@@ -323,6 +250,18 @@ var RootAtoms = class {
323
250
  } : void 0
324
251
  );
325
252
  }
253
+ treeEntries = dispense(
254
+ (locale) => atom(async (get) => {
255
+ get(shaAtom);
256
+ const data = get(this.data);
257
+ return loadTreeChildren(
258
+ get,
259
+ { workspace: this.workspace, root: this.key, parentId: null },
260
+ locale,
261
+ data.orderChildrenBy
262
+ );
263
+ })
264
+ );
326
265
  children = dispense(
327
266
  (parentId) => createExplorerAtoms(
328
267
  {
@@ -334,7 +273,7 @@ var RootAtoms = class {
334
273
  defaultOrderBy: parentId === null ? atom((get) => get(this.data).orderChildrenBy) : void 0,
335
274
  enableNavigation: true,
336
275
  rootData: this.data,
337
- selectedLocaleAtom: parentId === null ? this.#explorerLocale : void 0,
276
+ selectedLocaleAtom: this.#explorerLocale,
338
277
  treeItems: (locale) => this.tree(locale).items,
339
278
  selectionBehavior: "toggle",
340
279
  selectionMode: "multiple"
@@ -9,7 +9,7 @@ import type { User } from 'alinea/core/User';
9
9
  import type { WorkspaceInternal } from 'alinea/core/Workspace';
10
10
  import { Type } from 'alinea';
11
11
  import type { ComponentType, Dispatch, PropsWithChildren, SetStateAction } from 'react';
12
- import { type EditorModel, type EditorNode, EntryEditor } from './atoms/editor.js';
12
+ import { type EditorModel, type EditorNode, EntryEditor, type ResolvedEditorImage } from './atoms/editor.js';
13
13
  import type { EntryAtoms, EntryLocaleAtoms } from './atoms/entry.js';
14
14
  import type { Page } from './atoms/nav.js';
15
15
  import type { RootAtoms } from './atoms/root.js';
@@ -17,6 +17,7 @@ import type { ReactiveNode } from './atoms/ReactiveNode.js';
17
17
  interface EntryContextValue {
18
18
  entry: EntryAtoms;
19
19
  localeData: EntryLocaleAtoms;
20
+ richTextImages: ReadonlyMap<string, ResolvedEditorImage>;
20
21
  selectedEntry: EntryRecord<Record<string, unknown>>;
21
22
  }
22
23
  export interface DashboardOptions {
@@ -84,9 +85,10 @@ export declare function useDashboardContext(): DashboardContextValue;
84
85
  export interface EntryScopeProps {
85
86
  entry: EntryAtoms;
86
87
  localeData: EntryLocaleAtoms;
88
+ richTextImages: ReadonlyMap<string, ResolvedEditorImage>;
87
89
  selectedEntry: EntryRecord<Record<string, unknown>>;
88
90
  }
89
- export declare function EntryScope({ children, entry, localeData, selectedEntry }: PropsWithChildren<EntryScopeProps>): import("react").FunctionComponentElement<import("react").ProviderProps<EntryContextValue | null>>;
91
+ export declare function EntryScope({ children, entry, localeData, richTextImages, selectedEntry }: PropsWithChildren<EntryScopeProps>): import("react").FunctionComponentElement<import("react").ProviderProps<EntryContextValue | null>>;
90
92
  export declare function useEntryAtoms(): EntryContextValue;
91
93
  export declare function useOptionalEntryAtoms(): EntryContextValue | null;
92
94
  /**
@@ -22,7 +22,9 @@ import {
22
22
  localAtom,
23
23
  viewsAtom
24
24
  } from "./atoms/core.js";
25
- import { EntryEditor } from "./atoms/editor.js";
25
+ import {
26
+ EntryEditor
27
+ } from "./atoms/editor.js";
26
28
  import { previewMetadataAtom } from "./atoms/preview.js";
27
29
  import { policyAtom, userAtom } from "./atoms/user.js";
28
30
  var entryContext = createContext(null);
@@ -99,11 +101,12 @@ function EntryScope({
99
101
  children,
100
102
  entry,
101
103
  localeData,
104
+ richTextImages,
102
105
  selectedEntry
103
106
  }) {
104
107
  const value = useMemo(
105
- () => ({ entry, localeData, selectedEntry }),
106
- [entry, localeData, selectedEntry]
108
+ () => ({ entry, localeData, richTextImages, selectedEntry }),
109
+ [entry, localeData, richTextImages, selectedEntry]
107
110
  );
108
111
  return createElement(entryContext.Provider, { value }, children);
109
112
  }
@@ -137,9 +140,10 @@ function useNodeEditor(node, type) {
137
140
  node,
138
141
  parent instanceof EntryEditor ? parent : void 0,
139
142
  activeVersion ?? void 0,
140
- policy
143
+ policy,
144
+ scope?.richTextImages
141
145
  );
142
- }, [activeVersion, node, parent, policy, type]);
146
+ }, [activeVersion, node, parent, policy, scope?.richTextImages, type]);
143
147
  return editor;
144
148
  }
145
149
  function useFieldNode(field) {
@@ -107,6 +107,7 @@ export declare function IcRoundMoreHoriz(props: SVGProps<SVGSVGElement>): import
107
107
  export declare function IcRoundMoreVert(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
108
108
  export declare function IcRoundNorthEast(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
109
109
  export declare function IcRoundNumbers(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
110
+ export declare function IcRoundOpenInFull(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
110
111
  export declare function IcRoundOpenInNew(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
111
112
  export declare function IcRoundPanorama(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
112
113
  export declare function IcRoundPermMedia(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
@@ -1631,6 +1631,15 @@ function IcRoundNumbers(props) {
1631
1631
  }
1632
1632
  ) });
1633
1633
  }
1634
+ function IcRoundOpenInFull(props) {
1635
+ return /* @__PURE__ */ jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", ...props, children: /* @__PURE__ */ jsx(
1636
+ "path",
1637
+ {
1638
+ fill: "currentColor",
1639
+ d: "M21 8.59V4c0-.55-.45-1-1-1h-4.59c-.89 0-1.34 1.08-.71 1.71l1.59 1.59l-10 10l-1.59-1.59c-.62-.63-1.7-.19-1.7.7V20c0 .55.45 1 1 1h4.59c.89 0 1.34-1.08.71-1.71L7.71 17.7l10-10l1.59 1.59c.62.63 1.7.19 1.7-.7"
1640
+ }
1641
+ ) });
1642
+ }
1634
1643
  function IcRoundOpenInNew(props) {
1635
1644
  return /* @__PURE__ */ jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", ...props, children: /* @__PURE__ */ jsx(
1636
1645
  "path",
@@ -2615,6 +2624,7 @@ export {
2615
2624
  IcRoundNorthEast,
2616
2625
  IcRoundNotes,
2617
2626
  IcRoundNumbers,
2627
+ IcRoundOpenInFull,
2618
2628
  IcRoundOpenInNew,
2619
2629
  IcRoundPanorama,
2620
2630
  IcRoundPermMedia,
@@ -9,9 +9,9 @@ import { useField, useFieldError, useFieldOptions } from "alinea/dashboard/hooks
9
9
 
10
10
  // src/field/check/CheckField.module.css
11
11
  var CheckField_default = {
12
+ "checkline": "alinea-checkline",
12
13
  "checkline-required": "alinea-checkline-required",
13
- "checklineRequired": "alinea-checkline-required",
14
- "checkline": "alinea-checkline"
14
+ "checklineRequired": "alinea-checkline-required"
15
15
  };
16
16
 
17
17
  // src/field/check/CheckField.view.tsx
@@ -64,27 +64,27 @@ import { Fragment, useId } from "react";
64
64
 
65
65
  // src/field/code/CodeField.module.css
66
66
  var CodeField_default = {
67
- "CodeEditorInput-number": "alinea-CodeEditorInput-number",
68
- "CodeEditorInputNumber": "alinea-CodeEditorInput-number",
67
+ "CodeEditorInput": "alinea-CodeEditorInput",
68
+ "CodeEditorInput-pre": "alinea-CodeEditorInput-pre",
69
+ "CodeEditorInputPre": "alinea-CodeEditorInput-pre",
70
+ "CodeEditorInput-keyword": "alinea-CodeEditorInput-keyword",
71
+ "CodeEditorInputKeyword": "alinea-CodeEditorInput-keyword",
69
72
  "CodeEditorInput-string": "alinea-CodeEditorInput-string",
70
73
  "CodeEditorInputString": "alinea-CodeEditorInput-string",
74
+ "CodeEditorInput-number": "alinea-CodeEditorInput-number",
75
+ "CodeEditorInputNumber": "alinea-CodeEditorInput-number",
76
+ "CodeEditorInput-editor": "alinea-CodeEditorInput-editor",
77
+ "CodeEditorInputEditor": "alinea-CodeEditorInput-editor",
71
78
  "CodeEditorInput-regex": "alinea-CodeEditorInput-regex",
72
79
  "CodeEditorInputRegex": "alinea-CodeEditorInput-regex",
73
80
  "CodeEditorInput-punctuation": "alinea-CodeEditorInput-punctuation",
74
81
  "CodeEditorInputPunctuation": "alinea-CodeEditorInput-punctuation",
82
+ "CodeEditorInput-comment": "alinea-CodeEditorInput-comment",
83
+ "CodeEditorInputComment": "alinea-CodeEditorInput-comment",
75
84
  "CodeEditorInput-identifier": "alinea-CodeEditorInput-identifier",
76
85
  "CodeEditorInputIdentifier": "alinea-CodeEditorInput-identifier",
77
- "CodeEditorInput": "alinea-CodeEditorInput",
78
- "CodeEditorInput-pre": "alinea-CodeEditorInput-pre",
79
- "CodeEditorInputPre": "alinea-CodeEditorInput-pre",
80
- "CodeEditorInput-keyword": "alinea-CodeEditorInput-keyword",
81
- "CodeEditorInputKeyword": "alinea-CodeEditorInput-keyword",
82
86
  "CodeEditorInput-textarea": "alinea-CodeEditorInput-textarea",
83
- "CodeEditorInputTextarea": "alinea-CodeEditorInput-textarea",
84
- "CodeEditorInput-comment": "alinea-CodeEditorInput-comment",
85
- "CodeEditorInputComment": "alinea-CodeEditorInput-comment",
86
- "CodeEditorInput-editor": "alinea-CodeEditorInput-editor",
87
- "CodeEditorInputEditor": "alinea-CodeEditorInput-editor"
87
+ "CodeEditorInputTextarea": "alinea-CodeEditorInput-textarea"
88
88
  };
89
89
 
90
90
  // src/field/code/CodeField.view.tsx
@@ -1,6 +1,16 @@
1
+ import "../../chunks/chunk-VXZM6V4P.js";
2
+ import "../../chunks/chunk-O7XWTMCB.js";
3
+ import "../../chunks/chunk-RKDPDEF7.js";
4
+ import "../../chunks/chunk-NIVGVRDS.js";
1
5
  import {
2
6
  $58246871e4652552$export$6b862160d295c8e
3
7
  } from "../../chunks/chunk-IYAQC63Y.js";
8
+ import "../../chunks/chunk-SJBZFMQ2.js";
9
+ import "../../chunks/chunk-6V4TAD2N.js";
10
+ import {
11
+ $2eb8e6d23f3d0cb0$export$a54013f0d02a8f82
12
+ } from "../../chunks/chunk-S4AU6SRS.js";
13
+ import "../../chunks/chunk-AC4U3IMS.js";
4
14
  import "../../chunks/chunk-CQ52GEHY.js";
5
15
 
6
16
  // src/field/date/DateField.view.tsx
@@ -16,7 +26,7 @@ function DateFieldView({ field }) {
16
26
  if (!value) return null;
17
27
  return $58246871e4652552$export$6b862160d295c8e(value);
18
28
  }, [value]);
19
- return /* @__PURE__ */ jsx(
29
+ return /* @__PURE__ */ jsx($2eb8e6d23f3d0cb0$export$a54013f0d02a8f82, { locale: "en-GB", children: /* @__PURE__ */ jsx(
20
30
  DatePicker,
21
31
  {
22
32
  description: options.help,
@@ -28,7 +38,7 @@ function DateFieldView({ field }) {
28
38
  onChange: (next) => setValue(next?.toString() || ""),
29
39
  value: parsedValue
30
40
  }
31
- );
41
+ ) });
32
42
  }
33
43
  export {
34
44
  DateFieldView
@@ -14,8 +14,8 @@ export interface FileLink<InferredFields = undefined> extends EntryReference {
14
14
  }
15
15
  export declare namespace FileLink {
16
16
  const title: import("../../core/Expr").Expr<string>;
17
- const url: import("../hidden").HiddenField<string>;
18
- const href: import("../hidden").HiddenField<string>;
17
+ const url: import("../../core/Expr").Expr<string>;
18
+ const href: import("../../core/Expr").Expr<string>;
19
19
  const extension: import("../hidden").HiddenField<string>;
20
20
  const size: import("../hidden").HiddenField<number>;
21
21
  }
@@ -12,14 +12,16 @@ import { entryPicker } from "alinea/picker/entry";
12
12
  var FileLink;
13
13
  ((FileLink2) => {
14
14
  FileLink2.title = Entry.title;
15
- FileLink2.url = MediaFile.location;
16
- FileLink2.href = MediaFile.location;
15
+ FileLink2.url = Entry.url;
16
+ FileLink2.href = Entry.url;
17
17
  FileLink2.extension = MediaFile.extension;
18
18
  FileLink2.size = MediaFile.size;
19
19
  })(FileLink || (FileLink = {}));
20
20
  var fileCondition = {
21
21
  _type: "MediaFile",
22
- extension: { notIn: imageExtensions }
22
+ extension: {
23
+ notIn: [...imageExtensions, ...imageExtensions.map((e) => e.toUpperCase())]
24
+ }
23
25
  };
24
26
  function filePicker(multiple, options) {
25
27
  return entryPicker({
@@ -27,7 +27,7 @@ export interface ImageLink<InferredFields = undefined> extends EntryReference {
27
27
  export declare namespace ImageLink {
28
28
  const title: import("../../core/Expr").Expr<string>;
29
29
  const alt: import("../../core/media/MediaAltField").MediaAltField;
30
- const src: import("../hidden").HiddenField<string>;
30
+ const src: import("../../core/Expr").Expr<string>;
31
31
  const extension: import("../hidden").HiddenField<string>;
32
32
  const size: import("../hidden").HiddenField<number>;
33
33
  const hash: import("../hidden").HiddenField<string>;
@@ -13,7 +13,7 @@ var ImageLink;
13
13
  ((ImageLink2) => {
14
14
  ImageLink2.title = Entry.title;
15
15
  ImageLink2.alt = MediaFile.alt;
16
- ImageLink2.src = MediaFile.location;
16
+ ImageLink2.src = Entry.url;
17
17
  ImageLink2.extension = MediaFile.extension;
18
18
  ImageLink2.size = MediaFile.size;
19
19
  ImageLink2.hash = MediaFile.hash;
@@ -20,7 +20,7 @@ function link(label, options = {}) {
20
20
  selection: EntryLink
21
21
  }),
22
22
  url: urlPicker(options),
23
- file: filePicker(false, options)
23
+ file: filePicker(false, { ...options, location: void 0 })
24
24
  }
25
25
  });
26
26
  }
@@ -35,7 +35,7 @@ function link(label, options = {}) {
35
35
  selection: EntryLink
36
36
  }),
37
37
  url: urlPicker(options),
38
- file: filePicker(true, options)
38
+ file: filePicker(true, { ...options, location: void 0 })
39
39
  }
40
40
  });
41
41
  }