@c-rex/templates 0.1.26 → 0.1.28
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 -1
- package/src/articles/wrapper.tsx +31 -30
- package/src/home/layout.tsx +1 -2
- package/src/home/page.tsx +2 -2
- package/src/home/page2.tsx +2 -2
- package/src/layout.tsx +9 -7
- package/src/utils.ts +1 -1
- package/src/collectors/BaseArticleCollector.ts +0 -289
- package/src/collectors/DocumentArticleCollector.ts +0 -73
- package/src/collectors/TopicArticleCollector.ts +0 -57
- package/src/home/components/filter-sidebar.tsx +0 -105
package/package.json
CHANGED
package/src/articles/wrapper.tsx
CHANGED
|
@@ -6,11 +6,12 @@ import { LeftSidebar } from "@c-rex/components/left-sidebar";
|
|
|
6
6
|
import { RightSidebar } from "@c-rex/components/right-sidebar";
|
|
7
7
|
import { Breadcrumb } from "@c-rex/components/breadcrumb";
|
|
8
8
|
import { RenderArticle } from "@c-rex/components/render-article";
|
|
9
|
-
import { articleInfoItemType, DocumentsType
|
|
9
|
+
import { articleInfoItemType, DocumentsType } from "@c-rex/types";
|
|
10
10
|
import { AvailableVersionsInterface, TreeOfContent } from "@c-rex/interfaces";
|
|
11
11
|
import { Separator } from "@c-rex/ui/separator";
|
|
12
12
|
import { ArrowBigLeft, PanelRight, ArrowBigRight, FileSearchIcon, X, Search } from "lucide-react";
|
|
13
|
-
import { SearchInput } from "../../../components/src/
|
|
13
|
+
import { SearchInput } from "../../../components/src/search-input";
|
|
14
|
+
|
|
14
15
|
import { useMultiSidebar } from "@c-rex/ui/sidebar";
|
|
15
16
|
import { Button } from "@c-rex/ui/button";
|
|
16
17
|
import { useQueryState } from "nuqs";
|
|
@@ -106,36 +107,36 @@ export const ArticleWrapper = ({
|
|
|
106
107
|
<RenderArticle htmlContent={htmlContent} contentLang={articleLang} />
|
|
107
108
|
|
|
108
109
|
{/*
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
>
|
|
119
|
-
{item.id == id && (
|
|
120
|
-
<div className={cn(
|
|
121
|
-
"absolute -left-[16px] top-1/2 -translate-y-1/2 h-8 border-t-[16px] border-t-transparent border-b-[16px] border-b-transparent border-r-[16px]",
|
|
122
|
-
`border-r-${item.color}`,
|
|
123
|
-
)} />
|
|
124
|
-
)}
|
|
125
|
-
<a
|
|
126
|
-
href={`../topics/${item.id}`}
|
|
127
|
-
className="flex items-center justify-end h-8 opacity-0 group-hover:opacity-100 text-primary-foreground transition-all duration-300 text-right px-2"
|
|
110
|
+
<div className="absolute top-0 right-0 flex flex-col gap-2 items-end">
|
|
111
|
+
{favoritesList.map((item) => (
|
|
112
|
+
<div
|
|
113
|
+
key={item.id}
|
|
114
|
+
className={cn(
|
|
115
|
+
"group h-8 cursor-pointer w-4 hover:w-40 transition-all duration-300 relative",
|
|
116
|
+
`bg-${item.color}`,
|
|
117
|
+
item.id == id ? "rounded-r-sm" : "rounded-sm"
|
|
118
|
+
)}
|
|
128
119
|
>
|
|
129
|
-
|
|
130
|
-
className=
|
|
131
|
-
|
|
120
|
+
{item.id == id && (
|
|
121
|
+
<div className={cn(
|
|
122
|
+
"absolute -left-[16px] top-1/2 -translate-y-1/2 h-8 border-t-[16px] border-t-transparent border-b-[16px] border-b-transparent border-r-[16px]",
|
|
123
|
+
`border-r-${item.color}`,
|
|
124
|
+
)} />
|
|
125
|
+
)}
|
|
126
|
+
<a
|
|
127
|
+
href={`../topics/${item.id}`}
|
|
128
|
+
className="flex items-center justify-end h-8 opacity-0 group-hover:opacity-100 text-primary-foreground transition-all duration-300 text-right px-2"
|
|
132
129
|
>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
<span
|
|
131
|
+
className="text-right text-ellipsis overflow-hidden whitespace-nowrap"
|
|
132
|
+
title={item.label}
|
|
133
|
+
>
|
|
134
|
+
{item.label}
|
|
135
|
+
</span>
|
|
136
|
+
</a>
|
|
137
|
+
</div>
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
139
140
|
*/}
|
|
140
141
|
</div>
|
|
141
142
|
|
package/src/home/layout.tsx
CHANGED
|
@@ -3,7 +3,6 @@ import { PageWrapper } from "@c-rex/components/page-wrapper";
|
|
|
3
3
|
import { OperatorType, WildCardType } from "@c-rex/types";
|
|
4
4
|
import { InformationUnitsService } from "@c-rex/services";
|
|
5
5
|
import { informationUnitsResponse } from "@c-rex/interfaces";
|
|
6
|
-
import { SearchProvider } from "@c-rex/contexts/search";
|
|
7
6
|
import { CrexSDK } from "@c-rex/core/sdk";
|
|
8
7
|
|
|
9
8
|
interface HomeProps {
|
|
@@ -57,7 +56,7 @@ export const HomeLayout = async ({ searchParams }: HomeProps) => {
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
return (
|
|
60
|
-
<PageWrapper
|
|
59
|
+
<PageWrapper>
|
|
61
60
|
<HomePage data={data} />
|
|
62
61
|
</PageWrapper>
|
|
63
62
|
);
|
package/src/home/page.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { parseAsBoolean, parseAsInteger, parseAsString, useQueryStates } from 'n
|
|
|
7
7
|
import { informationUnitsResponse } from "@c-rex/interfaces";
|
|
8
8
|
import { Button } from "@c-rex/ui/button";
|
|
9
9
|
import { Badge } from "@c-rex/ui/badge";
|
|
10
|
-
import {
|
|
10
|
+
import { ResultContainer } from "@c-rex/components/result-container";
|
|
11
11
|
import { DialogFilter } from "@c-rex/components/dialog-filter";
|
|
12
12
|
import { AutoComplete } from "@c-rex/components/autocomplete";
|
|
13
13
|
import { DEVICE_OPTIONS, OPERATOR_OPTIONS } from "@c-rex/constants";
|
|
@@ -366,7 +366,7 @@ export const HomePage: FC<HomePageProps> = ({ data }) => {
|
|
|
366
366
|
</Sheet>
|
|
367
367
|
|
|
368
368
|
<div className="flex-1">
|
|
369
|
-
<
|
|
369
|
+
<ResultContainer
|
|
370
370
|
items={data.items}
|
|
371
371
|
pagination={data.pageInfo}
|
|
372
372
|
/>
|
package/src/home/page2.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { parseAsBoolean, parseAsInteger, parseAsString, useQueryStates } from 'n
|
|
|
7
7
|
import { informationUnitsResponse } from "@c-rex/interfaces";
|
|
8
8
|
import { Button } from "@c-rex/ui/button";
|
|
9
9
|
import { Badge } from "@c-rex/ui/badge";
|
|
10
|
-
import {
|
|
10
|
+
import { ResultContainer } from "@c-rex/components/result-container";
|
|
11
11
|
import { DialogFilter } from "@c-rex/components/dialog-filter";
|
|
12
12
|
import { AutoComplete } from "@c-rex/components/autocomplete";
|
|
13
13
|
import { DEVICE_OPTIONS, OPERATOR_OPTIONS } from "@c-rex/constants";
|
|
@@ -373,7 +373,7 @@ export const HomePage: FC<HomePageProps> = ({ data }) => {
|
|
|
373
373
|
</Sheet>
|
|
374
374
|
|
|
375
375
|
<div className="flex-1">
|
|
376
|
-
<
|
|
376
|
+
<ResultContainer
|
|
377
377
|
items={data.items}
|
|
378
378
|
pagination={data.pageInfo}
|
|
379
379
|
/>
|
package/src/layout.tsx
CHANGED
|
@@ -8,8 +8,10 @@ import { cookies } from "next/headers";
|
|
|
8
8
|
import { CrexSDK } from "@c-rex/core/sdk";
|
|
9
9
|
import { getIssuerMetadata } from "@c-rex/core/OIDC";
|
|
10
10
|
import { resolveUILanguage, resolveContentLanguage } from "./utils";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { informationUnitsLanguagesServer } from "@c-rex/services/server-requests";
|
|
12
|
+
import { UI_LANG_KEY } from "@c-rex/constants";
|
|
13
|
+
import { transformLanguageData } from "@c-rex/utils";
|
|
14
|
+
import { getSearchSettingsFromCookie } from "@c-rex/components/search-settings-store";
|
|
13
15
|
|
|
14
16
|
interface DefaultRootLayoutProps {
|
|
15
17
|
children: React.ReactNode;
|
|
@@ -23,15 +25,15 @@ export const DefaultRootLayout = async ({ children }: DefaultRootLayoutProps) =>
|
|
|
23
25
|
const uiLangCookie = cookieStore.get(UI_LANG_KEY)?.value ?? null;
|
|
24
26
|
const clientConfigs = sdk.getClientConfig();
|
|
25
27
|
const serverConfigs = sdk.getServerConfig();
|
|
26
|
-
const
|
|
27
|
-
const contentLangCookie = cookieStore.get(CONTENT_LANG_KEY)?.value ?? null;
|
|
28
|
+
const searchSettings = getSearchSettingsFromCookie(cookieStore.get("c-rex-search-settings")?.value);
|
|
28
29
|
|
|
29
30
|
sdk.updateConfigProp('OIDC', {
|
|
30
31
|
...serverConfigs.OIDC,
|
|
31
32
|
issuerMetadata: metadata
|
|
32
33
|
});
|
|
33
34
|
|
|
34
|
-
const
|
|
35
|
+
const data = await informationUnitsLanguagesServer();
|
|
36
|
+
const availableLanguages = transformLanguageData(data as { value: string; score: number; }[]);
|
|
35
37
|
|
|
36
38
|
const uiLang = resolveUILanguage({
|
|
37
39
|
uiLangCookie,
|
|
@@ -39,7 +41,7 @@ export const DefaultRootLayout = async ({ children }: DefaultRootLayoutProps) =>
|
|
|
39
41
|
});
|
|
40
42
|
|
|
41
43
|
const contentLang = resolveContentLanguage({
|
|
42
|
-
contentLangCookie,
|
|
44
|
+
contentLangCookie: searchSettings.language,
|
|
43
45
|
availableLanguages,
|
|
44
46
|
defaultLang: clientConfigs.languageSwitcher.default
|
|
45
47
|
});
|
|
@@ -66,4 +68,4 @@ export const DefaultRootLayout = async ({ children }: DefaultRootLayoutProps) =>
|
|
|
66
68
|
</html>
|
|
67
69
|
</NuqsAdapter>
|
|
68
70
|
);
|
|
69
|
-
}
|
|
71
|
+
};
|
package/src/utils.ts
CHANGED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { DirectoryNodesService, InformationUnitsService } from "@c-rex/services";
|
|
2
|
-
import { CollectionContext, CollectionResult, DirectoryNodes, informationUnitsItems, informationUnitsResponseItem } from "@c-rex/interfaces";
|
|
3
|
-
import * as cheerio from "cheerio"
|
|
4
|
-
import { articleInfoItemType, metaTags } from "@c-rex/types";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export abstract class BaseArticleCollector {
|
|
8
|
-
protected informationService = new InformationUnitsService();
|
|
9
|
-
protected directoryNodeService = new DirectoryNodesService();
|
|
10
|
-
|
|
11
|
-
private collectVersions: boolean = false;
|
|
12
|
-
private collectDocument: boolean = false;
|
|
13
|
-
private collectArticleInfo: boolean = false;
|
|
14
|
-
private collectDocumentInfo: boolean = false;
|
|
15
|
-
private additionalTasks: Map<string, (context: CollectionContext) => Promise<any>> = new Map();
|
|
16
|
-
private collectHtmlContent: boolean = false;
|
|
17
|
-
|
|
18
|
-
async collect(id: string): Promise<CollectionResult> {
|
|
19
|
-
const informationUnitsItem = await this.getInformationUnit(id);
|
|
20
|
-
const rootNode = await this.getRootNode(informationUnitsItem.directoryNodes);
|
|
21
|
-
|
|
22
|
-
if (!rootNode) throw new Error("Root node not found");
|
|
23
|
-
|
|
24
|
-
const context: CollectionContext = {
|
|
25
|
-
id,
|
|
26
|
-
informationUnitsItem,
|
|
27
|
-
rootNode
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
this.configureTasks();
|
|
31
|
-
|
|
32
|
-
const tasks = await this.buildTasks(context);
|
|
33
|
-
const results = await Promise.all(tasks);
|
|
34
|
-
return this.buildResult(context, this.processResults(results));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
protected abstract configureTasks(): void;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
protected withVersions(): this {
|
|
41
|
-
this.collectVersions = true;
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
protected withDocument(): this {
|
|
46
|
-
this.collectDocument = true;
|
|
47
|
-
return this;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
protected withHtmlContent(): this {
|
|
51
|
-
this.collectHtmlContent = true;
|
|
52
|
-
return this;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
protected withArticleInfo(): this {
|
|
56
|
-
this.collectArticleInfo = true;
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
protected withDocumentInfo(): this {
|
|
61
|
-
this.collectDocumentInfo = true;
|
|
62
|
-
return this;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
protected withCustomTask(name: string, task: (context: CollectionContext) => Promise<any>): this {
|
|
66
|
-
this.additionalTasks.set(name, task);
|
|
67
|
-
return this;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private async buildTasks(context: CollectionContext): Promise<Array<{ name: string, result: any }>> {
|
|
71
|
-
const tasks: Array<{ name: string, task: () => Promise<any> }> = [];
|
|
72
|
-
|
|
73
|
-
if (this.collectVersions) {
|
|
74
|
-
tasks.push({
|
|
75
|
-
name: 'articleVersions',
|
|
76
|
-
task: () => this.getArticleVersions(context)
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
tasks.push({
|
|
80
|
-
name: 'documentVersions',
|
|
81
|
-
task: () => this.getDocumentVersions(context)
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (this.collectDocument) {
|
|
86
|
-
tasks.push({
|
|
87
|
-
name: 'document',
|
|
88
|
-
task: () => this.getDocument(context)
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (this.collectHtmlContent) {
|
|
93
|
-
tasks.push({
|
|
94
|
-
name: 'htmlContent',
|
|
95
|
-
task: () => this.getHtmlContent(context)
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
for (const [name, taskFn] of this.additionalTasks) {
|
|
100
|
-
tasks.push({
|
|
101
|
-
name,
|
|
102
|
-
task: () => taskFn(context)
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return Promise.all(
|
|
107
|
-
tasks.map(async ({ name, task }) => ({
|
|
108
|
-
name,
|
|
109
|
-
result: await task()
|
|
110
|
-
}))
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private processResults(results: Array<{ name: string, result: any }>): Record<string, any> {
|
|
115
|
-
return results.reduce((acc, { name, result }) => {
|
|
116
|
-
acc[name] = result;
|
|
117
|
-
return acc;
|
|
118
|
-
}, {} as Record<string, any>);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
protected async getInformationUnit(id: string) {
|
|
122
|
-
return await this.informationService.getItem({
|
|
123
|
-
id,
|
|
124
|
-
shouldGetAllFields: true
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
protected async getDocument(context: CollectionContext) {
|
|
129
|
-
if (context.rootNode.informationUnits[0]) {
|
|
130
|
-
const infoId = context.rootNode.informationUnits[0].shortId;
|
|
131
|
-
return await this.informationService.getItem({
|
|
132
|
-
id: infoId!,
|
|
133
|
-
shouldGetAllFields: true
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
protected async getRootNode(directoryNodes: DirectoryNodes[]): Promise<DirectoryNodes | null> {
|
|
140
|
-
if (directoryNodes.length === 0 || !directoryNodes[0]) {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
let id = directoryNodes[0].shortId;
|
|
145
|
-
let response = await this.directoryNodeService.getItem(id);
|
|
146
|
-
|
|
147
|
-
if (!response.ancestors || response.ancestors.length === 0) {
|
|
148
|
-
return response;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const noHasInfo = !response.informationUnits?.[0];
|
|
152
|
-
const notHasLabel = !response.labels?.[0];
|
|
153
|
-
|
|
154
|
-
if (noHasInfo || notHasLabel) return null
|
|
155
|
-
if (response.ancestors == undefined) return null
|
|
156
|
-
if (response.ancestors[0] == undefined) return null
|
|
157
|
-
|
|
158
|
-
const lastIndex = response.ancestors[0].length - 1;
|
|
159
|
-
|
|
160
|
-
if (response.ancestors[0][lastIndex] == undefined) return null
|
|
161
|
-
|
|
162
|
-
id = response.ancestors[0][lastIndex].shortId;
|
|
163
|
-
response = await this.directoryNodeService.getItem(id);
|
|
164
|
-
|
|
165
|
-
return response;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
protected async getHtmlContent(context: CollectionContext): Promise<string> {
|
|
169
|
-
throw new Error("getHtmlContent must be implemented by subclass");
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
protected async getArticleVersions(context: CollectionContext): Promise<informationUnitsResponseItem[]> {
|
|
173
|
-
throw new Error("getArticleVersions must be implemented by subclass");
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
protected async getDocumentVersions(context: CollectionContext): Promise<informationUnitsResponseItem[]> {
|
|
177
|
-
throw new Error("getDocumentVersions must be implemented by subclass");
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
protected splitHtmlContentAndTags(html: string): { metaTags: metaTags, articleHtml: string } {
|
|
181
|
-
const $ = cheerio.load(html)
|
|
182
|
-
|
|
183
|
-
const metaTags = $("meta").map((_, el) => {
|
|
184
|
-
const name = $(el).attr("name")
|
|
185
|
-
const content = $(el).attr("content")
|
|
186
|
-
return name && content ? { name, content } : null
|
|
187
|
-
}).get().filter(Boolean)
|
|
188
|
-
|
|
189
|
-
const articleHtml = $("main").html() || ""
|
|
190
|
-
|
|
191
|
-
return {
|
|
192
|
-
metaTags,
|
|
193
|
-
articleHtml,
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
protected buildResult(context: CollectionContext, data: Record<string, any>): CollectionResult {
|
|
198
|
-
const { metaTags, articleHtml } = this.splitHtmlContentAndTags(data.htmlContent);
|
|
199
|
-
const result: CollectionResult = {
|
|
200
|
-
articleHtml: articleHtml,
|
|
201
|
-
metaTags: metaTags,
|
|
202
|
-
document: data.document,
|
|
203
|
-
article: context.informationUnitsItem,
|
|
204
|
-
rootNode: context.rootNode,
|
|
205
|
-
articleAvailableVersions: data.articleVersions || [],
|
|
206
|
-
documentAvailableVersions: data.documentVersions || [],
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (this.collectArticleInfo) {
|
|
210
|
-
result['articleInfo'] = this.processArticleInfo(context.informationUnitsItem)
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (this.collectDocumentInfo) {
|
|
214
|
-
result['documentInfo'] = this.processArticleInfo(data.document)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
...result,
|
|
219
|
-
...data
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
protected processArticleInfo = (
|
|
224
|
-
informationUnit: informationUnitsItems,
|
|
225
|
-
excludeKeys: string[] = ['shortId', 'id']
|
|
226
|
-
): articleInfoItemType[] => {
|
|
227
|
-
const result: articleInfoItemType[] = [];
|
|
228
|
-
|
|
229
|
-
Object.entries(informationUnit).forEach(([key, value]) => {
|
|
230
|
-
|
|
231
|
-
if (excludeKeys.includes(key) || value === null || value === undefined) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const processedValue = processValue(value);
|
|
236
|
-
|
|
237
|
-
if (processedValue !== null) {
|
|
238
|
-
result.push({
|
|
239
|
-
label: key,
|
|
240
|
-
value: processedValue
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
return result;
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const processValue = (value: any): string | null => {
|
|
250
|
-
|
|
251
|
-
if (Array.isArray(value)) {
|
|
252
|
-
if (value.length === 0) return null;
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if (value.length === 1) {
|
|
256
|
-
return processSingleValue(value[0]);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const processedValues = value
|
|
261
|
-
.map(item => processSingleValue(item))
|
|
262
|
-
.filter(item => item !== null);
|
|
263
|
-
|
|
264
|
-
return processedValues.length > 0 ? processedValues.join(", ") : null;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return processSingleValue(value);
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
const processSingleValue = (item: any): string | null => {
|
|
271
|
-
|
|
272
|
-
if (item === null || item === undefined) {
|
|
273
|
-
return null;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (typeof item === 'object') {
|
|
277
|
-
if ('shortId' in item || 'id' in item) {
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if ('value' in item && item.value !== null && item.value !== undefined) {
|
|
282
|
-
return String(item.value);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return String(item);
|
|
289
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { BaseArticleCollector } from './BaseArticleCollector';
|
|
2
|
-
import { CollectionContext, informationUnitsResponseItem } from "@c-rex/interfaces";
|
|
3
|
-
import { RenditionsService } from "@c-rex/services";
|
|
4
|
-
import { DocumentsType } from '@c-rex/types';
|
|
5
|
-
import { getFileRenditions } from '@c-rex/utils';
|
|
6
|
-
|
|
7
|
-
export class DocumentArticleCollector extends BaseArticleCollector {
|
|
8
|
-
private renditionService = new RenditionsService();
|
|
9
|
-
|
|
10
|
-
protected configureTasks(): void {
|
|
11
|
-
this.withVersions()
|
|
12
|
-
.withDocument()
|
|
13
|
-
.withHtmlContent()
|
|
14
|
-
.withArticleInfo()
|
|
15
|
-
.withDocumentInfo()
|
|
16
|
-
.withCustomTask('attachments', this.getAttachments.bind(this))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
protected async getHtmlContent(context: CollectionContext): Promise<string> {
|
|
20
|
-
if (!context.rootNode.childNodes[0]) {
|
|
21
|
-
return "";
|
|
22
|
-
}
|
|
23
|
-
const directoryId = context.rootNode.childNodes[0].shortId;
|
|
24
|
-
const response = await this.directoryNodeService.getItem(directoryId);
|
|
25
|
-
|
|
26
|
-
const infoId = response.informationUnits[0]?.shortId as string
|
|
27
|
-
const childInformationUnit = await this.informationService.getItem({
|
|
28
|
-
id: infoId
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
return await this.renditionService.getHTMLRendition({
|
|
32
|
-
renditions: childInformationUnit.renditions
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
protected async getDocumentVersions(context: CollectionContext): Promise<informationUnitsResponseItem[]> {
|
|
37
|
-
const versions = await this.informationService.getList({
|
|
38
|
-
restrict: [`versionOf.shortId=${context.informationUnitsItem.versionOf.shortId}`],
|
|
39
|
-
fields: ["renditions", "class", "languages", "labels"],
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
return versions.items;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
protected async getArticleVersions(context: CollectionContext): Promise<informationUnitsResponseItem[]> {
|
|
46
|
-
if (!context.rootNode.childNodes[0]) {
|
|
47
|
-
return [];
|
|
48
|
-
}
|
|
49
|
-
const directoryId = context.rootNode.childNodes[0].shortId;
|
|
50
|
-
const response = await this.directoryNodeService.getItem(directoryId);
|
|
51
|
-
|
|
52
|
-
const infoId = response.informationUnits[0]?.shortId as string
|
|
53
|
-
const childInformationUnit = await this.informationService.getItem({
|
|
54
|
-
id: infoId
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const versions = await this.informationService.getList({
|
|
58
|
-
restrict: [`versionOf.shortId=${childInformationUnit.versionOf.shortId}`],
|
|
59
|
-
fields: ["renditions", "class", "languages", "labels"],
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
return versions.items;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private async getAttachments(context: CollectionContext): Promise<DocumentsType> {
|
|
66
|
-
const rootNodeInfoID = context.rootNode.informationUnits[0]?.shortId as string
|
|
67
|
-
const childInformationUnit = await this.informationService.getItem({
|
|
68
|
-
id: rootNodeInfoID
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
return getFileRenditions({ renditions: childInformationUnit.renditions });
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { BaseArticleCollector } from './BaseArticleCollector';
|
|
2
|
-
import { CollectionContext, informationUnitsResponseItem } from "@c-rex/interfaces";
|
|
3
|
-
import { RenditionsService } from "@c-rex/services";
|
|
4
|
-
import { DocumentsType } from '@c-rex/types';
|
|
5
|
-
import { getFileRenditions } from '@c-rex/utils';
|
|
6
|
-
|
|
7
|
-
export class TopicArticleCollector extends BaseArticleCollector {
|
|
8
|
-
private renditionService = new RenditionsService();
|
|
9
|
-
|
|
10
|
-
protected configureTasks(): void {
|
|
11
|
-
this.withVersions()
|
|
12
|
-
.withDocument()
|
|
13
|
-
.withHtmlContent()
|
|
14
|
-
.withArticleInfo()
|
|
15
|
-
.withDocumentInfo()
|
|
16
|
-
.withCustomTask('attachments', this.getAttachments.bind(this))
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
protected async getHtmlContent(context: CollectionContext): Promise<string> {
|
|
21
|
-
return await this.renditionService.getHTMLRendition({
|
|
22
|
-
renditions: context.informationUnitsItem.renditions
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
protected async getDocumentVersions(context: CollectionContext): Promise<informationUnitsResponseItem[]> {
|
|
27
|
-
const rootNodeInfoID = context.rootNode.informationUnits[0]?.shortId as string
|
|
28
|
-
const childInformationUnit = await this.informationService.getItem({
|
|
29
|
-
id: rootNodeInfoID
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const versions = await this.informationService.getList({
|
|
33
|
-
restrict: [`versionOf.shortId=${childInformationUnit.versionOf.shortId}`],
|
|
34
|
-
fields: ["renditions", "class", "languages", "labels"],
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
return versions.items;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
protected async getArticleVersions(context: CollectionContext): Promise<informationUnitsResponseItem[]> {
|
|
41
|
-
const versions = await this.informationService.getList({
|
|
42
|
-
restrict: [`versionOf.shortId=${context.informationUnitsItem.versionOf.shortId}`],
|
|
43
|
-
fields: ["renditions", "class", "languages", "labels"],
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
return versions.items;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private async getAttachments(context: CollectionContext): Promise<DocumentsType> {
|
|
50
|
-
const rootNodeInfoID = context.rootNode.informationUnits[0]?.shortId as string
|
|
51
|
-
const childInformationUnit = await this.informationService.getItem({
|
|
52
|
-
id: rootNodeInfoID
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
return getFileRenditions({ renditions: childInformationUnit.renditions });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, { FC } 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 { useBreakpoint } from "@c-rex/ui/hooks";
|
|
19
|
-
import { DEVICE_OPTIONS } from "@c-rex/constants";
|
|
20
|
-
import { SheetContent, SheetHeader } from "@c-rex/ui/sheet";
|
|
21
|
-
|
|
22
|
-
interface FilterSidebarProps {
|
|
23
|
-
tags: { [key: string]: any[] }
|
|
24
|
-
totalItemCount: number
|
|
25
|
-
updateFilterParam: (key: string, item: any) => void
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const FilterSidebar: FC<FilterSidebarProps> = ({ tags, totalItemCount, updateFilterParam }) => {
|
|
29
|
-
const t = useTranslations();
|
|
30
|
-
const device = useBreakpoint();
|
|
31
|
-
const isMobile = device !== null && (device === DEVICE_OPTIONS.MOBILE);
|
|
32
|
-
|
|
33
|
-
if (Object.keys(tags).length === 0) return null;
|
|
34
|
-
|
|
35
|
-
const content = (
|
|
36
|
-
<SidebarContent className="!gap-0">
|
|
37
|
-
|
|
38
|
-
{Object.entries(tags).map(([key, value]: any) => (
|
|
39
|
-
|
|
40
|
-
<Collapsible defaultOpen key={key} className="py-0 group/collapsible">
|
|
41
|
-
<SidebarGroup>
|
|
42
|
-
|
|
43
|
-
<SidebarGroupLabel asChild className="hover:bg-sidebar-accent text-sidebar-accent-foreground text-sm font-bold">
|
|
44
|
-
<CollapsibleTrigger className="!h-9">
|
|
45
|
-
{t(`filter.tags.${key}`)}
|
|
46
|
-
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
|
|
47
|
-
</CollapsibleTrigger>
|
|
48
|
-
</SidebarGroupLabel>
|
|
49
|
-
|
|
50
|
-
<CollapsibleContent>
|
|
51
|
-
<SidebarGroupContent>
|
|
52
|
-
<SidebarMenu>
|
|
53
|
-
<SidebarMenuSub>
|
|
54
|
-
{value.map((item: any) => (
|
|
55
|
-
<SidebarMenuSubItem key={item.shortId}>
|
|
56
|
-
<SidebarMenuSubButton
|
|
57
|
-
className="cursor-pointer"
|
|
58
|
-
isActive={item.active}
|
|
59
|
-
onClick={() => updateFilterParam(key, item)}
|
|
60
|
-
>
|
|
61
|
-
{item.label} ({item.hits}/{item.total})
|
|
62
|
-
{item.active && <Check className="ml-2" />}
|
|
63
|
-
</SidebarMenuSubButton>
|
|
64
|
-
</SidebarMenuSubItem>
|
|
65
|
-
))}
|
|
66
|
-
</SidebarMenuSub>
|
|
67
|
-
</SidebarMenu>
|
|
68
|
-
</SidebarGroupContent>
|
|
69
|
-
</CollapsibleContent>
|
|
70
|
-
</SidebarGroup>
|
|
71
|
-
</Collapsible>
|
|
72
|
-
))}
|
|
73
|
-
</SidebarContent>
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
if (isMobile) {
|
|
77
|
-
return (
|
|
78
|
-
|
|
79
|
-
<SheetContent
|
|
80
|
-
side="left"
|
|
81
|
-
className="!pt-6 !px-2 w-[400px] overflow-y-auto"
|
|
82
|
-
>
|
|
83
|
-
<SheetHeader className="justify-center items-end font-bold">
|
|
84
|
-
{t("filter.filters")}
|
|
85
|
-
<span className="text-xs text-muted-foreground leading-5">
|
|
86
|
-
{totalItemCount} {t("results.results")}
|
|
87
|
-
</span>
|
|
88
|
-
</SheetHeader>
|
|
89
|
-
{content}
|
|
90
|
-
</SheetContent>
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return (
|
|
95
|
-
<div className="w-60 lg:w-80 bg-sidebar rounded-md border pb-4">
|
|
96
|
-
<SidebarHeader className="justify-center items-end font-bold">
|
|
97
|
-
{t("filter.filters")}
|
|
98
|
-
<span className="text-xs text-muted-foreground leading-5">
|
|
99
|
-
{totalItemCount} {t("results.results")}
|
|
100
|
-
</span>
|
|
101
|
-
</SidebarHeader>
|
|
102
|
-
{content}
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
};
|