@akemona-org/strapi-plugin-i18n 3.7.0
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/LICENSE +22 -0
- package/README.md +19 -0
- package/admin/src/assets/images/logo.svg +1 -0
- package/admin/src/components/CMEditViewCopyLocale/index.js +183 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/cleanData.js +36 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/generateOptions.js +22 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/index.js +2 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/removePasswordAndRelationsFieldFromData.js +54 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/tests/cleanData.test.js +83 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/tests/data.js +219 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/tests/generateOptions.test.js +79 -0
- package/admin/src/components/CMEditViewCopyLocale/utils/tests/removePasswordAndRelationsFieldFromData.test.js +40 -0
- package/admin/src/components/CMEditViewInjectedComponents/index.js +58 -0
- package/admin/src/components/CMEditViewLocalePicker/Option.js +66 -0
- package/admin/src/components/CMEditViewLocalePicker/Wrapper.js +8 -0
- package/admin/src/components/CMEditViewLocalePicker/index.js +160 -0
- package/admin/src/components/CMEditViewLocalePicker/utils/addStatusColorToLocale.js +24 -0
- package/admin/src/components/CMEditViewLocalePicker/utils/createLocalesOption.js +20 -0
- package/admin/src/components/CMEditViewLocalePicker/utils/index.js +2 -0
- package/admin/src/components/CheckboxConfirmation/Wrapper.js +12 -0
- package/admin/src/components/CheckboxConfirmation/index.js +70 -0
- package/admin/src/components/DeleteModalAdditionalInfos/index.js +25 -0
- package/admin/src/components/LocaleList/index.js +101 -0
- package/admin/src/components/LocaleListCell/LocaleListCell.js +90 -0
- package/admin/src/components/LocaleListCell/tests/LocaleListCell.test.js +128 -0
- package/admin/src/components/LocalePicker/index.js +126 -0
- package/admin/src/components/LocaleRow/index.js +77 -0
- package/admin/src/components/ModalCreate/AdvancedForm.js +45 -0
- package/admin/src/components/ModalCreate/BaseForm.js +103 -0
- package/admin/src/components/ModalCreate/index.js +136 -0
- package/admin/src/components/ModalDelete/index.js +49 -0
- package/admin/src/components/ModalEdit/AdvancedForm.js +51 -0
- package/admin/src/components/ModalEdit/BaseForm.js +91 -0
- package/admin/src/components/ModalEdit/index.js +122 -0
- package/admin/src/components/SettingsModal.js +66 -0
- package/admin/src/components/index.js +2 -0
- package/admin/src/containers/Initializer.js +31 -0
- package/admin/src/containers/SettingsPage/LocaleSettingsPage.js +69 -0
- package/admin/src/containers/SettingsPage/index.js +33 -0
- package/admin/src/containers/SettingsPage/tests/SettingsPage.test.js +744 -0
- package/admin/src/containers/SettingsPage/tests/__snapshots__/SettingsPage.test.js.snap +241 -0
- package/admin/src/hooks/constants.js +6 -0
- package/admin/src/hooks/reducers.js +63 -0
- package/admin/src/hooks/tests/reducers.test.js +203 -0
- package/admin/src/hooks/useAddLocale/index.js +60 -0
- package/admin/src/hooks/useContentTypePermissions/index.js +16 -0
- package/admin/src/hooks/useDefaultLocales/index.js +27 -0
- package/admin/src/hooks/useDeleteLocale/index.js +45 -0
- package/admin/src/hooks/useEditLocale/index.js +46 -0
- package/admin/src/hooks/useHasI18n/index.js +13 -0
- package/admin/src/hooks/useLocales/index.js +35 -0
- package/admin/src/index.js +169 -0
- package/admin/src/middlewares/addCommonFieldsToInitialDataMiddleware.js +83 -0
- package/admin/src/middlewares/addLocaleColumnToListViewMiddleware.js +32 -0
- package/admin/src/middlewares/addLocaleToCollectionTypesMiddleware.js +25 -0
- package/admin/src/middlewares/addLocaleToSingleTypesMiddleware.js +25 -0
- package/admin/src/middlewares/extendCMEditViewLayoutMiddleware.js +159 -0
- package/admin/src/middlewares/extendCTBAttributeInitialDataMiddleware.js +58 -0
- package/admin/src/middlewares/extendCTBInitialDataMiddleware.js +33 -0
- package/admin/src/middlewares/index.js +21 -0
- package/admin/src/middlewares/localePermissionMiddleware.js +39 -0
- package/admin/src/middlewares/tests/addCommonFieldsToInitialDataMiddleware.test.js +97 -0
- package/admin/src/middlewares/tests/addLocaleColumnToListViewMiddleware.test.js +68 -0
- package/admin/src/middlewares/tests/addLocaleToCollectionTypesMiddleware.test.js +200 -0
- package/admin/src/middlewares/tests/addLocaleToSingleTypesMiddleware.test.js +193 -0
- package/admin/src/middlewares/tests/extendCMEditViewLayoutMiddleware.test.js +556 -0
- package/admin/src/middlewares/tests/extendCTBAttrributeInitialDataMiddleware.test.js +124 -0
- package/admin/src/middlewares/tests/extendCTBInitialDataMiddleware.test.js +92 -0
- package/admin/src/middlewares/tests/localePermissionMiddleware.test.js +150 -0
- package/admin/src/middlewares/utils/addLocaleToLinksSearch.js +56 -0
- package/admin/src/middlewares/utils/tests/addLocaleToLinksSearch.test.js +137 -0
- package/admin/src/permissions.js +9 -0
- package/admin/src/pluginId.js +5 -0
- package/admin/src/schemas.js +7 -0
- package/admin/src/selectors/selectCollectionTypesRelatedPermissions.js +4 -0
- package/admin/src/selectors/selectI18nLocales.js +3 -0
- package/admin/src/translations/en.json +60 -0
- package/admin/src/translations/fr.json +9 -0
- package/admin/src/translations/index.js +11 -0
- package/admin/src/translations/zh-Hans.json +60 -0
- package/admin/src/utils/getDefaultLocale.js +60 -0
- package/admin/src/utils/getInitialLocale.js +14 -0
- package/admin/src/utils/getLocaleFromQuery.js +7 -0
- package/admin/src/utils/getTrad.js +5 -0
- package/admin/src/utils/index.js +2 -0
- package/admin/src/utils/localizedFields.js +23 -0
- package/admin/src/utils/mutateCTBContentTypeSchema.js +66 -0
- package/admin/src/utils/tests/getDefaultLocale.test.js +337 -0
- package/admin/src/utils/tests/getInitialLocale.test.js +106 -0
- package/admin/src/utils/tests/mutateCTBContentTypeSchema.test.js +205 -0
- package/config/functions/bootstrap.js +57 -0
- package/config/functions/migrations/__tests__/content-type.test.js +255 -0
- package/config/functions/migrations/__tests__/field.test.js +150 -0
- package/config/functions/migrations/content-type/disable/index.js +34 -0
- package/config/functions/migrations/content-type/disable/migrate-for-bookshelf.js +58 -0
- package/config/functions/migrations/content-type/disable/migrate-for-mongoose.js +39 -0
- package/config/functions/migrations/content-type/enable/index.js +40 -0
- package/config/functions/migrations/content-type/utils/index.js +27 -0
- package/config/functions/migrations/field/__tests__/utils.test.js +53 -0
- package/config/functions/migrations/field/index.js +37 -0
- package/config/functions/migrations/field/migrate-for-bookshelf.js +72 -0
- package/config/functions/migrations/field/migrate-for-mongoose.js +24 -0
- package/config/functions/migrations/field/migrate.js +55 -0
- package/config/functions/migrations/field/utils.js +58 -0
- package/config/functions/register.js +46 -0
- package/config/policies/validateLocaleCreation.js +68 -0
- package/config/routes.json +64 -0
- package/constants/__tests__/index.test.js +27 -0
- package/constants/index.js +36 -0
- package/constants/iso-locales.json +2002 -0
- package/controllers/__tests__/content-types.test.js +113 -0
- package/controllers/__tests__/iso-locales.test.js +26 -0
- package/controllers/__tests__/locales.test.js +308 -0
- package/controllers/content-types.js +64 -0
- package/controllers/iso-locales.js +11 -0
- package/controllers/locales.js +104 -0
- package/domain/locale.js +10 -0
- package/middlewares/i18n/defaults.json +5 -0
- package/middlewares/i18n/index.js +28 -0
- package/models/Locale.settings.json +31 -0
- package/oas.yml +195 -0
- package/package.json +31 -0
- package/services/__tests__/__snapshots__/iso-locales.test.js.snap +2006 -0
- package/services/__tests__/content-types.test.js +545 -0
- package/services/__tests__/core-api.test.js +106 -0
- package/services/__tests__/entity-service-decorator.test.js +280 -0
- package/services/__tests__/iso-locales.test.js +11 -0
- package/services/__tests__/locales.test.js +237 -0
- package/services/__tests__/localizations.test.js +187 -0
- package/services/__tests__/metrics.test.js +90 -0
- package/services/content-types.js +200 -0
- package/services/core-api.js +296 -0
- package/services/entity-service-decorator.js +155 -0
- package/services/iso-locales.js +9 -0
- package/services/locales.js +97 -0
- package/services/localizations.js +65 -0
- package/services/metrics.js +24 -0
- package/services/permissions/actions.js +124 -0
- package/services/permissions/engine.js +63 -0
- package/services/permissions/sections-builder.js +48 -0
- package/services/permissions.js +11 -0
- package/tests/content-manager/list-relation.test.e2e.js +122 -0
- package/tests/graphql.test.e2e.js +120 -0
- package/tests/locales.test.e2e.js +414 -0
- package/utils/index.js +20 -0
- package/validation/content-types.js +30 -0
- package/validation/locales.js +39 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import middleware from '../extendCTBInitialDataMiddleware';
|
|
2
|
+
|
|
3
|
+
describe('i18n | middlewares | extendCTBInitialDataMiddleware', () => {
|
|
4
|
+
describe('the action type matches "ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT"', () => {
|
|
5
|
+
it('forwards the action when the action type does not match', () => {
|
|
6
|
+
const extendCTBInitialDataMiddleware = middleware();
|
|
7
|
+
const next = jest.fn();
|
|
8
|
+
const action = {};
|
|
9
|
+
|
|
10
|
+
extendCTBInitialDataMiddleware()(next)(action);
|
|
11
|
+
|
|
12
|
+
expect(next).toBeCalledWith(action);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('forwards the action when the modalType and actionType are undefined', () => {
|
|
16
|
+
const extendCTBInitialDataMiddleware = middleware();
|
|
17
|
+
const next = jest.fn();
|
|
18
|
+
const action = {
|
|
19
|
+
type: 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT',
|
|
20
|
+
modalType: undefined,
|
|
21
|
+
actionType: undefined,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
extendCTBInitialDataMiddleware()(next)(action);
|
|
25
|
+
|
|
26
|
+
expect(next).toBeCalledWith(action);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('forwards the action when the action.data.pluginOptions.i18n.localized path exists', () => {
|
|
30
|
+
const extendCTBInitialDataMiddleware = middleware();
|
|
31
|
+
const next = jest.fn();
|
|
32
|
+
const action = {
|
|
33
|
+
type: 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT',
|
|
34
|
+
modalType: undefined,
|
|
35
|
+
actionType: undefined,
|
|
36
|
+
data: { pluginOptions: { i18n: { localized: false } } },
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
extendCTBInitialDataMiddleware()(next)(action);
|
|
40
|
+
|
|
41
|
+
expect(next).toBeCalledWith(action);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('adds a pluginOptions to the action when data is defined and the action', () => {
|
|
45
|
+
const extendCTBInitialDataMiddleware = middleware();
|
|
46
|
+
const next = jest.fn();
|
|
47
|
+
const action = {
|
|
48
|
+
type: 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT',
|
|
49
|
+
modalType: 'contentType',
|
|
50
|
+
actionType: 'edit',
|
|
51
|
+
data: {},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
extendCTBInitialDataMiddleware()(next)(action);
|
|
55
|
+
|
|
56
|
+
expect(next).toBeCalledWith({
|
|
57
|
+
type: 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT',
|
|
58
|
+
modalType: 'contentType',
|
|
59
|
+
actionType: 'edit',
|
|
60
|
+
data: {
|
|
61
|
+
pluginOptions: { i18n: { localized: false } },
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('modifies the data.pluginOptions in the action when it already exists', () => {
|
|
67
|
+
const extendCTBInitialDataMiddleware = middleware();
|
|
68
|
+
const next = jest.fn();
|
|
69
|
+
const action = {
|
|
70
|
+
type: 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT',
|
|
71
|
+
modalType: 'contentType',
|
|
72
|
+
actionType: 'edit',
|
|
73
|
+
data: {
|
|
74
|
+
pluginOptions: {
|
|
75
|
+
somePluginThings: true,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
extendCTBInitialDataMiddleware()(next)(action);
|
|
81
|
+
|
|
82
|
+
expect(next).toBeCalledWith({
|
|
83
|
+
type: 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT',
|
|
84
|
+
modalType: 'contentType',
|
|
85
|
+
actionType: 'edit',
|
|
86
|
+
data: {
|
|
87
|
+
pluginOptions: { i18n: { localized: false }, somePluginThings: true },
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import localePermissionMiddleware from '../localePermissionMiddleware';
|
|
2
|
+
|
|
3
|
+
describe('localePermissionMiddleware', () => {
|
|
4
|
+
it('does not modify the action when the type is not "ContentManager/RBACManager/SET_PERMISSIONS"', () => {
|
|
5
|
+
const nextFn = jest.fn(x => x);
|
|
6
|
+
const action = {
|
|
7
|
+
type: 'UNKNOWN_TYPE',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
11
|
+
|
|
12
|
+
expect(nextAction).toBe(action);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('does not modify the action when it the __meta__ key is not set', () => {
|
|
16
|
+
const nextFn = jest.fn(x => x);
|
|
17
|
+
const action = {
|
|
18
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
19
|
+
__meta__: undefined,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
23
|
+
|
|
24
|
+
expect(nextAction).toBe(action);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('does not modify the action when it the __meta__.containerName is not "listView"', () => {
|
|
28
|
+
const nextFn = jest.fn(x => x);
|
|
29
|
+
const action = {
|
|
30
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
31
|
+
__meta__: { containerName: undefined },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
35
|
+
|
|
36
|
+
expect(nextAction).toBe(action);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('does not modify the action when it the __meta__.plugins is not set', () => {
|
|
40
|
+
const nextFn = jest.fn(x => x);
|
|
41
|
+
const action = {
|
|
42
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
43
|
+
__meta__: { containerName: 'listView' },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
47
|
+
|
|
48
|
+
expect(nextAction).toBe(action);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('does not modify the action when it the __meta__.plugins.i18n.locale is not set', () => {
|
|
52
|
+
const nextFn = jest.fn(x => x);
|
|
53
|
+
const action = {
|
|
54
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
55
|
+
__meta__: {
|
|
56
|
+
containerName: 'listView',
|
|
57
|
+
plugins: {},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
62
|
+
|
|
63
|
+
expect(nextAction).toBe(action);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('creates an empty permissions object from an empty array', () => {
|
|
67
|
+
const nextFn = jest.fn(x => x);
|
|
68
|
+
const action = {
|
|
69
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
70
|
+
__meta__: {
|
|
71
|
+
containerName: 'listView',
|
|
72
|
+
plugins: {
|
|
73
|
+
i18n: {
|
|
74
|
+
locale: 'en',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
permissions: {},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
82
|
+
|
|
83
|
+
expect(nextAction).toEqual({
|
|
84
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
85
|
+
__meta__: { containerName: 'listView', plugins: { i18n: { locale: 'en' } } },
|
|
86
|
+
permissions: {},
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('creates a valid permissions object from a filled array', () => {
|
|
91
|
+
const nextFn = jest.fn(x => x);
|
|
92
|
+
const action = {
|
|
93
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
94
|
+
__meta__: {
|
|
95
|
+
containerName: 'listView',
|
|
96
|
+
plugins: {
|
|
97
|
+
i18n: {
|
|
98
|
+
locale: 'en',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
permissions: {
|
|
103
|
+
'plugins::content-manager.explorer.create': [
|
|
104
|
+
{
|
|
105
|
+
id: 459,
|
|
106
|
+
action: 'plugins::content-manager.explorer.create',
|
|
107
|
+
subject: 'application::article.article',
|
|
108
|
+
properties: {
|
|
109
|
+
fields: ['Name'],
|
|
110
|
+
locales: ['en'],
|
|
111
|
+
},
|
|
112
|
+
conditions: [],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 459,
|
|
116
|
+
action: 'plugins::content-manager.explorer.create',
|
|
117
|
+
subject: 'application::article.article',
|
|
118
|
+
properties: {
|
|
119
|
+
fields: ['test'],
|
|
120
|
+
locales: ['it'],
|
|
121
|
+
},
|
|
122
|
+
conditions: [],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const nextAction = localePermissionMiddleware()()(nextFn)(action);
|
|
129
|
+
|
|
130
|
+
expect(nextAction).toEqual({
|
|
131
|
+
type: 'ContentManager/RBACManager/SET_PERMISSIONS',
|
|
132
|
+
__meta__: { containerName: 'listView', plugins: { i18n: { locale: 'en' } } },
|
|
133
|
+
permissions: {
|
|
134
|
+
'plugins::content-manager.explorer.create': [
|
|
135
|
+
{
|
|
136
|
+
id: 459,
|
|
137
|
+
action: 'plugins::content-manager.explorer.create',
|
|
138
|
+
subject: 'application::article.article',
|
|
139
|
+
properties: {
|
|
140
|
+
fields: ['Name'],
|
|
141
|
+
locales: ['en'],
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
conditions: [],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import { stringify, parse } from 'qs';
|
|
3
|
+
import getDefaultLocale from '../../utils/getDefaultLocale';
|
|
4
|
+
|
|
5
|
+
const addLocaleToLinksSearch = (links, kind, contentTypeSchemas, locales, permissions) => {
|
|
6
|
+
return links.map(link => {
|
|
7
|
+
const contentTypeUID = link.destination.split(`/${kind}/`)[1];
|
|
8
|
+
|
|
9
|
+
const contentTypeSchema = contentTypeSchemas.find(({ uid }) => uid === contentTypeUID);
|
|
10
|
+
|
|
11
|
+
const hasI18nEnabled = get(contentTypeSchema, 'pluginOptions.i18n.localized', false);
|
|
12
|
+
|
|
13
|
+
if (!hasI18nEnabled) {
|
|
14
|
+
return link;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const contentTypePermissions = permissions[contentTypeUID];
|
|
18
|
+
const requiredPermissionsToViewALink =
|
|
19
|
+
kind === 'collectionType'
|
|
20
|
+
? ['plugins::content-manager.explorer.read', 'plugins::content-manager.explorer.create']
|
|
21
|
+
: ['plugins::content-manager.explorer.read'];
|
|
22
|
+
|
|
23
|
+
const contentTypeNeededPermissions = Object.keys(contentTypePermissions).reduce(
|
|
24
|
+
(acc, current) => {
|
|
25
|
+
if (requiredPermissionsToViewALink.includes(current)) {
|
|
26
|
+
acc[current] = contentTypePermissions[current];
|
|
27
|
+
|
|
28
|
+
return acc;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
acc[current] = [];
|
|
32
|
+
|
|
33
|
+
return acc;
|
|
34
|
+
},
|
|
35
|
+
{}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const defaultLocale = getDefaultLocale(contentTypeNeededPermissions, locales);
|
|
39
|
+
|
|
40
|
+
if (!defaultLocale) {
|
|
41
|
+
return { ...link, isDisplayed: false };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const linkParams = link.search ? parse(link.search) : {};
|
|
45
|
+
|
|
46
|
+
const params = linkParams
|
|
47
|
+
? { ...linkParams, plugins: { ...linkParams.plugins, i18n: { locale: defaultLocale } } }
|
|
48
|
+
: { plugins: { i18n: { locale: defaultLocale } } };
|
|
49
|
+
|
|
50
|
+
const search = stringify(params, { encode: false });
|
|
51
|
+
|
|
52
|
+
return { ...link, search };
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default addLocaleToLinksSearch;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import addLocaleToLinksSearch from '../addLocaleToLinksSearch';
|
|
2
|
+
|
|
3
|
+
describe('i18n | middlewares | utils | addLocaleToLinksSearch', () => {
|
|
4
|
+
it('should return an array', () => {
|
|
5
|
+
expect(addLocaleToLinksSearch([])).toEqual([]);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it('should not modify the links when i18n is not enabled on a content type', () => {
|
|
9
|
+
const links = [{ uid: 'test', destination: 'cm/collectionType/test' }];
|
|
10
|
+
const schemas = [{ uid: 'test', pluginOptions: { i18n: { localized: false } } }];
|
|
11
|
+
|
|
12
|
+
expect(addLocaleToLinksSearch(links, 'collectionType', schemas)).toEqual(links);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should set the isDisplayed key to false when the user does not have the permission to read or create a locale on a collection type', () => {
|
|
16
|
+
const links = [
|
|
17
|
+
{ uid: 'foo', destination: 'cm/collectionType/foo', isDisplayed: true },
|
|
18
|
+
{ uid: 'bar', destination: 'cm/collectionType/bar', isDisplayed: true },
|
|
19
|
+
];
|
|
20
|
+
const schemas = [
|
|
21
|
+
{ uid: 'foo', pluginOptions: { i18n: { localized: true } } },
|
|
22
|
+
{ uid: 'bar', pluginOptions: { i18n: { localized: true } } },
|
|
23
|
+
];
|
|
24
|
+
const permissions = {
|
|
25
|
+
foo: {
|
|
26
|
+
'plugins::content-manager.explorer.create': [
|
|
27
|
+
{
|
|
28
|
+
properties: {
|
|
29
|
+
fields: ['name'],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
'plugins::content-manager.explorer.read': [
|
|
34
|
+
{
|
|
35
|
+
properties: {
|
|
36
|
+
fields: ['name'],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
bar: {
|
|
42
|
+
'plugins::content-manager.explorer.create': [
|
|
43
|
+
{
|
|
44
|
+
properties: {
|
|
45
|
+
fields: ['name'],
|
|
46
|
+
locales: [],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
'plugins::content-manager.explorer.read': [
|
|
51
|
+
{
|
|
52
|
+
properties: {
|
|
53
|
+
fields: ['name'],
|
|
54
|
+
locales: [],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
const expected = [
|
|
61
|
+
{ uid: 'foo', destination: 'cm/collectionType/foo', isDisplayed: false },
|
|
62
|
+
{ uid: 'bar', destination: 'cm/collectionType/bar', isDisplayed: false },
|
|
63
|
+
];
|
|
64
|
+
const locales = [{ code: 'en', isDefault: true }, { code: 'fr' }];
|
|
65
|
+
|
|
66
|
+
expect(addLocaleToLinksSearch(links, 'collectionType', schemas, locales, permissions)).toEqual(
|
|
67
|
+
expected
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should add the locale to a link search', () => {
|
|
72
|
+
const links = [
|
|
73
|
+
{ uid: 'foo', destination: 'cm/collectionType/foo', isDisplayed: true, search: 'page=1' },
|
|
74
|
+
{ uid: 'bar', destination: 'cm/collectionType/bar', isDisplayed: true },
|
|
75
|
+
];
|
|
76
|
+
const schemas = [
|
|
77
|
+
{ uid: 'foo', pluginOptions: { i18n: { localized: true } } },
|
|
78
|
+
{ uid: 'bar', pluginOptions: { i18n: { localized: true } } },
|
|
79
|
+
];
|
|
80
|
+
const permissions = {
|
|
81
|
+
foo: {
|
|
82
|
+
'plugins::content-manager.explorer.create': [
|
|
83
|
+
{
|
|
84
|
+
properties: {
|
|
85
|
+
fields: ['name'],
|
|
86
|
+
locales: ['fr'],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
'plugins::content-manager.explorer.read': [
|
|
91
|
+
{
|
|
92
|
+
properties: {
|
|
93
|
+
fields: ['name'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
bar: {
|
|
99
|
+
'plugins::content-manager.explorer.create': [
|
|
100
|
+
{
|
|
101
|
+
properties: {
|
|
102
|
+
fields: ['name'],
|
|
103
|
+
locales: ['fr'],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
'plugins::content-manager.explorer.read': [
|
|
108
|
+
{
|
|
109
|
+
properties: {
|
|
110
|
+
fields: ['name'],
|
|
111
|
+
locales: ['en'],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
const expected = [
|
|
118
|
+
{
|
|
119
|
+
uid: 'foo',
|
|
120
|
+
destination: 'cm/collectionType/foo',
|
|
121
|
+
isDisplayed: true,
|
|
122
|
+
search: 'page=1&plugins[i18n][locale]=fr',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
uid: 'bar',
|
|
126
|
+
destination: 'cm/collectionType/bar',
|
|
127
|
+
isDisplayed: true,
|
|
128
|
+
search: 'plugins[i18n][locale]=en',
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
const locales = [{ code: 'en', isDefault: true }, { code: 'fr' }];
|
|
132
|
+
|
|
133
|
+
expect(addLocaleToLinksSearch(links, 'collectionType', schemas, locales, permissions)).toEqual(
|
|
134
|
+
expected
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const i18nPermissions = {
|
|
2
|
+
accessMain: [{ action: 'plugins::i18n.locale.read', subject: null }],
|
|
3
|
+
create: [{ action: 'plugins::i18n.locale.create', subject: null }],
|
|
4
|
+
delete: [{ action: 'plugins::i18n.locale.delete', subject: null }],
|
|
5
|
+
update: [{ action: 'plugins::i18n.locale.update', subject: null }],
|
|
6
|
+
read: [{ action: 'plugins::i18n.locale.read', subject: null }],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default i18nPermissions;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugin.name": "Internationalization",
|
|
3
|
+
"plugin.description.long": "This plugin enables to create, to read and to update content in different languages, both from the Admin Panel and from the API.",
|
|
4
|
+
"plugin.description.short": "This plugin enables to create, to read and to update content in different languages, both from the Admin Panel and from the API.",
|
|
5
|
+
"Settings.permissions.loading": "Loading permissions",
|
|
6
|
+
"Settings.permissions.read.denied.title": "You don't have the permissions to access this content.",
|
|
7
|
+
"Settings.permissions.read.denied.description": "In order to be able to read this, make sure to get in touch with the administrator of your system.",
|
|
8
|
+
"plugin.schema.i18n.localized.label": "Enable localization for this Content-Type",
|
|
9
|
+
"plugin.schema.i18n.localized.description": "Allow you to have content in different locales",
|
|
10
|
+
"plugin.schema.i18n.localized.label-content-type": "Enable localization for this Content-Type",
|
|
11
|
+
"plugin.schema.i18n.localized.description-content-type": "Allow you to have content in different locales",
|
|
12
|
+
"plugin.schema.i18n.localized.label-field": "Enable localization for this field",
|
|
13
|
+
"plugin.schema.i18n.localized.description-field": "The field can have different values in each locale",
|
|
14
|
+
"plugin.schema.i18n.ensure-unique-localization": "Unique fields must be localized",
|
|
15
|
+
"CheckboxConfirmation.Modal.content": "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing).",
|
|
16
|
+
"CheckboxConfirmation.Modal.body": "Do you want to disable it?",
|
|
17
|
+
"CheckboxConfirmation.Modal.button-confirm": "Yes, disable",
|
|
18
|
+
"CMEditViewCopyLocale.copy-success": "Locale copied",
|
|
19
|
+
"CMEditViewCopyLocale.copy-failure": "Failed to copy locale",
|
|
20
|
+
"CMEditViewCopyLocale.copy-text": "Fill in from another locale",
|
|
21
|
+
"CMEditViewCopyLocale.submit-text": "Yes, fill in",
|
|
22
|
+
"CMEditViewCopyLocale.ModalConfirm.title": "Select Locale",
|
|
23
|
+
"CMEditViewCopyLocale.ModalConfirm.content": "Your current content will be erased and filled by the content of the selected locale:",
|
|
24
|
+
"Field.localized": "This value is unique for the selected locale",
|
|
25
|
+
"Field.not-localized": "This value is common to all locales",
|
|
26
|
+
"Settings.list.description": "Configure the settings for the internationalization plugin",
|
|
27
|
+
"Settings.list.empty.title": "There are no locales.",
|
|
28
|
+
"Settings.list.empty.description": "This is not a usual behavior, meaning that you have eventually modified the database manually. Make sure to have at least one locale saved in your database in order to be able to use Strapi correctly.",
|
|
29
|
+
"Settings.list.actions.add": "Add a locale",
|
|
30
|
+
"Settings.list.actions.edit": "Edit a locale",
|
|
31
|
+
"Settings.list.actions.delete": "Delete a locale",
|
|
32
|
+
"Settings.list.actions.deleteAdditionalInfos": "This will delete the active locale versions <em>(from Internationalization)</em>",
|
|
33
|
+
"Settings.locales.list.title.singular": "{number} Locale",
|
|
34
|
+
"Settings.locales.list.title.plural": "{number} Locales",
|
|
35
|
+
"Settings.locales.row.default-locale": "Default locale",
|
|
36
|
+
"Settings.locales.modal.title": "Configurations",
|
|
37
|
+
"Settings.locales.modal.delete.confirm": "Yes, delete",
|
|
38
|
+
"Settings.locales.modal.delete.message": "Deleting this locale will delete all associated content. If you want to keep some content, make sure to reallocate it to another locale first.",
|
|
39
|
+
"Settings.locales.modal.delete.secondMessage": "Do you want to delete this locale?",
|
|
40
|
+
"Settings.locales.modal.delete.success": "Locale successfully deleted",
|
|
41
|
+
"Settings.locales.modal.edit.confirmation": "Finish",
|
|
42
|
+
"Settings.locales.modal.edit.success": "Locale successfully edited",
|
|
43
|
+
"Settings.locales.modal.edit.tab.label":"Navigating between the I18N base settings and advanced settings",
|
|
44
|
+
"Settings.locales.modal.base": "Base settings",
|
|
45
|
+
"Settings.locales.modal.advanced": "Advanced settings",
|
|
46
|
+
"Settings.locales.modal.advanced.settings": "Settings",
|
|
47
|
+
"Settings.locales.modal.advanced.setAsDefault": "Set as default locale",
|
|
48
|
+
"Settings.locales.modal.advanced.setAsDefault.hint": "One default locale is required, change it by selecting another one",
|
|
49
|
+
"Settings.locales.modal.create.defaultLocales.loading": "Loading the available locales...",
|
|
50
|
+
"Settings.locales.modal.create.confirmation": "Add locale",
|
|
51
|
+
"Settings.locales.modal.create.success": "Locale successfully added",
|
|
52
|
+
"Settings.locales.modal.create.alreadyExist": "This locale already exists",
|
|
53
|
+
"Settings.locales.modal.locales.label": "Locales",
|
|
54
|
+
"Settings.locales.modal.edit.locales.label": "Locales",
|
|
55
|
+
"Settings.locales.modal.locales.displayName": "Locale display name",
|
|
56
|
+
"Settings.locales.modal.locales.displayName.error": "The locale display name can only be less than 50 characters.",
|
|
57
|
+
"Settings.locales.modal.locales.displayName.description":"Locale will be displayed under that name in the administration panel",
|
|
58
|
+
"Settings.locales.modal.create.tab.label":"Navigating between the I18N base settings and advanced settings",
|
|
59
|
+
"components.Select.locales.not-available": "No content available"
|
|
60
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugin.name": "Internationalisation",
|
|
3
|
+
"plugin.description.long": "Créez, lisez et modifiez votre contenu en différentes langues depuis le panel d'administration et votre API.",
|
|
4
|
+
"plugin.description.short": "Créez, lisez et modifiez votre contenu en différentes langues depuis le panel d'administration et votre API.",
|
|
5
|
+
"Settings.list.description": "Configurer les paramètres du plugin d'internationalisation",
|
|
6
|
+
"Settings.locales.list.title.singular": "{number} locale",
|
|
7
|
+
"Settings.locales.list.title.plural": "{number} locales",
|
|
8
|
+
"Settings.locales.row.default-locale": "Locale par défaut"
|
|
9
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugin.name": "国际化 i18n",
|
|
3
|
+
"plugin.description.long": "此插件可以帮助您在后台面板和 API 中管理不同内容的多语言版本。",
|
|
4
|
+
"plugin.description.short": "内容多语言管理",
|
|
5
|
+
"Settings.permissions.loading": "加载权限",
|
|
6
|
+
"Settings.permissions.read.denied.title": "您没有权限来访问该内容",
|
|
7
|
+
"Settings.permissions.read.denied.description": "请联系系统管理员以访问此内容",
|
|
8
|
+
"plugin.schema.i18n.localized.label": "多语言支持",
|
|
9
|
+
"plugin.schema.i18n.localized.description": "开启内容在多语言环境下的区别展示",
|
|
10
|
+
"plugin.schema.i18n.localized.label-content-type": "多语言支持",
|
|
11
|
+
"plugin.schema.i18n.localized.description-content-type": "支持内容在多语言环境下的区别展示",
|
|
12
|
+
"plugin.schema.i18n.localized.label-field": "允许字段的多语言内容",
|
|
13
|
+
"plugin.schema.i18n.localized.description-field": "允许该字段在不同语言中展示不同内容",
|
|
14
|
+
"plugin.schema.i18n.ensure-unique-localization": "唯一字段必须本地化",
|
|
15
|
+
"CheckboxConfirmation.Modal.content": "禁用国际化将会删除已保存的其他语言内容,近保留默认语言包的内容。",
|
|
16
|
+
"CheckboxConfirmation.Modal.body": "确定要禁用吗?",
|
|
17
|
+
"CheckboxConfirmation.Modal.button-confirm": "确认禁用",
|
|
18
|
+
"CMEditViewCopyLocale.copy-success": "语言包内容复制成功",
|
|
19
|
+
"CMEditViewCopyLocale.copy-failure": "语言包内容复制失败",
|
|
20
|
+
"CMEditViewCopyLocale.copy-text": "复制其他语言的内容",
|
|
21
|
+
"CMEditViewCopyLocale.submit-text": "确认覆盖",
|
|
22
|
+
"CMEditViewCopyLocale.ModalConfirm.content": "已有内容将会被清空,并用以下语言的内容覆盖:",
|
|
23
|
+
"CMEditViewCopyLocale.ModalConfirm.title":"选择语言",
|
|
24
|
+
"Field.localized": "每种语言中不同(如:名称)",
|
|
25
|
+
"Field.not-localized": "在各语言中通用(如:价格)",
|
|
26
|
+
"Settings.list.description": "内容多国语言插件设置",
|
|
27
|
+
"Settings.list.empty.title": "没有可用的语言包",
|
|
28
|
+
"Settings.list.empty.description": "产生了非常规行为,您可能手动修改了数据库。 请确保在您的数据库中至少存在一种语言包记录,以便能够正确使用 Strapi。",
|
|
29
|
+
"Settings.list.actions.add": "添加语言包",
|
|
30
|
+
"Settings.list.actions.edit": "编辑语言包",
|
|
31
|
+
"Settings.list.actions.delete": "删除语言包",
|
|
32
|
+
"Settings.list.actions.deleteAdditionalInfos": "此操作将会删除正在使用的语言包 <em>(由国际化插件提供支持)</em>",
|
|
33
|
+
"Settings.locales.list.title.singular": "已有 {number} 个语言包",
|
|
34
|
+
"Settings.locales.list.title.plural": "已有 number} 个语言包",
|
|
35
|
+
"Settings.locales.row.default-locale": "默认语言包",
|
|
36
|
+
"Settings.locales.modal.title": "语言包配置",
|
|
37
|
+
"Settings.locales.modal.delete.confirm": "是的,删除",
|
|
38
|
+
"Settings.locales.modal.delete.message": "删除该语言包会导致相关内容一并删除。如果您想保留相关的内容,请确保已将它们移至其他语言包。",
|
|
39
|
+
"Settings.locales.modal.delete.secondMessage": "是否要删除该语言包?",
|
|
40
|
+
"Settings.locales.modal.delete.success": "语言包已删除",
|
|
41
|
+
"Settings.locales.modal.edit.confirmation": "完成",
|
|
42
|
+
"Settings.locales.modal.edit.success": "语言包编辑成功",
|
|
43
|
+
"Settings.locales.modal.edit.tab.label":"在国际化插件的基础设置和高级设置间的导航",
|
|
44
|
+
"Settings.locales.modal.base": "基础设置",
|
|
45
|
+
"Settings.locales.modal.advanced": "高级设置",
|
|
46
|
+
"Settings.locales.modal.advanced.settings": "设置",
|
|
47
|
+
"Settings.locales.modal.advanced.setAsDefault": "默认语言包",
|
|
48
|
+
"Settings.locales.modal.advanced.setAsDefault.hint": "必须存在一个默认语言包",
|
|
49
|
+
"Settings.locales.modal.create.defaultLocales.loading": "正在加载可用的语言包...",
|
|
50
|
+
"Settings.locales.modal.create.confirmation": "新增语言包",
|
|
51
|
+
"Settings.locales.modal.create.success": "语言包添加成功",
|
|
52
|
+
"Settings.locales.modal.create.alreadyExist": "该语言包已存在",
|
|
53
|
+
"Settings.locales.modal.locales.label": "语言包",
|
|
54
|
+
"Settings.locales.modal.edit.locales.label": "语言包",
|
|
55
|
+
"Settings.locales.modal.locales.displayName": "语言包显示名",
|
|
56
|
+
"Settings.locales.modal.locales.displayName.error": "语言包展示名称最多只能包含50个字符",
|
|
57
|
+
"Settings.locales.modal.locales.displayName.description":"管理面板中该语言包显示的名称",
|
|
58
|
+
"Settings.locales.modal.create.tab.label":"在国际化插件的基础设置和高级设置间的导航",
|
|
59
|
+
"components.Select.locales.not-available": "暂无内容"
|
|
60
|
+
}
|