@c-rex/components 0.1.36 → 0.1.38
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/package.json +1 -18
- package/src/article/article-content.tsx +26 -35
- package/src/autocomplete.tsx +26 -5
- package/src/carousel/carousel.tsx +53 -52
- package/src/check-article-lang.tsx +8 -4
- package/src/favorites/bookmark-button.tsx +26 -11
- package/src/favorites/favorite-button.tsx +67 -21
- package/src/info/info-table.tsx +60 -38
- package/src/info/set-available-versions.tsx +19 -0
- package/src/navbar/language-switcher/content-language-switch.tsx +36 -36
- package/src/navbar/language-switcher/ui-language-switch.tsx +5 -6
- package/src/navbar/navbar.tsx +17 -8
- package/src/renditions/html.tsx +38 -31
- package/src/restriction-menu/restriction-menu-item.tsx +8 -5
- package/src/restriction-menu/restriction-menu.tsx +26 -25
- package/src/results/generic/table-result-list.tsx +1 -1
- package/src/results/utils.ts +9 -2
- package/src/stores/favorites-store.ts +21 -21
- package/src/stores/language-store.ts +2 -31
- package/src/article/article-action-bar.analysis.md +0 -15
- package/src/article/article-action-bar.stories.tsx +0 -15
- package/src/article/article-content.analysis.md +0 -15
- package/src/article/article-content.stories.tsx +0 -21
- package/src/autocomplete.analysis.md +0 -17
- package/src/breadcrumb.analysis.md +0 -15
- package/src/carousel/carousel.analysis.md +0 -17
- package/src/check-article-lang.analysis.md +0 -15
- package/src/directoryNodes/tree-of-content.analysis.md +0 -14
- package/src/directoryNodes/tree-of-content.stories.tsx +0 -22
- package/src/documents/result-list.analysis.md +0 -14
- package/src/documents/result-list.stories.tsx +0 -19
- package/src/favorites/bookmark-button.analysis.md +0 -17
- package/src/favorites/bookmark-button.stories.tsx +0 -19
- package/src/favorites/favorite-button.analysis.md +0 -18
- package/src/favorites/favorite-button.stories.tsx +0 -22
- package/src/icons/file-icon.analysis.md +0 -14
- package/src/icons/file-icon.stories.tsx +0 -19
- package/src/icons/flag-icon.analysis.md +0 -14
- package/src/icons/flag-icon.stories.tsx +0 -25
- package/src/icons/loading.analysis.md +0 -14
- package/src/icons/loading.stories.tsx +0 -21
- package/src/info/info-table.analysis.md +0 -15
- package/src/info/shared.analysis.md +0 -14
- package/src/info/stories/info-table.stories.tsx +0 -31
- package/src/info/stories/shared.stories.tsx +0 -24
- package/src/navbar/language-switcher/content-language-switch.analysis.md +0 -15
- package/src/navbar/language-switcher/shared.analysis.md +0 -14
- package/src/navbar/language-switcher/ui-language-switch.analysis.md +0 -15
- package/src/navbar/navbar.analysis.md +0 -14
- package/src/navbar/settings.analysis.md +0 -14
- package/src/navbar/sign-in-out-btns.analysis.md +0 -14
- package/src/navbar/stories/navbar.stories.tsx +0 -31
- package/src/navbar/stories/settings.stories.tsx +0 -15
- package/src/navbar/stories/sign-in-out-btns.stories.tsx +0 -15
- package/src/navbar/stories/user-menu.stories.tsx +0 -20
- package/src/navbar/user-menu.analysis.md +0 -14
- package/src/page-wrapper.analysis.md +0 -14
- package/src/render-article.analysis.md +0 -15
- package/src/renditions/file-download.analysis.md +0 -14
- package/src/renditions/file-download.stories.tsx +0 -19
- package/src/renditions/html.analysis.md +0 -17
- package/src/renditions/html.stories.tsx +0 -19
- package/src/renditions/image/container.analysis.md +0 -15
- package/src/renditions/image/container.stories.tsx +0 -19
- package/src/renditions/image/rendition.analysis.md +0 -14
- package/src/renditions/image/rendition.stories.tsx +0 -19
- package/src/restriction-menu/restriction-menu-container.analysis.md +0 -14
- package/src/restriction-menu/restriction-menu-item.analysis.md +0 -14
- package/src/restriction-menu/restriction-menu.analysis.md +0 -17
- package/src/results/analysis/cards.analysis.md +0 -14
- package/src/results/analysis/dialog-filter.analysis.md +0 -17
- package/src/results/analysis/empty.analysis.md +0 -14
- package/src/results/analysis/filter-navbar.analysis.md +0 -16
- package/src/results/analysis/pagination.analysis.md +0 -14
- package/src/results/analysis/table-with-images.analysis.md +0 -15
- package/src/results/analysis/table.analysis.md +0 -15
- package/src/results/filter-sidebar/index.analysis.md +0 -14
- package/src/results/generic/table-result-list.analysis.md +0 -15
- package/src/results/generic/table-result-list.stories.tsx +0 -21
- package/src/results/stories/cards.stories.tsx +0 -66
- package/src/results/stories/dialog-filter.stories.tsx +0 -20
- package/src/results/stories/empty.stories.tsx +0 -25
- package/src/results/stories/filter-navbar.stories.tsx +0 -19
- package/src/results/stories/filter-sidebar.stories.tsx +0 -20
- package/src/results/stories/pagination.stories.tsx +0 -24
- package/src/results/stories/table-with-images.stories.tsx +0 -19
- package/src/results/stories/table.stories.tsx +0 -78
- package/src/search-input.analysis.md +0 -15
- package/src/share-button.analysis.md +0 -19
- package/src/stories/autocomplete.stories.tsx +0 -20
- package/src/stories/breadcrumb.stories.tsx +0 -93
- package/src/stories/check-article-lang.stories.tsx +0 -22
- package/src/stories/render-article.stories.tsx +0 -19
- package/src/stories/search-input.stories.tsx +0 -21
- package/src/stories/share-button.stories.tsx +0 -15
package/src/info/info-table.tsx
CHANGED
|
@@ -20,40 +20,79 @@ import { Flag } from "../icons/flag-icon";
|
|
|
20
20
|
import { Button } from "@c-rex/ui/button";
|
|
21
21
|
import { FileIcon } from "../icons/file-icon";
|
|
22
22
|
import { BookmarkButton } from "../favorites/bookmark-button";
|
|
23
|
-
import {
|
|
23
|
+
import { informationUnitsGetAllServer } from "@c-rex/services/server-requests";
|
|
24
24
|
import { getTranslations } from "next-intl/server";
|
|
25
25
|
import { EN_LANG } from "@c-rex/constants";
|
|
26
26
|
import { getFileRenditions } from "../results/utils";
|
|
27
27
|
import Link from "next/link";
|
|
28
28
|
import { processDataToLabelValuePairs } from "@c-rex/utils";
|
|
29
|
+
import { AvailableVersionsInterface } from "@c-rex/interfaces";
|
|
30
|
+
import { SetAvailableVersions } from "./set-available-versions";
|
|
29
31
|
|
|
30
32
|
type Props = {
|
|
31
33
|
title: string;
|
|
32
|
-
|
|
34
|
+
linkPattern: string;
|
|
33
35
|
data: InformationUnitModel;
|
|
34
36
|
excludeKeys?: string[];
|
|
35
37
|
showBookmarkButton?: boolean;
|
|
38
|
+
saveVersionsInContext?: boolean;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
export const InfoTable: FC<Props> = async ({
|
|
39
42
|
title,
|
|
40
43
|
data,
|
|
41
|
-
|
|
44
|
+
linkPattern,
|
|
42
45
|
showBookmarkButton = false,
|
|
46
|
+
saveVersionsInContext = false
|
|
43
47
|
}) => {
|
|
44
|
-
const
|
|
48
|
+
const versionBaseShortId = data.versionOf?.shortId ?? null;
|
|
49
|
+
const [t, informationUnits] = await Promise.all([
|
|
50
|
+
getTranslations(),
|
|
51
|
+
versionBaseShortId
|
|
52
|
+
? informationUnitsGetAllServer({
|
|
53
|
+
Restrict: [`versionOf.shortId=${versionBaseShortId}`],
|
|
54
|
+
Fields: ["renditions", "class", "languages", "labels"],
|
|
55
|
+
})
|
|
56
|
+
: Promise.resolve({ items: [] }),
|
|
57
|
+
])
|
|
45
58
|
const files = getFileRenditions({ renditions: data.renditions! });
|
|
59
|
+
const versionsByShortId = new Map<string, { shortId: string; language: string }>();
|
|
60
|
+
|
|
61
|
+
if (data.shortId && data.languages?.[0]) {
|
|
62
|
+
versionsByShortId.set(data.shortId, {
|
|
63
|
+
shortId: data.shortId,
|
|
64
|
+
language: data.languages[0],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
informationUnits.items.forEach((item) => {
|
|
69
|
+
if (!item.shortId || !item.languages?.[0]) return;
|
|
70
|
+
versionsByShortId.set(item.shortId, {
|
|
71
|
+
shortId: item.shortId,
|
|
72
|
+
language: item.languages[0],
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const availableVersions = Array.from(versionsByShortId.values())
|
|
77
|
+
.map((item) => ({
|
|
78
|
+
shortId: item.shortId,
|
|
79
|
+
active: item.shortId === data.shortId,
|
|
80
|
+
lang: item.language,
|
|
81
|
+
country: item.language.split("-")[1] ?? item.language,
|
|
82
|
+
link: linkPattern.replace("{shortId}", item.shortId),
|
|
83
|
+
}))
|
|
84
|
+
.sort((a, b) => a.lang.localeCompare(b.lang)) as AvailableVersionsInterface[];
|
|
46
85
|
|
|
47
86
|
return (
|
|
48
87
|
<Card className="p-0 !pt-4">
|
|
49
88
|
<CardHeader>
|
|
50
89
|
<CardTitle className="text-lg flex justify-between items-end">
|
|
51
90
|
{title}
|
|
52
|
-
|
|
53
91
|
{showBookmarkButton && <BookmarkButton shortId={data.shortId!} />}
|
|
54
92
|
</CardTitle>
|
|
55
93
|
</CardHeader>
|
|
56
94
|
<CardContent className="space-y-3 !p-0">
|
|
95
|
+
{saveVersionsInContext && <SetAvailableVersions versions={availableVersions} />}
|
|
57
96
|
<Table>
|
|
58
97
|
<TableBody>
|
|
59
98
|
{processDataToLabelValuePairs(data).map((item) => (
|
|
@@ -67,39 +106,22 @@ export const InfoTable: FC<Props> = async ({
|
|
|
67
106
|
</TableRow>
|
|
68
107
|
))}
|
|
69
108
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<TableCell className="text-xs text-muted-foreground flex items-center gap-2 min-h-12">
|
|
87
|
-
{data.items.map((item) => {
|
|
88
|
-
const language = item.languages?.[0] ?? "NO LANGUAGE";
|
|
89
|
-
const country = language.split("-")[1]!;
|
|
90
|
-
return (
|
|
91
|
-
<span className="w-8 block border" key={item.shortId}>
|
|
92
|
-
<Link href={`/${linkPath}/${item.shortId}/content`} title={language}>
|
|
93
|
-
<Flag countryCode={country} />
|
|
94
|
-
</Link>
|
|
95
|
-
</span>
|
|
96
|
-
)
|
|
97
|
-
})}
|
|
98
|
-
</TableCell>
|
|
99
|
-
</TableRow>
|
|
100
|
-
)
|
|
101
|
-
}}
|
|
102
|
-
/>
|
|
109
|
+
<TableRow className="min-h-12">
|
|
110
|
+
<TableCell className="font-medium w-28 pl-4">
|
|
111
|
+
<h4 className="text-sm font-medium">{t("availableIn")}</h4>
|
|
112
|
+
</TableCell>
|
|
113
|
+
<TableCell className="text-xs text-muted-foreground flex items-center gap-2 min-h-12">
|
|
114
|
+
{availableVersions.map((item) => {
|
|
115
|
+
return (
|
|
116
|
+
<span className="w-8 block border" key={item.shortId}>
|
|
117
|
+
<Link href={item.link} title={item.lang}>
|
|
118
|
+
<Flag countryCode={item.country} />
|
|
119
|
+
</Link>
|
|
120
|
+
</span>
|
|
121
|
+
)
|
|
122
|
+
})}
|
|
123
|
+
</TableCell>
|
|
124
|
+
</TableRow>
|
|
103
125
|
|
|
104
126
|
{Object.keys(files).length > 0 && (
|
|
105
127
|
<TableRow className="min-h-12">
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import { AvailableVersionsInterface } from "@c-rex/interfaces";
|
|
5
|
+
import { useAppConfig } from "@c-rex/contexts/config-provider";
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
versions: AvailableVersionsInterface[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const SetAvailableVersions = ({ versions }: Props) => {
|
|
12
|
+
const { setAvailableVersions } = useAppConfig();
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
setAvailableVersions(versions);
|
|
16
|
+
}, [setAvailableVersions, versions]);
|
|
17
|
+
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { startTransition } from "react";
|
|
3
|
+
import { startTransition, useCallback, useMemo } from "react";
|
|
4
4
|
import { SharedLanguageSwitch } from "./shared";
|
|
5
|
-
import { BLOG_TYPE_AND_LINK, DOCUMENTS_TYPE_AND_LINK, TOPICS_TYPE_AND_LINK } from "@c-rex/constants";
|
|
6
5
|
import { useQueryState } from "nuqs"
|
|
7
6
|
import { useAppConfig } from "@c-rex/contexts/config-provider";
|
|
8
7
|
import { useTranslations } from "next-intl";
|
|
@@ -16,26 +15,36 @@ type Props = {
|
|
|
16
15
|
|
|
17
16
|
export const ContentLanguageSwitch = ({ contentLangDefault }: Props) => {
|
|
18
17
|
const t = useTranslations();
|
|
19
|
-
const contentLang = useSearchSettingsStore
|
|
20
|
-
const updatePreferences = useSearchSettingsStore
|
|
21
|
-
|
|
18
|
+
const contentLang = useSearchSettingsStore((state) => state.language) || contentLangDefault;
|
|
19
|
+
const updatePreferences = useSearchSettingsStore((state) => state.updatePreferences);
|
|
20
|
+
const availableLanguages = useLanguageStore((state) => state.availableLanguages);
|
|
22
21
|
const { availableVersions } = useAppConfig()
|
|
23
22
|
|
|
24
|
-
const availableLanguagesAndCountries = () => {
|
|
25
|
-
const aux = useLanguageStore.getState().availableLanguages;
|
|
26
|
-
let result = aux.map(item => ({ ...item, link: "#" }))
|
|
27
|
-
if (availableVersions == null) return result
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
const normalizeLang = (lang: string) => lang.trim().toLowerCase();
|
|
25
|
+
|
|
26
|
+
const findVersionByLocale = useCallback((locale: string) => {
|
|
27
|
+
if (!availableVersions || availableVersions.length === 0) return undefined;
|
|
28
|
+
const normalizedLocale = normalizeLang(locale);
|
|
29
|
+
|
|
30
|
+
return availableVersions.find((item) => normalizeLang(item.lang) === normalizedLocale)
|
|
31
|
+
?? availableVersions.find((item) => {
|
|
32
|
+
const langCode = normalizeLang(item.lang).split("-")[0];
|
|
33
|
+
const localeCode = normalizedLocale.split("-")[0];
|
|
34
|
+
return langCode === localeCode;
|
|
35
|
+
});
|
|
36
|
+
}, [availableVersions]);
|
|
37
|
+
|
|
38
|
+
const availableLanguagesAndCountries = useMemo(() => {
|
|
39
|
+
return availableLanguages.map((item) => {
|
|
40
|
+
const availableVersion = findVersionByLocale(item.value);
|
|
31
41
|
return {
|
|
32
42
|
...item,
|
|
33
|
-
link: availableVersion?.link ?? "#"
|
|
34
|
-
}
|
|
35
|
-
})
|
|
43
|
+
link: availableVersion?.link ?? "#",
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}, [availableLanguages, availableVersions]);
|
|
36
47
|
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
48
|
const [queryLanguage, setContentLanguage] = useQueryState('language', {
|
|
40
49
|
history: 'push',
|
|
41
50
|
shallow: false,
|
|
@@ -44,34 +53,25 @@ export const ContentLanguageSwitch = ({ contentLangDefault }: Props) => {
|
|
|
44
53
|
const changeContentLanguage = (locale: string) => {
|
|
45
54
|
startTransition(() => {
|
|
46
55
|
updatePreferences({ language: locale })
|
|
47
|
-
|
|
48
56
|
if (queryLanguage != null) {
|
|
49
57
|
setContentLanguage(locale)
|
|
58
|
+
return;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
//TODO en: needs to be fixed as it's not working
|
|
53
|
-
|
|
54
61
|
const currentPath = window.location.pathname;
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
const isArticlePage = currentPath.includes("/pages");
|
|
63
|
+
if (!isArticlePage) {
|
|
64
|
+
window.location.reload();
|
|
65
|
+
return;
|
|
66
|
+
};
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
const targetVersion = findVersionByLocale(locale);
|
|
69
|
+
if (targetVersion?.link) {
|
|
70
|
+
window.location.href = targetVersion.link;
|
|
63
71
|
return;
|
|
64
72
|
}
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
const filteredList = availableVersions.filter((item) => item.lang === locale)
|
|
68
|
-
|
|
69
|
-
if (filteredList.length > 0 && filteredList[0]) {
|
|
70
|
-
window.location.href = filteredList[0].link as string;
|
|
71
|
-
} else {
|
|
72
|
-
articleNotAvailableToast()
|
|
73
|
-
}
|
|
74
|
-
}
|
|
74
|
+
articleNotAvailableToast()
|
|
75
75
|
});
|
|
76
76
|
};
|
|
77
77
|
|
|
@@ -84,7 +84,7 @@ export const ContentLanguageSwitch = ({ contentLangDefault }: Props) => {
|
|
|
84
84
|
|
|
85
85
|
return (
|
|
86
86
|
<SharedLanguageSwitch
|
|
87
|
-
availableLanguagesAndCountries={availableLanguagesAndCountries
|
|
87
|
+
availableLanguagesAndCountries={availableLanguagesAndCountries}
|
|
88
88
|
changeLanguage={changeContentLanguage}
|
|
89
89
|
selected={contentLang}
|
|
90
90
|
/>
|
|
@@ -5,11 +5,12 @@ import { SharedLanguageSwitch } from "./shared";
|
|
|
5
5
|
import { UI_LANG_KEY, UI_LANG_OPTIONS } from "@c-rex/constants";
|
|
6
6
|
import { getCountryCodeByLang, } from "@c-rex/utils";
|
|
7
7
|
import { setCookie } from "@c-rex/utils/cookies";
|
|
8
|
-
import {
|
|
8
|
+
import { useLocale } from "next-intl";
|
|
9
|
+
import { useRouter } from "next/navigation";
|
|
9
10
|
|
|
10
11
|
export const UILanguageSwitch: FC = () => {
|
|
11
|
-
const uiLang =
|
|
12
|
-
const
|
|
12
|
+
const uiLang = useLocale().toLowerCase();
|
|
13
|
+
const router = useRouter();
|
|
13
14
|
const UILanguages = UI_LANG_OPTIONS.map((lang) => {
|
|
14
15
|
const langCode = lang.split("-")[0] as string;
|
|
15
16
|
return {
|
|
@@ -21,10 +22,8 @@ export const UILanguageSwitch: FC = () => {
|
|
|
21
22
|
|
|
22
23
|
const setUILanguage = (locale: string) => {
|
|
23
24
|
startTransition(() => {
|
|
24
|
-
setUiLang(locale)
|
|
25
25
|
setCookie(UI_LANG_KEY, locale, { httpOnly: false });
|
|
26
|
-
|
|
27
|
-
//window.location.reload()
|
|
26
|
+
router.refresh();
|
|
28
27
|
});
|
|
29
28
|
}
|
|
30
29
|
|
package/src/navbar/navbar.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FC } from "react";
|
|
2
2
|
import Link from "next/link";
|
|
3
3
|
import { SignInBtn } from "./sign-in-out-btns";
|
|
4
4
|
import { getServerSession } from "next-auth";
|
|
@@ -30,7 +30,7 @@ export const NavBar: FC<NavBarProps> = async ({
|
|
|
30
30
|
showInput,
|
|
31
31
|
autocompleteType,
|
|
32
32
|
onSelectPath,
|
|
33
|
-
showMenu =
|
|
33
|
+
showMenu = true,
|
|
34
34
|
...props
|
|
35
35
|
}) => {
|
|
36
36
|
const t = await getTranslations();
|
|
@@ -75,27 +75,32 @@ export const NavBar: FC<NavBarProps> = async ({
|
|
|
75
75
|
</Button>
|
|
76
76
|
}
|
|
77
77
|
>
|
|
78
|
-
<Button asChild variant="link">
|
|
78
|
+
<Button asChild variant="link" className="flex justify-start">
|
|
79
|
+
<Link href="/">
|
|
80
|
+
{t('navigation.home')}
|
|
81
|
+
</Link>
|
|
82
|
+
</Button>
|
|
83
|
+
<Button asChild variant="link" className="flex justify-start">
|
|
79
84
|
<Link href="/documents">
|
|
80
85
|
{t('navigation.documents')}
|
|
81
86
|
</Link>
|
|
82
87
|
</Button>
|
|
83
|
-
<Button asChild variant="link">
|
|
88
|
+
<Button asChild variant="link" className="flex justify-start">
|
|
84
89
|
<Link href="/topics">
|
|
85
90
|
{t('navigation.topics')}
|
|
86
91
|
</Link>
|
|
87
92
|
</Button>
|
|
88
|
-
<Button asChild variant="link">
|
|
93
|
+
<Button asChild variant="link" className="flex justify-start">
|
|
89
94
|
<Link href="/fragments">
|
|
90
95
|
{t('navigation.fragments')}
|
|
91
96
|
</Link>
|
|
92
97
|
</Button>
|
|
93
|
-
<Button asChild variant="link">
|
|
98
|
+
<Button asChild variant="link" className="flex justify-start">
|
|
94
99
|
<Link href="/packages">
|
|
95
100
|
{t('navigation.packages')}
|
|
96
101
|
</Link>
|
|
97
102
|
</Button>
|
|
98
|
-
<Button asChild variant="link">
|
|
103
|
+
<Button asChild variant="link" className="flex justify-start">
|
|
99
104
|
<Link href="/information-units">
|
|
100
105
|
{t('navigation.informationUnits')}
|
|
101
106
|
</Link>
|
|
@@ -113,7 +118,11 @@ export const NavBar: FC<NavBarProps> = async ({
|
|
|
113
118
|
<div className="flex gap-2">
|
|
114
119
|
{willShowInput &&
|
|
115
120
|
<div className="hidden sm:flex flex-1 items-center px-3 border rounded-full h-8 c-rex-search-bar">
|
|
116
|
-
<SearchInput
|
|
121
|
+
<SearchInput
|
|
122
|
+
autocompleteType={autocompleteType}
|
|
123
|
+
onSelectPath={onSelectPath}
|
|
124
|
+
{...props}
|
|
125
|
+
/>
|
|
117
126
|
</div>
|
|
118
127
|
}
|
|
119
128
|
|
package/src/renditions/html.tsx
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { FC, JSX } from "react";
|
|
2
2
|
import * as cheerio from "cheerio"
|
|
3
|
-
import {
|
|
3
|
+
import { RenditionModel } from "@c-rex/interfaces";
|
|
4
|
+
import { fragmentsGetAllServer } from "@c-rex/services/server-requests";
|
|
5
|
+
import { call } from "@c-rex/utils";
|
|
4
6
|
|
|
5
7
|
interface HtmlRenditionProps {
|
|
6
8
|
htmlFormats?: string[]
|
|
7
9
|
shortId: string,
|
|
8
|
-
render?: (html: string) => JSX.Element
|
|
10
|
+
render?: (html: string) => JSX.Element,
|
|
11
|
+
renditions?: RenditionModel[] | null
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
const defaultRender = (html: string) => {
|
|
@@ -14,45 +17,49 @@ const defaultRender = (html: string) => {
|
|
|
14
17
|
return <div dangerouslySetInnerHTML={{ __html: articleHtml }} />;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
export const HtmlRendition: FC<HtmlRenditionProps> = ({
|
|
20
|
+
export const HtmlRendition: FC<HtmlRenditionProps> = async ({
|
|
18
21
|
shortId,
|
|
19
22
|
htmlFormats = ["application/xhtml+xml", "application/html", "text/html"],
|
|
20
|
-
render
|
|
23
|
+
render = defaultRender,
|
|
24
|
+
renditions
|
|
21
25
|
}) => {
|
|
22
26
|
const empty = <div>No rendition available</div>;
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
if (renditions == undefined) {
|
|
29
|
+
const result = await fragmentsGetAllServer({
|
|
30
|
+
Fields: ["titles", "renditions"],
|
|
31
|
+
Embed: ["renditions"],
|
|
32
|
+
PageSize: 1,
|
|
33
|
+
Links: true,
|
|
34
|
+
Restrict: [
|
|
35
|
+
`informationUnits=${shortId}`,
|
|
36
|
+
...htmlFormats.map(format => `renditions.format=${format}`)
|
|
37
|
+
],
|
|
38
|
+
})
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (error) {
|
|
39
|
-
return <div>Error loading content</div>;
|
|
40
|
-
}
|
|
40
|
+
renditions = result.items?.[0]?.renditions;
|
|
41
|
+
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
if (renditions == null || renditions.length == 0) return empty;
|
|
44
|
+
renditions = renditions.filter(rendition => htmlFormats.includes(rendition.format!));
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
if (renditions.length == 0 || renditions[0] == undefined || renditions[0].links == undefined) return empty;
|
|
46
|
+
if (renditions.length == 0 || renditions[0] == undefined || renditions[0].links == undefined) return empty;
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
const filteredLinks = renditions[0].links.filter((item) => item.rel == "view");
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
if (filteredLinks.length == 0 || filteredLinks[0] == undefined || filteredLinks[0].href == undefined) return empty;
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
const url = filteredLinks[0].href;
|
|
53
|
+
try {
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const html = await fetch(url).then(res => res.text());
|
|
56
|
+
return render(html);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
call("CrexLogger.log", {
|
|
59
|
+
level: "error",
|
|
60
|
+
message: `HtmlRendition error: ${error}`
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return empty;
|
|
64
|
+
}
|
|
58
65
|
}
|
|
@@ -77,23 +77,26 @@ export const RestrictionDropdownItem: FC<Props> = ({
|
|
|
77
77
|
shortId,
|
|
78
78
|
label,
|
|
79
79
|
restrictField,
|
|
80
|
+
selected = false,
|
|
80
81
|
}) => {
|
|
81
82
|
const [restrict, setRestrict] = useQueryState("restrict", {
|
|
82
83
|
shallow: false,
|
|
83
84
|
history: "push",
|
|
84
85
|
});
|
|
85
86
|
|
|
86
|
-
const { restrictionValue } = getRestrictionValue({
|
|
87
|
+
const { restrictionValue, shouldRemoveRestrictParam } = getRestrictionValue({
|
|
87
88
|
shortId,
|
|
88
89
|
restrictField,
|
|
90
|
+
selected,
|
|
89
91
|
currentRestrict: restrict,
|
|
90
92
|
});
|
|
91
93
|
|
|
92
94
|
return (
|
|
93
95
|
<Button
|
|
94
|
-
variant="ghost"
|
|
95
|
-
onClick={() => setRestrict(restrictionValue)}
|
|
96
|
-
|
|
96
|
+
variant={selected ? "default" : "ghost"}
|
|
97
|
+
onClick={() => shouldRemoveRestrictParam ? setRestrict(null) : setRestrict(restrictionValue)}
|
|
98
|
+
rounded="full"
|
|
99
|
+
className="text-left text-wrap !h-auto min-h-10 w-full !justify-start cursor-pointer"
|
|
97
100
|
>
|
|
98
101
|
{label}
|
|
99
102
|
</Button>
|
|
@@ -141,4 +144,4 @@ function getRestrictionValue({
|
|
|
141
144
|
const restrictionValue = shouldRemoveRestrictParam ? null : restrictParam
|
|
142
145
|
|
|
143
146
|
return { restrictionValue, shouldRemoveRestrictParam };
|
|
144
|
-
}
|
|
147
|
+
}
|
|
@@ -5,17 +5,15 @@ import {
|
|
|
5
5
|
NavigationMenu,
|
|
6
6
|
NavigationMenuList,
|
|
7
7
|
NavigationMenuItem,
|
|
8
|
+
NavigationMenuTrigger,
|
|
9
|
+
NavigationMenuContent,
|
|
8
10
|
} from "@c-rex/ui/navigation-menu";
|
|
9
|
-
import { Button } from "@c-rex/ui/button";
|
|
10
|
-
import { ChevronDown } from "lucide-react";
|
|
11
|
-
import { DropdownHoverItem } from "@c-rex/ui/dropdown-hover-item";
|
|
12
11
|
import { RestrictionDropdownItem, RestrictionNavigationItem } from "./restriction-menu-item";
|
|
13
12
|
import { parseAsString, useQueryStates } from "nuqs";
|
|
14
13
|
import { InformationSubjectModel } from "@c-rex/interfaces";
|
|
15
|
-
import { useTranslations } from 'next-intl'
|
|
14
|
+
import { useLocale, useTranslations } from 'next-intl'
|
|
16
15
|
import { cn, getLabelByLang } from "@c-rex/utils";
|
|
17
16
|
import { useRestrictionStore } from "../stores/restriction-store";
|
|
18
|
-
import { useLanguageStore } from "../stores/language-store";
|
|
19
17
|
import { useBreakpoint } from "@c-rex/ui/hooks";
|
|
20
18
|
import { DEVICE_OPTIONS } from "@c-rex/constants";
|
|
21
19
|
|
|
@@ -53,7 +51,7 @@ export const RestrictionMenu: FC<Props> = ({
|
|
|
53
51
|
|
|
54
52
|
const restrictionValues = useMemo(() => params.restrict?.split(`${restrictField}=`)[1]?.split(",") || [], [params.restrict, restrictField]);
|
|
55
53
|
|
|
56
|
-
const uiLang =
|
|
54
|
+
const uiLang = useLocale();
|
|
57
55
|
const lang = uiLang?.split("-")[0] ?? "";
|
|
58
56
|
|
|
59
57
|
useEffect(() => {
|
|
@@ -110,13 +108,13 @@ export const RestrictionMenu: FC<Props> = ({
|
|
|
110
108
|
}, [sortedItems, visibleCount]);
|
|
111
109
|
|
|
112
110
|
return (
|
|
113
|
-
<NavigationMenu className="max-w-full w-full c-rex-restriction-menu">
|
|
111
|
+
<NavigationMenu viewport={false} className="max-w-full w-full c-rex-restriction-menu">
|
|
114
112
|
<NavigationMenuList className={cn("w-full", navigationMenuListClassName)}>
|
|
115
113
|
|
|
116
114
|
|
|
117
115
|
<RestrictionNavigationItem
|
|
118
116
|
removeRestrictParam
|
|
119
|
-
label=
|
|
117
|
+
label={t('all')}
|
|
120
118
|
selected={restrictionValues.length === 0}
|
|
121
119
|
/>
|
|
122
120
|
|
|
@@ -131,23 +129,26 @@ export const RestrictionMenu: FC<Props> = ({
|
|
|
131
129
|
))}
|
|
132
130
|
|
|
133
131
|
<NavigationMenuItem>
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
132
|
+
<NavigationMenuTrigger>
|
|
133
|
+
{t('more')}
|
|
134
|
+
</NavigationMenuTrigger>
|
|
135
|
+
<NavigationMenuContent className="w-96 sm:w-[] md:w-[700px] lg:w-[65rem]">
|
|
136
|
+
<ul className="grid gap-1 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4">
|
|
137
|
+
{hiddenItems.map((item) => (
|
|
138
|
+
<li
|
|
139
|
+
key={item.shortId}
|
|
140
|
+
className="flex items-center"
|
|
141
|
+
>
|
|
142
|
+
<RestrictionDropdownItem
|
|
143
|
+
shortId={item.shortId!}
|
|
144
|
+
restrictField={restrictField as string}
|
|
145
|
+
label={getLabelByLang(item.labels, lang)}
|
|
146
|
+
selected={restrictionValues.includes(item.shortId!)}
|
|
147
|
+
/>
|
|
148
|
+
</li>
|
|
149
|
+
))}
|
|
150
|
+
</ul>
|
|
151
|
+
</NavigationMenuContent>
|
|
151
152
|
</NavigationMenuItem>
|
|
152
153
|
</NavigationMenuList>
|
|
153
154
|
</NavigationMenu>
|
|
@@ -58,7 +58,7 @@ export const GenericTableResultList: FC<Props> = async ({
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const params = generateQueryParams(queryParams)
|
|
61
|
-
const link = linkPattern.replace("{
|
|
61
|
+
const link = linkPattern.replace("{shortId}", item.shortId!) + (params.length > 0 ? `?${params}` : "")
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
64
|
<div
|
package/src/results/utils.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { RenditionModel } from "@c-rex/interfaces";
|
|
2
2
|
import { DocumentsType } from "@c-rex/types";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type Props = {
|
|
5
|
+
renditions: RenditionModel[];
|
|
6
|
+
ignoreFormat?: string[];
|
|
7
|
+
}
|
|
8
|
+
export const getFileRenditions = ({
|
|
9
|
+
renditions,
|
|
10
|
+
ignoreFormat = ["application/xhtml+xml", "application/json", "application/llm+xml", "text/html"]
|
|
11
|
+
}: Props): DocumentsType => {
|
|
5
12
|
if (renditions == undefined || renditions.length == 0) {
|
|
6
13
|
return {} as DocumentsType;
|
|
7
14
|
}
|
|
8
15
|
|
|
9
16
|
const filteredRenditions = renditions.filter(
|
|
10
|
-
(item) =>
|
|
17
|
+
(item) => !ignoreFormat.includes(item.format!)
|
|
11
18
|
);
|
|
12
19
|
|
|
13
20
|
if (filteredRenditions.length == 0 || filteredRenditions[0] == undefined) {
|