@c-rex/components 0.1.21 → 0.1.23

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 (53) hide show
  1. package/package.json +78 -62
  2. package/src/article/article-action-bar.tsx +89 -0
  3. package/src/article/article-content.tsx +55 -0
  4. package/src/autocomplete.tsx +55 -50
  5. package/src/breadcrumb.tsx +3 -1
  6. package/src/directoryNodes/tree-of-content.tsx +49 -0
  7. package/src/{bookmark-button.tsx → favorites/bookmark-button.tsx} +12 -3
  8. package/src/{favorite-button.tsx → favorites/favorite-button.tsx} +1 -1
  9. package/src/generated/client-components.tsx +1350 -0
  10. package/src/generated/create-client-request.tsx +105 -0
  11. package/src/generated/create-server-request.tsx +61 -0
  12. package/src/generated/create-suggestions-request.tsx +56 -0
  13. package/src/generated/server-components.tsx +1056 -0
  14. package/src/generated/suggestions.tsx +299 -0
  15. package/src/info/bookmark.tsx +51 -0
  16. package/src/info/info-table.tsx +127 -60
  17. package/src/info/shared.tsx +1 -1
  18. package/src/navbar/language-switcher/shared.tsx +1 -1
  19. package/src/navbar/navbar.tsx +1 -1
  20. package/src/{stories → navbar/stories}/navbar.stories.tsx +1 -1
  21. package/src/page-wrapper.tsx +1 -1
  22. package/src/renditions/file-download.tsx +84 -0
  23. package/src/renditions/html.tsx +55 -0
  24. package/src/renditions/image/container.tsx +52 -0
  25. package/src/renditions/image/rendition.tsx +61 -0
  26. package/src/{dialog-filter.tsx → results/dialog-filter.tsx} +22 -23
  27. package/src/results/filter-navbar.tsx +241 -0
  28. package/src/results/filter-sidebar/index.tsx +125 -0
  29. package/src/results/filter-sidebar/utils.ts +164 -0
  30. package/src/{pagination.tsx → results/pagination.tsx} +12 -10
  31. package/src/results/result-container.tsx +70 -0
  32. package/src/{stories/blog-view.stories.tsx → results/stories/cards.stories.tsx} +1 -1
  33. package/src/{stories/table-view.stories.tsx → results/stories/table.stories.tsx} +1 -1
  34. package/src/results/table-with-images.tsx +140 -0
  35. package/src/{result-view → results}/table.tsx +1 -2
  36. package/src/results/utils.ts +67 -0
  37. package/src/{navbar/search-input.tsx → search-input.tsx} +9 -6
  38. package/src/share-button.tsx +49 -0
  39. package/src/stores/search-settings-store.ts +1 -1
  40. package/src/blur-image.tsx +0 -23
  41. package/src/left-sidebar.tsx +0 -90
  42. package/src/result-list.tsx +0 -43
  43. package/src/result-view/table-with-images.tsx +0 -199
  44. package/src/right-sidebar.tsx +0 -70
  45. package/src/search-modal.tsx +0 -140
  46. package/src/stories/blur-image.stories.tsx +0 -51
  47. package/src/stories/sidebar.stories.tsx +0 -94
  48. /package/src/{file-icon.tsx → icons/file-icon.tsx} +0 -0
  49. /package/src/{flag.tsx → icons/flag-icon.tsx} +0 -0
  50. /package/src/{loading.tsx → icons/loading.tsx} +0 -0
  51. /package/src/{result-view/blog.tsx → results/cards.tsx} +0 -0
  52. /package/src/{empty.tsx → results/empty.tsx} +0 -0
  53. /package/src/{stories → results/stories}/empty.stories.tsx +0 -0
@@ -0,0 +1,125 @@
1
+ "use client";
2
+
3
+ import { FC, useMemo } from "react";
4
+ import { useTranslations } from 'next-intl'
5
+ import { Check, ChevronDown } from "lucide-react"
6
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@c-rex/ui/collapsible";
7
+ import {
8
+ SidebarContent,
9
+ SidebarGroup,
10
+ SidebarGroupContent,
11
+ SidebarGroupLabel,
12
+ SidebarHeader,
13
+ SidebarMenu,
14
+ SidebarMenuSub,
15
+ SidebarMenuSubButton,
16
+ SidebarMenuSubItem
17
+ } from "@c-rex/ui/sidebar";
18
+ import { parseAsString, useQueryStates } from "nuqs";
19
+ import { memoizeFilteredTags, removeFilterItem, updateFilterParam } from "./utils";
20
+ import { FilterItem, Tags } from "@c-rex/interfaces";
21
+
22
+
23
+ export interface FilterSidebarProps {
24
+ tags?: Tags
25
+ totalItemCount?: number
26
+ }
27
+
28
+
29
+ //TODO; check layout on mobile
30
+ export const FilterSidebar: FC<FilterSidebarProps> = ({ tags, totalItemCount }) => {
31
+ const t = useTranslations();
32
+ const [params, setParams] = useQueryStates({
33
+ packages: parseAsString,
34
+ filter: parseAsString,
35
+ }, {
36
+ history: 'push',
37
+ shallow: false,
38
+ });
39
+
40
+ const filteredTags = useMemo(() => {
41
+ return memoizeFilteredTags(tags, params.filter, params.packages);
42
+ }, [tags, params.filter, params.packages]);
43
+
44
+ const onClickHandler = (key: string, item: FilterItem) => {
45
+ if (item.active) {
46
+ setParams(removeFilterItem(key, item, params.filter))
47
+ return;
48
+ }
49
+
50
+ setParams(updateFilterParam(key, item, params.filter))
51
+ }
52
+
53
+ const content = (
54
+ <SidebarContent className="!gap-0" suppressHydrationWarning>
55
+
56
+ {Object.entries(filteredTags).map(([key, value]) => (
57
+
58
+ <Collapsible defaultOpen key={key} className="py-0 group/collapsible">
59
+ <SidebarGroup>
60
+
61
+ <SidebarGroupLabel asChild className="hover:bg-sidebar-accent text-sidebar-accent-foreground text-sm font-bold">
62
+ <CollapsibleTrigger className="!h-9">
63
+ {t(`filter.tags.${key}`)}
64
+ <ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
65
+ </CollapsibleTrigger>
66
+ </SidebarGroupLabel>
67
+
68
+ <CollapsibleContent>
69
+ <SidebarGroupContent>
70
+ <SidebarMenu>
71
+ <SidebarMenuSub>
72
+ {value.map((item) => (
73
+ <SidebarMenuSubItem key={item.shortId}>
74
+ <SidebarMenuSubButton
75
+ className="cursor-pointer"
76
+ isActive={item.active}
77
+ onClick={() => onClickHandler(key, item)}
78
+ >
79
+ {item.label} ({item.hits}/{item.total})
80
+ {item.active && <Check className="ml-2" />}
81
+ </SidebarMenuSubButton>
82
+ </SidebarMenuSubItem>
83
+ ))}
84
+ </SidebarMenuSub>
85
+ </SidebarMenu>
86
+ </SidebarGroupContent>
87
+ </CollapsibleContent>
88
+ </SidebarGroup>
89
+ </Collapsible>
90
+ ))}
91
+ </SidebarContent>
92
+ )
93
+
94
+ /*
95
+ if (isMobile) {
96
+ return (
97
+
98
+ <SheetContent
99
+ side="left"
100
+ className="!pt-6 !px-2 w-[400px] overflow-y-auto"
101
+ >
102
+ <SheetHeader className="justify-center items-end font-bold">
103
+ {t("filter.filters")}
104
+ <span className="text-xs text-muted-foreground leading-5">
105
+ {totalItemCount} {t("results.results")}
106
+ </span>
107
+ </SheetHeader>
108
+ {content}
109
+ </SheetContent>
110
+ )
111
+ }
112
+ */
113
+
114
+ return (
115
+ <div className="w-60 lg:w-80 bg-sidebar rounded-md border pb-4">
116
+ <SidebarHeader className="justify-center items-end font-bold">
117
+ {t("filter.filters")}
118
+ <span className="text-xs text-muted-foreground leading-5">
119
+ {totalItemCount} {t("results.results")}
120
+ </span>
121
+ </SidebarHeader>
122
+ {content}
123
+ </div>
124
+ );
125
+ };
@@ -0,0 +1,164 @@
1
+ import { FilterItem, Tags } from "@c-rex/interfaces";
2
+ import { EN_LANG } from "@c-rex/constants";
3
+
4
+ export const updateFilterParam = (key: string, item: FilterItem, filter: string | null): Record<string, string | null> => {
5
+
6
+ if (key === "packages") {
7
+ return { packages: item.shortId }
8
+ }
9
+
10
+ const value = `${key}.shortId=${item.shortId}`
11
+ let aux = value
12
+
13
+ if (filter != null) {
14
+ const splittedParam = filter.split(",")
15
+ const finalValue = [...splittedParam]
16
+
17
+ const hasParams = filter.includes(key)
18
+
19
+ if (hasParams) {
20
+ let mainIndex = -1
21
+
22
+ splittedParam.forEach((el, index) => {
23
+ if (el.includes(key)) {
24
+ mainIndex = index
25
+ }
26
+ })
27
+ finalValue[mainIndex] = value
28
+ } else {
29
+ finalValue.push(value)
30
+ }
31
+
32
+ aux = finalValue.join(",")
33
+ }
34
+
35
+ return { filter: aux }
36
+ };
37
+
38
+ export const removeFilterItem = (key: string, item: FilterItem, filter: string | null): Record<string, string | null> => {
39
+ if (key === "packages") {
40
+ return { packages: null }
41
+ }
42
+
43
+ if (filter !== null) {
44
+ const value = `${key}.shortId=${item.shortId}`
45
+ const newValue = filter.split(",").filter(item => item !== value).join(",")
46
+ return { filter: newValue.length === 0 ? null : newValue }
47
+ }
48
+
49
+ return {}
50
+ }
51
+
52
+ export const clearData = (tags: Tags): Record<string, FilterItem[]> => {
53
+ const contentLang = EN_LANG.toLowerCase()
54
+ const splittedContentLang = contentLang.split("-")[0];
55
+ const filteredTags: Record<string, FilterItem[]> = {}
56
+
57
+ for (const [key, value] of Object.entries(tags)) {
58
+ if (!value || !value.items || value.items.length === 0) {
59
+ continue;
60
+ }
61
+
62
+ const aux = value.items.map(item => {
63
+ if (item?.shortId === undefined) return null
64
+ if (Number(item.hits) === 0) return null
65
+ if (item?.labels === undefined || item?.labels.length === 0) {
66
+ /*
67
+ logger.log({
68
+ level: "warning",
69
+ message: `No labels on item with id ${item.shortId} from category ${key}`
70
+ })
71
+ */
72
+
73
+ return null;
74
+ }
75
+
76
+ let label = ""
77
+
78
+ for (const labelItem of item.labels) {
79
+ if (labelItem.language === undefined) {
80
+ /*
81
+ logger.log({
82
+ level: "info",
83
+ message: `No language on label ${labelItem.value} from category ${key}`
84
+ })
85
+ */
86
+ label = labelItem.value
87
+ break;
88
+ }
89
+
90
+ if (labelItem.language.toLowerCase() === contentLang || labelItem.language.toLowerCase() === splittedContentLang) {
91
+ label = labelItem.value
92
+ break;
93
+ }
94
+
95
+ label = labelItem.value
96
+
97
+ // todo: fallback in english
98
+ }
99
+
100
+ return {
101
+ hits: item.hits,
102
+ total: item.total,
103
+ label: label,
104
+ active: false,
105
+ shortId: item.shortId,
106
+ }
107
+ }).filter((item) => item !== null)
108
+
109
+ if (aux.length === 0) {
110
+ continue;
111
+ }
112
+
113
+ filteredTags[key] = aux;
114
+ }
115
+
116
+ return filteredTags;
117
+ }
118
+
119
+ export const memoizeFilteredTags = (tags: Tags | undefined, filter: string | null, packages: string | null) => {
120
+
121
+ if (!tags) return {};
122
+
123
+ const newTags: Record<string, FilterItem[]> = clearData(tags);
124
+
125
+ if (filter !== null) {
126
+ const splittedParam = filter.split(",")
127
+
128
+ splittedParam.forEach((item) => {
129
+ const aux = item.split(".shortId=")
130
+ const name = aux[0] as string
131
+ const shortId = aux[1] as string
132
+
133
+ if (!Object.keys(newTags).includes(name)) {
134
+ newTags[name] = []
135
+ }
136
+
137
+ newTags[name]?.forEach((el) => {
138
+ if (el.shortId == shortId) {
139
+ el.active = true
140
+ } else {
141
+ el.active = false
142
+ }
143
+ })
144
+ })
145
+ } else {
146
+ Object.keys(newTags).forEach((key) => {
147
+ newTags[key]?.forEach((el) => {
148
+ el.active = false
149
+ })
150
+ })
151
+ }
152
+
153
+ if (packages !== null && newTags["packages"]) {
154
+ newTags["packages"].forEach((el) => {
155
+ if (el.shortId == packages) {
156
+ el.active = true
157
+ } else {
158
+ el.active = false
159
+ }
160
+ })
161
+ }
162
+
163
+ return newTags
164
+ }
@@ -1,4 +1,6 @@
1
- import React, { FC } from "react";
1
+ "use client"
2
+
3
+ import { FC } from "react";
2
4
  import {
3
5
  Pagination as PaginationUI,
4
6
  PaginationContent,
@@ -8,13 +10,13 @@ import {
8
10
  PaginationPrevious,
9
11
  } from "@c-rex/ui/pagination"
10
12
  import { parseAsInteger, useQueryState } from "nuqs";
13
+ import { ResultContainerPageInfoModel } from "@c-rex/interfaces";
11
14
 
12
15
  interface PaginationProps {
13
- totalPages: number;
14
- currentPage: number;
16
+ pageInfo: ResultContainerPageInfoModel;
15
17
  }
16
18
 
17
- export const Pagination: FC<PaginationProps> = ({ totalPages, currentPage }) => {
19
+ export const Pagination: FC<PaginationProps> = ({ pageInfo }) => {
18
20
  const disabledClass = "opacity-50 pointer-events-none";
19
21
 
20
22
  const [_, setPage] = useQueryState('page',
@@ -34,16 +36,16 @@ export const Pagination: FC<PaginationProps> = ({ totalPages, currentPage }) =>
34
36
  <PaginationItem>
35
37
  <PaginationPrevious
36
38
  href="#"
37
- className={currentPage === 1 ? disabledClass : ""}
38
- onClick={() => onChangePage(currentPage - 1)}
39
+ className={pageInfo.pageNumber === 1 ? disabledClass : ""}
40
+ onClick={() => onChangePage(pageInfo.pageNumber! - 1)}
39
41
  />
40
42
  </PaginationItem>
41
43
 
42
- {Array.from({ length: totalPages }, (_, index) => index + 1).map((page) => (
44
+ {Array.from({ length: pageInfo.pageCount || 1 }, (_, index) => index + 1).map((page) => (
43
45
  <PaginationItem key={page}>
44
46
  <PaginationLink
45
47
  href="#"
46
- isActive={page === currentPage}
48
+ isActive={page === pageInfo.pageNumber}
47
49
  onClick={() => onChangePage(page)}
48
50
  >
49
51
  {page}
@@ -59,8 +61,8 @@ export const Pagination: FC<PaginationProps> = ({ totalPages, currentPage }) =>
59
61
  <PaginationItem>
60
62
  <PaginationNext
61
63
  href="#"
62
- onClick={() => onChangePage(currentPage + 1)}
63
- className={currentPage === totalPages ? disabledClass : ""}
64
+ onClick={() => onChangePage(pageInfo.pageNumber! + 1)}
65
+ className={pageInfo.pageNumber === pageInfo.pageCount ? disabledClass : ""}
64
66
  />
65
67
  </PaginationItem>
66
68
  </PaginationContent>
@@ -0,0 +1,70 @@
1
+ import React, { FC } from "react";
2
+ import {
3
+ DocumentModel,
4
+ ResultContainerModel,
5
+ ExternalProductGraphicModel,
6
+ FragmentModel,
7
+ InformationUnitModel,
8
+ PackageModel,
9
+ TopicModel
10
+ } from "@c-rex/interfaces";
11
+ import { Empty } from "./empty";
12
+
13
+ type ResultData = ResultContainerModel<
14
+ DocumentModel |
15
+ ExternalProductGraphicModel |
16
+ FragmentModel |
17
+ InformationUnitModel |
18
+ PackageModel |
19
+ TopicModel
20
+ >;
21
+
22
+ const vertical = "vertical";
23
+ const horizontal = "horizontal";
24
+
25
+ interface ResultContainerProps {
26
+ data?: ResultData;
27
+ error?: { message: string; name: string };
28
+ layout?: typeof vertical | typeof horizontal;
29
+
30
+ FilterComponent?: FC<any>;
31
+ ResultsComponent: FC<any>;
32
+ PaginationComponent: FC<any>;
33
+ [key: string]: unknown;
34
+ }
35
+
36
+ export const ResultContainer: FC<ResultContainerProps> = ({
37
+ data,
38
+ error,
39
+ layout = horizontal,
40
+ FilterComponent,
41
+ ResultsComponent,
42
+ PaginationComponent,
43
+ ...props
44
+ }) => {
45
+ if (error) {
46
+ return <div>Error: {error.message}</div>;
47
+ }
48
+
49
+ if (!data || data.items.length === 0) {
50
+ return <Empty />;
51
+ }
52
+
53
+ return (
54
+ <div className="flex flex-row gap-6 pb-6">
55
+
56
+ {(data.tags && FilterComponent) && (
57
+ <FilterComponent
58
+ tags={data.tags}
59
+ totalItemCount={data.pageInfo.totalItemCount!}
60
+ {...props}
61
+ />
62
+ )}
63
+ <div className="flex-1">
64
+ <ResultsComponent items={data.items} {...props} />
65
+
66
+ <PaginationComponent pageInfo={data.pageInfo} {...props} />
67
+ </div>
68
+ </div>
69
+ );
70
+ };
@@ -1,5 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
- import BlogView from '../result-view/blog';
2
+ import BlogView from '../cards';
3
3
 
4
4
  const meta: Meta<typeof BlogView> = {
5
5
  title: 'Components/ResultView/Blog',
@@ -1,5 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
- import TableView from '../result-view/table';
2
+ import TableView from '../table';
3
3
 
4
4
  const meta: Meta<typeof TableView> = {
5
5
  title: 'Components/ResultView/Table',
@@ -0,0 +1,140 @@
1
+ import { FC } from "react";
2
+ import {
3
+ DocumentModel,
4
+ ExternalProductGraphicModel,
5
+ FragmentModel,
6
+ InformationUnitModel,
7
+ PackageModel,
8
+ TopicModel
9
+ } from "@c-rex/interfaces";
10
+ import { FileStack } from "lucide-react";
11
+ import { OpenOrDownloadFileDropdown } from "../renditions/file-download";
12
+ import { cn, getType, getTitle, getLanguage } from "@c-rex/utils";
13
+ import { Button } from "@c-rex/ui/button";
14
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@c-rex/ui/tooltip";
15
+ import { Favorite, ResultTypes } from "@c-rex/types";
16
+ import { getVersions } from "./utils";
17
+ import { RESULT_TYPES } from "@c-rex/constants";
18
+ import { FavoriteButton } from "../favorites/favorite-button";
19
+ import { ImageRenditionContainer } from "../renditions/image/container";
20
+ import { BookmarkButton } from "../favorites/bookmark-button";
21
+ import { HtmlRendition } from "../renditions/html";
22
+
23
+ interface TableWithImageProps {
24
+ items: (
25
+ DocumentModel |
26
+ ExternalProductGraphicModel |
27
+ FragmentModel |
28
+ InformationUnitModel |
29
+ PackageModel |
30
+ TopicModel
31
+ )[];
32
+ query?: string;
33
+ markersList?: Favorite[];
34
+ disabledResults?: ResultTypes[];
35
+ imageRestrictions?: string[];
36
+ }
37
+
38
+
39
+ export const TableWithImage: FC<TableWithImageProps> = ({ items, query = "", disabledResults = [], imageRestrictions = [] }) => {
40
+ return (
41
+ <div className="flex-1">
42
+ {items.map((item, index) => {
43
+ const title = getTitle(item.titles, item.labels);
44
+ const language = getLanguage(item.languages);
45
+ const itemType = getType(item.class);
46
+ const disabled = disabledResults.includes(itemType);
47
+ const isDocument = itemType === RESULT_TYPES.DOCUMENT;
48
+ const multipleVersions = getVersions(item.versionOf);
49
+ const packageId = item.packages && item.packages.length > 0 ? item.packages[0]?.shortId : null;
50
+
51
+ let itemLink = `/topics/${item.shortId}/content`
52
+ if (isDocument) {
53
+ itemLink = `/documents/${item.shortId}/details`
54
+ }
55
+ itemLink += `?q=${query}`
56
+
57
+ if (packageId) {
58
+ itemLink += `&package=${packageId}`
59
+ }
60
+
61
+
62
+ return (
63
+ <div
64
+ key={index}
65
+ className={cn(
66
+ "min-h-12 flex flex-wrap items-center border px-4 py-2 gap-2 rounded",
67
+ index == items.length - 1 ? "" : "mb-4",
68
+ `c-rex-result-item c-rex-result-${itemType}`,
69
+ disabled && "c-rex-result-item-disabled",
70
+ )}
71
+ >
72
+ <div className="h-16 w-16 flex items-start">
73
+ <ImageRenditionContainer
74
+ itemShortId={item.shortId!}
75
+ imageRestrictions={imageRestrictions}
76
+ emptyImageStyle="h-16 w-16"
77
+ />
78
+ </div>
79
+
80
+ <div className="flex-1 p-2 flex flex-col">
81
+ <span className="text-sm text-muted-foreground">
82
+ {language} - {item.shortId}
83
+ </span>
84
+
85
+ <span className="text-lg font-medium">
86
+ {disabled ? (
87
+ title
88
+ ) : (
89
+ <a className="hover:underline" href={itemLink}>{title}</a>
90
+ )}
91
+ </span>
92
+
93
+ <span className="text-sm">
94
+ {itemType}
95
+ </span>
96
+ <span className="text-sm">
97
+ <HtmlRendition shortId={item.shortId!} />
98
+ </span>
99
+ </div>
100
+
101
+ <div className="flex flex-col p-2 ml-auto justify-center">
102
+ <span className="text-end text-sm text-muted-foreground mb-2">
103
+ {item.revision}
104
+ </span>
105
+ <div className="flex gap-2">
106
+ <OpenOrDownloadFileDropdown renditions={item.renditions} />
107
+
108
+ {isDocument && (
109
+ <BookmarkButton
110
+ shortId={item.shortId!}
111
+
112
+ />
113
+ )}
114
+
115
+ <FavoriteButton
116
+ id={item.shortId!}
117
+ type={itemType}
118
+ label={title}
119
+ />
120
+
121
+ {multipleVersions.length > 1 && (
122
+ <Tooltip>
123
+ <TooltipTrigger asChild>
124
+ <Button variant="ghost" size="icon">
125
+ <FileStack />
126
+ </Button>
127
+ </TooltipTrigger>
128
+ <TooltipContent>
129
+ Available in: {multipleVersions.join(", ")}
130
+ </TooltipContent>
131
+ </Tooltip>
132
+ )}
133
+ </div>
134
+ </div>
135
+ </div>
136
+ );
137
+ })}
138
+ </div>
139
+ );
140
+ };
@@ -5,7 +5,7 @@ import { CloudDownload, Eye } from "lucide-react";
5
5
  import { FaFilePdf } from "react-icons/fa6";
6
6
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@c-rex/ui/dropdown-menu";
7
7
  import { cn } from "@c-rex/utils";
8
- import { Flag } from "../flag";
8
+ import { Flag } from "../icons/flag-icon";
9
9
  import { Badge } from "@c-rex/ui/badge";
10
10
  import { useQueryState } from "nuqs";
11
11
 
@@ -13,7 +13,6 @@ interface TableViewProps {
13
13
  items: informationUnitsResponseItem[];
14
14
  }
15
15
 
16
-
17
16
  const IconsToFileExtension: Record<string, React.ReactNode> = {
18
17
  "application/pdf": <FaFilePdf className="h-6 w-6" />,
19
18
  };
@@ -0,0 +1,67 @@
1
+ import { LiteralModel, ObjectRefModel, RenditionModel } from "@c-rex/interfaces";
2
+ import { DocumentsType } from "@c-rex/types";
3
+
4
+ export const getFileRenditions = ({ renditions }: { renditions: RenditionModel[] }): DocumentsType => {
5
+ if (renditions == undefined || renditions.length == 0) {
6
+ return {} as DocumentsType;
7
+ }
8
+
9
+ const filteredRenditions = renditions.filter(
10
+ (item) => item.format != "application/xhtml+xml" && item.format != "application/json" && item.format != "application/llm+xml"
11
+ );
12
+
13
+ if (filteredRenditions.length == 0 || filteredRenditions[0] == undefined) {
14
+ return {} as DocumentsType;
15
+ }
16
+
17
+ const result: {
18
+ [key: string]: {
19
+ view: string;
20
+ download: string;
21
+ }
22
+ } = {}
23
+
24
+ filteredRenditions.forEach((item) => {
25
+ const key = item.format!
26
+
27
+ if (result[key] == undefined) {
28
+ result[key] = {
29
+ view: "",
30
+ download: ""
31
+ }
32
+ }
33
+ const download = item.links?.filter((link) => link.rel == "download")[0]?.href
34
+ const view = item.links?.filter((link) => link.rel == "view")[0]?.href
35
+
36
+ if (download != null && download != undefined) {
37
+ result[key].download = download
38
+ }
39
+
40
+ if (view != null && view != undefined) {
41
+ result[key].view = view
42
+ }
43
+ })
44
+
45
+ return result
46
+ }
47
+
48
+
49
+ export const getDescription = (descriptions?: LiteralModel[] | null, abstracts?: LiteralModel[] | null): string => {
50
+ const desc = descriptions?.[0]?.value || abstracts?.[0]?.value;
51
+ return desc || "";
52
+ };
53
+
54
+ export const getClassLabel = (classObj?: { labels?: LiteralModel[] | null }): string => {
55
+ return classObj?.labels?.[0]?.value || "Document";
56
+ };
57
+
58
+ export const getVersions = (versionOf?: ObjectRefModel) => {
59
+ let versionList: string[] = []
60
+ if (versionOf && versionOf.labels) {
61
+ const aux = versionOf.labels.map(item => item.language!)
62
+ versionList = aux.filter((value) => value !== undefined);
63
+ }
64
+ return versionList;
65
+ };
66
+
67
+