@se-studio/core-ui 1.0.45 → 1.0.47
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/ANALYTICS.md +136 -0
- package/CHANGELOG.md +466 -0
- package/CMS_INFRASTRUCTURE.md +335 -0
- package/CONSENT.md +121 -0
- package/README.md +13 -8
- package/dist/cmsRegistration.d.ts +152 -0
- package/dist/cmsRegistration.d.ts.map +1 -0
- package/dist/cmsRegistration.js +145 -0
- package/dist/cmsRegistration.js.map +1 -0
- package/dist/components/CmsCollection.d.ts +2 -1
- package/dist/components/CmsCollection.d.ts.map +1 -1
- package/dist/components/CmsCollection.js +1 -1
- package/dist/components/CmsCollection.js.map +1 -1
- package/dist/components/CmsComponent.d.ts +2 -1
- package/dist/components/CmsComponent.d.ts.map +1 -1
- package/dist/components/CmsComponent.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/showcase/components/AllViewPanel.d.ts +7 -0
- package/dist/showcase/components/AllViewPanel.d.ts.map +1 -0
- package/dist/showcase/components/AllViewPanel.js +35 -0
- package/dist/showcase/components/AllViewPanel.js.map +1 -0
- package/dist/showcase/components/Controls.d.ts +15 -0
- package/dist/showcase/components/Controls.d.ts.map +1 -0
- package/dist/showcase/components/Controls.js +74 -0
- package/dist/showcase/components/Controls.js.map +1 -0
- package/dist/showcase/components/ControlsWrapper.d.ts +13 -0
- package/dist/showcase/components/ControlsWrapper.d.ts.map +1 -0
- package/dist/showcase/components/ControlsWrapper.js +9 -0
- package/dist/showcase/components/ControlsWrapper.js.map +1 -0
- package/dist/showcase/components/PreviewPanel.d.ts +10 -0
- package/dist/showcase/components/PreviewPanel.d.ts.map +1 -0
- package/dist/showcase/components/PreviewPanel.js +42 -0
- package/dist/showcase/components/PreviewPanel.js.map +1 -0
- package/dist/showcase/components/ScaledIframe.d.ts +10 -0
- package/dist/showcase/components/ScaledIframe.d.ts.map +1 -0
- package/dist/showcase/components/ScaledIframe.js +16 -0
- package/dist/showcase/components/ScaledIframe.js.map +1 -0
- package/dist/showcase/components/ShowcaseAllRenderPage.d.ts +19 -0
- package/dist/showcase/components/ShowcaseAllRenderPage.d.ts.map +1 -0
- package/dist/showcase/components/ShowcaseAllRenderPage.js +46 -0
- package/dist/showcase/components/ShowcaseAllRenderPage.js.map +1 -0
- package/dist/showcase/components/ShowcasePage.d.ts +15 -0
- package/dist/showcase/components/ShowcasePage.d.ts.map +1 -0
- package/dist/showcase/components/ShowcasePage.js +16 -0
- package/dist/showcase/components/ShowcasePage.js.map +1 -0
- package/dist/showcase/components/ShowcaseRenderPage.d.ts +19 -0
- package/dist/showcase/components/ShowcaseRenderPage.d.ts.map +1 -0
- package/dist/showcase/components/ShowcaseRenderPage.js +51 -0
- package/dist/showcase/components/ShowcaseRenderPage.js.map +1 -0
- package/dist/showcase/components/TopBar.d.ts +11 -0
- package/dist/showcase/components/TopBar.d.ts.map +1 -0
- package/dist/showcase/components/TopBar.js +103 -0
- package/dist/showcase/components/TopBar.js.map +1 -0
- package/dist/showcase/index.d.ts +12 -0
- package/dist/showcase/index.d.ts.map +1 -0
- package/dist/showcase/index.js +12 -0
- package/dist/showcase/index.js.map +1 -0
- package/dist/showcase/mockFactory.d.ts +34 -0
- package/dist/showcase/mockFactory.d.ts.map +1 -0
- package/dist/showcase/mockFactory.js +352 -0
- package/dist/showcase/mockFactory.js.map +1 -0
- package/dist/showcase/types.d.ts +20 -0
- package/dist/showcase/types.d.ts.map +1 -0
- package/dist/showcase/types.js +18 -0
- package/dist/showcase/types.js.map +1 -0
- package/dist/utils/buildPageMetadata.d.ts +20 -1
- package/dist/utils/buildPageMetadata.d.ts.map +1 -1
- package/dist/utils/buildPageMetadata.js +37 -0
- package/dist/utils/buildPageMetadata.js.map +1 -1
- package/dist/utils/componentUtils.d.ts +39 -146
- package/dist/utils/componentUtils.d.ts.map +1 -1
- package/dist/utils/componentUtils.js +142 -101
- package/dist/utils/componentUtils.js.map +1 -1
- package/dist/utils/urlUtils.d.ts +5 -0
- package/dist/utils/urlUtils.d.ts.map +1 -1
- package/dist/utils/urlUtils.js +10 -0
- package/dist/utils/urlUtils.js.map +1 -1
- package/package.json +9 -6
- package/src/showcase/README.md +131 -0
- package/dist/__tests__/setup.d.ts +0 -2
- package/dist/__tests__/setup.d.ts.map +0 -1
- package/dist/__tests__/setup.js +0 -2
- package/dist/__tests__/setup.js.map +0 -1
|
@@ -1,147 +1,40 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* Extract specific collection information fields that a collection needs.
|
|
41
|
-
* This is used when you only need a subset of the collection fields.
|
|
42
|
-
*
|
|
43
|
-
* @param information - The full collection information object
|
|
44
|
-
* @param keys - Array of keys to extract from the information object
|
|
45
|
-
* @returns Object with only the specified keys
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```tsx
|
|
49
|
-
* const props = extractCollectionInfo(information, ['heading', 'body', 'contents']);
|
|
50
|
-
* // props will have type { heading?: string | null, body?: unknown, contents?: ReadonlyArray<CollectionContent> }
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
export declare function extractCollectionInfo<K extends keyof IBaseCollection>(information: IBaseCollection, keys: ReadonlyArray<K>): Pick<IBaseCollection, K>;
|
|
54
|
-
/**
|
|
55
|
-
* Extract specific page context fields that a component needs.
|
|
56
|
-
*
|
|
57
|
-
* @param pageContext - The full page context object
|
|
58
|
-
* @param keys - Array of keys to extract from the page context
|
|
59
|
-
* @returns Object with only the specified keys
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```tsx
|
|
63
|
-
* const contextProps = extractPageContext(pageContext, ['articleLink', 'pageLink']);
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export declare function extractPageContext<K extends keyof IPageContext>(pageContext: IPageContext, keys: ReadonlyArray<K>): Pick<IPageContext, K>;
|
|
67
|
-
/**
|
|
68
|
-
* Helper type to create a component renderer function with specific prop requirements.
|
|
69
|
-
* This provides better type safety when defining component renderers.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```tsx
|
|
73
|
-
* const config = {
|
|
74
|
-
* componentProps: ['heading', 'body', 'links'],
|
|
75
|
-
* contextProps: ['pageLink'],
|
|
76
|
-
* additionalProps: { theme: 'dark' as const }
|
|
77
|
-
* } as const satisfies ComponentConfig;
|
|
78
|
-
*
|
|
79
|
-
* const MyComponent: ComponentRenderer<typeof config> = ({ heading, body, links, pageLink, theme }) => {
|
|
80
|
-
* // All props are properly typed
|
|
81
|
-
* return <div>{heading}</div>;
|
|
82
|
-
* };
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
export type ComponentRenderer<T extends ComponentConfig> = (props: GeneratePropsFromComponentConfig<T>) => React.ReactElement | null;
|
|
86
|
-
/**
|
|
87
|
-
* Helper type to create a collection renderer function with specific prop requirements.
|
|
88
|
-
* This provides better type safety when defining collection renderers.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```tsx
|
|
92
|
-
* const config = {
|
|
93
|
-
* collectionProps: ['heading', 'body', 'contents'],
|
|
94
|
-
* contextProps: ['articleLink'],
|
|
95
|
-
* additionalProps: { layout: 'grid' as const }
|
|
96
|
-
* } as const satisfies CollectionConfig;
|
|
97
|
-
*
|
|
98
|
-
* const MyCollection: CollectionRenderer<typeof config> = ({ heading, body, contents, articleLink, layout }) => {
|
|
99
|
-
* // All props are properly typed
|
|
100
|
-
* return <div>{heading}</div>;
|
|
101
|
-
* };
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
export type CollectionRenderer<T extends CollectionConfig> = (props: GeneratePropsFromCollectionConfig<T>) => React.ReactElement | null;
|
|
105
|
-
/**
|
|
106
|
-
* Create props object for a component renderer from component information and page context.
|
|
107
|
-
* This function extracts the specified fields and combines them with additional props.
|
|
108
|
-
*
|
|
109
|
-
* @param config - Configuration specifying which props to extract
|
|
110
|
-
* @param information - The component information object
|
|
111
|
-
* @param pageContext - The page context object
|
|
112
|
-
* @param additionalProps - Additional props to include (optional)
|
|
113
|
-
* @returns Combined props object ready to pass to the component
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```tsx
|
|
117
|
-
* const config = {
|
|
118
|
-
* componentProps: ['heading', 'body'],
|
|
119
|
-
* contextProps: ['pageLink'],
|
|
120
|
-
* } as const;
|
|
121
|
-
*
|
|
122
|
-
* const props = createComponentProps(config, information, pageContext);
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
export declare function createComponentProps<T extends ComponentConfig>(config: T, information: IBaseComponent, pageContext: IPageContext, additionalProps?: T['additionalProps']): GeneratePropsFromComponentConfig<T>;
|
|
126
|
-
/**
|
|
127
|
-
* Create props object for a collection renderer from collection information and page context.
|
|
128
|
-
* This function extracts the specified fields and combines them with additional props.
|
|
129
|
-
*
|
|
130
|
-
* @param config - Configuration specifying which props to extract
|
|
131
|
-
* @param information - The collection information object
|
|
132
|
-
* @param pageContext - The page context object
|
|
133
|
-
* @param additionalProps - Additional props to include (optional)
|
|
134
|
-
* @returns Combined props object ready to pass to the collection
|
|
135
|
-
*
|
|
136
|
-
* @example
|
|
137
|
-
* ```tsx
|
|
138
|
-
* const config = {
|
|
139
|
-
* collectionProps: ['heading', 'contents'],
|
|
140
|
-
* contextProps: ['articleLink'],
|
|
141
|
-
* } as const;
|
|
142
|
-
*
|
|
143
|
-
* const props = createCollectionProps(config, information, pageContext);
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
export declare function createCollectionProps<T extends CollectionConfig>(config: T, information: IBaseCollection, pageContext: IPageContext, additionalProps?: T['additionalProps']): GeneratePropsFromCollectionConfig<T>;
|
|
1
|
+
import { type BaseConverterContext, type ContentfulConfig, type FetchOptions, type IContentfulCollection } from '@se-studio/contentful-rest-api';
|
|
2
|
+
import { type BaseCollectionContent, type IArticleLink, type IContentContext, type IPersonLink } from '@se-studio/core-data-types';
|
|
3
|
+
/**
|
|
4
|
+
* Generic helper to get related articles for a collection.
|
|
5
|
+
*
|
|
6
|
+
* This function orchestrates the fetching of related articles by:
|
|
7
|
+
* 1. Extracting hard-coded articles from collection contents
|
|
8
|
+
* 2. Extracting filter criteria from collection links (tags, article type)
|
|
9
|
+
* 3. Extracting fallback criteria from page context (article type, current article)
|
|
10
|
+
* 4. Fetching additional articles if needed to reach the requested count
|
|
11
|
+
* 5. Returning manual articles followed by fetched articles
|
|
12
|
+
*
|
|
13
|
+
* @param information - The collection information containing contents and links
|
|
14
|
+
* @param contentContext - The content context containing page context
|
|
15
|
+
* @param converterContext - The project-specific converter context (contains URL rules)
|
|
16
|
+
* @param config - Contentful configuration
|
|
17
|
+
* @param count - Maximum number of articles to return (optional)
|
|
18
|
+
* @param options - Optional fetch options for preview mode and caching
|
|
19
|
+
* @returns Array of article links (manual articles first, then fetched)
|
|
20
|
+
*/
|
|
21
|
+
export declare function getRelatedArticles<T extends BaseCollectionContent>(information: IContentfulCollection<T>, contentContext: IContentContext, converterContext: BaseConverterContext, config: ContentfulConfig, count: number | undefined, options: FetchOptions): Promise<IArticleLink[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Generic helper to get related people for a collection.
|
|
24
|
+
*
|
|
25
|
+
* This function orchestrates the fetching of related people by:
|
|
26
|
+
* 1. Extracting hard-coded people from collection contents
|
|
27
|
+
* 2. Fetching additional people if needed to reach the requested count
|
|
28
|
+
* 3. Excluding the current person (if on a person page) and manually added people
|
|
29
|
+
* 4. Returning manual people followed by fetched people
|
|
30
|
+
*
|
|
31
|
+
* @param information - The collection information containing contents
|
|
32
|
+
* @param contentContext - The content context containing page context
|
|
33
|
+
* @param converterContext - The project-specific converter context
|
|
34
|
+
* @param config - Contentful configuration
|
|
35
|
+
* @param count - Maximum number of people to return (default: 4)
|
|
36
|
+
* @param options - Optional fetch options for preview mode and caching
|
|
37
|
+
* @returns Array of person links (manual people first, then fetched)
|
|
38
|
+
*/
|
|
39
|
+
export declare function getRelatedPeople<T extends BaseCollectionContent>(information: IContentfulCollection<T>, contentContext: IContentContext, converterContext: BaseConverterContext, config: ContentfulConfig, count: number, options: FetchOptions): Promise<IPersonLink[]>;
|
|
147
40
|
//# sourceMappingURL=componentUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentUtils.d.ts","sourceRoot":"","sources":["../../src/utils/componentUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"componentUtils.d.ts","sourceRoot":"","sources":["../../src/utils/componentUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAGrB,KAAK,YAAY,EAEjB,KAAK,qBAAqB,EAE3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAEjB,KAAK,eAAe,EACpB,KAAK,WAAW,EAKjB,MAAM,4BAA4B,CAAC;AA8EpC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,SAAS,qBAAqB,EACtE,WAAW,EAAE,qBAAqB,CAAC,CAAC,CAAC,EACrC,cAAc,EAAE,eAAe,EAC/B,gBAAgB,EAAE,oBAAoB,EACtC,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC,CA6CzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,qBAAqB,EACpE,WAAW,EAAE,qBAAqB,CAAC,CAAC,CAAC,EACrC,cAAc,EAAE,eAAe,EAC/B,gBAAgB,EAAE,oBAAoB,EACtC,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,EAAE,CAAC,CAmCxB"}
|
|
@@ -1,126 +1,167 @@
|
|
|
1
|
+
import { contentfulAllArticleLinks, contentfulAllPersonLinks, filterRelatedArticles, } from '@se-studio/contentful-rest-api';
|
|
2
|
+
import { isArticleLink, isArticleTypeLink, isPersonLink, isTagLink, } from '@se-studio/core-data-types';
|
|
1
3
|
/**
|
|
2
|
-
* Extract
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @param information - The full component information object
|
|
6
|
-
* @param keys - Array of keys to extract from the information object
|
|
7
|
-
* @returns Object with only the specified keys
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```tsx
|
|
11
|
-
* const props = extractComponentInfo(information, ['heading', 'body', 'links']);
|
|
12
|
-
* // props will have type { heading?: string | null, body?: unknown, links?: ReadonlyArray<ILinkProps> }
|
|
13
|
-
* ```
|
|
4
|
+
* Extract filter criteria (article types, tags, authors) from collection links.
|
|
5
|
+
* Internal helper for getRelatedArticles.
|
|
14
6
|
*/
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
function extractFilterCriteria(links) {
|
|
8
|
+
const articleTypeIds = [];
|
|
9
|
+
const tagIds = [];
|
|
10
|
+
const authorIds = [];
|
|
11
|
+
if (links) {
|
|
12
|
+
for (const link of links) {
|
|
13
|
+
if (isArticleTypeLink(link)) {
|
|
14
|
+
articleTypeIds.push(link.id);
|
|
15
|
+
}
|
|
16
|
+
else if (isTagLink(link)) {
|
|
17
|
+
tagIds.push(link.id);
|
|
18
|
+
}
|
|
19
|
+
else if (isPersonLink(link)) {
|
|
20
|
+
authorIds.push(link.id);
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
|
-
return
|
|
24
|
+
return { articleTypeIds, tagIds, authorIds };
|
|
23
25
|
}
|
|
24
26
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param information - The full collection information object
|
|
29
|
-
* @param keys - Array of keys to extract from the information object
|
|
30
|
-
* @returns Object with only the specified keys
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```tsx
|
|
34
|
-
* const props = extractCollectionInfo(information, ['heading', 'body', 'contents']);
|
|
35
|
-
* // props will have type { heading?: string | null, body?: unknown, contents?: ReadonlyArray<CollectionContent> }
|
|
36
|
-
* ```
|
|
27
|
+
* Apply fallback criteria from page context when no explicit criteria provided.
|
|
28
|
+
* Internal helper for getRelatedArticles.
|
|
37
29
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
30
|
+
function applyFallbackCriteria(criteria, contentContext) {
|
|
31
|
+
if (criteria.articleTypeIds.length === 0) {
|
|
32
|
+
const articleType = contentContext.pageContext?.articleType;
|
|
33
|
+
if (articleType) {
|
|
34
|
+
criteria.articleTypeIds.push(articleType.id);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const article = contentContext.pageContext?.article;
|
|
38
|
+
if (article?.articleType?.id) {
|
|
39
|
+
criteria.articleTypeIds.push(article.articleType.id);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (criteria.authorIds.length === 0) {
|
|
44
|
+
const person = contentContext.pageContext?.person;
|
|
45
|
+
if (person) {
|
|
46
|
+
criteria.authorIds.push(person.id);
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
|
-
return result;
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* @param pageContext - The full page context object
|
|
51
|
-
* @param keys - Array of keys to extract from the page context
|
|
52
|
-
* @returns Object with only the specified keys
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```tsx
|
|
56
|
-
* const contextProps = extractPageContext(pageContext, ['articleLink', 'pageLink']);
|
|
57
|
-
* ```
|
|
51
|
+
* Determine whether we should fetch additional articles.
|
|
52
|
+
* Internal helper for getRelatedArticles.
|
|
58
53
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (key in pageContext) {
|
|
63
|
-
result[key] = pageContext[key];
|
|
64
|
-
}
|
|
54
|
+
function shouldFetchArticles(isAll, remainingSlots, criteria) {
|
|
55
|
+
if (isAll) {
|
|
56
|
+
return true;
|
|
65
57
|
}
|
|
66
|
-
|
|
58
|
+
const hasSlots = remainingSlots !== undefined && remainingSlots > 0;
|
|
59
|
+
const hasFilters = criteria.articleTypeIds.length > 0 ||
|
|
60
|
+
criteria.tagIds.length > 0 ||
|
|
61
|
+
criteria.authorIds.length > 0;
|
|
62
|
+
return hasSlots && hasFilters;
|
|
67
63
|
}
|
|
68
64
|
/**
|
|
69
|
-
*
|
|
70
|
-
* This function extracts the specified fields and combines them with additional props.
|
|
65
|
+
* Generic helper to get related articles for a collection.
|
|
71
66
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
67
|
+
* This function orchestrates the fetching of related articles by:
|
|
68
|
+
* 1. Extracting hard-coded articles from collection contents
|
|
69
|
+
* 2. Extracting filter criteria from collection links (tags, article type)
|
|
70
|
+
* 3. Extracting fallback criteria from page context (article type, current article)
|
|
71
|
+
* 4. Fetching additional articles if needed to reach the requested count
|
|
72
|
+
* 5. Returning manual articles followed by fetched articles
|
|
77
73
|
*
|
|
78
|
-
* @
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* const props = createComponentProps(config, information, pageContext);
|
|
86
|
-
* ```
|
|
74
|
+
* @param information - The collection information containing contents and links
|
|
75
|
+
* @param contentContext - The content context containing page context
|
|
76
|
+
* @param converterContext - The project-specific converter context (contains URL rules)
|
|
77
|
+
* @param config - Contentful configuration
|
|
78
|
+
* @param count - Maximum number of articles to return (optional)
|
|
79
|
+
* @param options - Optional fetch options for preview mode and caching
|
|
80
|
+
* @returns Array of article links (manual articles first, then fetched)
|
|
87
81
|
*/
|
|
88
|
-
export function
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
82
|
+
export async function getRelatedArticles(information, contentContext, converterContext, config, count, options) {
|
|
83
|
+
const isAll = typeof count === 'undefined';
|
|
84
|
+
// Step 1: Extract hard-coded articles from contents
|
|
85
|
+
const manualArticles = information.contents?.filter((item) => isArticleLink(item)) ?? [];
|
|
86
|
+
// Early return if we have enough manual articles
|
|
87
|
+
if (!isAll && count !== undefined && manualArticles.length >= count) {
|
|
88
|
+
return manualArticles.slice(0, count);
|
|
89
|
+
}
|
|
90
|
+
// Step 2: Extract and apply filter criteria
|
|
91
|
+
const criteria = extractFilterCriteria(information.links);
|
|
92
|
+
applyFallbackCriteria(criteria, contentContext);
|
|
93
|
+
// Step 3: Build exclusion list
|
|
94
|
+
const currentArticle = contentContext.pageContext?.article;
|
|
95
|
+
const excludeArticleIds = [
|
|
96
|
+
...manualArticles.map((article) => article.id),
|
|
97
|
+
...(currentArticle ? [currentArticle.id] : []),
|
|
98
|
+
];
|
|
99
|
+
// Step 4: Fetch additional articles if needed
|
|
100
|
+
const remainingSlots = isAll || count === undefined ? undefined : count - manualArticles.length;
|
|
101
|
+
let fetchedArticles = [];
|
|
102
|
+
if (shouldFetchArticles(isAll, remainingSlots, criteria)) {
|
|
103
|
+
try {
|
|
104
|
+
const response = await contentfulAllArticleLinks(converterContext, config, options);
|
|
105
|
+
const filterOptions = {
|
|
106
|
+
excludeArticleIds,
|
|
107
|
+
tagIds: criteria.tagIds,
|
|
108
|
+
articleTypeIds: criteria.articleTypeIds,
|
|
109
|
+
authorIds: criteria.authorIds,
|
|
110
|
+
count: remainingSlots,
|
|
111
|
+
};
|
|
112
|
+
fetchedArticles = filterRelatedArticles(response.data, filterOptions);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
console.error('[getRelatedArticles] Error fetching articles:', error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Step 5: Return manual articles followed by fetched articles
|
|
119
|
+
return [...manualArticles, ...fetchedArticles].slice(0, count);
|
|
96
120
|
}
|
|
97
121
|
/**
|
|
98
|
-
*
|
|
99
|
-
* This function extracts the specified fields and combines them with additional props.
|
|
122
|
+
* Generic helper to get related people for a collection.
|
|
100
123
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
124
|
+
* This function orchestrates the fetching of related people by:
|
|
125
|
+
* 1. Extracting hard-coded people from collection contents
|
|
126
|
+
* 2. Fetching additional people if needed to reach the requested count
|
|
127
|
+
* 3. Excluding the current person (if on a person page) and manually added people
|
|
128
|
+
* 4. Returning manual people followed by fetched people
|
|
106
129
|
*
|
|
107
|
-
* @
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* const props = createCollectionProps(config, information, pageContext);
|
|
115
|
-
* ```
|
|
130
|
+
* @param information - The collection information containing contents
|
|
131
|
+
* @param contentContext - The content context containing page context
|
|
132
|
+
* @param converterContext - The project-specific converter context
|
|
133
|
+
* @param config - Contentful configuration
|
|
134
|
+
* @param count - Maximum number of people to return (default: 4)
|
|
135
|
+
* @param options - Optional fetch options for preview mode and caching
|
|
136
|
+
* @returns Array of person links (manual people first, then fetched)
|
|
116
137
|
*/
|
|
117
|
-
export function
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
return
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
export async function getRelatedPeople(information, contentContext, converterContext, config, count, options) {
|
|
139
|
+
// Step 1: Extract hard-coded people from contents
|
|
140
|
+
const manualPeople = information.contents?.filter((item) => isPersonLink(item)) ?? [];
|
|
141
|
+
// Early return if we have enough manual people
|
|
142
|
+
if (manualPeople.length >= count) {
|
|
143
|
+
return manualPeople.slice(0, count);
|
|
144
|
+
}
|
|
145
|
+
// Step 2: Build exclusion list
|
|
146
|
+
const currentPerson = contentContext.pageContext?.person;
|
|
147
|
+
const excludePersonIds = new Set([
|
|
148
|
+
...manualPeople.map((person) => person.id),
|
|
149
|
+
...(currentPerson ? [currentPerson.id] : []),
|
|
150
|
+
]);
|
|
151
|
+
// Step 3: Fetch additional people if needed
|
|
152
|
+
const remainingSlots = count - manualPeople.length;
|
|
153
|
+
let fetchedPeople = [];
|
|
154
|
+
try {
|
|
155
|
+
const response = await contentfulAllPersonLinks(converterContext, config, options);
|
|
156
|
+
// Filter out excluded people
|
|
157
|
+
fetchedPeople = response.data
|
|
158
|
+
.filter((person) => isPersonLink(person) && !excludePersonIds.has(person.id))
|
|
159
|
+
.slice(0, remainingSlots);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console.error('[getRelatedPeople] Error fetching people:', error);
|
|
163
|
+
}
|
|
164
|
+
// Step 4: Return manual people followed by fetched people
|
|
165
|
+
return [...manualPeople, ...fetchedPeople].slice(0, count);
|
|
125
166
|
}
|
|
126
167
|
//# sourceMappingURL=componentUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentUtils.js","sourceRoot":"","sources":["../../src/utils/componentUtils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"componentUtils.js","sourceRoot":"","sources":["../../src/utils/componentUtils.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/urlUtils.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export declare function isAbsoluteUrl(url: string): boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Utility function to get the current page URL safely.
|
|
4
|
+
* Returns an empty string when running on the server.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getCurrentPageUrl(): string;
|
|
2
7
|
//# sourceMappingURL=urlUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/urlUtils.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOlD"}
|
|
1
|
+
{"version":3,"file":"urlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/urlUtils.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C"}
|
package/dist/utils/urlUtils.js
CHANGED
|
@@ -7,4 +7,14 @@ export function isAbsoluteUrl(url) {
|
|
|
7
7
|
return false;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Utility function to get the current page URL safely.
|
|
12
|
+
* Returns an empty string when running on the server.
|
|
13
|
+
*/
|
|
14
|
+
export function getCurrentPageUrl() {
|
|
15
|
+
if (typeof window !== 'undefined') {
|
|
16
|
+
return window.location.href;
|
|
17
|
+
}
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
10
20
|
//# sourceMappingURL=urlUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urlUtils.js","sourceRoot":"","sources":["../../src/utils/urlUtils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"urlUtils.js","sourceRoot":"","sources":["../../src/utils/urlUtils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/core-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.47",
|
|
4
4
|
"description": "Shared React UI component library with Tailwind CSS v4 for SE Studio applications",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"dist"
|
|
21
|
+
"dist",
|
|
22
|
+
"*.md",
|
|
23
|
+
"src/showcase/README.md"
|
|
22
24
|
],
|
|
23
25
|
"keywords": [
|
|
24
26
|
"react",
|
|
@@ -58,19 +60,20 @@
|
|
|
58
60
|
"html-entities": "^2.6.0",
|
|
59
61
|
"mustache": "4.2.0",
|
|
60
62
|
"tailwind-merge": "^3.4.0",
|
|
61
|
-
"@se-studio/contentful-rest-api": "1.0.
|
|
62
|
-
"@se-studio/core-data-types": "1.0.
|
|
63
|
+
"@se-studio/contentful-rest-api": "1.0.47",
|
|
64
|
+
"@se-studio/core-data-types": "1.0.47"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@biomejs/biome": "^2.3.10",
|
|
66
68
|
"@testing-library/jest-dom": "^6.9.1",
|
|
67
69
|
"@testing-library/react": "^16.3.1",
|
|
68
|
-
"@types/node": "^
|
|
70
|
+
"@types/node": "^22.19.3",
|
|
69
71
|
"@types/react": "^19.2.7",
|
|
70
72
|
"@types/react-dom": "^19.2.3",
|
|
71
73
|
"@vitejs/plugin-react": "^5.1.2",
|
|
72
|
-
"jsdom": "^27.
|
|
74
|
+
"jsdom": "^27.4.0",
|
|
73
75
|
"next": "^15.5.9",
|
|
76
|
+
"tsup": "^8.5.1",
|
|
74
77
|
"typescript": "^5.9.3",
|
|
75
78
|
"vitest": "^4.0.16"
|
|
76
79
|
},
|