@vertesia/ui 0.65.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/lib/esm/core/components/EmptyCollection.js +2 -2
  2. package/lib/esm/core/components/EmptyCollection.js.map +1 -1
  3. package/lib/esm/core/components/InputList.js +2 -2
  4. package/lib/esm/core/components/InputList.js.map +1 -1
  5. package/lib/esm/core/components/SidePanel.js +1 -1
  6. package/lib/esm/core/components/SidePanel.js.map +1 -1
  7. package/lib/esm/core/components/Switch.js +2 -2
  8. package/lib/esm/core/components/Switch.js.map +1 -1
  9. package/lib/esm/core/components/shadcn/calendar.js +0 -1
  10. package/lib/esm/core/components/shadcn/calendar.js.map +1 -1
  11. package/lib/esm/core/components/shadcn/checkbox.js +0 -1
  12. package/lib/esm/core/components/shadcn/checkbox.js.map +1 -1
  13. package/lib/esm/core/components/shadcn/command.js +0 -1
  14. package/lib/esm/core/components/shadcn/command.js.map +1 -1
  15. package/lib/esm/core/components/shadcn/dialog.js +0 -1
  16. package/lib/esm/core/components/shadcn/dialog.js.map +1 -1
  17. package/lib/esm/core/components/shadcn/filters/comboBox.js +18 -0
  18. package/lib/esm/core/components/shadcn/filters/comboBox.js.map +1 -1
  19. package/lib/esm/core/components/shadcn/filters/filterBar.js +38 -17
  20. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  21. package/lib/esm/core/components/shadcn/filters/filters.js +11 -5
  22. package/lib/esm/core/components/shadcn/filters/filters.js.map +1 -1
  23. package/lib/esm/core/components/shadcn/filters/selectFilter.js +1 -1
  24. package/lib/esm/core/components/shadcn/filters/selectFilter.js.map +1 -1
  25. package/lib/esm/core/components/shadcn/filters/stringListFilter.js +24 -0
  26. package/lib/esm/core/components/shadcn/filters/stringListFilter.js.map +1 -0
  27. package/lib/esm/core/components/shadcn/filters/textFilter.js +2 -1
  28. package/lib/esm/core/components/shadcn/filters/textFilter.js.map +1 -1
  29. package/lib/esm/core/components/shadcn/label.js +0 -1
  30. package/lib/esm/core/components/shadcn/label.js.map +1 -1
  31. package/lib/esm/features/agent/PayloadBuilder.js +27 -0
  32. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  33. package/lib/esm/features/agent/chat/ModernAgentConversation.js +1 -1
  34. package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
  35. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js +3 -3
  36. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  37. package/lib/esm/features/facets/VEnvironmentFacet.js +24 -0
  38. package/lib/esm/features/facets/VEnvironmentFacet.js.map +1 -0
  39. package/lib/esm/features/facets/VFacetsNav.js +69 -26
  40. package/lib/esm/features/facets/VFacetsNav.js.map +1 -1
  41. package/lib/esm/features/facets/VInteractionFacet.js +45 -0
  42. package/lib/esm/features/facets/VInteractionFacet.js.map +1 -0
  43. package/lib/esm/features/facets/VStringFacet.js +6 -5
  44. package/lib/esm/features/facets/VStringFacet.js.map +1 -1
  45. package/lib/esm/features/facets/VUserFacet.js +6 -6
  46. package/lib/esm/features/facets/VUserFacet.js.map +1 -1
  47. package/lib/esm/features/layout/GenericPageNavHeader.js +1 -1
  48. package/lib/esm/features/magic-pdf/TextPageView.js +1 -2
  49. package/lib/esm/features/magic-pdf/TextPageView.js.map +1 -1
  50. package/lib/esm/features/store/collections/CollectionsTable.js +9 -5
  51. package/lib/esm/features/store/collections/CollectionsTable.js.map +1 -1
  52. package/lib/esm/features/store/collections/{CollectionsView.js → CreateCollection.js} +6 -14
  53. package/lib/esm/features/store/collections/CreateCollection.js.map +1 -0
  54. package/lib/esm/features/store/collections/EditCollectionView.js +1 -1
  55. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  56. package/lib/esm/features/store/collections/SelectCollection.js +24 -0
  57. package/lib/esm/features/store/collections/SelectCollection.js.map +1 -0
  58. package/lib/esm/features/store/collections/index.js +2 -2
  59. package/lib/esm/features/store/collections/index.js.map +1 -1
  60. package/lib/esm/features/store/objects/DocumentSearchResults.js +6 -3
  61. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  62. package/lib/esm/features/store/objects/components/ContentOverview.js +17 -16
  63. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  64. package/lib/esm/features/store/objects/components/DocumentIcon.js +7 -10
  65. package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
  66. package/lib/esm/features/store/objects/components/DocumentInput.js +1 -2
  67. package/lib/esm/features/store/objects/components/DocumentInput.js.map +1 -1
  68. package/lib/esm/features/store/objects/components/PropertiesEditorModal.js +4 -2
  69. package/lib/esm/features/store/objects/components/PropertiesEditorModal.js.map +1 -1
  70. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js +1 -2
  71. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
  72. package/lib/esm/features/store/objects/components/SelectDocument.js +9 -3
  73. package/lib/esm/features/store/objects/components/SelectDocument.js.map +1 -1
  74. package/lib/esm/features/store/objects/components/SelectDocumentModal.js +2 -2
  75. package/lib/esm/features/store/objects/components/SelectDocumentModal.js.map +1 -1
  76. package/lib/esm/features/store/objects/layout/documentLayout.js +2 -2
  77. package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
  78. package/lib/esm/features/store/objects/search/DocumentSearchContext.js +4 -2
  79. package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  80. package/lib/esm/features/store/objects/selection/SelectionActions.js +1 -1
  81. package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
  82. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +7 -10
  83. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  84. package/lib/esm/features/store/objects/selection/actions/ChangeTypeAction.js +1 -1
  85. package/lib/esm/features/store/objects/selection/actions/ChangeTypeAction.js.map +1 -1
  86. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js +2 -2
  87. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js.map +1 -1
  88. package/lib/esm/features/store/objects/selection/actions/ExportPropertiesAction.js +1 -1
  89. package/lib/esm/features/store/objects/selection/actions/ExportPropertiesAction.js.map +1 -1
  90. package/lib/esm/features/store/objects/selection/actions/RemoveFromCollectionAction.js +1 -1
  91. package/lib/esm/features/store/objects/selection/actions/RemoveFromCollectionAction.js.map +1 -1
  92. package/lib/esm/features/store/types/ContentObjectTypesSearch.js +2 -3
  93. package/lib/esm/features/store/types/ContentObjectTypesSearch.js.map +1 -1
  94. package/lib/esm/features/store/types/ContentObjectTypesTable.js +1 -1
  95. package/lib/esm/features/store/types/ContentObjectTypesTable.js.map +1 -1
  96. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js +2 -2
  97. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js.map +1 -1
  98. package/lib/esm/features/store/types/ObjectSchemaEditor.js +2 -3
  99. package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
  100. package/lib/esm/features/store/types/TableLayoutEditor.js +1 -1
  101. package/lib/esm/features/store/types/TableLayoutEditor.js.map +1 -1
  102. package/lib/esm/features/store/types/index.js +0 -2
  103. package/lib/esm/features/store/types/index.js.map +1 -1
  104. package/lib/esm/features/user/UserInfo.js +1 -2
  105. package/lib/esm/features/user/UserInfo.js.map +1 -1
  106. package/lib/esm/features/utils/rendition.js +22 -2
  107. package/lib/esm/features/utils/rendition.js.map +1 -1
  108. package/lib/esm/layout/FullHeightLayout.js +2 -4
  109. package/lib/esm/layout/FullHeightLayout.js.map +1 -1
  110. package/lib/esm/session/UserSession.js +2 -2
  111. package/lib/esm/session/UserSession.js.map +1 -1
  112. package/lib/esm/session/auth/composable.js +1 -1
  113. package/lib/esm/session/auth/composable.js.map +1 -1
  114. package/lib/esm/session/constants.js +3 -0
  115. package/lib/esm/session/constants.js.map +1 -0
  116. package/lib/esm/widgets/codemirror/CodeMirrorEditor.js +2 -2
  117. package/lib/esm/widgets/codemirror/CodeMirrorEditor.js.map +1 -1
  118. package/lib/esm/widgets/properties/PropertiesView.js +4 -2
  119. package/lib/esm/widgets/properties/PropertiesView.js.map +1 -1
  120. package/lib/esm/widgets/schema-editor/editor/SchemaEditor.js +1 -1
  121. package/lib/esm/widgets/schema-editor/editor/SchemaEditor.js.map +1 -1
  122. package/lib/tsconfig.tsbuildinfo +1 -1
  123. package/lib/types/core/components/InputList.d.ts +2 -1
  124. package/lib/types/core/components/Switch.d.ts +2 -1
  125. package/lib/types/core/components/shadcn/filters/comboBox.d.ts +5 -0
  126. package/lib/types/core/components/shadcn/filters/stringListFilter.d.ts +10 -0
  127. package/lib/types/core/components/shadcn/filters/types.d.ts +3 -3
  128. package/lib/types/features/agent/PayloadBuilder.d.ts +8 -1
  129. package/lib/types/features/facets/VEnvironmentFacet.d.ts +11 -0
  130. package/lib/types/features/facets/VFacetsNav.d.ts +9 -1
  131. package/lib/types/features/facets/VInteractionFacet.d.ts +14 -0
  132. package/lib/types/features/facets/VStringFacet.d.ts +3 -2
  133. package/lib/types/features/facets/VUserFacet.d.ts +3 -2
  134. package/lib/types/features/store/collections/{CollectionsView.d.ts → CreateCollection.d.ts} +5 -3
  135. package/lib/types/features/store/collections/SelectCollection.d.ts +14 -0
  136. package/lib/types/features/store/collections/index.d.ts +2 -2
  137. package/lib/types/features/store/objects/components/ContentOverview.d.ts +2 -1
  138. package/lib/types/features/store/objects/components/DocumentIcon.d.ts +2 -1
  139. package/lib/types/features/store/objects/components/PropertiesEditorModal.d.ts +2 -1
  140. package/lib/types/features/store/objects/layout/documentLayout.d.ts +1 -1
  141. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +3 -2
  142. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts +2 -1
  143. package/lib/types/features/store/objects/selection/actions/RemoveFromCollectionAction.d.ts +2 -1
  144. package/lib/types/features/store/types/index.d.ts +0 -2
  145. package/lib/types/features/utils/rendition.d.ts +1 -1
  146. package/lib/types/session/UserSession.d.ts +2 -2
  147. package/lib/types/session/constants.d.ts +2 -0
  148. package/lib/vertesia-ui-core.js +1 -1
  149. package/lib/vertesia-ui-core.js.map +1 -1
  150. package/lib/vertesia-ui-features.js +1 -1
  151. package/lib/vertesia-ui-features.js.map +1 -1
  152. package/lib/vertesia-ui-layout.js +1 -1
  153. package/lib/vertesia-ui-layout.js.map +1 -1
  154. package/lib/vertesia-ui-session.js +1 -1
  155. package/lib/vertesia-ui-session.js.map +1 -1
  156. package/lib/vertesia-ui-widgets.js +1 -1
  157. package/lib/vertesia-ui-widgets.js.map +1 -1
  158. package/package.json +4 -4
  159. package/src/core/components/EmptyCollection.tsx +26 -24
  160. package/src/core/components/InputList.tsx +3 -1
  161. package/src/core/components/SidePanel.tsx +2 -2
  162. package/src/core/components/Switch.tsx +4 -3
  163. package/src/core/components/shadcn/calendar.tsx +0 -2
  164. package/src/core/components/shadcn/checkbox.tsx +0 -2
  165. package/src/core/components/shadcn/command.tsx +0 -2
  166. package/src/core/components/shadcn/dialog.tsx +0 -2
  167. package/src/core/components/shadcn/filters/comboBox.tsx +73 -0
  168. package/src/core/components/shadcn/filters/filterBar.tsx +41 -17
  169. package/src/core/components/shadcn/filters/filters.tsx +30 -14
  170. package/src/core/components/shadcn/filters/selectFilter.tsx +3 -3
  171. package/src/core/components/shadcn/filters/stringListFilter.tsx +58 -0
  172. package/src/core/components/shadcn/filters/textFilter.tsx +2 -1
  173. package/src/core/components/shadcn/filters/types.ts +3 -3
  174. package/src/core/components/shadcn/label.tsx +0 -2
  175. package/src/features/agent/PayloadBuilder.tsx +34 -1
  176. package/src/features/agent/chat/ModernAgentConversation.tsx +639 -639
  177. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +12 -13
  178. package/src/features/facets/VEnvironmentFacet.tsx +42 -0
  179. package/src/features/facets/VFacetsNav.tsx +87 -29
  180. package/src/features/facets/VInteractionFacet.tsx +73 -0
  181. package/src/features/facets/VStringFacet.tsx +7 -6
  182. package/src/features/facets/VUserFacet.tsx +7 -6
  183. package/src/features/layout/GenericPageNavHeader.tsx +1 -1
  184. package/src/features/magic-pdf/TextPageView.tsx +1 -2
  185. package/src/features/store/collections/CollectionsTable.tsx +49 -40
  186. package/src/features/store/collections/{CollectionsView.tsx → CreateCollection.tsx} +15 -42
  187. package/src/features/store/collections/EditCollectionView.tsx +1 -1
  188. package/src/features/store/collections/SelectCollection.tsx +46 -0
  189. package/src/features/store/collections/index.ts +2 -2
  190. package/src/features/store/objects/DocumentSearchResults.tsx +6 -3
  191. package/src/features/store/objects/components/ContentOverview.tsx +38 -98
  192. package/src/features/store/objects/components/DocumentIcon.tsx +27 -14
  193. package/src/features/store/objects/components/DocumentInput.tsx +1 -2
  194. package/src/features/store/objects/components/PropertiesEditorModal.tsx +7 -3
  195. package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +2 -2
  196. package/src/features/store/objects/components/SelectDocument.tsx +18 -3
  197. package/src/features/store/objects/components/SelectDocumentModal.tsx +6 -6
  198. package/src/features/store/objects/layout/documentLayout.tsx +2 -2
  199. package/src/features/store/objects/search/DocumentSearchContext.ts +6 -3
  200. package/src/features/store/objects/selection/ObjectsActionContext.tsx +1 -1
  201. package/src/features/store/objects/selection/SelectionActions.tsx +0 -1
  202. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +10 -21
  203. package/src/features/store/objects/selection/actions/ChangeTypeAction.tsx +1 -1
  204. package/src/features/store/objects/selection/actions/DeleteObjectsAction.tsx +2 -2
  205. package/src/features/store/objects/selection/actions/ExportPropertiesAction.tsx +1 -1
  206. package/src/features/store/objects/selection/actions/RemoveFromCollectionAction.tsx +1 -1
  207. package/src/features/store/types/ContentObjectTypesSearch.tsx +3 -4
  208. package/src/features/store/types/ContentObjectTypesTable.tsx +3 -1
  209. package/src/features/store/types/CreateOrUpdateTypeModal.tsx +2 -9
  210. package/src/features/store/types/ObjectSchemaEditor.tsx +4 -5
  211. package/src/features/store/types/TableLayoutEditor.tsx +4 -4
  212. package/src/features/store/types/index.ts +0 -2
  213. package/src/features/user/UserInfo.tsx +1 -2
  214. package/src/features/utils/rendition.ts +23 -1
  215. package/src/layout/FullHeightLayout.tsx +2 -2
  216. package/src/session/UserSession.ts +2 -2
  217. package/src/session/auth/composable.ts +1 -1
  218. package/src/session/constants.ts +2 -0
  219. package/src/widgets/codemirror/CodeMirrorEditor.tsx +2 -2
  220. package/src/widgets/properties/PropertiesView.tsx +10 -2
  221. package/src/widgets/schema-editor/editor/SchemaEditor.tsx +1 -1
  222. package/lib/esm/features/store/collections/CollectionView.js +0 -53
  223. package/lib/esm/features/store/collections/CollectionView.js.map +0 -1
  224. package/lib/esm/features/store/collections/CollectionsView.js.map +0 -1
  225. package/lib/esm/features/store/types/ContentObjectTypeView.js +0 -158
  226. package/lib/esm/features/store/types/ContentObjectTypeView.js.map +0 -1
  227. package/lib/esm/features/store/types/ContentObjectTypesView.js +0 -55
  228. package/lib/esm/features/store/types/ContentObjectTypesView.js.map +0 -1
  229. package/lib/types/features/store/collections/CollectionView.d.ts +0 -5
  230. package/lib/types/features/store/types/ContentObjectTypeView.d.ts +0 -5
  231. package/lib/types/features/store/types/ContentObjectTypesView.d.ts +0 -8
  232. package/src/features/store/collections/CollectionView.tsx +0 -94
  233. package/src/features/store/types/ContentObjectTypeView.tsx +0 -244
  234. package/src/features/store/types/ContentObjectTypesView.tsx +0 -71
@@ -0,0 +1,46 @@
1
+ import { ErrorBox, useFetch, VSelectBox } from "@vertesia/ui/core";
2
+ import { useUserSession } from "@vertesia/ui/session";
3
+
4
+ interface SelectCollectionProps {
5
+ value?: string; // Collection ID
6
+ onChange: (collectionId: string | undefined, collection?: any) => void;
7
+ disabled?: boolean;
8
+ className?: string;
9
+ }
10
+
11
+ /**
12
+ * A component to select a collection from a list of collections.
13
+ * It fetches the collections from the store and displays them in a dropdown.
14
+ * @param props - The properties for the component.
15
+ * @returns A dropdown to select a collection.
16
+ */
17
+ export function SelectCollection({ onChange, value, disabled = false, className }: SelectCollectionProps) {
18
+ const { client } = useUserSession();
19
+ const { data: collections, error } = useFetch(() => client.store.collections.list({ dynamic: false }), []);
20
+
21
+ if (error) {
22
+ return <ErrorBox title='Collection fetch failed'>{error.message}</ErrorBox>
23
+ }
24
+
25
+ // Find the selected collection object from the ID
26
+ const selectedCollection = value ? collections?.find(col => col.id === value) : undefined;
27
+
28
+ const handleChange = (collection: any) => {
29
+ // Call onChange with both the ID and the full collection object
30
+ onChange(collection?.id, collection);
31
+ };
32
+
33
+ return (
34
+ <VSelectBox
35
+ filterBy={"name"}
36
+ value={selectedCollection}
37
+ onChange={handleChange}
38
+ placeholder="Select a collection"
39
+ options={collections || []}
40
+ optionLabel={(col: any) => col.name}
41
+ by="id"
42
+ className={className}
43
+ disabled={disabled}
44
+ />
45
+ );
46
+ }
@@ -1,5 +1,5 @@
1
1
  export * from "./BrowseCollectionView";
2
2
  export * from "./CollectionsTable";
3
- export * from "./CollectionsView";
4
- export * from "./CollectionView";
5
3
  export * from "./EditCollectionView";
4
+ export * from "./CreateCollection";
5
+ export * from "./SelectCollection";
@@ -4,11 +4,14 @@ import { ColumnLayout, ContentObject, ContentObjectItem, VectorSearchQuery } fro
4
4
  import { Button, Divider, ErrorBox, SidePanel, Spinner, useDebounce, useIntersectionObserver, useToast } from '@vertesia/ui/core';
5
5
  import { useNavigate } from "@vertesia/ui/router";
6
6
  import { TypeRegistry, useUserSession } from '@vertesia/ui/session';
7
- import { Download, RefreshCw, SquareArrowOutUpRight } from 'lucide-react';
7
+ import { Download, RefreshCw, Eye } from 'lucide-react';
8
8
  import { VFacetsNav } from "../../facets";
9
9
  import { VectorSearchWidget } from './components/VectorSearchWidget';
10
10
 
11
- import { ContentDispositionButton, DocumentTable, useDocumentSearch, useDocumentUploadHandler, useWatchDocumentSearchFacets, useWatchDocumentSearchResult } from "../../store";
11
+ import { ContentDispositionButton } from './components/ContentDispositionButton';
12
+ import { DocumentTable } from './DocumentTable';
13
+ import { useDocumentSearch, useWatchDocumentSearchFacets, useWatchDocumentSearchResult } from './search/DocumentSearchContext';
14
+ import { useDocumentUploadHandler } from './upload/useUploadHandler';
12
15
  import { ContentOverview } from './components/ContentOverview';
13
16
  import { useDownloadDocument } from './components/useDownloadObject';
14
17
 
@@ -192,7 +195,7 @@ function OverviewDrawer({ object, onClose }: OverviewDrawerProps) {
192
195
  <SidePanel title={object.properties?.title || object.name} isOpen={true} onClose={onClose}>
193
196
  <div className="flex items-center gap-x-2">
194
197
  <Button variant="ghost" size="sm" title="Open Object" onClick={() => navigate(`/objects/${object.id}`)}>
195
- <SquareArrowOutUpRight className="size-4" />
198
+ <Eye className="size-4" />
196
199
  </Button>
197
200
  {object.content?.source && (
198
201
  <Button variant="ghost" size="sm" title="Download" onClick={onDownload}>
@@ -3,19 +3,22 @@ import Markdown from "react-markdown";
3
3
  import remarkGfm from "remark-gfm";
4
4
 
5
5
  import { useUserSession } from "@vertesia/ui/session";
6
- import { Button, Link, Spinner, useToast } from "@vertesia/ui/core";
6
+ import { Button, Spinner, useToast } from "@vertesia/ui/core";
7
7
  import { JSONDisplay } from "@vertesia/ui/widgets";
8
8
  import { ContentObject, ImageRenditionFormat } from "@vertesia/common";
9
9
  import { Copy, Download, SquarePen } from "lucide-react";
10
10
  import { PropertiesEditorModal } from "./PropertiesEditorModal";
11
+ import { NavLink } from "@vertesia/ui/router";
11
12
 
12
13
  interface ContentOverviewProps {
13
14
  object: ContentObject;
14
15
  loadText?: boolean;
16
+ refetch?: () => Promise<unknown>;
15
17
  }
16
18
  export function ContentOverview({
17
19
  object,
18
20
  loadText,
21
+ refetch,
19
22
  }: ContentOverviewProps) {
20
23
  const { client, store } = useUserSession();
21
24
  const [isLoadingText, setIsLoadingText] = useState(false);
@@ -144,7 +147,7 @@ export function ContentOverview({
144
147
  };
145
148
 
146
149
  const handleExportDocx = () => handleExportDocument("docx");
147
- //const handleExportPdf = () => handleExportDocument("pdf");
150
+ const handleExportPdf = () => handleExportDocument("pdf");
148
151
 
149
152
  const content = object.content;
150
153
  const isImage =
@@ -295,6 +298,15 @@ export function ContentOverview({
295
298
  <Download className="h-4 w-4" />
296
299
  DOCX
297
300
  </Button>
301
+ <Button
302
+ variant="ghost"
303
+ size="sm"
304
+ onClick={handleExportPdf}
305
+ className="flex items-center gap-2"
306
+ >
307
+ <Download className="h-4 w-4" />
308
+ PDF
309
+ </Button>
298
310
  </>
299
311
  )}
300
312
  </div>
@@ -303,64 +315,30 @@ export function ContentOverview({
303
315
  {text ? (
304
316
  <div className="border shadow-xs rounded-xs max-w-7xl">
305
317
  {seemsMarkdown ? (
306
- <div className="prose prose-sm max-w-none prose-p:bg-transparent prose-p:my-0 prose-pre:bg-gray-800 dark:prose-pre:bg-gray-900 prose-pre:my-2 prose-code:bg-gray-200/70 dark:prose-code:bg-gray-700/50 prose-headings:bg-transparent prose-li:bg-transparent dark:prose-invert dark:text-gray-100">
318
+ <div className="vprose prose-sm p-1">
307
319
  <Markdown
308
320
  remarkPlugins={[remarkGfm]}
309
321
  components={{
310
- a: ({
311
- node,
312
- ...props
313
- }: {
314
- node?: any;
315
- href?: string;
316
- children?: React.ReactNode;
317
- }) => {
322
+ a: ({ node, ...props }: { node?: any; href?: string; children?: React.ReactNode }) => {
318
323
  const href = props.href || "";
319
- if (
320
- href.startsWith(
321
- "/store/objects/",
322
- )
323
- ) {
324
+ if (href.includes("/store/objects/")) {
324
325
  return (
325
- <Link
326
+ <NavLink
327
+ topLevelNav
326
328
  href={href}
327
- className="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
329
+ className="text-info"
328
330
  >
329
331
  {props.children}
330
- </Link>
332
+ </NavLink>
331
333
  );
332
334
  }
333
- return (
334
- <a
335
- {...props}
336
- target="_blank"
337
- rel="noopener noreferrer"
338
- />
339
- );
335
+ return <a {...props} data-debug="test" target="_blank" rel="noopener noreferrer" />;
340
336
  },
341
- p: ({
342
- node,
343
- ...props
344
- }: {
345
- node?: any;
346
- children?: React.ReactNode;
347
- }) => (
348
- <p
349
- {...props}
350
- className="my-0 text-gray-800 dark:text-gray-100"
351
- />
337
+ p: ({ node, ...props }: { node?: any; children?: React.ReactNode }) => (
338
+ <p {...props} className={`my-0`} />
352
339
  ),
353
- pre: ({
354
- node,
355
- ...props
356
- }: {
357
- node?: any;
358
- children?: React.ReactNode;
359
- }) => (
360
- <pre
361
- {...props}
362
- className="my-2 bg-gray-800 dark:bg-gray-900 p-2 rounded text-gray-100"
363
- />
340
+ pre: ({ node, ...props }: { node?: any; children?: React.ReactNode }) => (
341
+ <pre {...props} className={`my-2 p-2 rounded`} />
364
342
  ),
365
343
  code: ({
366
344
  node,
@@ -372,71 +350,32 @@ export function ContentOverview({
372
350
  className?: string;
373
351
  children?: React.ReactNode;
374
352
  }) => {
375
- const match =
376
- /language-(\w+)/.exec(
377
- className || "",
378
- );
353
+ const match = /language-(\w+)/.exec(className || "");
379
354
  const isInline = !match;
380
355
  return (
381
356
  <code
382
357
  {...props}
383
358
  className={
384
359
  isInline
385
- ? "px-1.5 py-0.5 rounded text-muted bg-gray-200/70 dark:bg-gray-700/50"
386
- : "text-gray-100"
360
+ ? `px-1.5 py-0.5 rounded`
361
+ : "text-muted"
387
362
  }
388
363
  >
389
364
  {children}
390
365
  </code>
391
366
  );
392
367
  },
393
- h1: ({
394
- node,
395
- ...props
396
- }: {
397
- node?: any;
398
- children?: React.ReactNode;
399
- }) => (
400
- <h1
401
- {...props}
402
- className="text-gray-900 dark:text-gray-50 font-bold text-2xl my-2"
403
- />
368
+ h1: ({ node, ...props }: { node?: any; children?: React.ReactNode }) => (
369
+ <h1 {...props} className={`font-bold text-2xl my-2`} />
404
370
  ),
405
- h2: ({
406
- node,
407
- ...props
408
- }: {
409
- node?: any;
410
- children?: React.ReactNode;
411
- }) => (
412
- <h2
413
- {...props}
414
- className="text-gray-900 dark:text-gray-50 font-bold text-xl my-2"
415
- />
371
+ h2: ({ node, ...props }: { node?: any; children?: React.ReactNode }) => (
372
+ <h2 {...props} className={`font-bold text-xl my-2`} />
416
373
  ),
417
- h3: ({
418
- node,
419
- ...props
420
- }: {
421
- node?: any;
422
- children?: React.ReactNode;
423
- }) => (
424
- <h3
425
- {...props}
426
- className="text-gray-900 dark:text-gray-50 font-bold text-lg my-2"
427
- />
374
+ h3: ({ node, ...props }: { node?: any; children?: React.ReactNode }) => (
375
+ <h3 {...props} className={`font-bold text-lg my-2`} />
428
376
  ),
429
- li: ({
430
- node,
431
- ...props
432
- }: {
433
- node?: any;
434
- children?: React.ReactNode;
435
- }) => (
436
- <li
437
- {...props}
438
- className="text-gray-800 dark:text-gray-100"
439
- />
377
+ li: ({ node, ...props }: { node?: any; children?: React.ReactNode }) => (
378
+ <li {...props} />
440
379
  ),
441
380
  }}
442
381
  >
@@ -460,6 +399,7 @@ export function ContentOverview({
460
399
  isOpen={isPropertiesModalOpen}
461
400
  onClose={handleClosePropertiesModal}
462
401
  object={object}
402
+ refetch={refetch}
463
403
  />
464
404
  </div>
465
405
  );
@@ -3,27 +3,25 @@ import { ChangeEvent, useEffect, useState } from 'react'
3
3
  import { retrieveRendition } from '../../../utils'
4
4
 
5
5
  import { ContentObjectItem } from '@vertesia/common'
6
- import { Card, CardContent, Separator, VTooltip } from "@vertesia/ui/core"
7
- import { useNavigate } from "@vertesia/ui/router"
6
+ import { Button, Card, CardContent, Separator, VTooltip } from "@vertesia/ui/core"
7
+ import { NavLink } from "@vertesia/ui/router"
8
8
  import { useUserSession } from "@vertesia/ui/session"
9
9
  import { DocumentSelection } from '../DocumentSelectionProvider'
10
+ import { Eye } from 'lucide-react'
10
11
 
11
12
  interface DocumentIconProps {
12
13
  document: ContentObjectItem
13
14
  onSelectionChange: ((object: ContentObjectItem, ev: ChangeEvent<HTMLInputElement>) => void);
14
15
  selection: DocumentSelection;
15
-
16
+ onRowClick?: (object: ContentObjectItem) => void;
16
17
  }
17
- export function DocumentIcon({ selection, document, onSelectionChange }: Readonly<DocumentIconProps>) {
18
+ export function DocumentIcon({ selection, document, onSelectionChange, onRowClick }: Readonly<DocumentIconProps>) {
18
19
  const { client } = useUserSession()
19
- const navigate = useNavigate()
20
20
 
21
21
  const [renditionUrl, setRenditionUrl] = useState<string | undefined>(undefined)
22
22
  const [renditionAlt, setRenditionAlt] = useState<string | undefined>(undefined)
23
+ const [renditionStatus, setRenditionStatus] = useState<string | undefined>(undefined)
23
24
 
24
- const handleNavigateToDocument = () => {
25
- navigate(`/objects/${document.id}`)
26
- }
27
25
 
28
26
  const handleSelect = (ev: React.ChangeEvent<HTMLInputElement>) => {
29
27
  ev.stopPropagation()
@@ -35,13 +33,11 @@ export function DocumentIcon({ selection, document, onSelectionChange }: Readonl
35
33
  return
36
34
  }
37
35
 
38
- retrieveRendition(client, document, setRenditionUrl, setRenditionAlt)
36
+ retrieveRendition(client, document, setRenditionUrl, setRenditionAlt, setRenditionStatus)
39
37
  }, [document])
40
38
 
41
- console.log("renditionUrl", document)
42
-
43
39
  return (
44
- <Card className="relative flex flex-col border h-fit" onClick={handleNavigateToDocument}>
40
+ <Card className="relative flex flex-col border h-fit" onClick={() => (onRowClick && onRowClick(document))}>
45
41
  {
46
42
  selection && (
47
43
  <div
@@ -56,11 +52,28 @@ export function DocumentIcon({ selection, document, onSelectionChange }: Readonl
56
52
  )
57
53
  }
58
54
 
55
+ <div
56
+ className="absolute top-1 right-1 z-10 flex flex-col items-center"
57
+ >
58
+ <NavLink
59
+ topLevelNav
60
+ href={`/store/objects/${document.id}`}
61
+ >
62
+ <Button
63
+ variant="ghost" size="sm" title="Open Object"
64
+ >
65
+ <Eye className={`size-4 ${renditionStatus === 'ready' ? 'text-muted' : 'text-white'}`} />
66
+ </Button>
67
+ </NavLink>
68
+ </div>
69
+
59
70
  {
60
- renditionUrl ? (
71
+ (renditionUrl && renditionStatus == 'ready') ? (
61
72
  <img src={renditionUrl} alt={renditionAlt} className="w-auto h-48 object-cover rounded-t-xl" />
62
73
  ) : (
63
- <div className="h-48 bg-gray-700 rounded-t-xl"></div>
74
+ <div className="h-48 bg-gray-700 rounded-t-xl flex items-center justify-center text-muted">
75
+ {renditionStatus}
76
+ </div>
64
77
  )
65
78
  }
66
79
  <Separator className='bg-gray-200 h-[2px]' />
@@ -4,8 +4,7 @@ import { ChangeEvent, useEffect, useState } from 'react';
4
4
  import { useUserSession } from '@vertesia/ui/session';
5
5
  import { ContentObjectItem } from '@vertesia/common';
6
6
  import { ChevronsUpDown, X } from 'lucide-react';
7
- import { Button, Styles } from '@vertesia/ui/core';
8
- import { useFlag } from '@vertesia/ui/core';
7
+ import { Button, Styles, useFlag } from '@vertesia/ui/core';
9
8
  import { Node } from '@vertesia/ui/widgets';
10
9
 
11
10
  import { SelectDocumentModal } from './SelectDocumentModal';
@@ -22,9 +22,10 @@ export interface PropertiesEditorModalProps {
22
22
  isOpen: boolean;
23
23
  onClose: () => void;
24
24
  object: ContentObject;
25
+ refetch?: () => Promise<unknown>;
25
26
  }
26
27
 
27
- export function PropertiesEditorModal({ isOpen, onClose, object }: PropertiesEditorModalProps) {
28
+ export function PropertiesEditorModal({ isOpen, onClose, object, refetch }: PropertiesEditorModalProps) {
28
29
  const { client, store } = useUserSession();
29
30
  const toast = useToast();
30
31
  const navigate = useNavigate();
@@ -169,8 +170,11 @@ export function PropertiesEditorModal({ isOpen, onClose, object }: PropertiesEdi
169
170
  description: 'The object properties have been updated successfully.',
170
171
  duration: 2000
171
172
  });
172
-
173
- // Close modals
173
+
174
+ if (refetch) {
175
+ await refetch();
176
+ }
177
+
174
178
  setShowConfirmation(false);
175
179
  onClose();
176
180
  }
@@ -7,9 +7,9 @@ import {
7
7
  ModalTitle,
8
8
  Input,
9
9
  RadioGroup,
10
- RadioOptionAdapter
10
+ RadioOptionAdapter,
11
+ FormItem
11
12
  } from '@vertesia/ui/core';
12
- import { FormItem } from '@vertesia/ui/core';
13
13
 
14
14
  export interface SaveVersionConfirmModalProps {
15
15
  isOpen: boolean;
@@ -1,11 +1,12 @@
1
1
  import { ColumnLayout, ContentObjectItem } from "@vertesia/common";
2
- import { ErrorBox, Spinner, useIntersectionObserver } from "@vertesia/ui/core";
2
+ import { Button, ErrorBox, Spinner, useIntersectionObserver } from "@vertesia/ui/core";
3
3
  import { useEffect, useRef, useState } from "react";
4
4
  import { VFacetsNav } from "../../../facets";
5
5
  import { DocumentTable } from "../DocumentTable";
6
6
  import { useDocumentSearch, useWatchDocumentSearchFacets, useWatchDocumentSearchResult } from "../search/DocumentSearchContext";
7
7
  import { DocumentSearchProvider } from "../search/DocumentSearchProvider";
8
8
  import { ContentDispositionButton } from "./ContentDispositionButton";
9
+ import { RefreshCw } from "lucide-react";
9
10
 
10
11
  const layout: ColumnLayout[] = [
11
12
  { "name": "Name", "field": "properties.title", "type": "string", "fallback": "name" },
@@ -33,15 +34,19 @@ export function SelectDocument({ onChange }: SelectDocumentProps) {
33
34
  interface SelectDocumentImplProps {
34
35
  onRowClick: (selected: ContentObjectItem) => void;
35
36
  }
37
+ const LAST_DISPLAYED_VIEW = 'vertesia.content_store.lastDisplayedView'
38
+
36
39
  function SelectDocumentImpl({ onRowClick }: SelectDocumentImplProps) {
37
40
  const [isReady, setIsReady] = useState(false);
38
- const [isGridView, setIsGridView] = useState(localStorage.getItem('lastDisplayedView') === 'grid');
41
+ const [isGridView, setIsGridView] = useState(localStorage.getItem(LAST_DISPLAYED_VIEW) === 'grid');
39
42
  const { search, isLoading, error, objects } = useWatchDocumentSearchResult();
40
43
 
41
44
  const loadMoreRef = useRef<HTMLDivElement>(null);
45
+
42
46
  useIntersectionObserver(loadMoreRef, () => {
43
47
  isReady && search.loadMore(true)
44
48
  }, { deps: [isReady] });
49
+
45
50
  useEffect(() => {
46
51
  search.search().then(() => setIsReady(true));
47
52
  }, []);
@@ -49,6 +54,11 @@ function SelectDocumentImpl({ onRowClick }: SelectDocumentImplProps) {
49
54
  const facets = useWatchDocumentSearchFacets();
50
55
  const facetSearch = useDocumentSearch();
51
56
 
57
+ const handleRefetch = () => {
58
+ setIsReady(false);
59
+ search.search().then(() => setIsReady(true));
60
+ }
61
+
52
62
  if (error) {
53
63
  return <ErrorBox title="Search failed">{error.message}</ErrorBox>
54
64
  }
@@ -57,7 +67,12 @@ function SelectDocumentImpl({ onRowClick }: SelectDocumentImplProps) {
57
67
  <div>
58
68
  <div className="flex justify-between items-center mb-4">
59
69
  <VFacetsNav facets={facets} search={facetSearch} textSearch="Filter content" />
60
- <ContentDispositionButton onUpdate={setIsGridView} />
70
+ <div className="flex items-center gap-2">
71
+ <Button variant="outline" onClick={handleRefetch} alt="Refresh">
72
+ <RefreshCw size={16} />
73
+ </Button>
74
+ <ContentDispositionButton onUpdate={setIsGridView} />
75
+ </div>
61
76
  </div>
62
77
  <DocumentTable objects={objects || []} isLoading={false} layout={layout} onRowClick={onRowClick} isGridView={isGridView} />
63
78
  <div ref={loadMoreRef} className='mt-10' />
@@ -1,5 +1,5 @@
1
1
  import { ContentObjectItem } from "@vertesia/common";
2
- import { Modal, ModalBody, ModalTitle } from "@vertesia/ui/core";
2
+ import { VModal, VModalBody, VModalTitle } from "@vertesia/ui/core";
3
3
  import { SelectDocument } from "./SelectDocument";
4
4
 
5
5
  interface SelectDocumentModalProps {
@@ -10,11 +10,11 @@ interface SelectDocumentModalProps {
10
10
  }
11
11
  export function SelectDocumentModal({ isOpen, onClose }: SelectDocumentModalProps) {
12
12
  return (
13
- <Modal onClose={() => onClose()} isOpen={!!isOpen} className='min-w-[60vw]'>
14
- <ModalTitle>Select Content</ModalTitle>
15
- <ModalBody className='p-4 pt-0 overflow-y-auto max-h-[80vh] min-h-[80vh]'>
13
+ <VModal onClose={() => onClose()} isOpen={!!isOpen} className='min-w-[60vw]'>
14
+ <VModalTitle>Select Content</VModalTitle>
15
+ <VModalBody className='pt-0 overflow-y-auto max-h-[80vh] min-h-[80vh]'>
16
16
  {isOpen && <SelectDocument onChange={onClose} />}
17
- </ModalBody>
18
- </Modal>
17
+ </VModalBody>
18
+ </VModal>
19
19
  )
20
20
  }
@@ -52,7 +52,7 @@ export function DocumentTableView({ objects, selection, isLoading, onRowClick, c
52
52
  )
53
53
  }
54
54
 
55
- export function DocumentGridView({ objects, selection, isLoading, onSelectionChange }: ViewProps) {
55
+ export function DocumentGridView({ objects, selection, isLoading, onSelectionChange, onRowClick }: ViewProps) {
56
56
 
57
57
  return (
58
58
  <>
@@ -61,7 +61,7 @@ export function DocumentGridView({ objects, selection, isLoading, onSelectionCha
61
61
  </div>
62
62
  <div className="w-full gap-2 grid lg:grid-cols-6">
63
63
  {objects.map((document) => (
64
- <DocumentIcon key={document.id} document={document} selection={selection} onSelectionChange={onSelectionChange} />
64
+ <DocumentIcon key={document.id} document={document} selection={selection} onSelectionChange={onSelectionChange} onRowClick={onRowClick} />
65
65
  ))}
66
66
  </div>
67
67
  </>
@@ -3,6 +3,7 @@ import { createContext, useContext } from 'react';
3
3
  import { SharedState, useWatchSharedState } from '@vertesia/ui/core';
4
4
  import { ComputeFacetsResponse, ZenoClient } from '@vertesia/client';
5
5
  import { ComplexSearchQuery, ContentObjectItem, FacetBucket, FacetSpec, ObjectSearchQuery } from '@vertesia/common';
6
+ import { SearchInterface } from '@vertesia/ui/features'
6
7
 
7
8
  interface DocumentSearchResult {
8
9
  objects: ContentObjectItem[],
@@ -11,7 +12,7 @@ interface DocumentSearchResult {
11
12
  }
12
13
 
13
14
 
14
- export class DocumentSearch {
15
+ export class DocumentSearch implements SearchInterface {
15
16
 
16
17
  collectionId?: string;
17
18
  facets = new SharedState<ComputeFacetsResponse>({});
@@ -49,13 +50,15 @@ export class DocumentSearch {
49
50
  this.search();
50
51
  }
51
52
 
52
- clearFilters() {
53
+ clearFilters(autoSearch: boolean = true) {
53
54
  const parent = this.query.parent;
54
55
  this.query = {
55
56
  parent
56
57
  };
57
58
 
58
- this.search();
59
+ if (autoSearch) {
60
+ this.search();
61
+ }
59
62
  }
60
63
 
61
64
  getFacetBuckets(name: string): FacetBucket[] {
@@ -193,4 +193,4 @@ export function useStartWorkflowCallback(cb: ObjectsActionCallback) {
193
193
  }
194
194
  }, [cb, ctx]);
195
195
  return ctx;
196
- }
196
+ }
@@ -28,7 +28,6 @@ export function SelectionActions() {
28
28
  <div className="flex items-center gap-x-1 shrink-0">
29
29
  <div className='text-sm nowrap'>{size} document{plural} selected</div>
30
30
  <Button title="Clear selection" variant={"ghost"}
31
- className=" rounded-md p-2"
32
31
  onClick={onClearSelection}>
33
32
  <X className="size-4" />
34
33
  </Button>
@@ -1,7 +1,7 @@
1
- import { Button, ErrorBox, Portal, useFetch, useToast, VModal, VModalBody, VModalFooter, VModalTitle, VSelectBox } from "@vertesia/ui/core";
1
+ import { Button, Portal, useToast, VModal, VModalBody, VModalFooter, VModalTitle } from "@vertesia/ui/core";
2
2
  import { useUserSession } from "@vertesia/ui/session";
3
3
  import { useCallback, useState } from "react";
4
- import { CreateCollectionForm } from "../../../collections";
4
+ import { CreateCollectionForm, SelectCollection } from "../../../collections";
5
5
  import { useObjectsActionCallback } from "../ObjectsActionContext";
6
6
  import { ActionComponentTypeProps, ObjectsActionSpec } from "../ObjectsActionSpec";
7
7
 
@@ -43,7 +43,7 @@ function SelectCollectionModal({ isOpen, onClose, objectIds }: SelectCollectionM
43
43
  return (
44
44
  <VModal isOpen={isOpen} onClose={onClose}>
45
45
  <VModalTitle>Add to a Collection</VModalTitle>
46
- <AddToCollectionForm onClose={onClose} objectIds={objectIds} />
46
+ <AddToCollectionForm onClose={onClose} objectIds={objectIds}/>
47
47
  </VModal>
48
48
  )
49
49
  }
@@ -55,8 +55,7 @@ interface AddToCollectionFormProps {
55
55
  function AddToCollectionForm({ onClose, objectIds }: AddToCollectionFormProps) {
56
56
  const toast = useToast();
57
57
  const { client } = useUserSession();
58
- const [selectedCol, setSelectedCol] = useState<any>();
59
- const { data: collections, error } = useFetch(() => client.store.collections.list({ dynamic: false }), []);
58
+ const [selectedCollectionId, setSelectedCollectionId] = useState<string>();
60
59
  const onAddToCollection = ({ collectionId }: { collectionId: string }) => {
61
60
  if (!collectionId || !objectIds?.length) {
62
61
  return;
@@ -78,28 +77,18 @@ function AddToCollectionForm({ onClose, objectIds }: AddToCollectionFormProps) {
78
77
  });
79
78
  });
80
79
  }
81
- if (error) {
82
- return <ErrorBox title='Collection fetch failed'>{error.message}</ErrorBox>
83
- }
80
+
81
+ const onCollectionChange = (collectionId: string | undefined) => {
82
+ setSelectedCollectionId(collectionId);
83
+ };
84
84
 
85
85
  return (
86
86
  <>
87
87
  <VModalBody>
88
- <VSelectBox
89
- filterBy={"name"}
90
- value={selectedCol}
91
- onChange={(collection) => {
92
- setSelectedCol(collection);
93
- }}
94
- placeholder="Select a collection"
95
- options={collections || []}
96
- optionLabel={(col: any) => col.name}
97
- by="id"
98
- className="mb-4"
99
- />
88
+ <SelectCollection onChange={onCollectionChange} value={selectedCollectionId} className="mb-4"/>
100
89
  </VModalBody>
101
90
  <VModalFooter>
102
- <Button isDisabled={!selectedCol} onClick={() => selectedCol && onAddToCollection({ collectionId: selectedCol.id })}>
91
+ <Button isDisabled={!selectedCollectionId} onClick={() => selectedCollectionId && onAddToCollection({ collectionId: selectedCollectionId })}>
103
92
  Add to Collection
104
93
  </Button>
105
94
  </VModalFooter>