@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,255 @@
1
+ import React from 'react';
2
+ import dayjs from 'dayjs';
3
+ import { isDecimal, isInt, isFloat, isNumeric } from 'validator';
4
+ import { isURL } from '../CrateManager/lib';
5
+ import { useStateStore } from '../store';
6
+ import TextComponent from '../primitives/Text';
7
+ import DateComponent from '../primitives/Date';
8
+ import DateTimeComponent from '../primitives/DateTime';
9
+ import TimeComponent from '../primitives/Time';
10
+ import NumberComponent from '../primitives/Number';
11
+ import ValueComponent from '../primitives/Value';
12
+ import SelectComponent from '../primitives/Select';
13
+ import UrlComponent from '../primitives/Url';
14
+ import BooleanComponent from '../primitives/Boolean';
15
+
16
+ interface EntityPropertyInstanceProps {
17
+ property: string;
18
+ value: string | number | boolean | Date | any[];
19
+ idx: number;
20
+ definition: {
21
+ type: string;
22
+ value?: any;
23
+ values?: string[];
24
+ minValue?: number;
25
+ maxValue?: number;
26
+ numberType?: string[];
27
+ style?: 'dropdown' | 'radio' | 'checkbox';
28
+ // Add TextComponent definition properties
29
+ minLength?: number;
30
+ maxLength?: number;
31
+ regex?: string;
32
+ dateFormat?: string[];
33
+ };
34
+ className?: string;
35
+ placeholder?: string;
36
+ onSaveProperty: (data: any) => void;
37
+ onCreateEntity: (data: any) => void;
38
+ }
39
+
40
+ export const EntityPropertyInstance: React.FC<EntityPropertyInstanceProps> = ({
41
+ property,
42
+ value,
43
+ idx,
44
+ definition,
45
+ className,
46
+ placeholder,
47
+ onSaveProperty,
48
+ onCreateEntity
49
+ }) => {
50
+ const state = useStateStore();
51
+
52
+ const savePropertyValue = async (data: any) => {
53
+ if (!data.idx) {
54
+ data = { ...data, property, idx };
55
+ }
56
+ onSaveProperty(data);
57
+ };
58
+
59
+ const isDate = (value: any) => {
60
+ try {
61
+ if (typeof value === 'boolean') return false;
62
+ const date = dayjs(value);
63
+ return date.isValid() && definitionIncludes('Date');
64
+ } catch (error) {
65
+ return false;
66
+ }
67
+ };
68
+
69
+ const isDateTime = (value: any) => {
70
+ try {
71
+ if (typeof value === 'boolean') return false;
72
+ const date = dayjs(value);
73
+ return date.isValid() && definitionIncludes('DateTime');
74
+ } catch (error) {
75
+ return false;
76
+ }
77
+ };
78
+
79
+ const isTime = (value: any) => {
80
+ const stringValue = String(value);
81
+ return (stringValue.match(/^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/) ||
82
+ stringValue.match(/^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/)) &&
83
+ (definitionIncludes('DateTime') || definitionIncludes('Time'));
84
+ };
85
+
86
+ const isNumber = (value: any) => {
87
+ const stringValue = String(value);
88
+ return (isDecimal(stringValue) || isInt(stringValue) || isFloat(stringValue) || isNumeric(stringValue)) &&
89
+ (definitionIncludes('Number') || definitionIncludes('Float') || definitionIncludes('Integer'));
90
+ };
91
+
92
+ const isValue = () => {
93
+ return definition?.type === 'Value';
94
+ };
95
+
96
+ const isSelect = () => {
97
+ return (definition?.values?.includes(String(value)) || definitionIncludes('Select'));
98
+ };
99
+
100
+ const isBoolean = () => {
101
+ return definition?.type == 'Boolean';
102
+ };
103
+
104
+ const isText = (value: any) => {
105
+ return !isBoolean() &&
106
+ !isDate(value) &&
107
+ !isDateTime(value) &&
108
+ !isTime(value) &&
109
+ !isNumber(value) &&
110
+ !isURL(value) &&
111
+ !isSelect() &&
112
+ !isValue();
113
+ };
114
+
115
+ const definitionIncludes = (type: string) => {
116
+ return definition?.type?.includes(type);
117
+ };
118
+
119
+ if (state.configuration?.readonly) {
120
+ if (isDate(value)) {
121
+ try {
122
+ const dateValue = typeof value === 'string' || typeof value === 'number' || value instanceof Date ? value : String(value);
123
+ return <div>{dayjs(dateValue).format('dddd, MMM DD, YYYY')}</div>;
124
+ } catch (error) {
125
+ return <div>{String(value)}</div>;
126
+ }
127
+ }
128
+ if (isDateTime(value)) {
129
+ try {
130
+ const dateValue = typeof value === 'string' || typeof value === 'number' || value instanceof Date ? value : String(value);
131
+ return <div>{dayjs(dateValue).format('dddd, MMM DD, YYYY hh:mm A')}</div>;
132
+ } catch (error) {
133
+ return <div>{String(value)}</div>;
134
+ }
135
+ }
136
+ return <div className={className}>{String(value)}</div>;
137
+ }
138
+
139
+ if (isValue()) {
140
+ return <ValueComponent
141
+ value={typeof value === 'string' ? value : String(value)}
142
+ property={property}
143
+ />;
144
+ }
145
+
146
+ if (isBoolean()) {
147
+ return (
148
+ <BooleanComponent
149
+ property={property}
150
+ value={value as boolean}
151
+ onSaveProperty={savePropertyValue}
152
+ />
153
+ );
154
+ }
155
+
156
+ if (isDateTime(value)) {
157
+ return (
158
+ <DateTimeComponent
159
+ property={property}
160
+ value={value as string}
161
+ onSaveProperty={savePropertyValue}
162
+ />
163
+ );
164
+ }
165
+
166
+ if (isDate(value)) {
167
+ return (
168
+ <DateComponent
169
+ property={property}
170
+ value={value as string}
171
+ onSaveProperty={savePropertyValue}
172
+ />
173
+ );
174
+ }
175
+
176
+ if (isTime(value)) {
177
+ return (
178
+ <TimeComponent
179
+ property={property}
180
+ value={value as string}
181
+ onSaveProperty={savePropertyValue}
182
+ />
183
+ );
184
+ }
185
+
186
+ if (isNumber(value)) {
187
+ return (
188
+ <NumberComponent
189
+ property={property}
190
+ value={value as number}
191
+ definition={definition}
192
+ onSaveProperty={savePropertyValue}
193
+ />
194
+ );
195
+ }
196
+
197
+ if (isSelect()) {
198
+ return (
199
+ <SelectComponent
200
+ property={property}
201
+ value={value as string}
202
+ definition={{
203
+ values: definition.values || [],
204
+ style: definition.style
205
+ }}
206
+ onSaveProperty={savePropertyValue}
207
+ />
208
+ );
209
+ }
210
+
211
+ if (isURL(String(value)) && state.configuration?.enableUrlMarkup) {
212
+ return (
213
+ <UrlComponent
214
+ property={property}
215
+ value={String(value)}
216
+ onCreateEntity={onCreateEntity}
217
+ />
218
+ );
219
+ }
220
+
221
+ if (isText(value) && definition.type.includes('TextArea')) {
222
+ return (
223
+ <TextComponent
224
+ type="textarea"
225
+ property={property}
226
+ value={value as string}
227
+ definition={{
228
+ minLength: definition.minLength,
229
+ maxLength: definition.maxLength,
230
+ regex: definition.regex,
231
+ dateFormat: definition.dateFormat
232
+ }}
233
+ placeholder={placeholder}
234
+ onSaveProperty={savePropertyValue}
235
+ />
236
+ );
237
+ }
238
+
239
+ return (
240
+ <TextComponent
241
+ property={property}
242
+ value={value as string}
243
+ definition={{
244
+ minLength: definition.minLength,
245
+ maxLength: definition.maxLength,
246
+ regex: definition.regex,
247
+ dateFormat: definition.dateFormat
248
+ }}
249
+ placeholder={placeholder}
250
+ onSaveProperty={savePropertyValue}
251
+ />
252
+ );
253
+ };
254
+
255
+ export default EntityPropertyInstance;
@@ -0,0 +1,95 @@
1
+ import React, { useState, useMemo, useContext } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Tag, Select, Flex } from 'antd';
4
+ import { ProfileManagerContext } from '../Shell';
5
+ import { useStateStore } from '../store';
6
+
7
+ interface EntityTypeProps {
8
+ entity: {
9
+ '@type': string[];
10
+ };
11
+ onUpdateEntity: (data: { property: string; value: string[] }) => void;
12
+ }
13
+
14
+ export const EntityType: React.FC<EntityTypeProps> = ({ entity, onUpdateEntity }) => {
15
+ const [selectedClass, setSelectedClass] = useState<string | undefined>(undefined);
16
+ const profileManager = useContext(ProfileManagerContext);
17
+ const state = useStateStore();
18
+ const { t } = useTranslation();
19
+
20
+ const classes = useMemo(() => {
21
+ return profileManager?.getClasses().map((c: string) => ({ value: c, label: c })) || [];
22
+ }, [profileManager]);
23
+
24
+ const types = useMemo(() => {
25
+ return entity['@type'];
26
+ }, [entity]);
27
+
28
+ const closable = useMemo(() => {
29
+ return entity['@type'].length > 1;
30
+ }, [entity]);
31
+
32
+ const getTypeLabelFromProfile = (type: string) => {
33
+ return profileManager?.getTypeLabel(type) || type;
34
+ };
35
+
36
+ const handleSave = (newClass: string) => {
37
+ if (!newClass) return;
38
+ onUpdateEntity({
39
+ property: '@type',
40
+ value: [...entity['@type'], newClass],
41
+ });
42
+ setSelectedClass('');
43
+ };
44
+
45
+ const handleDelete = (typeToDelete: string) => {
46
+ const updatedTypes = entity['@type'].filter(t => t !== typeToDelete);
47
+ onUpdateEntity({
48
+ property: '@type',
49
+ value: updatedTypes,
50
+ });
51
+ setSelectedClass('');
52
+ };
53
+
54
+ return (
55
+ <Flex className="flex-row">
56
+ <div className="min-w-32 w-1/3 xl:w-1/5 flex flex-col describo-property-name">@type</div>
57
+ <Flex className="w-2/3 xl:w-4/5 flex-row flex-wrap">
58
+ {types.map((etype) => (
59
+ <Tag
60
+ key={etype}
61
+ closable={closable}
62
+ onClose={() => handleDelete(etype)}
63
+ style={{
64
+ backgroundColor: '#f0f0f0',
65
+ borderRadius: '16px',
66
+ padding: '0 12px',
67
+ height: '32px',
68
+ display: 'flex',
69
+ alignItems: 'center',
70
+ margin: '4px',
71
+ }}
72
+ >
73
+ {getTypeLabelFromProfile(etype)}
74
+ </Tag>
75
+ ))}
76
+ {!state.configuration?.readonly && (
77
+ <Select
78
+ value={selectedClass}
79
+ onChange={(value) => handleSave(value)}
80
+ placeholder={t("select_a_class_to_add")}
81
+ style={{ width: 250, margin: '4px', height: '32px' }}
82
+ >
83
+ {classes.map((classOption: { value: string; label: string }) => (
84
+ <Select.Option key={classOption.value} value={classOption.value}>
85
+ {classOption.label}
86
+ </Select.Option>
87
+ ))}
88
+ </Select>
89
+ )}
90
+ </Flex>
91
+ </Flex>
92
+ );
93
+ };
94
+
95
+ export default EntityType;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { Typography } from 'antd';
3
+ import RenderTypes from './RenderTypes';
4
+
5
+ interface ItemLinkProps {
6
+ entity: {
7
+ '@id': string;
8
+ '@type': string[];
9
+ name: string;
10
+ };
11
+ onLoadEntity: (data: { id: string }) => void;
12
+ className?: string; // Add this line
13
+ }
14
+
15
+ export const ItemLink: React.FC<ItemLinkProps> = ({ entity, onLoadEntity, className }) => {
16
+ const handleLoadEntity = () => {
17
+ onLoadEntity({ id: entity['@id'] });
18
+ };
19
+
20
+ return (
21
+ <div className={`flex flex-col w-full ${className || ''}`} onClick={handleLoadEntity}>
22
+ <Typography.Text type="secondary" style={{ fontSize: '0.75rem' }} className="pb-1 mb-1 border-b border-black/20">
23
+ {decodeURIComponent(entity['@id'])}
24
+ </Typography.Text>
25
+ <div className="flex flex-row space-x-2 items-center">
26
+ <div className="text-base flex flex-row space-x-1">
27
+ <RenderTypes types={entity['@type']} />
28
+ </div>
29
+ <Typography.Text strong>
30
+ {entity.name}
31
+ </Typography.Text>
32
+ </div>
33
+ </div>
34
+ );
35
+ };
36
+
37
+ export default ItemLink;
@@ -0,0 +1,43 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import PaginateLinkedEntities from './PaginateLinkedEntities';
3
+ import Chance from 'chance';
4
+ import range from 'lodash/range';
5
+
6
+ const chance = new Chance();
7
+
8
+ const meta: Meta<typeof PaginateLinkedEntities> = {
9
+ component: PaginateLinkedEntities,
10
+ argTypes: {
11
+ onLoadEntity: { action: 'loadEntity' },
12
+ },
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof PaginateLinkedEntities>;
17
+
18
+ function generateEntities(limit: number) {
19
+ return range(0, limit).map((i) => ({
20
+ idx: i,
21
+ value: {
22
+ '@id': chance.url(),
23
+ '@type': ['File'],
24
+ name: `/path/to/file/${chance.word()}`,
25
+ },
26
+ }));
27
+ }
28
+
29
+ export const ValidEntityInputWithOneEntity: Story = {
30
+ args: {
31
+ readonly: false,
32
+ property: 'something',
33
+ entities: generateEntities(1),
34
+ },
35
+ };
36
+
37
+ export const ValidEntityInputWithOneHundredEntities: Story = {
38
+ args: {
39
+ readonly: false,
40
+ property: 'something',
41
+ entities: generateEntities(100),
42
+ },
43
+ };
@@ -0,0 +1,141 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { Input, Pagination } from 'antd';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { useStateStore } from '../store';
5
+ import ItemLink from './ItemLink';
6
+ import RenderLinkedItem from './RenderLinkedItem';
7
+
8
+ interface PaginateLinkedEntitiesProps {
9
+ entities: Array<{
10
+ idx: number;
11
+ value: {
12
+ '@id': string;
13
+ '@type': string[];
14
+ name: string;
15
+ };
16
+ }>;
17
+ property: string;
18
+ readonly?: boolean;
19
+ className?: string;
20
+ onLoadEntity: (data: { id: string }) => void;
21
+ onUnlinkEntity: (data: { property: string; tgtEntityId: string }) => void;
22
+ }
23
+
24
+ const PaginateLinkedEntities: React.FC<PaginateLinkedEntitiesProps> = ({
25
+ entities,
26
+ property,
27
+ readonly = false,
28
+ className = '',
29
+ onLoadEntity,
30
+ onUnlinkEntity
31
+ }) => {
32
+ const { t } = useTranslation();
33
+ const editorState = useStateStore();
34
+ const [filter, setFilter] = useState<string>('');
35
+ const [pageSize] = useState(10);
36
+ const [currentPage, setCurrentPage] = useState(
37
+ editorState.editorState.latest()[property]?.paginator?.currentPage ?? 1
38
+ );
39
+ const [displayEntities, setDisplayEntities] = useState<typeof entities>([]);
40
+ const [total, setTotal] = useState(entities.length);
41
+
42
+ useEffect(() => {
43
+ setTotal(entities.length);
44
+ setCurrentPage(editorState.editorState.latest()[property]?.paginator?.currentPage ?? 1);
45
+ filterAndChunkEntitiesForDisplay();
46
+ }, [entities]);
47
+
48
+ const filterAndChunkEntitiesForDisplay = () => {
49
+ if (total < pageSize) {
50
+ setCurrentPage(1);
51
+ }
52
+
53
+ const offset = (currentPage - 1) * pageSize;
54
+ let filteredEntities = entities;
55
+
56
+ if (filter) {
57
+ const re = new RegExp(filter, 'i');
58
+ filteredEntities = entities.filter(
59
+ (e) => e.value?.name?.match(re) || e.value?.['@id']?.match(re)
60
+ );
61
+ setTotal(filteredEntities.length);
62
+ } else {
63
+ setTotal(entities.length);
64
+ }
65
+
66
+ setDisplayEntities(filteredEntities.slice(offset, offset + pageSize));
67
+
68
+ const currentState = editorState.editorState.latest();
69
+ if (currentPage !== currentState[property]?.paginator?.currentPage) {
70
+ currentState[property] = {
71
+ paginator: {
72
+ currentPage: currentPage,
73
+ },
74
+ };
75
+ editorState.editorState.update(currentState);
76
+ }
77
+ };
78
+
79
+ useEffect(() => {
80
+ filterAndChunkEntitiesForDisplay();
81
+ }, [filter, currentPage]);
82
+
83
+ const handlePageChange = (_event: React.ChangeEvent<unknown>, page: number) => {
84
+ setCurrentPage(page);
85
+ };
86
+
87
+ const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
88
+ setFilter(event.target.value);
89
+ };
90
+
91
+ return (
92
+ <div className="flex flex-col">
93
+ <div className="flex flex-row justify-center pt-2 mb-4">
94
+ <Pagination
95
+ current={currentPage}
96
+ pageSize={pageSize}
97
+ total={total}
98
+ onChange={setCurrentPage}
99
+ showSizeChanger={false}
100
+ hideOnSinglePage={true}
101
+ showTotal={(total) => t('pagination_total', { total })}
102
+ />
103
+ </div>
104
+ <div className="flex flex-row space-x-2 items-center">
105
+ <div className="flex-grow">
106
+ <Input.Search
107
+ value={filter}
108
+ onChange={handleFilterChange}
109
+ onSearch={filterAndChunkEntitiesForDisplay}
110
+ placeholder={t('filter_the_entities') || 'Filter the entities'}
111
+ />
112
+ </div>
113
+ </div>
114
+ <div className="flex flex-col pt-2">
115
+ {displayEntities.map((entity) => (
116
+ <RenderLinkedItem
117
+ key={entity.value['@id']}
118
+ entity={entity.value}
119
+ property={property}
120
+ readonly={readonly}
121
+ onLoadEntity={onLoadEntity}
122
+ onUnlinkEntity={onUnlinkEntity}
123
+ />
124
+ ))}
125
+ </div>
126
+ <div className="flex flex-row justify-center pt-2">
127
+ <Pagination
128
+ current={currentPage}
129
+ pageSize={pageSize}
130
+ total={total}
131
+ onChange={setCurrentPage}
132
+ showSizeChanger={false}
133
+ hideOnSinglePage={true}
134
+ showTotal={(total) => t('pagination_total', { total })}
135
+ />
136
+ </div>
137
+ </div>
138
+ );
139
+ };
140
+
141
+ export default PaginateLinkedEntities;
@@ -0,0 +1,39 @@
1
+ import React, { useState, useMemo } from 'react';
2
+
3
+ interface PropertyHelpProps {
4
+ help?: string;
5
+ }
6
+
7
+ export const PropertyHelp: React.FC<PropertyHelpProps> = ({ help }) => {
8
+ const [showMore, setShowMore] = useState(false);
9
+ const length = 100;
10
+
11
+ const showToggle = useMemo(() => {
12
+ return help ? help.length > length : false;
13
+ }, [help]);
14
+
15
+ const displayHelp = useMemo(() => {
16
+ if (!help) return '';
17
+ if (showMore) return help;
18
+ return help.slice(0, length);
19
+ }, [help, showMore]);
20
+
21
+ if (!showToggle) {
22
+ return (
23
+ <div className="text-gray-600 font-light text-sm pr-1 describo-property-help">
24
+ {displayHelp}
25
+ </div>
26
+ );
27
+ }
28
+
29
+ return (
30
+ <div
31
+ className="text-gray-600 font-light text-sm pr-1 cursor-pointer describo-property-help-more"
32
+ onClick={() => setShowMore(!showMore)}
33
+ >
34
+ {displayHelp} {!showMore && <span>...</span>}
35
+ </div>
36
+ );
37
+ };
38
+
39
+ export default PropertyHelp;