@vertesia/ui 0.79.0 → 0.79.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/core/components/Panel.js +8 -0
- package/lib/esm/core/components/Panel.js.map +1 -0
- package/lib/esm/core/components/SelectBox.js +1 -1
- package/lib/esm/core/components/SelectBox.js.map +1 -1
- package/lib/esm/core/components/SidePanel.js +2 -2
- package/lib/esm/core/components/SidePanel.js.map +1 -1
- package/lib/esm/core/components/index.js +1 -1
- package/lib/esm/core/components/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/breadcrumb.js +29 -8
- package/lib/esm/core/components/shadcn/breadcrumb.js.map +1 -1
- package/lib/esm/core/components/shadcn/button.js +3 -2
- package/lib/esm/core/components/shadcn/button.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/filterBar.js +2 -2
- package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/esm/core/components/shadcn/index.js +1 -0
- package/lib/esm/core/components/shadcn/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/input.js +4 -1
- package/lib/esm/core/components/shadcn/input.js.map +1 -1
- package/lib/esm/core/components/shadcn/resizeable.js +2 -2
- package/lib/esm/core/components/shadcn/resizeable.js.map +1 -1
- package/lib/esm/core/components/shadcn/selectBox.js +15 -9
- package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/esm/core/components/shadcn/tabs.js +10 -3
- package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
- package/lib/esm/core/components/shadcn/textarea.js +7 -0
- package/lib/esm/core/components/shadcn/textarea.js.map +1 -0
- package/lib/esm/core/hooks/CompositeState.js +139 -1
- package/lib/esm/core/hooks/CompositeState.js.map +1 -1
- package/lib/esm/core/hooks/index.js +1 -0
- package/lib/esm/core/hooks/index.js.map +1 -1
- package/lib/esm/core/hooks/useScrollableSearch.js +92 -0
- package/lib/esm/core/hooks/useScrollableSearch.js.map +1 -0
- package/lib/esm/env/index.js +1 -1
- package/lib/esm/env/index.js.map +1 -1
- package/lib/esm/features/agent/PayloadBuilder.js +80 -55
- package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentConversation.js +22 -24
- package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -3
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +2 -2
- package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +15 -20
- package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js +1 -0
- package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js +3 -3
- package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +6 -6
- package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
- package/lib/esm/features/facets/CollectionsFacetsNav.js +19 -0
- package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/InteractionsFacetsNav.js +9 -3
- package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/utils/VTypeFacet.js +4 -1
- package/lib/esm/features/facets/utils/VTypeFacet.js.map +1 -1
- package/lib/esm/features/layout/GenericPageNavHeader.js +58 -5
- package/lib/esm/features/layout/GenericPageNavHeader.js.map +1 -1
- package/lib/esm/features/store/collections/BrowseCollectionView.js +3 -0
- package/lib/esm/features/store/collections/BrowseCollectionView.js.map +1 -1
- package/lib/esm/features/store/collections/CreateCollection.js +2 -2
- package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
- package/lib/esm/features/store/collections/EditCollectionView.js +29 -30
- package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
- package/lib/esm/features/store/collections/SelectCollection.js +46 -45
- package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentSearchResults.js +35 -9
- package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentTable.js +6 -6
- package/lib/esm/features/store/objects/DocumentTable.js.map +1 -1
- package/lib/esm/features/store/objects/components/ContentOverview.js +158 -114
- package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/esm/features/store/objects/components/DocumentIcon.js +5 -3
- package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
- package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js +11 -2
- package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
- package/lib/esm/features/store/objects/components/useDownloadObject.js +2 -2
- package/lib/esm/features/store/objects/components/useDownloadObject.js.map +1 -1
- package/lib/esm/features/store/objects/layout/DocumentTableColumn.js +13 -1
- package/lib/esm/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
- package/lib/esm/features/store/objects/layout/documentLayout.js +5 -5
- package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
- package/lib/esm/features/store/objects/layout/renderers.js +28 -12
- package/lib/esm/features/store/objects/layout/renderers.js.map +1 -1
- package/lib/esm/features/store/objects/search/DocumentSearchContext.js +5 -1
- package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
- package/lib/esm/features/store/objects/search/DocumentSearchProvider.js +1 -1
- package/lib/esm/features/store/objects/search/DocumentSearchProvider.js.map +1 -1
- package/lib/esm/features/store/objects/selection/ObjectsActionContext.js +3 -2
- package/lib/esm/features/store/objects/selection/ObjectsActionContext.js.map +1 -1
- package/lib/esm/features/store/objects/selection/SelectionActions.js +2 -0
- package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +10 -2
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js +20 -2
- package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js.map +1 -1
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +15 -7
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js +1 -1
- package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js.map +1 -1
- package/lib/esm/features/user/UserInfo.js +2 -0
- package/lib/esm/features/user/UserInfo.js.map +1 -1
- package/lib/esm/router/HistoryNavigator.js +25 -2
- package/lib/esm/router/HistoryNavigator.js.map +1 -1
- package/lib/esm/router/Nav.js +3 -3
- package/lib/esm/router/Nav.js.map +1 -1
- package/lib/esm/session/UserSession.js +1 -0
- package/lib/esm/session/UserSession.js.map +1 -1
- package/lib/esm/session/UserSessionProvider.js +9 -2
- package/lib/esm/session/UserSessionProvider.js.map +1 -1
- package/lib/esm/session/auth/composable.js +66 -67
- package/lib/esm/session/auth/composable.js.map +1 -1
- package/lib/esm/widgets/form/Form.js +17 -30
- package/lib/esm/widgets/form/Form.js.map +1 -1
- package/lib/esm/widgets/form/FormContext.js +4 -2
- package/lib/esm/widgets/form/FormContext.js.map +1 -1
- package/lib/esm/widgets/form/ManagedObject.js +4 -0
- package/lib/esm/widgets/form/ManagedObject.js.map +1 -1
- package/lib/esm/widgets/form/fields.js +4 -3
- package/lib/esm/widgets/form/fields.js.map +1 -1
- package/lib/esm/widgets/form/inputs.js +2 -0
- package/lib/esm/widgets/form/inputs.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/components/Panel.d.ts +11 -0
- package/lib/types/core/components/Panel.d.ts.map +1 -0
- package/lib/types/core/components/SidePanel.d.ts.map +1 -1
- package/lib/types/core/components/index.d.ts +1 -1
- package/lib/types/core/components/index.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/breadcrumb.d.ts +3 -2
- package/lib/types/core/components/shadcn/breadcrumb.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/button.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/index.d.ts +1 -0
- package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/input.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/selectBox.d.ts +3 -2
- package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/textarea.d.ts +4 -0
- package/lib/types/core/components/shadcn/textarea.d.ts.map +1 -0
- package/lib/types/core/hooks/CompositeState.d.ts +115 -6
- package/lib/types/core/hooks/CompositeState.d.ts.map +1 -1
- package/lib/types/core/hooks/index.d.ts +1 -0
- package/lib/types/core/hooks/index.d.ts.map +1 -1
- package/lib/types/core/hooks/useScrollableSearch.d.ts +82 -0
- package/lib/types/core/hooks/useScrollableSearch.d.ts.map +1 -0
- package/lib/types/env/index.d.ts +3 -1
- package/lib/types/env/index.d.ts.map +1 -1
- package/lib/types/features/agent/PayloadBuilder.d.ts +11 -19
- package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/PlanPanel.d.ts.map +1 -1
- package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/facets/InteractionsFacetsNav.d.ts +1 -0
- package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/facets/utils/SearchInterface.d.ts +6 -1
- package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -1
- package/lib/types/features/facets/utils/VTypeFacet.d.ts +2 -1
- package/lib/types/features/facets/utils/VTypeFacet.d.ts.map +1 -1
- package/lib/types/features/layout/GenericPageNavHeader.d.ts +2 -1
- package/lib/types/features/layout/GenericPageNavHeader.d.ts.map +1 -1
- package/lib/types/features/store/collections/BrowseCollectionView.d.ts.map +1 -1
- package/lib/types/features/store/collections/CreateCollection.d.ts.map +1 -1
- package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
- package/lib/types/features/store/collections/SelectCollection.d.ts +6 -4
- package/lib/types/features/store/collections/SelectCollection.d.ts.map +1 -1
- package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
- package/lib/types/features/store/objects/DocumentTable.d.ts +4 -0
- package/lib/types/features/store/objects/DocumentTable.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/DocumentIcon.d.ts +3 -1
- package/lib/types/features/store/objects/components/DocumentIcon.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/SaveVersionConfirmModal.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/useDownloadObject.d.ts +1 -1
- package/lib/types/features/store/objects/components/useDownloadObject.d.ts.map +1 -1
- package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts +2 -1
- package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
- package/lib/types/features/store/objects/layout/documentLayout.d.ts +4 -2
- package/lib/types/features/store/objects/layout/documentLayout.d.ts.map +1 -1
- package/lib/types/features/store/objects/layout/renderers.d.ts +1 -1
- package/lib/types/features/store/objects/layout/renderers.d.ts.map +1 -1
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +1 -0
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/types/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
- package/lib/types/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
- package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts +1 -0
- package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts.map +1 -1
- package/lib/types/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
- package/lib/types/features/user/UserInfo.d.ts.map +1 -1
- package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
- package/lib/types/router/Nav.d.ts +2 -1
- package/lib/types/router/Nav.d.ts.map +1 -1
- package/lib/types/session/UserSession.d.ts.map +1 -1
- package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/types/session/auth/composable.d.ts.map +1 -1
- package/lib/types/widgets/form/Form.d.ts +2 -1
- package/lib/types/widgets/form/Form.d.ts.map +1 -1
- package/lib/types/widgets/form/FormContext.d.ts +5 -2
- package/lib/types/widgets/form/FormContext.d.ts.map +1 -1
- package/lib/types/widgets/form/ManagedObject.d.ts.map +1 -1
- package/lib/types/widgets/form/fields.d.ts +2 -2
- package/lib/types/widgets/form/fields.d.ts.map +1 -1
- package/lib/types/widgets/form/inputs.d.ts.map +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-env.js +1 -1
- package/lib/vertesia-ui-env.js.map +1 -1
- package/lib/vertesia-ui-features.js +1 -1
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-router.js +1 -1
- package/lib/vertesia-ui-router.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +1 -1
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/package.json +166 -166
- package/src/core/components/Panel.tsx +34 -0
- package/src/core/components/SidePanel.tsx +5 -3
- package/src/core/components/index.ts +1 -1
- package/src/core/components/shadcn/breadcrumb.tsx +49 -30
- package/src/core/components/shadcn/button.tsx +3 -2
- package/src/core/components/shadcn/filters/filterBar.tsx +3 -3
- package/src/core/components/shadcn/index.ts +2 -1
- package/src/core/components/shadcn/input.tsx +10 -7
- package/src/core/components/shadcn/resizeable.tsx +4 -4
- package/src/core/components/shadcn/selectBox.tsx +87 -67
- package/src/core/components/shadcn/tabs.tsx +10 -3
- package/src/core/components/shadcn/textarea.tsx +21 -0
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/useScrollableSearch.tsx +193 -0
- package/src/features/agent/chat/ModernAgentConversation.tsx +109 -118
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +2 -22
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +1 -9
- package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +39 -55
- package/src/features/agent/chat/ModernAgentOutput/PlanPanel.tsx +1 -0
- package/src/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.tsx +8 -8
- package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +8 -8
- package/src/features/facets/CollectionsFacetsNav.tsx +21 -0
- package/src/features/facets/InteractionsFacetsNav.tsx +13 -3
- package/src/features/facets/utils/SearchInterface.tsx +5 -1
- package/src/features/facets/utils/VTypeFacet.tsx +6 -2
- package/src/features/layout/GenericPageNavHeader.tsx +73 -10
- package/src/features/store/collections/BrowseCollectionView.tsx +4 -0
- package/src/features/store/collections/CreateCollection.tsx +3 -4
- package/src/features/store/collections/EditCollectionView.tsx +91 -85
- package/src/features/store/collections/SelectCollection.tsx +105 -49
- package/src/features/store/objects/DocumentSearchResults.tsx +117 -51
- package/src/features/store/objects/DocumentTable.tsx +14 -4
- package/src/features/store/objects/components/ContentOverview.tsx +208 -110
- package/src/features/store/objects/components/DocumentIcon.tsx +11 -12
- package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +12 -2
- package/src/features/store/objects/layout/DocumentTableColumn.tsx +16 -1
- package/src/features/store/objects/layout/documentLayout.tsx +7 -5
- package/src/features/store/objects/layout/knowledge.md +10 -10
- package/src/features/store/objects/layout/renderers.tsx +39 -18
- package/src/features/store/objects/search/DocumentSearchContext.ts +6 -1
- package/src/features/store/objects/search/DocumentSearchProvider.tsx +1 -1
- package/src/features/store/objects/selection/ObjectsActionContext.tsx +3 -2
- package/src/features/store/objects/selection/SelectionActions.tsx +2 -0
- package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +8 -2
- package/src/features/store/objects/selection/actions/DeleteObjectsAction.tsx +22 -2
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +18 -9
- package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +10 -7
- package/src/features/store/types/CreateOrUpdateTypeModal.tsx +1 -1
- package/src/router/HistoryNavigator.ts +33 -2
- package/src/router/Nav.tsx +4 -3
- package/src/widgets/form/Form.tsx +19 -43
- package/src/widgets/form/FormContext.ts +5 -2
- package/src/widgets/form/fields.tsx +8 -6
- package/src/widgets/form/inputs.tsx +1 -0
- package/lib/esm/core/components/Textarea.js +0 -15
- package/lib/esm/core/components/Textarea.js.map +0 -1
- package/lib/types/core/components/Textarea.d.ts +0 -8
- package/lib/types/core/components/Textarea.d.ts.map +0 -1
- package/src/core/components/Textarea.tsx +0 -25
|
@@ -30,8 +30,8 @@ Complete list of supported types:
|
|
|
30
30
|
1. **string** - Text display
|
|
31
31
|
2. **number** - Numeric display
|
|
32
32
|
3. **date** - Date/time display
|
|
33
|
-
4. **
|
|
34
|
-
5. **
|
|
33
|
+
4. **objectId** - object id with preview button
|
|
34
|
+
5. **objectName** - object name display
|
|
35
35
|
|
|
36
36
|
### Column Types and Renderers
|
|
37
37
|
Built-in renderers with parameters:
|
|
@@ -48,14 +48,14 @@ Built-in renderers with parameters:
|
|
|
48
48
|
- `currency`: Format as currency (e.g., USD)
|
|
49
49
|
- `decimals`: Number of decimal places (default: 2)
|
|
50
50
|
|
|
51
|
-
3. **
|
|
52
|
-
- `title`: Property to use as title (default: "title")
|
|
53
|
-
- `underline`: Link underline style (default: "hover")
|
|
54
|
-
|
|
55
|
-
4. **date**
|
|
51
|
+
3. **date**
|
|
56
52
|
- `localized`: Use localized format (e.g., "LLL")
|
|
57
53
|
- `relative`: Use relative time ("fromNow"/"toNow")
|
|
58
54
|
|
|
55
|
+
4. **objectId**
|
|
56
|
+
- `slice`: Take substring from index
|
|
57
|
+
|
|
58
|
+
|
|
59
59
|
### Parameter Syntax
|
|
60
60
|
Parameters are added using URL query string syntax:
|
|
61
61
|
```typescript
|
|
@@ -92,12 +92,12 @@ Parameters are added using URL query string syntax:
|
|
|
92
92
|
{
|
|
93
93
|
"name": "ID",
|
|
94
94
|
"field": "id",
|
|
95
|
-
"type": "
|
|
95
|
+
"type": "objectId?slice=-7"
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
"name": "Name",
|
|
99
99
|
"field": ".",
|
|
100
|
-
"type": "
|
|
100
|
+
"type": "objectName"
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
"name": "Price",
|
|
@@ -126,7 +126,7 @@ Parameters are added using URL query string syntax:
|
|
|
126
126
|
{
|
|
127
127
|
"name": "Document",
|
|
128
128
|
"field": ".",
|
|
129
|
-
"type": "
|
|
129
|
+
"type": "objectName"
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
"name": "Score",
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { NavLink } from "@vertesia/ui/router";
|
|
2
1
|
import dayjs from "dayjs";
|
|
3
2
|
import LocalizedFormat from "dayjs/plugin/localizedFormat";
|
|
4
3
|
import RelativeTime from "dayjs/plugin/relativeTime";
|
|
5
4
|
import { shortId } from "../../../utils";
|
|
5
|
+
import { Eye } from "lucide-react";
|
|
6
|
+
import { Button } from "@vertesia/ui/core";
|
|
6
7
|
dayjs.extend(RelativeTime);
|
|
7
8
|
dayjs.extend(LocalizedFormat);
|
|
8
9
|
|
|
9
|
-
const renderers: Record<string, (params?: URLSearchParams) => (value: any, index: number) => React.ReactNode> = {
|
|
10
|
-
string(params?: URLSearchParams) {
|
|
10
|
+
const renderers: Record<string, (params?: URLSearchParams, onClick?: (id: string) => void) => (value: any, index: number) => React.ReactNode> = {
|
|
11
|
+
string(params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
11
12
|
let transforms: ((value: string) => string)[] = [];
|
|
12
13
|
if (params) {
|
|
13
14
|
const slice = params.get("slice");
|
|
@@ -48,7 +49,7 @@ const renderers: Record<string, (params?: URLSearchParams) => (value: any, index
|
|
|
48
49
|
};
|
|
49
50
|
},
|
|
50
51
|
|
|
51
|
-
fileSize(_params?: URLSearchParams) {
|
|
52
|
+
fileSize(_params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
52
53
|
return (value: any, index: number) => {
|
|
53
54
|
let fileSize = "";
|
|
54
55
|
if (value) {
|
|
@@ -69,7 +70,7 @@ const renderers: Record<string, (params?: URLSearchParams) => (value: any, index
|
|
|
69
70
|
};
|
|
70
71
|
},
|
|
71
72
|
|
|
72
|
-
number(params?: URLSearchParams) {
|
|
73
|
+
number(params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
73
74
|
let currency: string | undefined;
|
|
74
75
|
let decimals: string | undefined;
|
|
75
76
|
if (params) {
|
|
@@ -88,34 +89,54 @@ const renderers: Record<string, (params?: URLSearchParams) => (value: any, index
|
|
|
88
89
|
return <td key={index}>{v}</td>;
|
|
89
90
|
};
|
|
90
91
|
},
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
objectId(params?: URLSearchParams, onClick?: (id: string) => void) {
|
|
93
|
+
let transforms: ((value: string) => string)[] = [];
|
|
94
|
+
let hasSlice = false;
|
|
95
|
+
if (params) {
|
|
96
|
+
const slice = params.get("slice");
|
|
97
|
+
if (slice) {
|
|
98
|
+
hasSlice = true;
|
|
99
|
+
transforms.push((value) => value.slice(parseInt(slice)));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return (value: any, index: number) => {
|
|
103
|
+
const displayValue = transforms.reduce((v, t) => t(v), value.id);
|
|
104
|
+
return (
|
|
105
|
+
<td key={index} className="flex justify-between items-center gap-2">
|
|
106
|
+
{hasSlice ? '~' : ''}{displayValue}
|
|
107
|
+
<Button
|
|
108
|
+
variant="ghost"
|
|
109
|
+
alt="Preview Object"
|
|
110
|
+
onClick={(e) => {
|
|
111
|
+
e.stopPropagation();
|
|
112
|
+
onClick?.(value.id);
|
|
113
|
+
}}
|
|
114
|
+
>
|
|
115
|
+
<Eye className="size-4" />
|
|
116
|
+
</Button>
|
|
117
|
+
</td>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
objectName(params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
93
122
|
let title = "title";
|
|
94
|
-
//let underline = "hover";
|
|
95
123
|
if (params) {
|
|
96
124
|
title = params.get("title") || "title";
|
|
97
|
-
//underline = params.get("underline") || "hover";
|
|
98
125
|
}
|
|
99
126
|
return (value: any, index: number) => {
|
|
100
127
|
return (
|
|
101
128
|
<td key={index}>
|
|
102
|
-
|
|
103
|
-
topLevelNav
|
|
104
|
-
className="underline text-indigo-800 dark:text-indigo-300"
|
|
105
|
-
href={`/store/objects/${value.id}`}
|
|
106
|
-
>
|
|
107
|
-
{value.properties?.[title] || value.name || shortId(value.id)}
|
|
108
|
-
</NavLink>
|
|
129
|
+
{value.properties?.[title] || value.name || shortId(value.id)}
|
|
109
130
|
</td>
|
|
110
131
|
);
|
|
111
132
|
};
|
|
112
133
|
},
|
|
113
|
-
typeLink(_params?: URLSearchParams) {
|
|
134
|
+
typeLink(_params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
114
135
|
return (value: any, index: number) => {
|
|
115
136
|
return <td key={index}>{value?.name || "n/a"}</td>;
|
|
116
137
|
};
|
|
117
138
|
},
|
|
118
|
-
date(params?: URLSearchParams) {
|
|
139
|
+
date(params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
119
140
|
let method = "format";
|
|
120
141
|
let arg: string | undefined = "LLL";
|
|
121
142
|
if (params) {
|
|
@@ -55,9 +55,13 @@ export class DocumentSearch implements SearchInterface {
|
|
|
55
55
|
this.search();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
setDefaultKeys(keys: any[]) {
|
|
59
|
+
void keys;
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
clearFilters(autoSearch: boolean = true) {
|
|
59
63
|
// Preserve search-related fields when clearing filters
|
|
60
|
-
const { parent, full_text, vector, weights, score_aggregation, dynamic_scaling, limit } = this.query;
|
|
64
|
+
const { parent, full_text, vector, weights, score_aggregation, dynamic_scaling, limit, all_revisions } = this.query;
|
|
61
65
|
this.query = {
|
|
62
66
|
parent,
|
|
63
67
|
...(full_text !== undefined && { full_text }),
|
|
@@ -65,6 +69,7 @@ export class DocumentSearch implements SearchInterface {
|
|
|
65
69
|
...(weights !== undefined && { weights }),
|
|
66
70
|
...(score_aggregation !== undefined && { score_aggregation }),
|
|
67
71
|
...(dynamic_scaling !== undefined && { dynamic_scaling }),
|
|
72
|
+
...(all_revisions !== undefined && { all_revisions }),
|
|
68
73
|
...(limit !== undefined && { limit })
|
|
69
74
|
};
|
|
70
75
|
|
|
@@ -42,7 +42,7 @@ export function DocumentSearchProvider({ children, limit, parent, typeId, facets
|
|
|
42
42
|
search.query.parent = parent;
|
|
43
43
|
search.query.name = name;
|
|
44
44
|
return search;
|
|
45
|
-
}, [typeId, limit]);
|
|
45
|
+
}, [typeId, limit, collectionId]);
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
48
|
<SearchContext.Provider value={search}>{children}</SearchContext.Provider>
|
|
@@ -6,7 +6,7 @@ import { useUserSession } from '@vertesia/ui/session';
|
|
|
6
6
|
import { useDocumentSearch, useDocumentSelection } from '../../../store';
|
|
7
7
|
import { AddToCollectionAction } from './actions/AddToCollectionAction';
|
|
8
8
|
import { ChangeTypeAction } from './actions/ChangeTypeAction';
|
|
9
|
-
import { DeleteObjectsAction } from './actions/DeleteObjectsAction';
|
|
9
|
+
import { DeleteObjectsAction, DeleteObjectsFromCollectionsAction } from './actions/DeleteObjectsAction';
|
|
10
10
|
import { ExportPropertiesAction } from './actions/ExportPropertiesAction';
|
|
11
11
|
import { RemoveFromCollectionAction } from './actions/RemoveFromCollectionAction';
|
|
12
12
|
import { StartWorkflowAction, StartWorkflowComponent } from './actions/StartWorkflowComponent';
|
|
@@ -22,6 +22,7 @@ export class ObjectsActionContext {
|
|
|
22
22
|
AddToCollectionAction,
|
|
23
23
|
DeleteObjectsAction,
|
|
24
24
|
RemoveFromCollectionAction,
|
|
25
|
+
DeleteObjectsFromCollectionsAction
|
|
25
26
|
];
|
|
26
27
|
wfRules: ObjectsActionSpec[] = [];
|
|
27
28
|
callbacks: Record<string, ObjectsActionCallback> = {};
|
|
@@ -38,7 +39,7 @@ export class ObjectsActionContext {
|
|
|
38
39
|
);
|
|
39
40
|
} else {
|
|
40
41
|
return this.allActions.filter(action =>
|
|
41
|
-
action.id !== 'removeFromCollection'
|
|
42
|
+
action.id !== 'removeFromCollection' && action.id !== 'deleteFromCollections'
|
|
42
43
|
);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
@@ -62,6 +62,8 @@ export function UploadObjectsButton({ collectionId }: { collectionId?: string })
|
|
|
62
62
|
const selectFile = () => {
|
|
63
63
|
const fileInput = document.createElement("input");
|
|
64
64
|
fileInput.type = "file";
|
|
65
|
+
fileInput.multiple = true;
|
|
66
|
+
fileInput.accept = "*";
|
|
65
67
|
fileInput?.click();
|
|
66
68
|
fileInput.onchange = (event) => {
|
|
67
69
|
const files = (event.target as HTMLInputElement).files;
|
|
@@ -85,8 +85,14 @@ function AddToCollectionForm({ onClose, objectIds }: AddToCollectionFormProps) {
|
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const onCollectionChange = (collectionId: string | undefined) => {
|
|
89
|
-
|
|
88
|
+
const onCollectionChange = (collectionId: string | string[] | undefined, _collection?: any) => {
|
|
89
|
+
if (typeof collectionId === "string" || typeof collectionId === "undefined") {
|
|
90
|
+
setSelectedCollectionId(collectionId);
|
|
91
|
+
} else if (Array.isArray(collectionId) && collectionId.length > 0) {
|
|
92
|
+
setSelectedCollectionId(collectionId[0]);
|
|
93
|
+
} else {
|
|
94
|
+
setSelectedCollectionId(undefined);
|
|
95
|
+
}
|
|
90
96
|
};
|
|
91
97
|
|
|
92
98
|
const tabs = [
|
|
@@ -28,12 +28,21 @@ export function DeleteObjectsActionComponent({ action, objectIds, children }: Ac
|
|
|
28
28
|
return Promise.resolve(false);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
function limitFilesName(names: string, maxLength: number) {
|
|
32
|
+
if (names.length <= maxLength) return names;
|
|
33
|
+
const extIndex = names.lastIndexOf('.');
|
|
34
|
+
const ext = extIndex !== -1 ? names.substring(extIndex) : '';
|
|
35
|
+
const baseName = extIndex !== -1 ? names.substring(0, extIndex) : names;
|
|
36
|
+
const limitedBaseName = baseName.substring(0, maxLength - ext.length - 3);
|
|
37
|
+
return `${limitedBaseName}...${ext}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
return Promise.all(objectIds.map(id => client.store.objects.delete(id))).then((res) => {
|
|
32
41
|
const plural = res.length > 1 ? 's' : '';
|
|
33
42
|
toast({
|
|
34
43
|
status: 'success',
|
|
35
44
|
title: `${res.length} object${plural} deleted`,
|
|
36
|
-
description: `Objects ${res.map(d => d.id).join(", ")} have been deleted`,
|
|
45
|
+
description: `Objects ${(limitFilesName(res.map(d => d.id).join(", "), 100))} have been deleted`,
|
|
37
46
|
duration: 2000
|
|
38
47
|
});
|
|
39
48
|
|
|
@@ -71,7 +80,18 @@ export const DeleteObjectsAction: ObjectsActionSpec = {
|
|
|
71
80
|
name: 'Delete',
|
|
72
81
|
description: 'Delete the selected objects',
|
|
73
82
|
confirm: true,
|
|
74
|
-
confirmationText: 'Are you sure you want to delete the selected objects?',
|
|
83
|
+
confirmationText: 'Are you sure you want to delete all the selected objects? This action cannot be undone.',
|
|
84
|
+
component: DeleteObjectsActionComponent,
|
|
85
|
+
destructive: true
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export const DeleteObjectsFromCollectionsAction: ObjectsActionSpec = {
|
|
90
|
+
id: 'deleteFromCollections',
|
|
91
|
+
name: 'Delete Objects',
|
|
92
|
+
description: 'Delete the selected objects',
|
|
93
|
+
confirm: true,
|
|
94
|
+
confirmationText: 'Are you sure you want to delete the selected objects?\nThis is not removable from collections.',
|
|
75
95
|
component: DeleteObjectsActionComponent,
|
|
76
96
|
destructive: true
|
|
77
97
|
}
|
|
@@ -314,6 +314,7 @@ export function DocumentUploadModal({
|
|
|
314
314
|
|
|
315
315
|
// Process files in batches of 50
|
|
316
316
|
const BATCH_SIZE = 50;
|
|
317
|
+
const PROGRESS_UPDATE_INTERVAL = 5; // Update progress every 5 files
|
|
317
318
|
|
|
318
319
|
// Helper function to process a batch of files
|
|
319
320
|
const processBatch = async (files: FileWithMetadata[], action: "create" | "update") => {
|
|
@@ -337,7 +338,8 @@ export function DocumentUploadModal({
|
|
|
337
338
|
});
|
|
338
339
|
}
|
|
339
340
|
|
|
340
|
-
// Process the batch
|
|
341
|
+
// Process the batch with progress tracking
|
|
342
|
+
let filesProcessedInBatch = 0;
|
|
341
343
|
await Promise.all(
|
|
342
344
|
batch.map(async (fileInfo) => {
|
|
343
345
|
try {
|
|
@@ -446,16 +448,23 @@ export function DocumentUploadModal({
|
|
|
446
448
|
// Mark the overall success as false if any file fails
|
|
447
449
|
result.success = false;
|
|
448
450
|
}
|
|
451
|
+
|
|
452
|
+
// Update progress every PROGRESS_UPDATE_INTERVAL files
|
|
453
|
+
filesProcessedInBatch++;
|
|
454
|
+
if (filesProcessedInBatch % PROGRESS_UPDATE_INTERVAL === 0 || filesProcessedInBatch === batch.length) {
|
|
455
|
+
setFileStatuses((currentStatuses) => {
|
|
456
|
+
const completedFiles = currentStatuses.filter(
|
|
457
|
+
(f) => f.status === "success" || f.status === "error",
|
|
458
|
+
).length;
|
|
459
|
+
const totalFiles = currentStatuses.length;
|
|
460
|
+
const progress = totalFiles > 0 ? Math.round((completedFiles / totalFiles) * 100) : 0;
|
|
461
|
+
setOverallProgress(progress);
|
|
462
|
+
return currentStatuses;
|
|
463
|
+
});
|
|
464
|
+
}
|
|
449
465
|
}),
|
|
450
466
|
);
|
|
451
467
|
|
|
452
|
-
// Calculate overall progress after each batch completion
|
|
453
|
-
const completedFiles = fileStatuses.filter(
|
|
454
|
-
(f) => f.status === "success" || f.status === "error",
|
|
455
|
-
).length;
|
|
456
|
-
const totalFiles = fileStatuses.length;
|
|
457
|
-
const progress = Math.round((completedFiles / totalFiles) * 100);
|
|
458
|
-
setOverallProgress(progress);
|
|
459
468
|
}
|
|
460
469
|
};
|
|
461
470
|
|
|
@@ -906,7 +915,7 @@ export function DocumentUploadModal({
|
|
|
906
915
|
};
|
|
907
916
|
|
|
908
917
|
return (
|
|
909
|
-
<VModal key={modalKey} isOpen={isOpen} onClose={handleClose} className="mx-auto">
|
|
918
|
+
<VModal key={modalKey} isOpen={isOpen} onClose={handleClose} className="mx-auto" disableCloseOnClickOutside>
|
|
910
919
|
<VModalTitle description={_description}>{_title}</VModalTitle>
|
|
911
920
|
{renderModalContent()}
|
|
912
921
|
{renderModalFooter()}
|
|
@@ -134,7 +134,10 @@ export function useSmartFileUploadProcessing() {
|
|
|
134
134
|
|
|
135
135
|
let res: ContentObjectItem[];
|
|
136
136
|
|
|
137
|
-
const payload: ComplexSearchPayload = {
|
|
137
|
+
const payload: ComplexSearchPayload = {
|
|
138
|
+
query: { match: query },
|
|
139
|
+
select: "id content.etag" // Only fetch fields needed for comparison
|
|
140
|
+
};
|
|
138
141
|
|
|
139
142
|
if (limitToCollectionId) {
|
|
140
143
|
res = (await client.store.collections.searchMembers(limitToCollectionId, payload)).results;
|
|
@@ -164,16 +167,16 @@ export function useSmartFileUploadProcessing() {
|
|
|
164
167
|
const namesInLocation = unskippedFiles
|
|
165
168
|
.filter((file) => file.location === location)
|
|
166
169
|
.map((file) => file.name);
|
|
167
|
-
const query = {
|
|
168
|
-
location: location ?? "",
|
|
170
|
+
const query: Record<string, any> = {
|
|
169
171
|
"content.name": { $in: namesInLocation },
|
|
172
|
+
location: location || "/"
|
|
170
173
|
};
|
|
171
174
|
if (limitToCollectionId) {
|
|
172
175
|
const res = client.store.collections.searchMembers(limitToCollectionId, {
|
|
173
176
|
query: {
|
|
174
177
|
match: query,
|
|
175
178
|
},
|
|
176
|
-
select:
|
|
179
|
+
select: "id content.name location" // Only fetch fields needed for comparison
|
|
177
180
|
}).then((response) => response.results);
|
|
178
181
|
queries.push(res);
|
|
179
182
|
} else {
|
|
@@ -181,7 +184,7 @@ export function useSmartFileUploadProcessing() {
|
|
|
181
184
|
query: {
|
|
182
185
|
match: query,
|
|
183
186
|
},
|
|
184
|
-
select:
|
|
187
|
+
select: "id content.name location" // Only fetch fields needed for comparison
|
|
185
188
|
});
|
|
186
189
|
queries.push(res);
|
|
187
190
|
}
|
|
@@ -193,10 +196,10 @@ export function useSmartFileUploadProcessing() {
|
|
|
193
196
|
//update fileWithMetadata
|
|
194
197
|
for (const doc of results) {
|
|
195
198
|
const file = filesWithMetadata.find(
|
|
196
|
-
//name must be the same, and location must
|
|
199
|
+
//name must be the same, and location must match (default is "/")
|
|
197
200
|
(f) =>
|
|
198
201
|
f.name === doc.content.name &&
|
|
199
|
-
(f.location ? f.location === doc.location : doc.location === ""),
|
|
202
|
+
(f.location ? f.location === doc.location : doc.location === "/"),
|
|
200
203
|
);
|
|
201
204
|
if (file) {
|
|
202
205
|
file.existingId = doc.id;
|
|
@@ -48,7 +48,7 @@ export function CreateOrUpdateTypeModal({ title, isOpen, onClose, okLabel, initi
|
|
|
48
48
|
</div>
|
|
49
49
|
<div>
|
|
50
50
|
<label className="block text-sm font-medium text-muted">Description</label>
|
|
51
|
-
<Textarea value={description} onChange={setDescription} />
|
|
51
|
+
<Textarea value={description} onChange={e => setDescription(e.target.value)} />
|
|
52
52
|
</div>
|
|
53
53
|
</div>
|
|
54
54
|
</ModalBody>
|
|
@@ -130,10 +130,41 @@ export class HistoryNavigator {
|
|
|
130
130
|
if (beforeEvent._canceled) {
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
|
-
|
|
133
|
+
|
|
134
|
+
// Build navigation chain by preserving previous history
|
|
135
|
+
const currentState = window.history.state;
|
|
136
|
+
const currentTitle = document.title;
|
|
137
|
+
|
|
138
|
+
// Create new history chain entry
|
|
139
|
+
const newChainEntry = {
|
|
140
|
+
title: currentTitle,
|
|
141
|
+
href: window.location.pathname + window.location.search + window.location.hash
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Build the history chain - clear if using replace
|
|
145
|
+
let historyChain: Array<{title: string, href: string}> = [];
|
|
146
|
+
if (!options.replace && currentState?.historyChain) {
|
|
147
|
+
historyChain = [...currentState.historyChain];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Only add to chain if not replacing
|
|
151
|
+
if (!options.replace) {
|
|
152
|
+
historyChain.push(newChainEntry);
|
|
153
|
+
|
|
154
|
+
// Limit chain length to prevent memory issues (keep last 10 entries)
|
|
155
|
+
if (historyChain.length > 10) {
|
|
156
|
+
historyChain = historyChain.slice(-10);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const stateToStore = {
|
|
134
161
|
from: window.location.href,
|
|
162
|
+
historyChain: historyChain,
|
|
135
163
|
data: options.state || undefined
|
|
136
|
-
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
window.history[options.replace ? 'replaceState' : 'pushState'](stateToStore, '', to.href);
|
|
167
|
+
|
|
137
168
|
this.fireLocationChange(new AfterLocationChangeEvent(type, to, options.state));
|
|
138
169
|
}
|
|
139
170
|
|
package/src/router/Nav.tsx
CHANGED
|
@@ -20,7 +20,7 @@ export function Nav({ children, onClick }: NavProps) {
|
|
|
20
20
|
if (link && link.href) {
|
|
21
21
|
ev.stopPropagation();
|
|
22
22
|
ev.preventDefault();
|
|
23
|
-
navigate(link.href);
|
|
23
|
+
navigate(link.href, { replace: true });
|
|
24
24
|
onClick?.(ev);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -40,14 +40,15 @@ interface NavLinkProps {
|
|
|
40
40
|
* use the root router to navigate
|
|
41
41
|
*/
|
|
42
42
|
topLevelNav?: boolean;
|
|
43
|
+
clearBreadcrumbs?: boolean;
|
|
43
44
|
}
|
|
44
|
-
export function NavLink({ children, href, className, topLevelNav }: NavLinkProps) {
|
|
45
|
+
export function NavLink({ children, href, className, topLevelNav, clearBreadcrumbs = false }: NavLinkProps) {
|
|
45
46
|
const { router } = useRouterContext();
|
|
46
47
|
const _onClick = (ev: SyntheticEvent) => {
|
|
47
48
|
ev.stopPropagation();
|
|
48
49
|
ev.preventDefault();
|
|
49
50
|
const actualRouter = topLevelNav ? router.getTopRouter() : router;
|
|
50
|
-
actualRouter.navigate(href);
|
|
51
|
+
actualRouter.navigate(href, { replace: clearBreadcrumbs });
|
|
51
52
|
}
|
|
52
53
|
return (
|
|
53
54
|
<a href={href} className={className} onClick={_onClick}>{children}</a>
|
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
|
|
2
2
|
import { Plus, Trash2 } from "lucide-react";
|
|
3
|
-
import { Button } from "@vertesia/ui/core";
|
|
3
|
+
import { Button, FormItem } from "@vertesia/ui/core";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import type { JSONSchemaObject } from "@vertesia/common";
|
|
6
6
|
import { ComponentType, ReactNode, SyntheticEvent, useState } from "react";
|
|
7
|
-
import { FormContextProvider, InputComponentProps, useForm } from "./FormContext.js";
|
|
7
|
+
import { FormContext, FormContextProvider, InputComponentProps, useForm } from "./FormContext.js";
|
|
8
8
|
import { ManagedListProperty, ManagedObject, ManagedObjectBase, ManagedProperty, Node } from "./ManagedObject.js";
|
|
9
|
-
import { FormLabel, FormHelper } from "./fields.js";
|
|
10
9
|
import { Input } from "./inputs.js";
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
11
|
interface FormProps {
|
|
16
12
|
object: ManagedObject;
|
|
17
13
|
components?: Record<string, ComponentType<InputComponentProps>>;
|
|
18
14
|
children?: ReactNode | ReactNode[];
|
|
19
15
|
onSubmit?: (data: JSONSchemaObject) => void;
|
|
20
16
|
onChange?: (prop: Node) => void;
|
|
17
|
+
disabled?: boolean;
|
|
21
18
|
}
|
|
22
|
-
export function Form({ object, components, onSubmit, children, onChange }: FormProps) {
|
|
19
|
+
export function Form({ object, components, onSubmit, children, onChange, disabled }: FormProps) {
|
|
23
20
|
const _onSubmit = (evt: SyntheticEvent) => {
|
|
24
21
|
evt.stopPropagation();
|
|
25
22
|
evt.preventDefault();
|
|
@@ -27,10 +24,7 @@ export function Form({ object, components, onSubmit, children, onChange }: FormP
|
|
|
27
24
|
}
|
|
28
25
|
object.observer = onChange;
|
|
29
26
|
return (
|
|
30
|
-
<FormContextProvider value={{
|
|
31
|
-
object,
|
|
32
|
-
components: components || {}
|
|
33
|
-
}}>
|
|
27
|
+
<FormContextProvider value={new FormContext(object, components || {}, disabled ?? false)}>
|
|
34
28
|
<form className="w-full" onSubmit={_onSubmit}>
|
|
35
29
|
{children}
|
|
36
30
|
</form>
|
|
@@ -58,24 +52,6 @@ export function GeneratedForm({ children, ...props }: FormProps) {
|
|
|
58
52
|
)
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
|
|
62
|
-
// interface FieldSetProps {
|
|
63
|
-
// name: string;
|
|
64
|
-
// children?: ReactNode | ReactNode[];
|
|
65
|
-
// }
|
|
66
|
-
// export function FieldSet({ name, children }: FieldSetProps) {
|
|
67
|
-
// const ctx = useForm();
|
|
68
|
-
// const newCtx = {
|
|
69
|
-
// ...ctx,
|
|
70
|
-
// object: ctx.object.getProperty(name) as ManagedObjectProperty
|
|
71
|
-
// }
|
|
72
|
-
// return (
|
|
73
|
-
// <FormContextProvider value={newCtx}>
|
|
74
|
-
// {children}
|
|
75
|
-
// </FormContextProvider>
|
|
76
|
-
// )
|
|
77
|
-
// }
|
|
78
|
-
|
|
79
55
|
function renderProperty(prop: Node) {
|
|
80
56
|
if (prop.isList) {
|
|
81
57
|
return <ListField key={prop.name} object={prop as ManagedListProperty} />
|
|
@@ -105,7 +81,7 @@ export function ScalarField({ object, editor, inline = false }: ScalarFieldProps
|
|
|
105
81
|
if (!editor) {
|
|
106
82
|
editor = object.schema.editor;
|
|
107
83
|
}
|
|
108
|
-
const { components } = useForm();
|
|
84
|
+
const { components, disabled } = useForm();
|
|
109
85
|
const Component = (editor && components[editor]) || Input;
|
|
110
86
|
const inputType = object.getInputType();
|
|
111
87
|
if (inputType === 'checkbox') {
|
|
@@ -113,20 +89,16 @@ export function ScalarField({ object, editor, inline = false }: ScalarFieldProps
|
|
|
113
89
|
}
|
|
114
90
|
|
|
115
91
|
const handleOnChange = (event: any) => {
|
|
92
|
+
if (disabled) return;
|
|
116
93
|
const { value } = event.target;
|
|
117
94
|
object.value = object.schema.isNumber ? parseFloat(value) : value
|
|
118
95
|
}
|
|
119
96
|
|
|
120
97
|
return (
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
</div>
|
|
126
|
-
{
|
|
127
|
-
object.schema.description && <FormHelper>{object.schema.description}</FormHelper>
|
|
128
|
-
}
|
|
129
|
-
</div>
|
|
98
|
+
<FormItem label={object.title} required={object.schema.isRequired} description={object.schema.description}
|
|
99
|
+
className={clsx('flex', inline ? 'flex-row items-center' : 'flex-col')}>
|
|
100
|
+
{!object.isListItem && <Component object={object} type={inputType} onChange={handleOnChange} />}
|
|
101
|
+
</FormItem>
|
|
130
102
|
)
|
|
131
103
|
}
|
|
132
104
|
|
|
@@ -149,13 +121,16 @@ interface ListFieldProps {
|
|
|
149
121
|
}
|
|
150
122
|
function ListField({ object }: ListFieldProps) {
|
|
151
123
|
const [value, setValue] = useState<any[]>(object.value || []);
|
|
124
|
+
const { disabled } = useForm();
|
|
152
125
|
|
|
153
126
|
const addItem = () => {
|
|
127
|
+
if (disabled) return;
|
|
154
128
|
object.add();
|
|
155
129
|
setValue([...object.value]);
|
|
156
130
|
};
|
|
157
131
|
|
|
158
132
|
const deleteItem = (index: number) => {
|
|
133
|
+
if (disabled) return;
|
|
159
134
|
object.remove(index);
|
|
160
135
|
setValue([...object.value]);
|
|
161
136
|
};
|
|
@@ -165,11 +140,11 @@ function ListField({ object }: ListFieldProps) {
|
|
|
165
140
|
{!object.isListItem && <div className='text-gray-900 dark:text-gray-200 font-semibold'>{object.title}</div>}
|
|
166
141
|
{
|
|
167
142
|
object.items.map((item, index) => {
|
|
168
|
-
return <ListItem key={`${index}-${value[index] ?? ''}`} object={item} list={object} onDelete={() => deleteItem(index)} />;
|
|
143
|
+
return <ListItem key={`${index}-${value[index] ?? ''}`} object={item} list={object} onDelete={() => deleteItem(index)} disabled={disabled} />;
|
|
169
144
|
})
|
|
170
145
|
}
|
|
171
146
|
<div>
|
|
172
|
-
<Button variant='secondary' onClick={addItem}><Plus className="size-6" /> Add</Button>
|
|
147
|
+
<Button variant='secondary' onClick={addItem} disabled={disabled}><Plus className="size-6" /> Add</Button>
|
|
173
148
|
</div>
|
|
174
149
|
</div>
|
|
175
150
|
)
|
|
@@ -179,8 +154,9 @@ interface ListItemProps {
|
|
|
179
154
|
list: ManagedListProperty;
|
|
180
155
|
object: Node & { index: number };
|
|
181
156
|
onDelete: () => void;
|
|
157
|
+
disabled?: boolean;
|
|
182
158
|
}
|
|
183
|
-
function ListItem({ list, object, onDelete }: ListItemProps) {
|
|
159
|
+
function ListItem({ list, object, onDelete, disabled }: ListItemProps) {
|
|
184
160
|
return (
|
|
185
161
|
<div className='flex gap-2 w-full'>
|
|
186
162
|
<div className="flex-1">
|
|
@@ -188,7 +164,7 @@ function ListItem({ list, object, onDelete }: ListItemProps) {
|
|
|
188
164
|
renderItemProperty(object, list.schema.arraySchema.editor)
|
|
189
165
|
}
|
|
190
166
|
</div>
|
|
191
|
-
<Button variant='secondary' onClick={onDelete}><Trash2 className='size-4' /></Button>
|
|
167
|
+
<Button variant='secondary' onClick={onDelete} disabled={disabled}><Trash2 className='size-4' /></Button>
|
|
192
168
|
</div>
|
|
193
169
|
)
|
|
194
170
|
}
|
|
@@ -15,10 +15,13 @@ export function useFieldSet() {
|
|
|
15
15
|
export interface InputComponentProps {
|
|
16
16
|
object: Node;
|
|
17
17
|
type: string; // the editor/input type
|
|
18
|
+
onChange?: (event: any) => void;
|
|
19
|
+
disabled?: boolean;
|
|
18
20
|
}
|
|
19
|
-
class FormContext {
|
|
21
|
+
export class FormContext {
|
|
20
22
|
constructor(public object: ManagedObject,
|
|
21
|
-
public components: Record<string, ComponentType<InputComponentProps>> = {}
|
|
23
|
+
public components: Record<string, ComponentType<InputComponentProps>> = {},
|
|
24
|
+
public disabled: boolean = false) {
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
}
|