Skip to content

Commit 139b9ac

Browse files
committed
refactor(editor): optimize dictionary loading for editor and bundle size
1 parent 84bab3f commit 139b9ac

File tree

8 files changed

+113
-49
lines changed

8 files changed

+113
-49
lines changed

packages/@intlayer/api/src/getIntlayerAPI/editor.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { IntlayerConfig } from '@intlayer/config/client';
21
import configuration from '@intlayer/config/built';
2+
import type { IntlayerConfig } from '@intlayer/config/client';
33

44
import type {
55
// @ts-ignore: intlayer-editor is not built yet
@@ -8,7 +8,6 @@ import type {
88
WriteContentDeclarationBody,
99
// @ts-ignore: intlayer-editor is not built yet
1010
WriteContentDeclarationResult,
11-
// @ts-ignore: intlayer-editor is not built yet
1211
} from 'intlayer-editor';
1312
import { fetcher, type FetcherOptions } from '../fetcher';
1413

@@ -40,6 +39,21 @@ export const getEditorAPI = (
4039
return response.data;
4140
};
4241

42+
/**
43+
* Get the Intlayer configuration
44+
*/
45+
const getDictionaries = async (
46+
otherOptions: FetcherOptions = {}
47+
): Promise<Record<string, any>> => {
48+
const response = await fetcher<Record<string, any>>(
49+
`${EDITOR_API_ROUTE}/dictionary`,
50+
authAPIOptions,
51+
otherOptions
52+
);
53+
54+
return response.data;
55+
};
56+
4357
/**
4458
* Adds a new dictionary to the database.
4559
* @param dictionary - Dictionary data.
@@ -59,6 +73,7 @@ export const getEditorAPI = (
5973
);
6074

6175
return {
76+
getDictionaries,
6277
getConfiguration,
6378
writeDictionary,
6479
};

packages/@intlayer/api/src/getIntlayerAPI/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export const getIntlayerAPI = (
2323
stripe: getStripeAPI(authAPIOptions, intlayerConfig),
2424
ai: getAiAPI(authAPIOptions, intlayerConfig),
2525
tag: getTagAPI(authAPIOptions, intlayerConfig),
26-
editor: getEditorAPI(authAPIOptions, intlayerConfig),
2726
search: getSearchAPI(authAPIOptions, intlayerConfig),
27+
editor: getEditorAPI(authAPIOptions, intlayerConfig),
2828
});
2929

3030
export type IntlayerAPI = ReturnType<typeof getIntlayerAPI>;

packages/@intlayer/design-system/src/hooks/intlayerAPIHooks.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,14 @@ export const useAutocomplete = (
728728
args?: UseAsyncOptions<IntlayerAPI['ai']['autocomplete']>
729729
) => useAppAsync('autocomplete', useIntlayerAuth().ai.autocomplete, args);
730730

731+
/**
732+
* Search
733+
*/
734+
735+
export const useSearchDoc = (
736+
args?: UseAsyncOptions<IntlayerAPI['search']['searchDoc']>
737+
) => useAppAsync('searchDoc', useIntlayerAuth().search.searchDoc, args);
738+
731739
/**
732740
* Editor
733741
*/
@@ -741,10 +749,11 @@ export const useWriteDictionary = (
741749
args
742750
);
743751

744-
/**
745-
* Search
746-
*/
747-
748-
export const useSearchDoc = (
749-
args?: UseAsyncOptions<IntlayerAPI['search']['searchDoc']>
750-
) => useAppAsync('searchDoc', useIntlayerAuth().search.searchDoc, args);
752+
export const useGetEditorDictionaries = (
753+
args?: UseAsyncOptions<IntlayerAPI['editor']['getDictionaries']>
754+
) =>
755+
useEditorAsync('getDictionaries', useIntlayerAuth().editor.getDictionaries, {
756+
store: true,
757+
cache: true,
758+
...args,
759+
});

packages/intlayer-editor/client/src/components/Editor/DictionaryListDrawer/DictionaryListDrawer.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,38 @@
22

33
import type { Locales } from '@intlayer/config';
44
import {
5-
RightDrawer,
65
Button,
6+
RightDrawer,
77
useRightDrawerStore,
88
} from '@intlayer/design-system';
9-
import { useGetAllDictionaries } from '@intlayer/design-system/hooks';
10-
import { useEditedContent, useFocusDictionary } from '@intlayer/editor-react';
9+
import {
10+
useGetAllDictionaries,
11+
useGetEditorDictionaries,
12+
} from '@intlayer/design-system/hooks';
13+
import {
14+
useDictionariesRecordActions,
15+
useEditedContent,
16+
useFocusDictionary,
17+
} from '@intlayer/editor-react';
1118
import { ChevronRight } from 'lucide-react';
12-
import { type FC, useCallback, useMemo } from 'react';
19+
import { type FC, useEffect } from 'react';
1320
import { getDrawerIdentifier } from '../DictionaryEditionDrawer/useDictionaryEditionDrawer';
1421
import { dictionaryListDrawerIdentifier } from './dictionaryListDrawerIdentifier';
1522

1623
export const DictionaryListDrawer: FC = () => {
1724
const { all: dictionaries } = useGetAllDictionaries();
18-
const dictionaryKeyList = useMemo(
19-
() => Object.keys(dictionaries) as Locales[],
20-
[dictionaries]
21-
);
25+
const dictionaryKeyList = Object.keys(dictionaries) as Locales[];
26+
27+
const { setLocaleDictionaries } = useDictionariesRecordActions();
28+
const { data: localeDictionaries } = useGetEditorDictionaries({
29+
autoFetch: true,
30+
});
31+
32+
useEffect(() => {
33+
if (!localeDictionaries) return;
34+
35+
setLocaleDictionaries(localeDictionaries);
36+
}, [dictionaries]);
2237

2338
const { close: closeDrawer, open: openDrawer } = useRightDrawerStore();
2439

@@ -37,11 +52,8 @@ export const DictionaryListDrawer: FC = () => {
3752
openDrawer(getDrawerIdentifier(dictionaryKey));
3853
};
3954

40-
const isDictionaryEdited = useCallback(
41-
(dictionaryKey: string) =>
42-
Object.keys(editedContent ?? {}).includes(dictionaryKey),
43-
[editedContent]
44-
);
55+
const isDictionaryEdited = (dictionaryKey: string) =>
56+
Object.keys(editedContent ?? {}).includes(dictionaryKey);
4557

4658
return (
4759
<RightDrawer

packages/intlayer-editor/client/src/components/Editor/EditorLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { type Locales } from '@intlayer/config/client';
44
import { MessageKey, useCrossFrameState } from '@intlayer/editor-react';
5-
import type { FC, PropsWithChildren } from 'react';
5+
import { type FC, type PropsWithChildren } from 'react';
66
import { DictionaryEditionDrawerController } from './DictionaryEditionDrawer';
77
import { DictionaryListDrawer } from './DictionaryListDrawer';
88

packages/intlayer-editor/server/src/controllers/dictionary.controller.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,49 @@
1-
import { getConfiguration } from '@intlayer/config';
2-
import { type Dictionary } from '@intlayer/core';
3-
import { type ResponseData, formatResponse } from '@utils/responseData';
41
import {
52
writeContentDeclaration as writeContentDeclarationEditor,
63
type DictionaryStatus,
74
} from '@intlayer/chokidar';
5+
import { getConfiguration } from '@intlayer/config';
6+
import { type Dictionary } from '@intlayer/core';
7+
import dictionaries from '@intlayer/dictionaries-entry';
8+
import { formatResponse, type ResponseData } from '@utils/responseData';
89
import type { NextFunction, Request, Response } from 'express';
910
import { t } from 'express-intlayer';
1011

12+
type GetDictionariesResult = ResponseData<Record<string, Dictionary>>;
13+
14+
/**
15+
* Get the Intlayer configuration
16+
*/
17+
export const getDictionaries = async (
18+
req: Request,
19+
res: Response<GetDictionariesResult>,
20+
_next: NextFunction
21+
): Promise<void> => {
22+
try {
23+
const formattedResponse = formatResponse<Record<string, Dictionary>>({
24+
data: dictionaries,
25+
});
26+
27+
res.json(formattedResponse);
28+
return;
29+
} catch (err) {
30+
const errorMessage =
31+
(err as { message?: string; status?: number }) ?? 'Internal Server Error';
32+
33+
const formattedErrorResponse = formatResponse<Record<string, Dictionary>>({
34+
error: {
35+
message: errorMessage.message ?? 'Internal Server Error',
36+
code: 'INTERNAL_SERVER_ERROR',
37+
title: 'Internal Server Error',
38+
},
39+
status: errorMessage.status ?? 500,
40+
});
41+
42+
res.json(formattedErrorResponse);
43+
return;
44+
}
45+
};
46+
1147
export type WriteContentDeclarationBody = { dictionary: Dictionary };
1248
type WriteContentDeclarationResultData = {
1349
status: DictionaryStatus;

packages/intlayer-editor/server/src/routes/dictionary.routes.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { writeContentDeclaration } from '@controllers/dictionary.controller';
1+
import type { Routes } from '@/types/Routes';
2+
import {
3+
getDictionaries,
4+
writeContentDeclaration,
5+
} from '@controllers/dictionary.controller';
26
import { getConfiguration } from '@intlayer/config';
37
import { Router } from 'express';
4-
import type { Routes } from '@/types/Routes';
58

69
export const dictionaryRouter: Router = Router();
710

@@ -11,13 +14,22 @@ const getBaseURL = () => `${editor.editorURL}/api/dictionary`;
1114

1215
export const getDictionaryRoutes = () =>
1316
({
17+
getDictionaries: {
18+
urlModel: '/',
19+
url: getBaseURL(),
20+
method: 'GET',
21+
},
1422
writeContentDeclaration: {
1523
urlModel: '/',
1624
url: getBaseURL(),
1725
method: 'POST',
1826
},
1927
}) satisfies Routes;
2028

29+
dictionaryRouter.get(
30+
getDictionaryRoutes().getDictionaries.urlModel,
31+
getDictionaries
32+
);
2133
dictionaryRouter.post(
2234
getDictionaryRoutes().writeContentDeclaration.urlModel,
2335
writeContentDeclaration

packages/react-intlayer/src/editor/IntlayerEditorProvider.tsx

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,10 @@
22

33
import { IntlayerEventListener } from '@intlayer/api';
44
import configuration from '@intlayer/config/built';
5-
6-
import type { Dictionary } from '@intlayer/core';
7-
/**
8-
* @intlayer/dictionaries-entry is a package that only returns the dictionary entry path.
9-
* Using an external package allow to alias it in the bundle configuration (such as webpack).
10-
* The alias allow hot reload the app (such as nextjs) on any dictionary change.
11-
*/
12-
import dictionaries from '@intlayer/dictionaries-entry';
135
import {
146
EditorProvider,
157
useChangedContentActions,
168
useCrossURLPathSetter,
17-
useDictionariesRecordActions,
189
useEditorEnabled,
1910
useIframeClickInterceptor,
2011
} from '@intlayer/editor-react';
@@ -26,17 +17,6 @@ const IntlayerEditorHooksEnabled: FC = () => {
2617
*/
2718
useCrossURLPathSetter();
2819

29-
/**
30-
* Locale Dictionaries Messages
31-
*/
32-
const { setLocaleDictionaries } = useDictionariesRecordActions();
33-
34-
useEffect(() => {
35-
setLocaleDictionaries(
36-
dictionaries as unknown as Record<string, Dictionary>
37-
);
38-
}, []);
39-
4020
/**
4121
* Click Messages
4222
*/

0 commit comments

Comments
 (0)