@arpproject/recrate 0.1.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 (286) hide show
  1. package/.eslintrc.json +37 -0
  2. package/.storybook/main.ts +40 -0
  3. package/.storybook/preview.tsx +46 -0
  4. package/LICENCE +18 -0
  5. package/README.md +83 -0
  6. package/babel.config.json +5 -0
  7. package/dist/app/App.d.ts +2 -0
  8. package/dist/app/EmbeddedComponent.d.ts +3 -0
  9. package/dist/app/index.d.ts +0 -0
  10. package/dist/app/lookup.d.ts +82 -0
  11. package/dist/crate-builder/CrateManager/contexts.d.ts +6 -0
  12. package/dist/crate-builder/CrateManager/crate-manager-benchmarking.spec.d.ts +1 -0
  13. package/dist/crate-builder/CrateManager/crate-manager-loading-exporting.spec.d.ts +1 -0
  14. package/dist/crate-builder/CrateManager/crate-manager-operations.spec.d.ts +0 -0
  15. package/dist/crate-builder/CrateManager/crate-manager.d.ts +641 -0
  16. package/dist/crate-builder/CrateManager/crate-manager.spec.d.ts +1 -0
  17. package/dist/crate-builder/CrateManager/lib.d.ts +26 -0
  18. package/dist/crate-builder/CrateManager/lib.spec.d.ts +1 -0
  19. package/dist/crate-builder/CrateManager/profile-manager.d.ts +143 -0
  20. package/dist/crate-builder/CrateManager/profile-manager.spec.d.ts +1 -0
  21. package/dist/crate-builder/CrateManager/schema-type-definitions.json.d.ts +35125 -0
  22. package/dist/crate-builder/CrateManager/validate-identifier.d.ts +10 -0
  23. package/dist/crate-builder/CrateManager/validate-identifier.spec.d.ts +1 -0
  24. package/dist/crate-builder/RenderEntity/Add.d.ts +26 -0
  25. package/dist/crate-builder/RenderEntity/AddControl.d.ts +14 -0
  26. package/dist/crate-builder/RenderEntity/AddControl.stories.d.ts +29 -0
  27. package/dist/crate-builder/RenderEntity/AutoComplete.d.ts +12 -0
  28. package/dist/crate-builder/RenderEntity/BulkAdd.d.ts +10 -0
  29. package/dist/crate-builder/RenderEntity/DeleteProperty.d.ts +8 -0
  30. package/dist/crate-builder/RenderEntity/DialogAddProperty.d.ts +9 -0
  31. package/dist/crate-builder/RenderEntity/DialogBrowseEntities.d.ts +8 -0
  32. package/dist/crate-builder/RenderEntity/DialogEditContext.d.ts +8 -0
  33. package/dist/crate-builder/RenderEntity/DialogPreviewCrate.d.ts +7 -0
  34. package/dist/crate-builder/RenderEntity/DialogSaveCrateAsTemplate.d.ts +13 -0
  35. package/dist/crate-builder/RenderEntity/DialogSaveEntityTemplate.d.ts +14 -0
  36. package/dist/crate-builder/RenderEntity/DisplayPropertyName.d.ts +8 -0
  37. package/dist/crate-builder/RenderEntity/DisplayPropertyName.stories.d.ts +6 -0
  38. package/dist/crate-builder/RenderEntity/EntityId.d.ts +13 -0
  39. package/dist/crate-builder/RenderEntity/EntityName.d.ts +13 -0
  40. package/dist/crate-builder/RenderEntity/EntityProperty.d.ts +19 -0
  41. package/dist/crate-builder/RenderEntity/EntityPropertyInstance.d.ts +25 -0
  42. package/dist/crate-builder/RenderEntity/EntityType.d.ts +12 -0
  43. package/dist/crate-builder/RenderEntity/ItemLink.d.ts +14 -0
  44. package/dist/crate-builder/RenderEntity/PaginateLinkedEntities.d.ts +23 -0
  45. package/dist/crate-builder/RenderEntity/PaginateLinkedEntities.stories.d.ts +7 -0
  46. package/dist/crate-builder/RenderEntity/PropertyHelp.d.ts +6 -0
  47. package/dist/crate-builder/RenderEntity/RenderControls.d.ts +22 -0
  48. package/dist/crate-builder/RenderEntity/RenderLinkedItem.d.ts +20 -0
  49. package/dist/crate-builder/RenderEntity/RenderPropertyHelp.d.ts +6 -0
  50. package/dist/crate-builder/RenderEntity/RenderReverseConnections.d.ts +16 -0
  51. package/dist/crate-builder/RenderEntity/RenderTypes.d.ts +6 -0
  52. package/dist/crate-builder/RenderEntity/Shell2.d.ts +14 -0
  53. package/dist/crate-builder/RenderEntity/UnlinkEntity.d.ts +14 -0
  54. package/dist/crate-builder/RenderEntity/auto-complete.lib.d.ts +25 -0
  55. package/dist/crate-builder/RenderEntity/keys.d.ts +4 -0
  56. package/dist/crate-builder/RenderEntity/layout.d.ts +14 -0
  57. package/dist/crate-builder/RenderEntity/layout.spec.d.ts +1 -0
  58. package/dist/crate-builder/Shell.d.ts +40 -0
  59. package/dist/crate-builder/editor-state.d.ts +72 -0
  60. package/dist/crate-builder/helpers.d.ts +9 -0
  61. package/dist/crate-builder/i18n.d.ts +2 -0
  62. package/dist/crate-builder/lib/validate-iri.d.ts +6 -0
  63. package/dist/crate-builder/locales/en.d.ts +79 -0
  64. package/dist/crate-builder/locales/hu.d.ts +79 -0
  65. package/dist/crate-builder/primitives/Boolean.d.ts +11 -0
  66. package/dist/crate-builder/primitives/Boolean.stories.d.ts +7 -0
  67. package/dist/crate-builder/primitives/Date.d.ts +11 -0
  68. package/dist/crate-builder/primitives/Date.stories.d.ts +5 -0
  69. package/dist/crate-builder/primitives/DateTime.d.ts +11 -0
  70. package/dist/crate-builder/primitives/DateTime.stories.d.ts +5 -0
  71. package/dist/crate-builder/primitives/Geo.d.ts +12 -0
  72. package/dist/crate-builder/primitives/Geo.stories.d.ts +26 -0
  73. package/dist/crate-builder/primitives/Map.SelectArea.d.ts +9 -0
  74. package/dist/crate-builder/primitives/Map.d.ts +15 -0
  75. package/dist/crate-builder/primitives/Map.stories.d.ts +6 -0
  76. package/dist/crate-builder/primitives/Number.d.ts +16 -0
  77. package/dist/crate-builder/primitives/Number.stories.d.ts +10 -0
  78. package/dist/crate-builder/primitives/Select.d.ts +15 -0
  79. package/dist/crate-builder/primitives/Select.stories.d.ts +9 -0
  80. package/dist/crate-builder/primitives/SelectObject.d.ts +13 -0
  81. package/dist/crate-builder/primitives/SelectObject.stories.d.ts +5 -0
  82. package/dist/crate-builder/primitives/SelectUrl.d.ts +14 -0
  83. package/dist/crate-builder/primitives/SelectUrl.stories.d.ts +7 -0
  84. package/dist/crate-builder/primitives/Text.d.ts +19 -0
  85. package/dist/crate-builder/primitives/Text.stories.d.ts +13 -0
  86. package/dist/crate-builder/primitives/Time.d.ts +11 -0
  87. package/dist/crate-builder/primitives/Time.stories.d.ts +7 -0
  88. package/dist/crate-builder/primitives/Url.d.ts +11 -0
  89. package/dist/crate-builder/primitives/Url.stories.d.ts +7 -0
  90. package/dist/crate-builder/primitives/Value.d.ts +7 -0
  91. package/dist/crate-builder/primitives/Value.stories.d.ts +7 -0
  92. package/dist/crate-builder/primitives/date-libs.d.ts +1 -0
  93. package/dist/crate-builder/property-definitions.d.ts +78 -0
  94. package/dist/crate-builder/store.d.ts +8 -0
  95. package/dist/favicon.ico +0 -0
  96. package/dist/index.d.ts +3 -0
  97. package/dist/index.html +43 -0
  98. package/dist/logo192.png +0 -0
  99. package/dist/logo512.png +0 -0
  100. package/dist/manifest.json +25 -0
  101. package/dist/marker-icon.png +0 -0
  102. package/dist/marker-shadow.png +0 -0
  103. package/dist/recrate.es.js +158699 -0
  104. package/dist/recrate.umd.js +158717 -0
  105. package/dist/robots.txt +3 -0
  106. package/dist/style.css +1721 -0
  107. package/dist/types.d.ts +42 -0
  108. package/docker-compose.yml +30 -0
  109. package/docs/.nojekyll +1 -0
  110. package/docs/assets/highlight.css +99 -0
  111. package/docs/assets/icons.js +18 -0
  112. package/docs/assets/icons.svg +1 -0
  113. package/docs/assets/main.js +60 -0
  114. package/docs/assets/navigation.js +1 -0
  115. package/docs/assets/search.js +1 -0
  116. package/docs/assets/style.css +1448 -0
  117. package/docs/classes/src_crate_builder_CrateManager_crate_manager.CrateManager.html +240 -0
  118. package/docs/classes/src_crate_builder_CrateManager_profile_manager.ProfileManager.html +42 -0
  119. package/docs/classes/src_crate_builder_editor_state.EditorState.html +28 -0
  120. package/docs/classes/src_crate_builder_types.CrateManagerType.html +57 -0
  121. package/docs/classes/src_crate_builder_types.ProfileManagerType.html +13 -0
  122. package/docs/functions/src_crate_builder_CrateManager_lib.isURL.html +2 -0
  123. package/docs/functions/src_crate_builder_CrateManager_lib.mintNewCrate.html +3 -0
  124. package/docs/functions/src_crate_builder_CrateManager_lib.normalise.html +5 -0
  125. package/docs/functions/src_crate_builder_CrateManager_lib.normaliseEntityType.html +1 -0
  126. package/docs/index.html +58 -0
  127. package/docs/interfaces/src_crate_builder_types.NormalisedCrate.html +3 -0
  128. package/docs/interfaces/src_crate_builder_types.NormalisedEntityDefinition.html +4 -0
  129. package/docs/interfaces/src_crate_builder_types.NormalisedProfile.html +9 -0
  130. package/docs/interfaces/src_crate_builder_types.ProfileLayout.html +2 -0
  131. package/docs/interfaces/src_crate_builder_types.ProfileLayoutGroup.html +9 -0
  132. package/docs/interfaces/src_crate_builder_types.UnverifiedCrate.html +3 -0
  133. package/docs/interfaces/src_crate_builder_types.UnverifiedEntityDefinition.html +4 -0
  134. package/docs/modules/src_crate_builder_CrateManager_crate_manager.html +2 -0
  135. package/docs/modules/src_crate_builder_CrateManager_lib.html +6 -0
  136. package/docs/modules/src_crate_builder_CrateManager_profile_manager.html +2 -0
  137. package/docs/modules/src_crate_builder_editor_state.html +2 -0
  138. package/docs/modules/src_crate_builder_types.html +16 -0
  139. package/docs/types/src_crate_builder_types.EntityReference.html +1 -0
  140. package/docs/types/src_crate_builder_types.NormalisedContext.html +1 -0
  141. package/docs/types/src_crate_builder_types.PrimitiveType.html +1 -0
  142. package/docs/types/src_crate_builder_types.ProfileAssociation.html +1 -0
  143. package/docs/types/src_crate_builder_types.ProfileInput.html +1 -0
  144. package/docs/types/src_crate_builder_types.UnverifiedContext.html +1 -0
  145. package/docs/variables/src_crate_builder_CrateManager_lib.urlProtocols.html +1 -0
  146. package/index.html +13 -0
  147. package/load-data-packs.cjs +38 -0
  148. package/package.json +135 -0
  149. package/postcss.config.cjs +6 -0
  150. package/public/favicon.ico +0 -0
  151. package/public/index.html +43 -0
  152. package/public/logo192.png +0 -0
  153. package/public/logo512.png +0 -0
  154. package/public/manifest.json +25 -0
  155. package/public/marker-icon.png +0 -0
  156. package/public/marker-shadow.png +0 -0
  157. package/public/robots.txt +3 -0
  158. package/react-app-env.d.ts +1 -0
  159. package/rollup.config.js +26 -0
  160. package/src/app/App.tsx +13 -0
  161. package/src/app/EmbeddedComponent.tsx +432 -0
  162. package/src/app/index.html +20 -0
  163. package/src/app/index.tsx +19 -0
  164. package/src/app/lookup.ts +141 -0
  165. package/src/app/override-styles.css +96 -0
  166. package/src/crate-builder/CrateManager/contexts/1.1-context.jsonld +2660 -0
  167. package/src/crate-builder/CrateManager/contexts/1.2-DRAFT-context.jsonld +2918 -0
  168. package/src/crate-builder/CrateManager/contexts.ts +42 -0
  169. package/src/crate-builder/CrateManager/crate-manager-benchmarking.spec.ts +31 -0
  170. package/src/crate-builder/CrateManager/crate-manager-loading-exporting.spec.ts +431 -0
  171. package/src/crate-builder/CrateManager/crate-manager-operations.spec.ts +298 -0
  172. package/src/crate-builder/CrateManager/crate-manager.spec.ts +2336 -0
  173. package/src/crate-builder/CrateManager/crate-manager.ts +2111 -0
  174. package/src/crate-builder/CrateManager/lib.spec.ts +133 -0
  175. package/src/crate-builder/CrateManager/lib.ts +170 -0
  176. package/src/crate-builder/CrateManager/profile-manager.spec.ts +593 -0
  177. package/src/crate-builder/CrateManager/profile-manager.ts +367 -0
  178. package/src/crate-builder/CrateManager/schema-type-definitions.json +35122 -0
  179. package/src/crate-builder/CrateManager/validate-identifier.spec.ts +82 -0
  180. package/src/crate-builder/CrateManager/validate-identifier.ts +65 -0
  181. package/src/crate-builder/RenderEntity/Add.tsx +249 -0
  182. package/src/crate-builder/RenderEntity/AddControl.stories.tsx +126 -0
  183. package/src/crate-builder/RenderEntity/AddControl.tsx +84 -0
  184. package/src/crate-builder/RenderEntity/AutoComplete.tsx +215 -0
  185. package/src/crate-builder/RenderEntity/BulkAdd.tsx +136 -0
  186. package/src/crate-builder/RenderEntity/DeleteProperty.tsx +33 -0
  187. package/src/crate-builder/RenderEntity/DialogAddProperty.tsx +83 -0
  188. package/src/crate-builder/RenderEntity/DialogBrowseEntities.tsx +136 -0
  189. package/src/crate-builder/RenderEntity/DialogEditContext.tsx +107 -0
  190. package/src/crate-builder/RenderEntity/DialogPreviewCrate.tsx +54 -0
  191. package/src/crate-builder/RenderEntity/DialogSaveCrateAsTemplate.tsx +65 -0
  192. package/src/crate-builder/RenderEntity/DialogSaveEntityTemplate.tsx +87 -0
  193. package/src/crate-builder/RenderEntity/DisplayPropertyName.stories.tsx +30 -0
  194. package/src/crate-builder/RenderEntity/DisplayPropertyName.tsx +21 -0
  195. package/src/crate-builder/RenderEntity/EntityId.tsx +75 -0
  196. package/src/crate-builder/RenderEntity/EntityName.tsx +49 -0
  197. package/src/crate-builder/RenderEntity/EntityProperty.tsx +188 -0
  198. package/src/crate-builder/RenderEntity/EntityPropertyInstance.tsx +255 -0
  199. package/src/crate-builder/RenderEntity/EntityType.tsx +95 -0
  200. package/src/crate-builder/RenderEntity/ItemLink.tsx +37 -0
  201. package/src/crate-builder/RenderEntity/PaginateLinkedEntities.stories.tsx +43 -0
  202. package/src/crate-builder/RenderEntity/PaginateLinkedEntities.tsx +141 -0
  203. package/src/crate-builder/RenderEntity/PropertyHelp.tsx +39 -0
  204. package/src/crate-builder/RenderEntity/RenderControls.tsx +278 -0
  205. package/src/crate-builder/RenderEntity/RenderLinkedItem.tsx +139 -0
  206. package/src/crate-builder/RenderEntity/RenderPropertyHelp.tsx +41 -0
  207. package/src/crate-builder/RenderEntity/RenderReverseConnections.tsx +150 -0
  208. package/src/crate-builder/RenderEntity/RenderTypes.tsx +102 -0
  209. package/src/crate-builder/RenderEntity/Shell2.tsx +576 -0
  210. package/src/crate-builder/RenderEntity/UnlinkEntity.tsx +30 -0
  211. package/src/crate-builder/RenderEntity/auto-complete.lib.ts +184 -0
  212. package/src/crate-builder/RenderEntity/keys.ts +4 -0
  213. package/src/crate-builder/RenderEntity/layout.spec.js +593 -0
  214. package/src/crate-builder/RenderEntity/layout.ts +220 -0
  215. package/src/crate-builder/Shell.tsx +323 -0
  216. package/src/crate-builder/component.css +65 -0
  217. package/src/crate-builder/editor-state.ts +114 -0
  218. package/src/crate-builder/helpers.ts +16 -0
  219. package/src/crate-builder/i18n.ts +22 -0
  220. package/src/crate-builder/lib/validate-iri.js +69 -0
  221. package/src/crate-builder/lib/validate-iri.ts +57 -0
  222. package/src/crate-builder/locales/en.js +149 -0
  223. package/src/crate-builder/locales/hu.js +147 -0
  224. package/src/crate-builder/primitives/Boolean.stories.tsx +33 -0
  225. package/src/crate-builder/primitives/Boolean.tsx +67 -0
  226. package/src/crate-builder/primitives/Date.stories.tsx +32 -0
  227. package/src/crate-builder/primitives/Date.tsx +58 -0
  228. package/src/crate-builder/primitives/DateTime.stories.tsx +32 -0
  229. package/src/crate-builder/primitives/DateTime.tsx +64 -0
  230. package/src/crate-builder/primitives/Geo.stories.tsx +57 -0
  231. package/src/crate-builder/primitives/Geo.tsx +225 -0
  232. package/src/crate-builder/primitives/Map.SelectArea.js +359 -0
  233. package/src/crate-builder/primitives/Map.stories.tsx +61 -0
  234. package/src/crate-builder/primitives/Map.tsx +124 -0
  235. package/src/crate-builder/primitives/Number.stories.tsx +74 -0
  236. package/src/crate-builder/primitives/Number.tsx +166 -0
  237. package/src/crate-builder/primitives/Select.stories.tsx +66 -0
  238. package/src/crate-builder/primitives/Select.tsx +122 -0
  239. package/src/crate-builder/primitives/SelectObject.stories.tsx +29 -0
  240. package/src/crate-builder/primitives/SelectObject.tsx +105 -0
  241. package/src/crate-builder/primitives/SelectUrl.stories.tsx +42 -0
  242. package/src/crate-builder/primitives/SelectUrl.tsx +110 -0
  243. package/src/crate-builder/primitives/Text.stories.tsx +106 -0
  244. package/src/crate-builder/primitives/Text.tsx +197 -0
  245. package/src/crate-builder/primitives/Time.stories.tsx +38 -0
  246. package/src/crate-builder/primitives/Time.tsx +71 -0
  247. package/src/crate-builder/primitives/Url.stories.tsx +43 -0
  248. package/src/crate-builder/primitives/Url.tsx +75 -0
  249. package/src/crate-builder/primitives/Value.stories.tsx +37 -0
  250. package/src/crate-builder/primitives/Value.tsx +30 -0
  251. package/src/crate-builder/primitives/date-libs.ts +12 -0
  252. package/src/crate-builder/profile-schema.json +145 -0
  253. package/src/crate-builder/property-definitions.ts +78 -0
  254. package/src/crate-builder/store.ts +14 -0
  255. package/src/crate-builder/tailwind.css +7 -0
  256. package/src/crate-builder/types.d.ts +318 -0
  257. package/src/examples/collection/collections-entity-example.json +131 -0
  258. package/src/examples/collection/crate-builder-entity-example.json +33 -0
  259. package/src/examples/item/complex-collection/ro-crate-metadata.json +174 -0
  260. package/src/examples/item/complex-item/ro-crate-metadata.json +769 -0
  261. package/src/examples/item/crate-with-language.json +38 -0
  262. package/src/examples/item/empty/ro-crate-metadata.json +20 -0
  263. package/src/examples/item/item-with-relationship-and-action/ro-crate-metadata.json +66 -0
  264. package/src/examples/item/large-crate/ro-crate-metadata.json +5762 -0
  265. package/src/examples/item/multiple-types/ro-crate-metadata.json +20 -0
  266. package/src/examples/item/ridiculously-big-collection/ro-crate-metadata.json +162977 -0
  267. package/src/examples/profile/aroma.complex.profile.json +11098 -0
  268. package/src/examples/profile/aroma.profile.json +9158 -0
  269. package/src/examples/profile/nyingarn-item-profile.json +426 -0
  270. package/src/examples/profile/profile-to-test-inverse-associations.json +73 -0
  271. package/src/examples/profile/profile-to-test-multiple-types.json +31 -0
  272. package/src/examples/profile/profile-with-all-primitives-and-groups.json +207 -0
  273. package/src/examples/profile/profile-with-all-primitives.json +244 -0
  274. package/src/examples/profile/profile-with-constraints.json +446 -0
  275. package/src/examples/profile/profile-with-resolve.json +57 -0
  276. package/src/examples/profile/vocabulary-creation-profile.json +231 -0
  277. package/src/images.d.ts +5 -0
  278. package/src/index.ts +10 -0
  279. package/src/types.ts +104 -0
  280. package/tailwind.config.js +20 -0
  281. package/tsconfig.app.json +31 -0
  282. package/tsconfig.json +26 -0
  283. package/typedoc.json +11 -0
  284. package/update-deps.sh +4 -0
  285. package/vite-env.d.ts +1 -0
  286. package/vite.config.ts +41 -0
@@ -0,0 +1,278 @@
1
+ import React, { useState, useEffect, useMemo, useContext } from 'react';
2
+ import { Button, Drawer, Popover, Typography, Modal, Flex } from 'antd';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { ArrowLeftOutlined, HomeOutlined, ArrowRightOutlined, CodeOutlined, EditOutlined, EyeOutlined, SaveOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
5
+ import AddPropertyDialog from './DialogAddProperty';
6
+ import EditContextDialog from './DialogEditContext';
7
+ import PreviewCrateDialog from './DialogPreviewCrate';
8
+ import BrowseEntitiesDialog from './DialogBrowseEntities';
9
+ import SaveEntityAsTemplateDialog from './DialogSaveEntityTemplate';
10
+ import { ProfileManagerContext } from '../Shell';
11
+ import { useStateStore } from '../store';
12
+
13
+ interface Config {
14
+ readonly?: boolean;
15
+ enableUrlMarkup?: boolean;
16
+ enableContextEditor?: boolean;
17
+ enableCratePreview?: boolean;
18
+ enableBrowseEntities?: boolean;
19
+ enableTemplateSave?: boolean;
20
+ }
21
+
22
+ interface RenderControlsProps {
23
+ entity: {
24
+ '@id': string;
25
+ '@type': string[];
26
+ etype?: string;
27
+ [key: string]: any;
28
+ };
29
+ onLoadEntity: (data: { id: string }) => void;
30
+ onBack: () => void;
31
+ onForward: () => void;
32
+ onAddPropertyPlaceholder: (property: any) => void;
33
+ onDeleteEntity: (data: { id: string }) => void;
34
+ onSaveEntityTemplate: (data: any) => void;
35
+ onUpdateContext: (data: any) => void;
36
+ }
37
+
38
+ const RenderControls: React.FC<RenderControlsProps> = ({
39
+ entity,
40
+ onLoadEntity,
41
+ onBack,
42
+ onForward,
43
+ onAddPropertyPlaceholder,
44
+ onDeleteEntity,
45
+ onSaveEntityTemplate,
46
+ onUpdateContext
47
+ }) => {
48
+ const { t } = useTranslation();
49
+ const profileManager = useContext(ProfileManagerContext);
50
+ const state = useStateStore();
51
+
52
+ const [dialogs, setDialogs] = useState({
53
+ previewCrate: false,
54
+ editContext: false,
55
+ addProperty: false,
56
+ browseEntities: false,
57
+ saveEntityAsTemplate: false,
58
+ deleteConfirm: false,
59
+ });
60
+
61
+ const [definition, setDefinition] = useState<any>({});
62
+
63
+ const isRootDataset = useMemo(() => entity['@id'] === './', [entity]);
64
+ const isRootDescriptor = useMemo(
65
+ () => entity['@id'] === 'ro-crate-metadata.json' && entity['@type'].includes('CreativeWork'),
66
+ [entity]
67
+ );
68
+
69
+ useEffect(() => {
70
+ loadEntityDefinition();
71
+ }, [profileManager?.$key, entity['@id']]);
72
+
73
+ const loadEntityDefinition = () => {
74
+ if (!entity?.['@type'] || !profileManager?.getTypeDefinition) {
75
+ setDefinition('inherit');
76
+ } else {
77
+ setDefinition(profileManager.getTypeDefinition({ entity }));
78
+ }
79
+ };
80
+
81
+ type DialogType = keyof typeof dialogs;
82
+
83
+ const toggle = (dialog: DialogType) => {
84
+ setDialogs(prev => {
85
+ const newState = { ...prev };
86
+ Object.keys(newState).forEach(d => {
87
+ newState[d as DialogType] = d === dialog ? !prev[d] : false;
88
+ });
89
+ return newState;
90
+ });
91
+ };
92
+
93
+ const loadRootDataset = () => {
94
+ onLoadEntity({ id: './' });
95
+ };
96
+
97
+ const handleDeleteEntity = () => {
98
+ onDeleteEntity({ id: entity['@id'] });
99
+ };
100
+
101
+ const handleBack = () => {
102
+ state.editorState.back();
103
+ const latest = state.editorState.latest();
104
+ if (latest.id) {
105
+ onLoadEntity({ id: latest.id });
106
+ }
107
+ };
108
+
109
+ const handleForward = () => {
110
+ state.editorState.forward();
111
+ const latest = state.editorState.latest();
112
+ if (latest.id) {
113
+ onLoadEntity({ id: latest.id });
114
+ }
115
+ };
116
+
117
+ const [popoverOpen, setPopoverOpen] = useState(false);
118
+
119
+ const handleDeleteClick = () => {
120
+ setPopoverOpen(true);
121
+ };
122
+
123
+ const handleClose = () => {
124
+ setPopoverOpen(false);
125
+ };
126
+
127
+ const handleDeleteConfirm = () => {
128
+ onDeleteEntity({ id: entity['@id'] });
129
+ handleClose();
130
+ };
131
+
132
+ return (
133
+ <Flex className="flex-row space-x-1">
134
+ {/* Navigation Controls */}
135
+ <Flex className="flex-row space-x-1">
136
+ <Button
137
+ onClick={handleBack}
138
+ type="primary"
139
+ icon={<ArrowLeftOutlined />}
140
+ />
141
+ <Button
142
+ onClick={loadRootDataset}
143
+ type="primary"
144
+ icon={<HomeOutlined />}
145
+ disabled={isRootDataset}
146
+ />
147
+ <Button
148
+ onClick={handleForward}
149
+ type="primary"
150
+ icon={<ArrowRightOutlined />}
151
+ />
152
+ </Flex>
153
+
154
+ {/* Add Property Button */}
155
+ {!state.configuration?.readonly && (
156
+ <Button
157
+ onClick={() => toggle('addProperty')}
158
+ type="primary"
159
+ disabled={definition !== 'inherit'}
160
+ icon={<PlusOutlined />}
161
+ >
162
+ {t('add_label')}
163
+ </Button>
164
+ )}
165
+
166
+ {/* Context Editor Button */}
167
+ {state.configuration?.enableContextEditor && !state.configuration?.readonly && (
168
+ <Button
169
+ onClick={() => toggle('editContext')}
170
+ type="primary"
171
+ icon={<EditOutlined />}
172
+ >
173
+ {t('edit_context_label')}
174
+ </Button>
175
+ )}
176
+
177
+ {/* Preview Button */}
178
+ {state.configuration?.enableCratePreview && (
179
+ <Button
180
+ onClick={() => toggle('previewCrate')}
181
+ type="primary"
182
+ icon={<EyeOutlined />}
183
+ >
184
+ {t('preview_label')}
185
+ </Button>
186
+ )}
187
+
188
+ {/* Browse Entities Button */}
189
+ {state.configuration?.enableBrowseEntities && (
190
+ <Button
191
+ onClick={() => toggle('browseEntities')}
192
+ type="primary"
193
+ icon={<CodeOutlined />}
194
+ >
195
+ {t('browse_entities_label')}
196
+ </Button>
197
+ )}
198
+
199
+ {/* Template and Delete Controls */}
200
+ <Flex className="flex-row space-x-1">
201
+ {state.configuration?.enableTemplateSave && !isRootDataset && !isRootDescriptor && (
202
+ <Button
203
+ onClick={() => toggle('saveEntityAsTemplate')}
204
+ type="primary"
205
+ icon={<SaveOutlined />}
206
+ >
207
+ {entity.etype !== 'File' && t('save_entity_template_label')}
208
+ </Button>
209
+ )}
210
+
211
+ {!isRootDataset && !isRootDescriptor && (
212
+ <Popover
213
+ open={popoverOpen}
214
+ onOpenChange={setPopoverOpen}
215
+ trigger="click"
216
+ placement="bottomLeft"
217
+ content={
218
+ <Flex vertical>
219
+ <Typography.Text style={{ marginBottom: 12 }}>
220
+ {t('are_you_sure_to_delete')}
221
+ </Typography.Text>
222
+ <Flex justify="flex-end" gap={8}>
223
+ <Button onClick={handleClose}>
224
+ {t('are_you_sure_to_delete_no')}
225
+ </Button>
226
+ <Button onClick={handleDeleteConfirm} danger>
227
+ {t('are_you_sure_to_delete_yes')}
228
+ </Button>
229
+ </Flex>
230
+ </Flex>
231
+ }
232
+ >
233
+ <Button
234
+ onClick={handleDeleteClick}
235
+ color='red'
236
+ variant='solid'
237
+ danger
238
+ icon={<DeleteOutlined />}
239
+ >
240
+ {entity.etype !== 'File' && t('delete_entity_label')}
241
+ </Button>
242
+ </Popover>
243
+ )}
244
+ </Flex>
245
+
246
+ {/* Dialogs */}
247
+ <AddPropertyDialog
248
+ entity={entity}
249
+ onAddPropertyPlaceholder={onAddPropertyPlaceholder}
250
+ open={dialogs.addProperty}
251
+ onClose={() => toggle('addProperty')}
252
+ />
253
+ <EditContextDialog
254
+ onUpdateContext={onUpdateContext}
255
+ open={dialogs.editContext}
256
+ onClose={() => toggle('editContext')}
257
+ />
258
+ <PreviewCrateDialog
259
+ open={dialogs.previewCrate}
260
+ onClose={() => toggle('previewCrate')}
261
+ key={Date.now().toString()} // This will force a re-render when the drawer is opened
262
+ />
263
+ <BrowseEntitiesDialog
264
+ onLoadEntity={onLoadEntity}
265
+ open={dialogs.browseEntities}
266
+ onClose={() => toggle('browseEntities')}
267
+ />
268
+ <SaveEntityAsTemplateDialog
269
+ entity={entity}
270
+ open={dialogs.saveEntityAsTemplate}
271
+ onClose={() => toggle('saveEntityAsTemplate')}
272
+ onSaveEntityTemplate={onSaveEntityTemplate}
273
+ />
274
+ </Flex>
275
+ );
276
+ };
277
+
278
+ export default RenderControls;
@@ -0,0 +1,139 @@
1
+ import React, { useState, useEffect, useMemo, useContext } from 'react';
2
+ import { Flex, Card } from 'antd';
3
+ import { ArrowRightOutlined } from '@ant-design/icons';
4
+ import RenderItemLink from './ItemLink';
5
+ import UnlinkEntity from './UnlinkEntity';
6
+ import MapComponent from '../primitives/Map';
7
+ import { useStateStore } from '../store';
8
+ import { CrateManagerContext, ProfileManagerContext } from '../Shell';
9
+
10
+ interface RenderLinkedItemProps {
11
+ entity: {
12
+ '@id': string;
13
+ '@type': string[];
14
+ name?: string;
15
+ [key: string]: any;
16
+ };
17
+ property: string;
18
+ readonly: boolean;
19
+ onLoadEntity: (entity: { id: string }) => void;
20
+ onUnlinkEntity: (data: { property: string; tgtEntityId: string }) => void;
21
+ }
22
+
23
+ const RenderLinkedItem: React.FC<RenderLinkedItemProps> = ({
24
+ entity,
25
+ property,
26
+ readonly,
27
+ onLoadEntity,
28
+ onUnlinkEntity
29
+ }) => {
30
+ const state = useStateStore();
31
+ const crateManager = useContext(CrateManagerContext);
32
+ const profileManager = useContext(ProfileManagerContext);
33
+
34
+ const [associations, setAssociations] = useState<any[]>([]);
35
+
36
+ const showMap = useMemo(() => {
37
+ return entity?.['@type'].join(', ').match(/Geo/) ? true : false;
38
+ }, [entity]);
39
+
40
+ const resolveAssociations = () => {
41
+ const profile = profileManager.profile;
42
+ const resolvedAssociations = crateManager.resolveLinkedEntityAssociations({
43
+ entity: crateManager.getEntity({ id: entity['@id'] }),
44
+ profile
45
+ });
46
+ setAssociations(resolvedAssociations);
47
+ };
48
+
49
+ useEffect(() => {
50
+ resolveAssociations();
51
+ }, [profileManager.$key, entity['@id']]);
52
+
53
+ const handleLoadEntity = (entityData: { id: string }) => {
54
+ onLoadEntity(entityData);
55
+ };
56
+
57
+ const handleUnlinkEntity = (unlinkData: { entity: { '@id': string } }) => {
58
+ if (unlinkData.entity && unlinkData.entity['@id']) {
59
+ onUnlinkEntity({ property, tgtEntityId: unlinkData.entity['@id'] });
60
+ }
61
+ };
62
+
63
+ if (showMap) {
64
+ return (
65
+ <Flex className="describo-render-item-link py-1 rounded bg-blue-200 hover:text-black hover:bg-blue-300 hover:rounded-r-none">
66
+ <Flex vertical className="space-y-2">
67
+ <Flex className="p-2">
68
+ <Flex>{entity.name}</Flex>
69
+ <Flex flex={1} />
70
+ {!state.configuration?.readonly && !readonly && (
71
+ <UnlinkEntity entity={entity} onUnlinkEntity={handleUnlinkEntity} />
72
+ )}
73
+ </Flex>
74
+ <MapComponent entity={entity} crateManager={crateManager} />
75
+ </Flex>
76
+ </Flex>
77
+ );
78
+ }
79
+
80
+ return (
81
+ <Flex className="describo-render-item-link py-1 rounded hover:rounded-r-none">
82
+ <Flex
83
+ vertical
84
+ style={{ margin: entity?.associations?.length ? 8 : 0 }}
85
+ >
86
+ <Card
87
+ style={{
88
+ backgroundColor: '#e6f0ff',
89
+ cursor: 'pointer',
90
+ transition: 'background-color 0.2s',
91
+ borderLeft: '3px solid #409eff'
92
+ }}
93
+ hoverable
94
+ >
95
+ <Flex justify="space-between" align="middle">
96
+ <RenderItemLink
97
+ entity={{
98
+ ...entity,
99
+ name: entity.name || entity['@id']
100
+ }}
101
+ onLoadEntity={handleLoadEntity}
102
+ />
103
+ {!state.configuration?.readonly && !readonly && (
104
+ <UnlinkEntity entity={entity} onUnlinkEntity={handleUnlinkEntity} />
105
+ )}
106
+ </Flex>
107
+ </Card>
108
+
109
+ {associations?.length > 0 && (
110
+ <Flex className="mt-2 flex-col space-y-2 border-l-2 pl-1 border-solid border-slate-700">
111
+ {associations.map(association => (
112
+ <Flex
113
+ key={association['@id']}
114
+ onClick={() => handleLoadEntity({ id: association['@id'] })}
115
+ className="cursor-pointer"
116
+ >
117
+ <Flex className="flex-row text-base border-solid border-black">
118
+ <Flex className="bg-slate-700 w-3 h-3 rounded-lg -4 mt-4" />
119
+ <Flex className="bg-slate-700 w-6 h-1 mt-5 -mx-1" />
120
+ <Flex className="bg-purple-200 hover:bg-cyan-200 flex flex-row p-2 rounded space-x-2">
121
+ <Flex>{association.property}</Flex>
122
+ <Flex><ArrowRightOutlined /></Flex>
123
+ <Flex className="flex-row space-x-1">
124
+ <Flex>
125
+ {association.name || association['@id']}
126
+ </Flex>
127
+ </Flex>
128
+ </Flex>
129
+ </Flex>
130
+ </Flex>
131
+ ))}
132
+ </Flex>
133
+ )}
134
+ </Flex>
135
+ </Flex>
136
+ );
137
+ };
138
+
139
+ export default RenderLinkedItem;
@@ -0,0 +1,41 @@
1
+ import React, { useState, useMemo } from 'react';
2
+ import { Flex } from 'antd';
3
+
4
+ interface RenderPropertyHelpProps {
5
+ help?: string;
6
+ }
7
+
8
+ const RenderPropertyHelp: React.FC<RenderPropertyHelpProps> = ({ help }) => {
9
+ const [showMore, setShowMore] = useState(false);
10
+ const length = 100;
11
+
12
+ const showToggle = useMemo(() => {
13
+ return help ? help.length > length : false;
14
+ }, [help]);
15
+
16
+ const helpText = useMemo(() => {
17
+ if (!help) return '';
18
+ if (showMore) return help;
19
+ return help.slice(0, length);
20
+ }, [help, showMore]);
21
+
22
+ if (!showToggle) {
23
+ return (
24
+ <Flex className="text-gray-600 font-light text-sm pr-1 describo-property-help">
25
+ {helpText}
26
+ </Flex>
27
+ );
28
+ }
29
+
30
+ return (
31
+ <Flex
32
+ className="text-gray-600 font-light text-sm pr-1 cursor-pointer describo-property-help-more"
33
+ onClick={() => setShowMore(!showMore)}
34
+ >
35
+ {helpText}
36
+ {!showMore && <span>...</span>}
37
+ </Flex>
38
+ );
39
+ };
40
+
41
+ export default RenderPropertyHelp;
@@ -0,0 +1,150 @@
1
+ import React, { useState, useEffect, useMemo } from 'react';
2
+ import { Flex, Pagination, Input, Typography, Card } from 'antd';
3
+ import { useTranslation } from 'react-i18next';
4
+ import RenderItemLink from './ItemLink';
5
+ import isPlainObject from 'lodash/isPlainObject';
6
+ import uniqBy from 'lodash/uniqBy';
7
+ import { CrateManagerContext } from '../Shell';
8
+ import { useContext } from 'react';
9
+
10
+ interface RenderReverseConnectionsProps {
11
+ entity: {
12
+ '@id': string;
13
+ '@type': string[];
14
+ '@reverse'?: {
15
+ [key: string]: any[];
16
+ };
17
+ [key: string]: any;
18
+ };
19
+ onLoadEntity: (data: { id: string }) => void;
20
+ }
21
+
22
+ const RenderReverseConnections: React.FC<RenderReverseConnectionsProps> = ({
23
+ entity,
24
+ onLoadEntity
25
+ }) => {
26
+ const { t } = useTranslation();
27
+ const crateManager = useContext(CrateManagerContext);
28
+ const pageSize = 10;
29
+
30
+ const [currentPage, setCurrentPage] = useState(1);
31
+ const [filterQuery, setFilterQuery] = useState('');
32
+ const [entities, setEntities] = useState<any[]>([]);
33
+
34
+ const connections = useMemo(() => {
35
+ const offset = (currentPage - 1) * pageSize;
36
+ const re = new RegExp(filterQuery, 'i');
37
+
38
+ const filteredEntities = entities.filter(entity => {
39
+ return (
40
+ entity['@id'].match(re) ||
41
+ entity['@type'].join(', ').match(re) ||
42
+ entity.name?.match(re)
43
+ );
44
+ });
45
+
46
+ return {
47
+ total: filteredEntities.length,
48
+ items: filteredEntities.slice(offset, offset + pageSize)
49
+ };
50
+ }, [entities, currentPage, filterQuery]);
51
+
52
+ const resolveConnections = async () => {
53
+ if (isPlainObject(entity) && entity['@reverse']) {
54
+ let allEntities: any[] = [];
55
+
56
+ Object.values(entity['@reverse']).forEach(reverseEntities => {
57
+ allEntities = [...allEntities, ...reverseEntities];
58
+ });
59
+
60
+ const resolvedEntities = allEntities.map(entity =>
61
+ crateManager.getEntity({ id: entity['@id'], stub: true })
62
+ );
63
+
64
+ const re = new RegExp(filterQuery, 'i');
65
+ const filteredEntities = resolvedEntities.filter(entity => {
66
+ if (!entity) return false;
67
+ return (
68
+ entity['@id'].match(re) ||
69
+ entity['@type'].join(', ').match(re) ||
70
+ entity.name?.match(re)
71
+ );
72
+ });
73
+
74
+ setEntities(uniqBy(filteredEntities, '@id'));
75
+ }
76
+ };
77
+
78
+ useEffect(() => {
79
+ const timer = setTimeout(() => {
80
+ resolveConnections();
81
+ }, 50);
82
+ return () => clearTimeout(timer);
83
+ }, [entity, filterQuery]);
84
+
85
+ const handleLoadEntity = (data: { id: string }) => {
86
+ onLoadEntity(data);
87
+ setTimeout(() => {
88
+ resolveConnections();
89
+ }, 200);
90
+ };
91
+
92
+ const handlePageChange = (page: number) => {
93
+ setCurrentPage(page);
94
+ };
95
+
96
+ const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
97
+ setCurrentPage(1);
98
+ setFilterQuery(event.target.value);
99
+ };
100
+
101
+ return (
102
+ <div className="w-full">
103
+ <div className="flex flex-row">
104
+ <Typography.Text className="text-lg mb-2">{t("links_to_this_entity")}</Typography.Text>
105
+ <div className="flex-grow" />
106
+ </div>
107
+ <div className="flex flex-col space-y-2">
108
+ <Pagination
109
+ current={currentPage}
110
+ total={connections.total}
111
+ pageSize={pageSize}
112
+ onChange={handlePageChange}
113
+ showSizeChanger={false}
114
+ />
115
+ <div className="flex-grow">
116
+ <Input.Search
117
+ value={filterQuery}
118
+ onChange={handleFilterChange}
119
+ placeholder={t('search_for_connection') || ''}
120
+ />
121
+ </div>
122
+ {connections.items.map(entity => (
123
+ <div key={entity['@id']} className="mb-2">
124
+ <Card
125
+ style={{
126
+ backgroundColor: '#e6f0ff',
127
+ cursor: 'pointer',
128
+ transition: 'background-color 0.2s',
129
+ borderLeft: '3px solid #409eff'
130
+ }}
131
+ hoverable
132
+ >
133
+ <Card.Meta
134
+ className="describo-render-item-link"
135
+ title={
136
+ <RenderItemLink
137
+ entity={entity}
138
+ onLoadEntity={handleLoadEntity}
139
+ />
140
+ }
141
+ />
142
+ </Card>
143
+ </div>
144
+ ))}
145
+ </div>
146
+ </div>
147
+ );
148
+ };
149
+
150
+ export default RenderReverseConnections;
@@ -0,0 +1,102 @@
1
+ import React, { useContext } from 'react';
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
+ import {
4
+ faBookOpen,
5
+ faAddressCard,
6
+ faPlus,
7
+ faImage,
8
+ faFlag,
9
+ faFolder,
10
+ faDownload,
11
+ faFile,
12
+ faMapMarkerAlt,
13
+ faBarcode,
14
+ faSignLanguage,
15
+ faUniversity,
16
+ faUser,
17
+ faGlobe,
18
+ faParagraph,
19
+ faNewspaper,
20
+ faCubes,
21
+ faCube,
22
+ faScroll,
23
+ faCode,
24
+ faLink,
25
+ faProjectDiagram,
26
+ } from '@fortawesome/free-solid-svg-icons';
27
+ import { faJs } from '@fortawesome/free-brands-svg-icons';
28
+ import { Tag } from 'antd';
29
+ import { ProfileManagerContext } from '../Shell';
30
+
31
+ interface RenderTypesProps {
32
+ types: string[];
33
+ }
34
+
35
+ const typeIcons = {
36
+ Book: faBookOpen,
37
+ ContactPoint: faAddressCard,
38
+ ComputerLanguage: faJs,
39
+ CreateAction: faPlus,
40
+ CreativeWork: faImage,
41
+ Country: faFlag,
42
+ Dataset: faFolder,
43
+ DataDownload: faDownload,
44
+ DerivedMaterial: faDownload,
45
+ File: faFile,
46
+ GeoCoordinates: faMapMarkerAlt,
47
+ GeoShape: faMapMarkerAlt,
48
+ IndividualProduct: faBarcode,
49
+ Language: faSignLanguage,
50
+ Organization: faUniversity,
51
+ Organisation: faUniversity,
52
+ Person: faUser,
53
+ Place: faGlobe,
54
+ PropertyValue: faParagraph,
55
+ Publication: faNewspaper,
56
+ RepositoryCollection: faCubes,
57
+ RepositoryObject: faCube,
58
+ ScholarlyArticle: faScroll,
59
+ Script: faCode,
60
+ SoftwareApplication: faCode,
61
+ URL: faLink,
62
+ Workflow: faProjectDiagram,
63
+ WorkflowSketch: faProjectDiagram,
64
+ };
65
+
66
+ const RenderTypes: React.FC<RenderTypesProps> = ({ types }) => {
67
+ const profileManager = useContext(ProfileManagerContext);
68
+
69
+ const getTypeLabelFromProfile = (type: string) => {
70
+ return profileManager?.getTypeLabel(type) || type;
71
+ };
72
+
73
+ return (
74
+ <div className="flex flex-row space-x-1">
75
+ {types.map((etype, idx) => (
76
+ <Tag
77
+ key={idx}
78
+ className="text-gray-800 font-light flex flex-row items-center space-x-1"
79
+ style={{
80
+ backgroundColor: '#f0f0f0',
81
+ borderRadius: '16px',
82
+ padding: '0 12px',
83
+ height: '32px',
84
+ display: 'flex',
85
+ alignItems: 'center',
86
+ margin: '4px',
87
+ }}
88
+ >
89
+ {typeIcons[etype as keyof typeof typeIcons] && (
90
+ <FontAwesomeIcon
91
+ icon={typeIcons[etype as keyof typeof typeIcons]}
92
+ fixedWidth
93
+ />
94
+ )}
95
+ <span>{getTypeLabelFromProfile(etype)}</span>
96
+ </Tag>
97
+ ))}
98
+ </div>
99
+ );
100
+ };
101
+
102
+ export default RenderTypes;