node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

37
server/node_modules/@strapi/i18n/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,37 @@
Copyright (c) 2015-present Strapi Solutions SAS
Portions of the Strapi software are licensed as follows:
* All software that resides under an "ee/" directory (the “EE Software”), if that directory exists, is licensed under the license defined below.
Enterprise License
If you or the company you represent has entered into a written agreement referencing the Enterprise Edition of the Strapi source code available at
https://github.com/strapi/strapi, then such agreement applies to your use of the Enterprise Edition of the Strapi Software. If you or the company you
represent is using the Enterprise Edition of the Strapi Software in connection with a subscription to our cloud offering, then the agreement you have
agreed to with respect to our cloud offering and the licenses included in such agreement apply to your use of the Enterprise Edition of the Strapi Software.
Otherwise, the Strapi Enterprise Software License Agreement (found here https://strapi.io/enterprise-terms) applies to your use of the Enterprise Edition of the Strapi Software.
BY ACCESSING OR USING THE ENTERPRISE EDITION OF THE STRAPI SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE RELEVANT REFERENCED AGREEMENT.
IF YOU ARE NOT AUTHORIZED TO ACCEPT THESE TERMS ON BEHALF OF THE COMPANY YOU REPRESENT OR IF YOU DO NOT AGREE TO ALL OF THE RELEVANT TERMS AND CONDITIONS REFERENCED AND YOU
HAVE NOT OTHERWISE EXECUTED A WRITTEN AGREEMENT WITH STRAPI, YOU ARE NOT AUTHORIZED TO ACCESS OR USE OR ALLOW ANY USER TO ACCESS OR USE ANY PART OF
THE ENTERPRISE EDITION OF THE STRAPI SOFTWARE. YOUR ACCESS RIGHTS ARE CONDITIONAL ON YOUR CONSENT TO THE RELEVANT REFERENCED TERMS TO THE EXCLUSION OF ALL OTHER TERMS;
IF THE RELEVANT REFERENCED TERMS ARE CONSIDERED AN OFFER BY YOU, ACCEPTANCE IS EXPRESSLY LIMITED TO THE RELEVANT REFERENCED TERMS.
* All software outside of the above-mentioned directories or restrictions above is available under the "MIT Expat" license as set forth below.
MIT Expat License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

17
server/node_modules/@strapi/i18n/README.md generated vendored Normal file
View File

@@ -0,0 +1,17 @@
# Strapi plugin i18n
The Internationalization (i18n) plugin allows Strapi users to create, manage and distribute localized content in different languages, called "locales". For more information about the concept of internationalization, please refer to the [W3C definition](https://www.w3.org/International/questions/qa-i18n.en#i18n).
## Features
- Admin panel users can create several localized versions of their content
- Developers can build localized projects by fetching and consuming the right content depending on the country/language of the audience
## Installation
This plugin is pre-installed & required with strapi
## Documentation
- [Developer documentation](https://docs.strapi.io/developer-docs/latest/plugins/i18n.html#installation)
- [User documentation](https://docs.strapi.io/user-docs/latest/content-manager/translating-content.html)

View File

@@ -0,0 +1,262 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var qs = require('qs');
var reactIntl = require('react-intl');
var reactRouterDom = require('react-router-dom');
var getTranslation = require('../utils/getTranslation.js');
var strings = require('../utils/strings.js');
const isErrorMessageDescriptor = (object)=>{
return typeof object === 'object' && object !== null && 'id' in object && 'defaultMessage' in object;
};
const EntryValidationText = ({ status = 'draft', validationErrors, action })=>{
const { formatMessage } = reactIntl.useIntl();
/**
* TODO: Should this be extracted an made into a factory to recursively get
* error messages??
*/ const getErrorStr = (key, value)=>{
if (typeof value === 'string') {
return `${key}: ${value}`;
} else if (isErrorMessageDescriptor(value)) {
return `${key}: ${formatMessage(value)}`;
} else if (Array.isArray(value)) {
return value.map((v)=>getErrorStr(key, v)).join(' ');
} else if (typeof value === 'object' && !Array.isArray(value)) {
return Object.entries(value).map(([k, v])=>getErrorStr(k, v)).join(' ');
} else {
/**
* unlikely to happen, but we need to return something
*/ return '';
}
};
if (validationErrors) {
const validationErrorsMessages = Object.entries(validationErrors).map(([key, value])=>{
return getErrorStr(key, value);
}).join(' ');
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
gap: 2,
children: [
/*#__PURE__*/ jsxRuntime.jsx(icons.CrossCircle, {
fill: "danger600"
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tooltip, {
label: validationErrorsMessages,
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
maxWidth: '30rem',
textColor: "danger600",
variant: "omega",
fontWeight: "semiBold",
ellipsis: true,
children: validationErrorsMessages
})
})
]
});
}
const getStatusMessage = ()=>{
if (action === 'bulk-publish') {
if (status === 'published') {
return {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'content-manager.bulk-publish.already-published',
defaultMessage: 'Already Published'
}),
textColor: 'success600',
fontWeight: 'bold'
};
} else if (status === 'modified') {
return {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.ArrowsCounterClockwise, {
fill: "alternative600"
}),
text: formatMessage({
id: 'app.utils.ready-to-publish-changes',
defaultMessage: 'Ready to publish changes'
})
};
} else {
return {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'app.utils.ready-to-publish',
defaultMessage: 'Ready to publish'
})
};
}
} else {
if (status === 'draft') {
return {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'content-manager.bulk-unpublish.already-unpublished',
defaultMessage: 'Already Unpublished'
}),
textColor: 'success600',
fontWeight: 'bold'
};
} else {
return {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'app.utils.ready-to-unpublish-changes',
defaultMessage: 'Ready to unpublish'
}),
textColor: 'success600',
fontWeight: 'bold'
};
}
}
};
const { icon, text, textColor = 'success600', fontWeight = 'normal' } = getStatusMessage();
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
gap: 2,
children: [
icon,
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: textColor,
fontWeight: fontWeight,
children: text
})
]
});
};
/* -------------------------------------------------------------------------------------------------
* BoldChunk
* -----------------------------------------------------------------------------------------------*/ const BoldChunk = (chunks)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
fontWeight: "bold",
children: chunks
});
const BulkLocaleActionModal = ({ headers, rows, localesMetadata, validationErrors = {}, action })=>{
const { formatMessage } = reactIntl.useIntl();
const selectedRows = strapiAdmin.useTable('BulkLocaleActionModal', (state)=>state.selectedRows);
const getFormattedCountMessage = ()=>{
const currentStatusByLocale = rows.reduce((acc, { locale, status })=>{
acc[locale] = status;
return acc;
}, {});
const localesWithErrors = Object.keys(validationErrors);
const publishedCount = selectedRows.filter(({ locale })=>currentStatusByLocale[locale] === 'published').length;
const draftCount = selectedRows.filter(({ locale })=>(currentStatusByLocale[locale] === 'draft' || currentStatusByLocale[locale] === 'modified') && !localesWithErrors.includes(locale)).length;
const withErrorsCount = localesWithErrors.length;
const messageId = action === 'bulk-publish' ? 'content-manager.containers.list.selectedEntriesModal.selectedCount.publish' : 'content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish';
const defaultMessage = action === 'bulk-publish' ? '<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action.' : '<b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} already unpublished. <b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} ready to unpublish.';
return formatMessage({
id: messageId,
defaultMessage
}, {
withErrorsCount,
draftCount,
publishedCount,
b: BoldChunk
});
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Body, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: getFormattedCountMessage()
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
marginTop: 5,
children: /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Table.Content, {
children: [
/*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Table.Head, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
headers.map((head)=>/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, {
...head
}, head.name))
]
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.Body, {
children: rows.map(({ locale, status }, index)=>{
const error = validationErrors?.[locale] ?? null;
const statusVariant = status === 'draft' ? 'primary' : status === 'published' ? 'success' : 'alternative';
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Table.Row, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, {
id: locale,
"aria-label": `Select ${locale}`
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.Cell, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: Array.isArray(localesMetadata) ? localesMetadata.find((localeEntry)=>localeEntry.code === locale)?.name : locale
})
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.Cell, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
display: "flex",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Status, {
display: "flex",
paddingLeft: "6px",
paddingRight: "6px",
paddingTop: "2px",
paddingBottom: "2px",
size: 'S',
variant: statusVariant,
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
tag: "span",
variant: "pi",
fontWeight: "bold",
children: strings.capitalize(status)
})
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.Cell, {
children: /*#__PURE__*/ jsxRuntime.jsx(EntryValidationText, {
validationErrors: error,
status: status,
action: action
})
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.Cell, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
tag: reactRouterDom.Link,
to: {
search: qs.stringify({
plugins: {
i18n: {
locale
}
}
})
},
label: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.edit'),
defaultMessage: 'Edit {name} locale'
}, {
name: locale
}),
variant: "ghost",
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Pencil, {})
})
})
]
}, index);
})
})
]
})
})
]
});
};
exports.BulkLocaleActionModal = BulkLocaleActionModal;
//# sourceMappingURL=BulkLocaleActionModal.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,260 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import 'react';
import { useTable, Table } from '@strapi/admin/strapi-admin';
import { Modal, Typography, Box, Status, IconButton, Flex, Tooltip } from '@strapi/design-system';
import { Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise } from '@strapi/icons';
import { stringify } from 'qs';
import { useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { getTranslation } from '../utils/getTranslation.mjs';
import { capitalize } from '../utils/strings.mjs';
const isErrorMessageDescriptor = (object)=>{
return typeof object === 'object' && object !== null && 'id' in object && 'defaultMessage' in object;
};
const EntryValidationText = ({ status = 'draft', validationErrors, action })=>{
const { formatMessage } = useIntl();
/**
* TODO: Should this be extracted an made into a factory to recursively get
* error messages??
*/ const getErrorStr = (key, value)=>{
if (typeof value === 'string') {
return `${key}: ${value}`;
} else if (isErrorMessageDescriptor(value)) {
return `${key}: ${formatMessage(value)}`;
} else if (Array.isArray(value)) {
return value.map((v)=>getErrorStr(key, v)).join(' ');
} else if (typeof value === 'object' && !Array.isArray(value)) {
return Object.entries(value).map(([k, v])=>getErrorStr(k, v)).join(' ');
} else {
/**
* unlikely to happen, but we need to return something
*/ return '';
}
};
if (validationErrors) {
const validationErrorsMessages = Object.entries(validationErrors).map(([key, value])=>{
return getErrorStr(key, value);
}).join(' ');
return /*#__PURE__*/ jsxs(Flex, {
gap: 2,
children: [
/*#__PURE__*/ jsx(CrossCircle, {
fill: "danger600"
}),
/*#__PURE__*/ jsx(Tooltip, {
label: validationErrorsMessages,
children: /*#__PURE__*/ jsx(Typography, {
maxWidth: '30rem',
textColor: "danger600",
variant: "omega",
fontWeight: "semiBold",
ellipsis: true,
children: validationErrorsMessages
})
})
]
});
}
const getStatusMessage = ()=>{
if (action === 'bulk-publish') {
if (status === 'published') {
return {
icon: /*#__PURE__*/ jsx(CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'content-manager.bulk-publish.already-published',
defaultMessage: 'Already Published'
}),
textColor: 'success600',
fontWeight: 'bold'
};
} else if (status === 'modified') {
return {
icon: /*#__PURE__*/ jsx(ArrowsCounterClockwise, {
fill: "alternative600"
}),
text: formatMessage({
id: 'app.utils.ready-to-publish-changes',
defaultMessage: 'Ready to publish changes'
})
};
} else {
return {
icon: /*#__PURE__*/ jsx(CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'app.utils.ready-to-publish',
defaultMessage: 'Ready to publish'
})
};
}
} else {
if (status === 'draft') {
return {
icon: /*#__PURE__*/ jsx(CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'content-manager.bulk-unpublish.already-unpublished',
defaultMessage: 'Already Unpublished'
}),
textColor: 'success600',
fontWeight: 'bold'
};
} else {
return {
icon: /*#__PURE__*/ jsx(CheckCircle, {
fill: "success600"
}),
text: formatMessage({
id: 'app.utils.ready-to-unpublish-changes',
defaultMessage: 'Ready to unpublish'
}),
textColor: 'success600',
fontWeight: 'bold'
};
}
}
};
const { icon, text, textColor = 'success600', fontWeight = 'normal' } = getStatusMessage();
return /*#__PURE__*/ jsxs(Flex, {
gap: 2,
children: [
icon,
/*#__PURE__*/ jsx(Typography, {
textColor: textColor,
fontWeight: fontWeight,
children: text
})
]
});
};
/* -------------------------------------------------------------------------------------------------
* BoldChunk
* -----------------------------------------------------------------------------------------------*/ const BoldChunk = (chunks)=>/*#__PURE__*/ jsx(Typography, {
fontWeight: "bold",
children: chunks
});
const BulkLocaleActionModal = ({ headers, rows, localesMetadata, validationErrors = {}, action })=>{
const { formatMessage } = useIntl();
const selectedRows = useTable('BulkLocaleActionModal', (state)=>state.selectedRows);
const getFormattedCountMessage = ()=>{
const currentStatusByLocale = rows.reduce((acc, { locale, status })=>{
acc[locale] = status;
return acc;
}, {});
const localesWithErrors = Object.keys(validationErrors);
const publishedCount = selectedRows.filter(({ locale })=>currentStatusByLocale[locale] === 'published').length;
const draftCount = selectedRows.filter(({ locale })=>(currentStatusByLocale[locale] === 'draft' || currentStatusByLocale[locale] === 'modified') && !localesWithErrors.includes(locale)).length;
const withErrorsCount = localesWithErrors.length;
const messageId = action === 'bulk-publish' ? 'content-manager.containers.list.selectedEntriesModal.selectedCount.publish' : 'content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish';
const defaultMessage = action === 'bulk-publish' ? '<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action.' : '<b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} already unpublished. <b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} ready to unpublish.';
return formatMessage({
id: messageId,
defaultMessage
}, {
withErrorsCount,
draftCount,
publishedCount,
b: BoldChunk
});
};
return /*#__PURE__*/ jsxs(Modal.Body, {
children: [
/*#__PURE__*/ jsx(Typography, {
children: getFormattedCountMessage()
}),
/*#__PURE__*/ jsx(Box, {
marginTop: 5,
children: /*#__PURE__*/ jsxs(Table.Content, {
children: [
/*#__PURE__*/ jsxs(Table.Head, {
children: [
/*#__PURE__*/ jsx(Table.HeaderCheckboxCell, {}),
headers.map((head)=>/*#__PURE__*/ jsx(Table.HeaderCell, {
...head
}, head.name))
]
}),
/*#__PURE__*/ jsx(Table.Body, {
children: rows.map(({ locale, status }, index)=>{
const error = validationErrors?.[locale] ?? null;
const statusVariant = status === 'draft' ? 'primary' : status === 'published' ? 'success' : 'alternative';
return /*#__PURE__*/ jsxs(Table.Row, {
children: [
/*#__PURE__*/ jsx(Table.CheckboxCell, {
id: locale,
"aria-label": `Select ${locale}`
}),
/*#__PURE__*/ jsx(Table.Cell, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: Array.isArray(localesMetadata) ? localesMetadata.find((localeEntry)=>localeEntry.code === locale)?.name : locale
})
}),
/*#__PURE__*/ jsx(Table.Cell, {
children: /*#__PURE__*/ jsx(Box, {
display: "flex",
children: /*#__PURE__*/ jsx(Status, {
display: "flex",
paddingLeft: "6px",
paddingRight: "6px",
paddingTop: "2px",
paddingBottom: "2px",
size: 'S',
variant: statusVariant,
children: /*#__PURE__*/ jsx(Typography, {
tag: "span",
variant: "pi",
fontWeight: "bold",
children: capitalize(status)
})
})
})
}),
/*#__PURE__*/ jsx(Table.Cell, {
children: /*#__PURE__*/ jsx(EntryValidationText, {
validationErrors: error,
status: status,
action: action
})
}),
/*#__PURE__*/ jsx(Table.Cell, {
children: /*#__PURE__*/ jsx(IconButton, {
tag: Link,
to: {
search: stringify({
plugins: {
i18n: {
locale
}
}
})
},
label: formatMessage({
id: getTranslation('Settings.list.actions.edit'),
defaultMessage: 'Edit {name} locale'
}, {
name: locale
}),
variant: "ghost",
children: /*#__PURE__*/ jsx(Pencil, {})
})
})
]
}, index);
})
})
]
})
})
]
});
};
export { BulkLocaleActionModal };
//# sourceMappingURL=BulkLocaleActionModal.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,721 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var query = require('@reduxjs/toolkit/query');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var strapiAdmin$1 = require('@strapi/content-manager/strapi-admin');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var reactRouterDom = require('react-router-dom');
var styledComponents = require('styled-components');
var useI18n = require('../hooks/useI18n.js');
var locales = require('../services/locales.js');
var relations = require('../services/relations.js');
var clean = require('../utils/clean.js');
var getTranslation = require('../utils/getTranslation.js');
var strings = require('../utils/strings.js');
var BulkLocaleActionModal = require('./BulkLocaleActionModal.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const statusVariants = {
draft: 'secondary',
published: 'success',
modified: 'alternative'
};
const LocaleOption = ({ isDraftAndPublishEnabled, locale, status, entryExists })=>{
const { formatMessage } = reactIntl.useIntl();
if (!entryExists) {
return formatMessage({
id: getTranslation.getTranslation('CMEditViewLocalePicker.locale.create'),
defaultMessage: 'Create <bold>{locale}</bold> locale'
}, {
bold: (locale)=>/*#__PURE__*/ jsxRuntime.jsx("b", {
children: locale
}),
locale: locale.name
});
}
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
width: "100%",
gap: 1,
justifyContent: "space-between",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: locale.name
}),
isDraftAndPublishEnabled ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.Status, {
display: "flex",
paddingLeft: "6px",
paddingRight: "6px",
paddingTop: "2px",
paddingBottom: "2px",
size: "S",
variant: statusVariants[status],
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
tag: "span",
variant: "pi",
fontWeight: "bold",
children: strings.capitalize(status)
})
}) : null
]
});
};
const LocalePickerAction = ({ document, meta, model, collectionType, documentId })=>{
const { formatMessage } = reactIntl.useIntl();
const [{ query }, setQuery] = strapiAdmin.useQueryParams();
const { hasI18n, canCreate, canRead } = useI18n.useI18n();
const { data: locales$1 = [] } = locales.useGetLocalesQuery();
const currentDesiredLocale = query.plugins?.i18n?.locale;
const { schema } = strapiAdmin$1.unstable_useDocument({
model,
collectionType,
documentId,
params: {
locale: currentDesiredLocale
}
});
const handleSelect = React__namespace.useCallback((value)=>{
setQuery({
plugins: {
...query.plugins,
i18n: {
locale: value
}
}
});
}, [
query.plugins,
setQuery
]);
React__namespace.useEffect(()=>{
if (!Array.isArray(locales$1) || !hasI18n) {
return;
}
/**
* Handle the case where the current locale query param doesn't exist
* in the list of available locales, so we redirect to the default locale.
*/ const doesLocaleExist = locales$1.find((loc)=>loc.code === currentDesiredLocale);
const defaultLocale = locales$1.find((locale)=>locale.isDefault);
if (!doesLocaleExist && defaultLocale?.code) {
handleSelect(defaultLocale.code);
}
}, [
handleSelect,
hasI18n,
locales$1,
currentDesiredLocale
]);
const currentLocale = Array.isArray(locales$1) ? locales$1.find((locale)=>locale.code === currentDesiredLocale) : undefined;
const allCurrentLocales = [
{
status: getDocumentStatus(document, meta),
locale: currentLocale?.code
},
...document?.localizations ?? []
];
if (!hasI18n || !Array.isArray(locales$1) || locales$1.length === 0) {
return null;
}
const displayedLocales = locales$1.filter((locale)=>{
/**
* If you can read we allow you to see the locale exists
* otherwise the locale is hidden.
*/ return canRead.includes(locale.code);
});
return {
label: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.locales.label'),
defaultMessage: 'Locales'
}),
options: displayedLocales.map((locale)=>{
const entryWithLocaleExists = allCurrentLocales.some((doc)=>doc.locale === locale.code);
const currentLocaleDoc = allCurrentLocales.find((doc)=>'locale' in doc ? doc.locale === locale.code : false);
const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
return {
disabled: !permissionsToCheck.includes(locale.code),
value: locale.code,
label: /*#__PURE__*/ jsxRuntime.jsx(LocaleOption, {
isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
locale: locale,
status: currentLocaleDoc?.status,
entryExists: entryWithLocaleExists
}),
startIcon: !entryWithLocaleExists ? /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {}) : null
};
}),
customizeContent: ()=>currentLocale?.name,
onSelect: handleSelect,
value: currentLocale
};
};
const getDocumentStatus = (document, meta)=>{
const docStatus = document?.status;
const statuses = meta?.availableStatus ?? [];
/**
* Creating an entry
*/ if (!docStatus) {
return 'draft';
}
/**
* We're viewing a draft, but the document could have a published version
*/ if (docStatus === 'draft' && statuses.find((doc)=>doc.publishedAt !== null)) {
return 'published';
}
return docStatus;
};
/* -------------------------------------------------------------------------------------------------
* FillFromAnotherLocaleAction
* -----------------------------------------------------------------------------------------------*/ const FillFromAnotherLocaleAction = ({ documentId, meta, model, collectionType })=>{
const { formatMessage } = reactIntl.useIntl();
const [{ query }] = strapiAdmin.useQueryParams();
const { hasI18n } = useI18n.useI18n();
const currentDesiredLocale = query.plugins?.i18n?.locale;
const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
const setValues = strapiAdmin.useForm('FillFromAnotherLocale', (state)=>state.setValues);
const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
const { schema, components } = strapiAdmin$1.unstable_useDocument({
model,
documentId,
collectionType,
params: {
locale: currentDesiredLocale
}
});
const { data: locales$1 = [] } = locales.useGetLocalesQuery();
const availableLocales = Array.isArray(locales$1) ? locales$1.filter((locale)=>meta?.availableLocales.some((l)=>l.locale === locale.code)) : [];
const fillFromLocale = (onClose)=>async ()=>{
const response = await getDocument({
collectionType,
model,
documentId,
params: {
locale: localeSelected
}
});
if (!response || !schema) {
return;
}
const { data } = response;
const cleanedData = clean.cleanData(data, schema, components);
setValues(cleanedData);
onClose();
};
if (!hasI18n) {
return null;
}
return {
type: 'icon',
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.Earth, {}),
disabled: availableLocales.length === 0,
label: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.copy-text'),
defaultMessage: 'Fill in from another locale'
}),
dialog: {
type: 'dialog',
title: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.dialog.title'),
defaultMessage: 'Confirmation'
}),
content: ({ onClose })=>/*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Body, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
gap: 3,
children: [
/*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {
width: "24px",
height: "24px",
fill: "danger600"
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textAlign: "center",
children: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.dialog.body'),
defaultMessage: 'Your current content will be erased and filled by the content of the selected locale:'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
width: "100%",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
children: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.dialog.field.label'),
defaultMessage: 'Locale'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelect, {
value: localeSelected,
placeholder: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.dialog.field.placeholder'),
defaultMessage: 'Select one locale...'
}),
// @ts-expect-error the DS will handle numbers, but we're not allowing the API.
onChange: (value)=>setLocaleSelected(value),
children: availableLocales.map((locale)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
value: locale.code,
children: locale.name
}, locale.code))
})
]
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Footer, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
gap: 2,
width: "100%",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
flex: "auto",
variant: "tertiary",
onClick: onClose,
children: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.cancel-text'),
defaultMessage: 'No, cancel'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
flex: "auto",
variant: "success",
onClick: fillFromLocale(onClose),
children: formatMessage({
id: getTranslation.getTranslation('CMEditViewCopyLocale.submit-text'),
defaultMessage: 'Yes, fill in'
})
})
]
})
})
]
})
}
};
};
/* -------------------------------------------------------------------------------------------------
* DeleteLocaleAction
* -----------------------------------------------------------------------------------------------*/ const DeleteLocaleAction = ({ document, documentId, model, collectionType })=>{
const { formatMessage } = reactIntl.useIntl();
const navigate = reactRouterDom.useNavigate();
const { toggleNotification } = strapiAdmin.useNotification();
const { delete: deleteAction, isLoading } = strapiAdmin$1.unstable_useDocumentActions();
const { hasI18n, canDelete } = useI18n.useI18n();
// Get the current locale object, using the URL instead of document so it works while creating
const [{ query }] = strapiAdmin.useQueryParams();
const { data: locales$1 = [] } = locales.useGetLocalesQuery();
const currentDesiredLocale = query.plugins?.i18n?.locale;
const locale = !('error' in locales$1) && locales$1.find((loc)=>loc.code === currentDesiredLocale);
if (!hasI18n) {
return null;
}
return {
disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
position: [
'header',
'table-row'
],
label: formatMessage({
id: getTranslation.getTranslation('actions.delete.label'),
defaultMessage: 'Delete entry ({locale})'
}, {
locale: locale && locale.name
}),
icon: /*#__PURE__*/ jsxRuntime.jsx(StyledTrash, {}),
variant: 'danger',
dialog: {
type: 'dialog',
title: formatMessage({
id: getTranslation.getTranslation('actions.delete.dialog.title'),
defaultMessage: 'Confirmation'
}),
content: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
gap: 2,
children: [
/*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {
width: "24px",
height: "24px",
fill: "danger600"
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
tag: "p",
variant: "omega",
textAlign: "center",
children: formatMessage({
id: getTranslation.getTranslation('actions.delete.dialog.body'),
defaultMessage: 'Are you sure?'
})
})
]
}),
loading: isLoading,
onConfirm: async ()=>{
const unableToDelete = // We are unable to delete a collection type without a document ID
// & unable to delete generally if there is no document locale
collectionType !== 'single-types' && !documentId || !document?.locale;
if (unableToDelete) {
console.error("You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue.");
toggleNotification({
message: formatMessage({
id: getTranslation.getTranslation('actions.delete.error'),
defaultMessage: 'An error occurred while trying to delete the document locale.'
}),
type: 'danger'
});
return;
}
const res = await deleteAction({
documentId,
model,
collectionType,
params: {
locale: document.locale
}
});
if (!('error' in res)) {
navigate({
pathname: `../${collectionType}/${model}`
}, {
replace: true
});
}
}
}
};
};
/* -------------------------------------------------------------------------------------------------
* BulkLocaleAction
*
* This component is used to handle bulk publish and unpublish actions on locales.
* -----------------------------------------------------------------------------------------------*/ const BulkLocaleAction = ({ document, documentId, model, collectionType, action })=>{
const locale = document?.locale ?? null;
const [{ query: query$1 }] = strapiAdmin.useQueryParams();
const params = React__namespace.useMemo(()=>strapiAdmin$1.buildValidParams(query$1), [
query$1
]);
const isOnPublishedTab = query$1.status === 'published';
const { formatMessage } = reactIntl.useIntl();
const { hasI18n, canPublish } = useI18n.useI18n();
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
const [selectedRows, setSelectedRows] = React__namespace.useState([]);
const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
const { schema, validate } = strapiAdmin$1.unstable_useDocument({
model,
collectionType,
documentId,
params: {
locale
}
}, {
// No need to fetch the document, the data is already available in the `document` prop
skip: true
});
const { data: localesMetadata = [] } = locales.useGetLocalesQuery(hasI18n ? undefined : query.skipToken);
const headers = [
{
label: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
}),
name: 'name'
},
{
label: formatMessage({
id: getTranslation.getTranslation('CMEditViewBulkLocale.status'),
defaultMessage: 'Status'
}),
name: 'status'
},
{
label: formatMessage({
id: getTranslation.getTranslation('CMEditViewBulkLocale.publication-status'),
defaultMessage: 'Publication Status'
}),
name: 'publication-status'
}
];
// Extract the rows for the bulk locale publish modal and any validation
// errors per locale
const [rows, validationErrors] = React__namespace.useMemo(()=>{
if (!document) {
return [
[],
{}
];
}
const localizations = document.localizations ?? [];
// Build the rows for the bulk locale publish modal by combining the current
// document with all the available locales from the document meta
const locales = localizations.map((doc)=>{
const { locale, status } = doc;
return {
locale,
status
};
});
// Add the current document locale
locales.unshift({
locale: document.locale,
status: document.status
});
// Build the validation errors for each locale.
const allDocuments = [
document,
...localizations
];
const errors = allDocuments.reduce((errs, document)=>{
if (!document) {
return errs;
}
// Validate each locale entry via the useDocument validate function and store any errors in a dictionary
const validation = validate(document);
if (validation !== null) {
errs[document.locale] = validation;
}
return errs;
}, {});
return [
locales,
errors
];
}, [
document,
validate
]);
const isBulkPublish = action === 'bulk-publish';
const localesForAction = selectedRows.reduce((acc, selectedRow)=>{
const isValidLocale = // Validation errors are irrelevant if we are trying to unpublish
!isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale);
const shouldAddLocale = isBulkPublish ? selectedRow.status !== 'published' && isValidLocale : selectedRow.status !== 'draft' && isValidLocale;
if (shouldAddLocale) {
acc.push(selectedRow.locale);
}
return acc;
}, []);
// TODO skipping this for now as there is a bug with the draft relation count that will be worked on separately
// see https://www.notion.so/strapi/Count-draft-relations-56901b492efb45ab90d42fe975b32bd8?pvs=4
const enableDraftRelationsCount = false;
const { data: draftRelationsCount = 0, isLoading: isDraftRelationsLoading, error: isDraftRelationsError } = relations.useGetManyDraftRelationCountQuery({
model,
documentIds: [
documentId
],
locale: localesForAction
}, {
skip: !enableDraftRelationsCount
});
React__namespace.useEffect(()=>{
if (isDraftRelationsError) {
toggleNotification({
type: 'danger',
message: formatAPIError(isDraftRelationsError)
});
}
}, [
isDraftRelationsError,
toggleNotification,
formatAPIError
]);
if (!schema?.options?.draftAndPublish) {
return null;
}
if (!hasI18n) {
return null;
}
if (!documentId) {
return null;
}
// This document action can be enabled given that draft and publish and i18n are
// enabled and we can publish the current locale.
const publish = async ()=>{
await publishManyAction({
model,
documentIds: [
documentId
],
params: {
...params,
locale: localesForAction
}
});
setSelectedRows([]);
};
const unpublish = async ()=>{
await unpublishManyAction({
model,
documentIds: [
documentId
],
params: {
...params,
locale: localesForAction
}
});
setSelectedRows([]);
};
const handleAction = async ()=>{
if (draftRelationsCount > 0) {
setIsDraftRelationConfirmationOpen(true);
} else if (isBulkPublish) {
await publish();
} else {
await unpublish();
}
};
if (isDraftRelationConfirmationOpen) {
return {
label: formatMessage({
id: 'app.components.ConfirmDialog.title',
defaultMessage: 'Confirmation'
}),
variant: 'danger',
dialog: {
onCancel: ()=>{
setIsDraftRelationConfirmationOpen(false);
},
onConfirm: async ()=>{
await publish();
setIsDraftRelationConfirmationOpen(false);
},
type: 'dialog',
title: formatMessage({
id: getTranslation.getTranslation('actions.publish.dialog.title'),
defaultMessage: 'Confirmation'
}),
content: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "center",
gap: 2,
children: [
/*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {
width: "2.4rem",
height: "2.4rem",
fill: "danger600"
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textAlign: "center",
children: formatMessage({
id: getTranslation.getTranslation('CMEditViewBulkLocale.draft-relation-warning'),
defaultMessage: 'Some locales are related to draft entries. Publishing them could leave broken links in your app.'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textAlign: "center",
children: formatMessage({
id: getTranslation.getTranslation('CMEditViewBulkLocale.continue-confirmation'),
defaultMessage: 'Are you sure you want to continue?'
})
})
]
})
}
};
}
const hasPermission = selectedRows.map(({ locale })=>locale).every((locale)=>canPublish.includes(locale));
return {
label: formatMessage({
id: getTranslation.getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? 'publish' : 'unpublish'}-title`),
defaultMessage: `${isBulkPublish ? 'Publish' : 'Unpublish'} Multiple Locales`
}),
variant: isBulkPublish ? 'secondary' : 'danger',
icon: isBulkPublish ? /*#__PURE__*/ jsxRuntime.jsx(icons.ListPlus, {}) : /*#__PURE__*/ jsxRuntime.jsx(icons.Cross, {}),
disabled: isOnPublishedTab || canPublish.length === 0,
position: [
'panel'
],
dialog: {
type: 'modal',
title: formatMessage({
id: getTranslation.getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? 'publish' : 'unpublish'}-title`),
defaultMessage: `${isBulkPublish ? 'Publish' : 'Unpublish'} Multiple Locales`
}),
content: ()=>{
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Table.Root, {
headers: headers,
rows: rows.map((row)=>({
...row,
id: row.locale
})),
selectedRows: selectedRows,
onSelectedRowsChange: (tableSelectedRows)=>setSelectedRows(tableSelectedRows),
children: /*#__PURE__*/ jsxRuntime.jsx(BulkLocaleActionModal.BulkLocaleActionModal, {
validationErrors: validationErrors,
headers: headers,
rows: rows,
localesMetadata: localesMetadata,
action: action ?? 'bulk-publish'
})
});
},
footer: ()=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Footer, {
justifyContent: "flex-end",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
loading: isDraftRelationsLoading,
disabled: !hasPermission || localesForAction.length === 0,
variant: "default",
onClick: handleAction,
children: formatMessage({
id: isBulkPublish ? 'app.utils.publish' : 'app.utils.unpublish',
defaultMessage: isBulkPublish ? 'Publish' : 'Unpublish'
})
})
})
}
};
};
/* -------------------------------------------------------------------------------------------------
* BulkLocalePublishAction
* -----------------------------------------------------------------------------------------------*/ const BulkLocalePublishAction = (props)=>{
return BulkLocaleAction({
action: 'bulk-publish',
...props
});
};
/* -------------------------------------------------------------------------------------------------
* BulkLocaleUnpublishAction
* -----------------------------------------------------------------------------------------------*/ const BulkLocaleUnpublishAction = (props)=>{
return BulkLocaleAction({
action: 'bulk-unpublish',
...props
});
};
/**
* Because the icon system is completely broken, we have to do
* this to remove the fill from the cog.
*/ const StyledTrash = styledComponents.styled(icons.Trash)`
path {
fill: currentColor;
}
`;
exports.BulkLocalePublishAction = BulkLocalePublishAction;
exports.BulkLocaleUnpublishAction = BulkLocaleUnpublishAction;
exports.DeleteLocaleAction = DeleteLocaleAction;
exports.FillFromAnotherLocaleAction = FillFromAnotherLocaleAction;
exports.LocalePickerAction = LocalePickerAction;
//# sourceMappingURL=CMHeaderActions.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,696 @@
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import * as React from 'react';
import { skipToken } from '@reduxjs/toolkit/query';
import { useQueryParams, useForm, useNotification, useAPIErrorHandler, Table } from '@strapi/admin/strapi-admin';
import { unstable_useDocument, unstable_useDocumentActions, buildValidParams } from '@strapi/content-manager/strapi-admin';
import { Dialog, Flex, Typography, Field, SingleSelect, SingleSelectOption, Button, Status, Modal } from '@strapi/design-system';
import { Trash, Plus, Earth, WarningCircle, ListPlus, Cross } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useNavigate } from 'react-router-dom';
import { styled } from 'styled-components';
import { useI18n } from '../hooks/useI18n.mjs';
import { useGetLocalesQuery } from '../services/locales.mjs';
import { useGetManyDraftRelationCountQuery } from '../services/relations.mjs';
import { cleanData } from '../utils/clean.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
import { capitalize } from '../utils/strings.mjs';
import { BulkLocaleActionModal } from './BulkLocaleActionModal.mjs';
const statusVariants = {
draft: 'secondary',
published: 'success',
modified: 'alternative'
};
const LocaleOption = ({ isDraftAndPublishEnabled, locale, status, entryExists })=>{
const { formatMessage } = useIntl();
if (!entryExists) {
return formatMessage({
id: getTranslation('CMEditViewLocalePicker.locale.create'),
defaultMessage: 'Create <bold>{locale}</bold> locale'
}, {
bold: (locale)=>/*#__PURE__*/ jsx("b", {
children: locale
}),
locale: locale.name
});
}
return /*#__PURE__*/ jsxs(Flex, {
width: "100%",
gap: 1,
justifyContent: "space-between",
children: [
/*#__PURE__*/ jsx(Typography, {
children: locale.name
}),
isDraftAndPublishEnabled ? /*#__PURE__*/ jsx(Status, {
display: "flex",
paddingLeft: "6px",
paddingRight: "6px",
paddingTop: "2px",
paddingBottom: "2px",
size: "S",
variant: statusVariants[status],
children: /*#__PURE__*/ jsx(Typography, {
tag: "span",
variant: "pi",
fontWeight: "bold",
children: capitalize(status)
})
}) : null
]
});
};
const LocalePickerAction = ({ document, meta, model, collectionType, documentId })=>{
const { formatMessage } = useIntl();
const [{ query }, setQuery] = useQueryParams();
const { hasI18n, canCreate, canRead } = useI18n();
const { data: locales = [] } = useGetLocalesQuery();
const currentDesiredLocale = query.plugins?.i18n?.locale;
const { schema } = unstable_useDocument({
model,
collectionType,
documentId,
params: {
locale: currentDesiredLocale
}
});
const handleSelect = React.useCallback((value)=>{
setQuery({
plugins: {
...query.plugins,
i18n: {
locale: value
}
}
});
}, [
query.plugins,
setQuery
]);
React.useEffect(()=>{
if (!Array.isArray(locales) || !hasI18n) {
return;
}
/**
* Handle the case where the current locale query param doesn't exist
* in the list of available locales, so we redirect to the default locale.
*/ const doesLocaleExist = locales.find((loc)=>loc.code === currentDesiredLocale);
const defaultLocale = locales.find((locale)=>locale.isDefault);
if (!doesLocaleExist && defaultLocale?.code) {
handleSelect(defaultLocale.code);
}
}, [
handleSelect,
hasI18n,
locales,
currentDesiredLocale
]);
const currentLocale = Array.isArray(locales) ? locales.find((locale)=>locale.code === currentDesiredLocale) : undefined;
const allCurrentLocales = [
{
status: getDocumentStatus(document, meta),
locale: currentLocale?.code
},
...document?.localizations ?? []
];
if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
return null;
}
const displayedLocales = locales.filter((locale)=>{
/**
* If you can read we allow you to see the locale exists
* otherwise the locale is hidden.
*/ return canRead.includes(locale.code);
});
return {
label: formatMessage({
id: getTranslation('Settings.locales.modal.locales.label'),
defaultMessage: 'Locales'
}),
options: displayedLocales.map((locale)=>{
const entryWithLocaleExists = allCurrentLocales.some((doc)=>doc.locale === locale.code);
const currentLocaleDoc = allCurrentLocales.find((doc)=>'locale' in doc ? doc.locale === locale.code : false);
const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
return {
disabled: !permissionsToCheck.includes(locale.code),
value: locale.code,
label: /*#__PURE__*/ jsx(LocaleOption, {
isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
locale: locale,
status: currentLocaleDoc?.status,
entryExists: entryWithLocaleExists
}),
startIcon: !entryWithLocaleExists ? /*#__PURE__*/ jsx(Plus, {}) : null
};
}),
customizeContent: ()=>currentLocale?.name,
onSelect: handleSelect,
value: currentLocale
};
};
const getDocumentStatus = (document, meta)=>{
const docStatus = document?.status;
const statuses = meta?.availableStatus ?? [];
/**
* Creating an entry
*/ if (!docStatus) {
return 'draft';
}
/**
* We're viewing a draft, but the document could have a published version
*/ if (docStatus === 'draft' && statuses.find((doc)=>doc.publishedAt !== null)) {
return 'published';
}
return docStatus;
};
/* -------------------------------------------------------------------------------------------------
* FillFromAnotherLocaleAction
* -----------------------------------------------------------------------------------------------*/ const FillFromAnotherLocaleAction = ({ documentId, meta, model, collectionType })=>{
const { formatMessage } = useIntl();
const [{ query }] = useQueryParams();
const { hasI18n } = useI18n();
const currentDesiredLocale = query.plugins?.i18n?.locale;
const [localeSelected, setLocaleSelected] = React.useState(null);
const setValues = useForm('FillFromAnotherLocale', (state)=>state.setValues);
const { getDocument } = unstable_useDocumentActions();
const { schema, components } = unstable_useDocument({
model,
documentId,
collectionType,
params: {
locale: currentDesiredLocale
}
});
const { data: locales = [] } = useGetLocalesQuery();
const availableLocales = Array.isArray(locales) ? locales.filter((locale)=>meta?.availableLocales.some((l)=>l.locale === locale.code)) : [];
const fillFromLocale = (onClose)=>async ()=>{
const response = await getDocument({
collectionType,
model,
documentId,
params: {
locale: localeSelected
}
});
if (!response || !schema) {
return;
}
const { data } = response;
const cleanedData = cleanData(data, schema, components);
setValues(cleanedData);
onClose();
};
if (!hasI18n) {
return null;
}
return {
type: 'icon',
icon: /*#__PURE__*/ jsx(Earth, {}),
disabled: availableLocales.length === 0,
label: formatMessage({
id: getTranslation('CMEditViewCopyLocale.copy-text'),
defaultMessage: 'Fill in from another locale'
}),
dialog: {
type: 'dialog',
title: formatMessage({
id: getTranslation('CMEditViewCopyLocale.dialog.title'),
defaultMessage: 'Confirmation'
}),
content: ({ onClose })=>/*#__PURE__*/ jsxs(Fragment, {
children: [
/*#__PURE__*/ jsx(Dialog.Body, {
children: /*#__PURE__*/ jsxs(Flex, {
direction: "column",
gap: 3,
children: [
/*#__PURE__*/ jsx(WarningCircle, {
width: "24px",
height: "24px",
fill: "danger600"
}),
/*#__PURE__*/ jsx(Typography, {
textAlign: "center",
children: formatMessage({
id: getTranslation('CMEditViewCopyLocale.dialog.body'),
defaultMessage: 'Your current content will be erased and filled by the content of the selected locale:'
})
}),
/*#__PURE__*/ jsxs(Field.Root, {
width: "100%",
children: [
/*#__PURE__*/ jsx(Field.Label, {
children: formatMessage({
id: getTranslation('CMEditViewCopyLocale.dialog.field.label'),
defaultMessage: 'Locale'
})
}),
/*#__PURE__*/ jsx(SingleSelect, {
value: localeSelected,
placeholder: formatMessage({
id: getTranslation('CMEditViewCopyLocale.dialog.field.placeholder'),
defaultMessage: 'Select one locale...'
}),
// @ts-expect-error the DS will handle numbers, but we're not allowing the API.
onChange: (value)=>setLocaleSelected(value),
children: availableLocales.map((locale)=>/*#__PURE__*/ jsx(SingleSelectOption, {
value: locale.code,
children: locale.name
}, locale.code))
})
]
})
]
})
}),
/*#__PURE__*/ jsx(Dialog.Footer, {
children: /*#__PURE__*/ jsxs(Flex, {
gap: 2,
width: "100%",
children: [
/*#__PURE__*/ jsx(Button, {
flex: "auto",
variant: "tertiary",
onClick: onClose,
children: formatMessage({
id: getTranslation('CMEditViewCopyLocale.cancel-text'),
defaultMessage: 'No, cancel'
})
}),
/*#__PURE__*/ jsx(Button, {
flex: "auto",
variant: "success",
onClick: fillFromLocale(onClose),
children: formatMessage({
id: getTranslation('CMEditViewCopyLocale.submit-text'),
defaultMessage: 'Yes, fill in'
})
})
]
})
})
]
})
}
};
};
/* -------------------------------------------------------------------------------------------------
* DeleteLocaleAction
* -----------------------------------------------------------------------------------------------*/ const DeleteLocaleAction = ({ document, documentId, model, collectionType })=>{
const { formatMessage } = useIntl();
const navigate = useNavigate();
const { toggleNotification } = useNotification();
const { delete: deleteAction, isLoading } = unstable_useDocumentActions();
const { hasI18n, canDelete } = useI18n();
// Get the current locale object, using the URL instead of document so it works while creating
const [{ query }] = useQueryParams();
const { data: locales = [] } = useGetLocalesQuery();
const currentDesiredLocale = query.plugins?.i18n?.locale;
const locale = !('error' in locales) && locales.find((loc)=>loc.code === currentDesiredLocale);
if (!hasI18n) {
return null;
}
return {
disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
position: [
'header',
'table-row'
],
label: formatMessage({
id: getTranslation('actions.delete.label'),
defaultMessage: 'Delete entry ({locale})'
}, {
locale: locale && locale.name
}),
icon: /*#__PURE__*/ jsx(StyledTrash, {}),
variant: 'danger',
dialog: {
type: 'dialog',
title: formatMessage({
id: getTranslation('actions.delete.dialog.title'),
defaultMessage: 'Confirmation'
}),
content: /*#__PURE__*/ jsxs(Flex, {
direction: "column",
gap: 2,
children: [
/*#__PURE__*/ jsx(WarningCircle, {
width: "24px",
height: "24px",
fill: "danger600"
}),
/*#__PURE__*/ jsx(Typography, {
tag: "p",
variant: "omega",
textAlign: "center",
children: formatMessage({
id: getTranslation('actions.delete.dialog.body'),
defaultMessage: 'Are you sure?'
})
})
]
}),
loading: isLoading,
onConfirm: async ()=>{
const unableToDelete = // We are unable to delete a collection type without a document ID
// & unable to delete generally if there is no document locale
collectionType !== 'single-types' && !documentId || !document?.locale;
if (unableToDelete) {
console.error("You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue.");
toggleNotification({
message: formatMessage({
id: getTranslation('actions.delete.error'),
defaultMessage: 'An error occurred while trying to delete the document locale.'
}),
type: 'danger'
});
return;
}
const res = await deleteAction({
documentId,
model,
collectionType,
params: {
locale: document.locale
}
});
if (!('error' in res)) {
navigate({
pathname: `../${collectionType}/${model}`
}, {
replace: true
});
}
}
}
};
};
/* -------------------------------------------------------------------------------------------------
* BulkLocaleAction
*
* This component is used to handle bulk publish and unpublish actions on locales.
* -----------------------------------------------------------------------------------------------*/ const BulkLocaleAction = ({ document, documentId, model, collectionType, action })=>{
const locale = document?.locale ?? null;
const [{ query }] = useQueryParams();
const params = React.useMemo(()=>buildValidParams(query), [
query
]);
const isOnPublishedTab = query.status === 'published';
const { formatMessage } = useIntl();
const { hasI18n, canPublish } = useI18n();
const { toggleNotification } = useNotification();
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
const [selectedRows, setSelectedRows] = React.useState([]);
const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React.useState(false);
const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = unstable_useDocumentActions();
const { schema, validate } = unstable_useDocument({
model,
collectionType,
documentId,
params: {
locale
}
}, {
// No need to fetch the document, the data is already available in the `document` prop
skip: true
});
const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? undefined : skipToken);
const headers = [
{
label: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
}),
name: 'name'
},
{
label: formatMessage({
id: getTranslation('CMEditViewBulkLocale.status'),
defaultMessage: 'Status'
}),
name: 'status'
},
{
label: formatMessage({
id: getTranslation('CMEditViewBulkLocale.publication-status'),
defaultMessage: 'Publication Status'
}),
name: 'publication-status'
}
];
// Extract the rows for the bulk locale publish modal and any validation
// errors per locale
const [rows, validationErrors] = React.useMemo(()=>{
if (!document) {
return [
[],
{}
];
}
const localizations = document.localizations ?? [];
// Build the rows for the bulk locale publish modal by combining the current
// document with all the available locales from the document meta
const locales = localizations.map((doc)=>{
const { locale, status } = doc;
return {
locale,
status
};
});
// Add the current document locale
locales.unshift({
locale: document.locale,
status: document.status
});
// Build the validation errors for each locale.
const allDocuments = [
document,
...localizations
];
const errors = allDocuments.reduce((errs, document)=>{
if (!document) {
return errs;
}
// Validate each locale entry via the useDocument validate function and store any errors in a dictionary
const validation = validate(document);
if (validation !== null) {
errs[document.locale] = validation;
}
return errs;
}, {});
return [
locales,
errors
];
}, [
document,
validate
]);
const isBulkPublish = action === 'bulk-publish';
const localesForAction = selectedRows.reduce((acc, selectedRow)=>{
const isValidLocale = // Validation errors are irrelevant if we are trying to unpublish
!isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale);
const shouldAddLocale = isBulkPublish ? selectedRow.status !== 'published' && isValidLocale : selectedRow.status !== 'draft' && isValidLocale;
if (shouldAddLocale) {
acc.push(selectedRow.locale);
}
return acc;
}, []);
// TODO skipping this for now as there is a bug with the draft relation count that will be worked on separately
// see https://www.notion.so/strapi/Count-draft-relations-56901b492efb45ab90d42fe975b32bd8?pvs=4
const enableDraftRelationsCount = false;
const { data: draftRelationsCount = 0, isLoading: isDraftRelationsLoading, error: isDraftRelationsError } = useGetManyDraftRelationCountQuery({
model,
documentIds: [
documentId
],
locale: localesForAction
}, {
skip: !enableDraftRelationsCount
});
React.useEffect(()=>{
if (isDraftRelationsError) {
toggleNotification({
type: 'danger',
message: formatAPIError(isDraftRelationsError)
});
}
}, [
isDraftRelationsError,
toggleNotification,
formatAPIError
]);
if (!schema?.options?.draftAndPublish) {
return null;
}
if (!hasI18n) {
return null;
}
if (!documentId) {
return null;
}
// This document action can be enabled given that draft and publish and i18n are
// enabled and we can publish the current locale.
const publish = async ()=>{
await publishManyAction({
model,
documentIds: [
documentId
],
params: {
...params,
locale: localesForAction
}
});
setSelectedRows([]);
};
const unpublish = async ()=>{
await unpublishManyAction({
model,
documentIds: [
documentId
],
params: {
...params,
locale: localesForAction
}
});
setSelectedRows([]);
};
const handleAction = async ()=>{
if (draftRelationsCount > 0) {
setIsDraftRelationConfirmationOpen(true);
} else if (isBulkPublish) {
await publish();
} else {
await unpublish();
}
};
if (isDraftRelationConfirmationOpen) {
return {
label: formatMessage({
id: 'app.components.ConfirmDialog.title',
defaultMessage: 'Confirmation'
}),
variant: 'danger',
dialog: {
onCancel: ()=>{
setIsDraftRelationConfirmationOpen(false);
},
onConfirm: async ()=>{
await publish();
setIsDraftRelationConfirmationOpen(false);
},
type: 'dialog',
title: formatMessage({
id: getTranslation('actions.publish.dialog.title'),
defaultMessage: 'Confirmation'
}),
content: /*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "center",
gap: 2,
children: [
/*#__PURE__*/ jsx(WarningCircle, {
width: "2.4rem",
height: "2.4rem",
fill: "danger600"
}),
/*#__PURE__*/ jsx(Typography, {
textAlign: "center",
children: formatMessage({
id: getTranslation('CMEditViewBulkLocale.draft-relation-warning'),
defaultMessage: 'Some locales are related to draft entries. Publishing them could leave broken links in your app.'
})
}),
/*#__PURE__*/ jsx(Typography, {
textAlign: "center",
children: formatMessage({
id: getTranslation('CMEditViewBulkLocale.continue-confirmation'),
defaultMessage: 'Are you sure you want to continue?'
})
})
]
})
}
};
}
const hasPermission = selectedRows.map(({ locale })=>locale).every((locale)=>canPublish.includes(locale));
return {
label: formatMessage({
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? 'publish' : 'unpublish'}-title`),
defaultMessage: `${isBulkPublish ? 'Publish' : 'Unpublish'} Multiple Locales`
}),
variant: isBulkPublish ? 'secondary' : 'danger',
icon: isBulkPublish ? /*#__PURE__*/ jsx(ListPlus, {}) : /*#__PURE__*/ jsx(Cross, {}),
disabled: isOnPublishedTab || canPublish.length === 0,
position: [
'panel'
],
dialog: {
type: 'modal',
title: formatMessage({
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? 'publish' : 'unpublish'}-title`),
defaultMessage: `${isBulkPublish ? 'Publish' : 'Unpublish'} Multiple Locales`
}),
content: ()=>{
return /*#__PURE__*/ jsx(Table.Root, {
headers: headers,
rows: rows.map((row)=>({
...row,
id: row.locale
})),
selectedRows: selectedRows,
onSelectedRowsChange: (tableSelectedRows)=>setSelectedRows(tableSelectedRows),
children: /*#__PURE__*/ jsx(BulkLocaleActionModal, {
validationErrors: validationErrors,
headers: headers,
rows: rows,
localesMetadata: localesMetadata,
action: action ?? 'bulk-publish'
})
});
},
footer: ()=>/*#__PURE__*/ jsx(Modal.Footer, {
justifyContent: "flex-end",
children: /*#__PURE__*/ jsx(Button, {
loading: isDraftRelationsLoading,
disabled: !hasPermission || localesForAction.length === 0,
variant: "default",
onClick: handleAction,
children: formatMessage({
id: isBulkPublish ? 'app.utils.publish' : 'app.utils.unpublish',
defaultMessage: isBulkPublish ? 'Publish' : 'Unpublish'
})
})
})
}
};
};
/* -------------------------------------------------------------------------------------------------
* BulkLocalePublishAction
* -----------------------------------------------------------------------------------------------*/ const BulkLocalePublishAction = (props)=>{
return BulkLocaleAction({
action: 'bulk-publish',
...props
});
};
/* -------------------------------------------------------------------------------------------------
* BulkLocaleUnpublishAction
* -----------------------------------------------------------------------------------------------*/ const BulkLocaleUnpublishAction = (props)=>{
return BulkLocaleAction({
action: 'bulk-unpublish',
...props
});
};
/**
* Because the icon system is completely broken, we have to do
* this to remove the fill from the cog.
*/ const StyledTrash = styled(Trash)`
path {
fill: currentColor;
}
`;
export { BulkLocalePublishAction, BulkLocaleUnpublishAction, DeleteLocaleAction, FillFromAnotherLocaleAction, LocalePickerAction };
//# sourceMappingURL=CMHeaderActions.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,69 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useI18n = require('../hooks/useI18n.js');
var getTranslation = require('../utils/getTranslation.js');
const Emphasis = (chunks)=>{
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
fontWeight: "semiBold",
textColor: "danger500",
children: chunks
});
};
const DeleteModalAdditionalInfo = ()=>{
const { hasI18n } = useI18n.useI18n();
const { formatMessage } = reactIntl.useIntl();
if (!hasI18n) {
return null;
}
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "danger500",
children: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.deleteAdditionalInfos'),
defaultMessage: 'This will delete the active locale versions <em>(from Internationalization)</em>'
}, {
em: Emphasis
})
});
};
const PublishModalAdditionalInfo = ()=>{
const { hasI18n } = useI18n.useI18n();
const { formatMessage } = reactIntl.useIntl();
if (!hasI18n) {
return null;
}
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "danger500",
children: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.publishAdditionalInfos'),
defaultMessage: 'This will publish the active locale versions <em>(from Internationalization)</em>'
}, {
em: Emphasis
})
});
};
const UnpublishModalAdditionalInfo = ()=>{
const { hasI18n } = useI18n.useI18n();
const { formatMessage } = reactIntl.useIntl();
if (!hasI18n) {
return null;
}
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "danger500",
children: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.unpublishAdditionalInfos'),
defaultMessage: 'This will unpublish the active locale versions <em>(from Internationalization)</em>'
}, {
em: Emphasis
})
});
};
exports.DeleteModalAdditionalInfo = DeleteModalAdditionalInfo;
exports.PublishModalAdditionalInfo = PublishModalAdditionalInfo;
exports.UnpublishModalAdditionalInfo = UnpublishModalAdditionalInfo;
//# sourceMappingURL=CMListViewModalsAdditionalInformation.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CMListViewModalsAdditionalInformation.js","sources":["../../../admin/src/components/CMListViewModalsAdditionalInformation.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useI18n } from '../hooks/useI18n';\nimport { getTranslation } from '../utils/getTranslation';\n\nconst Emphasis = (chunks: React.ReactNode) => {\n return (\n <Typography fontWeight=\"semiBold\" textColor=\"danger500\">\n {chunks}\n </Typography>\n );\n};\n\nconst DeleteModalAdditionalInfo = () => {\n const { hasI18n } = useI18n();\n const { formatMessage } = useIntl();\n\n if (!hasI18n) {\n return null;\n }\n\n return (\n <Typography textColor=\"danger500\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.deleteAdditionalInfos'),\n defaultMessage:\n 'This will delete the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n );\n};\n\nconst PublishModalAdditionalInfo = () => {\n const { hasI18n } = useI18n();\n const { formatMessage } = useIntl();\n\n if (!hasI18n) {\n return null;\n }\n\n return (\n <Typography textColor=\"danger500\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.publishAdditionalInfos'),\n defaultMessage:\n 'This will publish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n );\n};\n\nconst UnpublishModalAdditionalInfo = () => {\n const { hasI18n } = useI18n();\n const { formatMessage } = useIntl();\n\n if (!hasI18n) {\n return null;\n }\n\n return (\n <Typography textColor=\"danger500\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.unpublishAdditionalInfos'),\n defaultMessage:\n 'This will unpublish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n );\n};\n\nexport { DeleteModalAdditionalInfo, PublishModalAdditionalInfo, UnpublishModalAdditionalInfo };\n"],"names":["Emphasis","chunks","_jsx","Typography","fontWeight","textColor","DeleteModalAdditionalInfo","hasI18n","useI18n","formatMessage","useIntl","id","getTranslation","defaultMessage","em","PublishModalAdditionalInfo","UnpublishModalAdditionalInfo"],"mappings":";;;;;;;;;AAQA,MAAMA,WAAW,CAACC,MAAAA,GAAAA;AAChB,IAAA,qBACEC,cAACC,CAAAA,uBAAAA,EAAAA;QAAWC,UAAW,EAAA,UAAA;QAAWC,SAAU,EAAA,WAAA;AACzCJ,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;AAEA,MAAMK,yBAA4B,GAAA,IAAA;IAChC,MAAM,EAAEC,OAAO,EAAE,GAAGC,eAAAA,EAAAA;IACpB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,IAAI,CAACH,OAAS,EAAA;QACZ,OAAO,IAAA;AACT;AAEA,IAAA,qBACEL,cAACC,CAAAA,uBAAAA,EAAAA;QAAWE,SAAU,EAAA,WAAA;kBACnBI,aACC,CAAA;AACEE,YAAAA,EAAAA,EAAIC,6BAAe,CAAA,6CAAA,CAAA;YACnBC,cACE,EAAA;SAEJ,EAAA;YACEC,EAAId,EAAAA;AACN,SAAA;;AAIR;AAEA,MAAMe,0BAA6B,GAAA,IAAA;IACjC,MAAM,EAAER,OAAO,EAAE,GAAGC,eAAAA,EAAAA;IACpB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,IAAI,CAACH,OAAS,EAAA;QACZ,OAAO,IAAA;AACT;AAEA,IAAA,qBACEL,cAACC,CAAAA,uBAAAA,EAAAA;QAAWE,SAAU,EAAA,WAAA;kBACnBI,aACC,CAAA;AACEE,YAAAA,EAAAA,EAAIC,6BAAe,CAAA,8CAAA,CAAA;YACnBC,cACE,EAAA;SAEJ,EAAA;YACEC,EAAId,EAAAA;AACN,SAAA;;AAIR;AAEA,MAAMgB,4BAA+B,GAAA,IAAA;IACnC,MAAM,EAAET,OAAO,EAAE,GAAGC,eAAAA,EAAAA;IACpB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,IAAI,CAACH,OAAS,EAAA;QACZ,OAAO,IAAA;AACT;AAEA,IAAA,qBACEL,cAACC,CAAAA,uBAAAA,EAAAA;QAAWE,SAAU,EAAA,WAAA;kBACnBI,aACC,CAAA;AACEE,YAAAA,EAAAA,EAAIC,6BAAe,CAAA,gDAAA,CAAA;YACnBC,cACE,EAAA;SAEJ,EAAA;YACEC,EAAId,EAAAA;AACN,SAAA;;AAIR;;;;;;"}

View File

@@ -0,0 +1,65 @@
import { jsx } from 'react/jsx-runtime';
import 'react';
import { Typography } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useI18n } from '../hooks/useI18n.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
const Emphasis = (chunks)=>{
return /*#__PURE__*/ jsx(Typography, {
fontWeight: "semiBold",
textColor: "danger500",
children: chunks
});
};
const DeleteModalAdditionalInfo = ()=>{
const { hasI18n } = useI18n();
const { formatMessage } = useIntl();
if (!hasI18n) {
return null;
}
return /*#__PURE__*/ jsx(Typography, {
textColor: "danger500",
children: formatMessage({
id: getTranslation('Settings.list.actions.deleteAdditionalInfos'),
defaultMessage: 'This will delete the active locale versions <em>(from Internationalization)</em>'
}, {
em: Emphasis
})
});
};
const PublishModalAdditionalInfo = ()=>{
const { hasI18n } = useI18n();
const { formatMessage } = useIntl();
if (!hasI18n) {
return null;
}
return /*#__PURE__*/ jsx(Typography, {
textColor: "danger500",
children: formatMessage({
id: getTranslation('Settings.list.actions.publishAdditionalInfos'),
defaultMessage: 'This will publish the active locale versions <em>(from Internationalization)</em>'
}, {
em: Emphasis
})
});
};
const UnpublishModalAdditionalInfo = ()=>{
const { hasI18n } = useI18n();
const { formatMessage } = useIntl();
if (!hasI18n) {
return null;
}
return /*#__PURE__*/ jsx(Typography, {
textColor: "danger500",
children: formatMessage({
id: getTranslation('Settings.list.actions.unpublishAdditionalInfos'),
defaultMessage: 'This will unpublish the active locale versions <em>(from Internationalization)</em>'
}, {
em: Emphasis
})
});
};
export { DeleteModalAdditionalInfo, PublishModalAdditionalInfo, UnpublishModalAdditionalInfo };
//# sourceMappingURL=CMListViewModalsAdditionalInformation.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CMListViewModalsAdditionalInformation.mjs","sources":["../../../admin/src/components/CMListViewModalsAdditionalInformation.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useI18n } from '../hooks/useI18n';\nimport { getTranslation } from '../utils/getTranslation';\n\nconst Emphasis = (chunks: React.ReactNode) => {\n return (\n <Typography fontWeight=\"semiBold\" textColor=\"danger500\">\n {chunks}\n </Typography>\n );\n};\n\nconst DeleteModalAdditionalInfo = () => {\n const { hasI18n } = useI18n();\n const { formatMessage } = useIntl();\n\n if (!hasI18n) {\n return null;\n }\n\n return (\n <Typography textColor=\"danger500\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.deleteAdditionalInfos'),\n defaultMessage:\n 'This will delete the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n );\n};\n\nconst PublishModalAdditionalInfo = () => {\n const { hasI18n } = useI18n();\n const { formatMessage } = useIntl();\n\n if (!hasI18n) {\n return null;\n }\n\n return (\n <Typography textColor=\"danger500\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.publishAdditionalInfos'),\n defaultMessage:\n 'This will publish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n );\n};\n\nconst UnpublishModalAdditionalInfo = () => {\n const { hasI18n } = useI18n();\n const { formatMessage } = useIntl();\n\n if (!hasI18n) {\n return null;\n }\n\n return (\n <Typography textColor=\"danger500\">\n {formatMessage(\n {\n id: getTranslation('Settings.list.actions.unpublishAdditionalInfos'),\n defaultMessage:\n 'This will unpublish the active locale versions <em>(from Internationalization)</em>',\n },\n {\n em: Emphasis,\n }\n )}\n </Typography>\n );\n};\n\nexport { DeleteModalAdditionalInfo, PublishModalAdditionalInfo, UnpublishModalAdditionalInfo };\n"],"names":["Emphasis","chunks","_jsx","Typography","fontWeight","textColor","DeleteModalAdditionalInfo","hasI18n","useI18n","formatMessage","useIntl","id","getTranslation","defaultMessage","em","PublishModalAdditionalInfo","UnpublishModalAdditionalInfo"],"mappings":";;;;;;;AAQA,MAAMA,WAAW,CAACC,MAAAA,GAAAA;AAChB,IAAA,qBACEC,GAACC,CAAAA,UAAAA,EAAAA;QAAWC,UAAW,EAAA,UAAA;QAAWC,SAAU,EAAA,WAAA;AACzCJ,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;AAEA,MAAMK,yBAA4B,GAAA,IAAA;IAChC,MAAM,EAAEC,OAAO,EAAE,GAAGC,OAAAA,EAAAA;IACpB,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,IAAI,CAACH,OAAS,EAAA;QACZ,OAAO,IAAA;AACT;AAEA,IAAA,qBACEL,GAACC,CAAAA,UAAAA,EAAAA;QAAWE,SAAU,EAAA,WAAA;kBACnBI,aACC,CAAA;AACEE,YAAAA,EAAAA,EAAIC,cAAe,CAAA,6CAAA,CAAA;YACnBC,cACE,EAAA;SAEJ,EAAA;YACEC,EAAId,EAAAA;AACN,SAAA;;AAIR;AAEA,MAAMe,0BAA6B,GAAA,IAAA;IACjC,MAAM,EAAER,OAAO,EAAE,GAAGC,OAAAA,EAAAA;IACpB,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,IAAI,CAACH,OAAS,EAAA;QACZ,OAAO,IAAA;AACT;AAEA,IAAA,qBACEL,GAACC,CAAAA,UAAAA,EAAAA;QAAWE,SAAU,EAAA,WAAA;kBACnBI,aACC,CAAA;AACEE,YAAAA,EAAAA,EAAIC,cAAe,CAAA,8CAAA,CAAA;YACnBC,cACE,EAAA;SAEJ,EAAA;YACEC,EAAId,EAAAA;AACN,SAAA;;AAIR;AAEA,MAAMgB,4BAA+B,GAAA,IAAA;IACnC,MAAM,EAAET,OAAO,EAAE,GAAGC,OAAAA,EAAAA;IACpB,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,IAAI,CAACH,OAAS,EAAA;QACZ,OAAO,IAAA;AACT;AAEA,IAAA,qBACEL,GAACC,CAAAA,UAAAA,EAAAA;QAAWE,SAAU,EAAA,WAAA;kBACnBI,aACC,CAAA;AACEE,YAAAA,EAAAA,EAAIC,cAAe,CAAA,gDAAA,CAAA;YACnBC,cACE,EAAA;SAEJ,EAAA;YACEC,EAAId,EAAAA;AACN,SAAA;;AAIR;;;;"}

View File

@@ -0,0 +1,155 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var styledComponents = require('styled-components');
var getTranslation = require('../utils/getTranslation.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const TextAlignTypography = styledComponents.styled(designSystem.Typography)`
text-align: center;
`;
const CheckboxConfirmation = ({ description, isCreating = false, intlLabel, name, onChange, value })=>{
const { formatMessage } = reactIntl.useIntl();
const [isOpen, setIsOpen] = React__namespace.useState(false);
const handleChange = (value)=>{
if (isCreating || value) {
return onChange({
target: {
name,
value,
type: 'checkbox'
}
});
}
if (!value) {
return setIsOpen(true);
}
return null;
};
const handleConfirm = ()=>{
onChange({
target: {
name,
value: false,
type: 'checkbox'
}
});
};
const label = intlLabel.id ? formatMessage({
id: intlLabel.id,
defaultMessage: intlLabel.defaultMessage
}, {
...intlLabel.values
}) : name;
const hint = description ? formatMessage({
id: description.id,
defaultMessage: description.defaultMessage
}, {
...description.values
}) : '';
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Root, {
open: isOpen,
onOpenChange: setIsOpen,
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
hint: hint,
name: name,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Checkbox, {
onCheckedChange: handleChange,
checked: value,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {})
]
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Content, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Header, {
children: formatMessage({
id: getTranslation.getTranslation('CheckboxConfirmation.Modal.title'),
defaultMessage: 'Disable localization'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Body, {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {}),
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
gap: 2,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
justifyContent: "center",
children: /*#__PURE__*/ jsxRuntime.jsx(TextAlignTypography, {
children: formatMessage({
id: getTranslation.getTranslation('CheckboxConfirmation.Modal.content'),
defaultMessage: 'Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing).'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
justifyContent: "center",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
fontWeight: "semiBold",
children: formatMessage({
id: getTranslation.getTranslation('CheckboxConfirmation.Modal.body'),
defaultMessage: 'Do you want to disable it?'
})
})
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Footer, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Cancel, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
children: formatMessage({
id: 'components.popUpWarning.button.cancel',
defaultMessage: 'No, cancel'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Action, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "danger-light",
onClick: handleConfirm,
children: formatMessage({
id: getTranslation.getTranslation('CheckboxConfirmation.Modal.button-confirm'),
defaultMessage: 'Yes, disable'
})
})
})
]
})
]
})
]
});
};
exports.CheckboxConfirmation = CheckboxConfirmation;
//# sourceMappingURL=CheckboxConfirmation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,134 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { Typography, Dialog, Field, Checkbox, Flex, Button } from '@strapi/design-system';
import { WarningCircle } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { styled } from 'styled-components';
import { getTranslation } from '../utils/getTranslation.mjs';
const TextAlignTypography = styled(Typography)`
text-align: center;
`;
const CheckboxConfirmation = ({ description, isCreating = false, intlLabel, name, onChange, value })=>{
const { formatMessage } = useIntl();
const [isOpen, setIsOpen] = React.useState(false);
const handleChange = (value)=>{
if (isCreating || value) {
return onChange({
target: {
name,
value,
type: 'checkbox'
}
});
}
if (!value) {
return setIsOpen(true);
}
return null;
};
const handleConfirm = ()=>{
onChange({
target: {
name,
value: false,
type: 'checkbox'
}
});
};
const label = intlLabel.id ? formatMessage({
id: intlLabel.id,
defaultMessage: intlLabel.defaultMessage
}, {
...intlLabel.values
}) : name;
const hint = description ? formatMessage({
id: description.id,
defaultMessage: description.defaultMessage
}, {
...description.values
}) : '';
return /*#__PURE__*/ jsxs(Dialog.Root, {
open: isOpen,
onOpenChange: setIsOpen,
children: [
/*#__PURE__*/ jsxs(Field.Root, {
hint: hint,
name: name,
children: [
/*#__PURE__*/ jsx(Checkbox, {
onCheckedChange: handleChange,
checked: value,
children: label
}),
/*#__PURE__*/ jsx(Field.Hint, {})
]
}),
/*#__PURE__*/ jsxs(Dialog.Content, {
children: [
/*#__PURE__*/ jsx(Dialog.Header, {
children: formatMessage({
id: getTranslation('CheckboxConfirmation.Modal.title'),
defaultMessage: 'Disable localization'
})
}),
/*#__PURE__*/ jsx(Dialog.Body, {
icon: /*#__PURE__*/ jsx(WarningCircle, {}),
children: /*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "stretch",
gap: 2,
children: [
/*#__PURE__*/ jsx(Flex, {
justifyContent: "center",
children: /*#__PURE__*/ jsx(TextAlignTypography, {
children: formatMessage({
id: getTranslation('CheckboxConfirmation.Modal.content'),
defaultMessage: 'Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing).'
})
})
}),
/*#__PURE__*/ jsx(Flex, {
justifyContent: "center",
children: /*#__PURE__*/ jsx(Typography, {
fontWeight: "semiBold",
children: formatMessage({
id: getTranslation('CheckboxConfirmation.Modal.body'),
defaultMessage: 'Do you want to disable it?'
})
})
})
]
})
}),
/*#__PURE__*/ jsxs(Dialog.Footer, {
children: [
/*#__PURE__*/ jsx(Dialog.Cancel, {
children: /*#__PURE__*/ jsx(Button, {
variant: "tertiary",
children: formatMessage({
id: 'components.popUpWarning.button.cancel',
defaultMessage: 'No, cancel'
})
})
}),
/*#__PURE__*/ jsx(Dialog.Action, {
children: /*#__PURE__*/ jsx(Button, {
variant: "danger-light",
onClick: handleConfirm,
children: formatMessage({
id: getTranslation('CheckboxConfirmation.Modal.button-confirm'),
defaultMessage: 'Yes, disable'
})
})
})
]
})
]
})
]
});
};
export { CheckboxConfirmation };
//# sourceMappingURL=CheckboxConfirmation.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,395 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var yup = require('yup');
var locales = require('../services/locales.js');
var baseQuery = require('../utils/baseQuery.js');
var getTranslation = require('../utils/getTranslation.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
const CreateLocale = ({ disabled, variant = 'default' })=>{
const { formatMessage } = reactIntl.useIntl();
const [visible, setVisible] = React__namespace.useState(false);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Root, {
open: visible,
onOpenChange: setVisible,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Trigger, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: variant,
disabled: disabled,
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {}),
onClick: ()=>setVisible(true),
size: "S",
children: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.add'),
defaultMessage: 'Add new locale'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(CreateModal, {
onClose: ()=>setVisible(false)
})
]
});
};
/* -------------------------------------------------------------------------------------------------
* CreateModal
* -----------------------------------------------------------------------------------------------*/ const LOCALE_SCHEMA = yup__namespace.object().shape({
code: yup__namespace.string().nullable().required({
id: 'Settings.locales.modal.create.code.error',
defaultMessage: 'Please select a locale'
}),
name: yup__namespace.string().nullable().max(50, {
id: 'Settings.locales.modal.create.name.error.min',
defaultMessage: 'The locale display name can only be less than 50 characters.'
}).required({
id: 'Settings.locales.modal.create.name.error.required',
defaultMessage: 'Please give the locale a display name'
}),
isDefault: yup__namespace.boolean()
});
const initialFormValues = {
code: '',
name: '',
isDefault: false
};
const CreateModal = ({ onClose })=>{
const titleId = designSystem.useId();
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError, _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
const [createLocale] = locales.useCreateLocaleMutation();
const { formatMessage } = reactIntl.useIntl();
const refetchPermissions = strapiAdmin.useAuth('CreateModal', (state)=>state.refetchPermissions);
const handleSubmit = async (values, helpers)=>{
try {
const res = await createLocale(values);
if ('error' in res) {
if (baseQuery.isBaseQueryError(res.error) && res.error.name === 'ValidationError') {
helpers.setErrors(formatValidationErrors(res.error));
} else {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
}
return;
}
toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.create.success'),
defaultMessage: 'Created locale'
})
});
refetchPermissions();
onClose();
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred, please try again'
})
});
}
};
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Content, {
children: /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Form, {
method: "POST",
initialValues: initialFormValues,
validationSchema: LOCALE_SCHEMA,
onSubmit: handleSubmit,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Header, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Title, {
children: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.add'),
defaultMessage: 'Add new locale'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Body, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tabs.Root, {
variant: "simple",
defaultValue: "basic",
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
justifyContent: "space-between",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
tag: "h2",
variant: "beta",
id: titleId,
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.title'),
defaultMessage: 'Configuration'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tabs.List, {
"aria-labelledby": titleId,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Trigger, {
value: "basic",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.base'),
defaultMessage: 'Basic settings'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Trigger, {
value: "advanced",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.advanced'),
defaultMessage: 'Advanced settings'
})
})
]
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Divider, {}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
paddingTop: 7,
paddingBottom: 7,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Content, {
value: "basic",
children: /*#__PURE__*/ jsxRuntime.jsx(BaseForm, {})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Content, {
value: "advanced",
children: /*#__PURE__*/ jsxRuntime.jsx(AdvancedForm, {})
})
]
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Footer, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Close, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(SubmitButton, {})
]
})
]
})
});
};
/* -------------------------------------------------------------------------------------------------
* SubmitButton
* -----------------------------------------------------------------------------------------------*/ const SubmitButton = ()=>{
const { formatMessage } = reactIntl.useIntl();
const isSubmitting = strapiAdmin.useForm('SubmitButton', (state)=>state.isSubmitting);
const modified = strapiAdmin.useForm('SubmitButton', (state)=>state.modified);
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
type: "submit",
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Check, {}),
disabled: isSubmitting || !modified,
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
});
};
const BaseForm = ({ mode = 'create' })=>{
const { formatMessage } = reactIntl.useIntl();
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
const { data: defaultLocales, error } = locales.useGetDefaultLocalesQuery();
React__namespace.useEffect(()=>{
if (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
}, [
error,
formatAPIError,
toggleNotification
]);
if (!Array.isArray(defaultLocales)) {
return null;
}
const options = defaultLocales.map((locale)=>({
label: locale.name,
value: locale.code
}));
const translatedForm = [
{
disabled: mode !== 'create',
label: {
id: getTranslation.getTranslation('Settings.locales.modal.create.code.label'),
defaultMessage: 'Locales'
},
name: 'code',
options,
placeholder: {
id: 'components.placeholder.select',
defaultMessage: 'Select'
},
required: true,
size: 6,
type: 'enumeration'
},
{
hint: {
id: getTranslation.getTranslation('Settings.locales.modal.create.name.label.description'),
defaultMessage: 'Locale will be displayed under that name in the administration panel'
},
label: {
id: getTranslation.getTranslation('Settings.locales.modal.create.name.label'),
defaultMessage: 'Locale display name'
},
name: 'name',
required: true,
size: 6,
type: 'string'
}
].map((field)=>({
...field,
hint: field.hint ? formatMessage(field.hint) : undefined,
label: formatMessage(field.label),
placeholder: field.placeholder ? formatMessage(field.placeholder) : undefined
}));
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
gap: 4,
children: translatedForm.map(({ size, ...field })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsx(FormRenderer, {
...field
})
}, field.name))
});
};
const AdvancedForm = ({ isDefaultLocale })=>{
const { formatMessage } = reactIntl.useIntl();
const form = [
{
disabled: isDefaultLocale,
hint: {
id: getTranslation.getTranslation('Settings.locales.modal.advanced.setAsDefault.hint'),
defaultMessage: 'One default locale is required, change it by selecting another one'
},
label: {
id: getTranslation.getTranslation('Settings.locales.modal.advanced.setAsDefault'),
defaultMessage: 'Set as default locale'
},
name: 'isDefault',
size: 6,
type: 'boolean'
}
].map((field)=>({
...field,
hint: field.hint ? formatMessage(field.hint) : undefined,
label: formatMessage(field.label)
}));
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
gap: 4,
children: form.map(({ size, ...field })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsx(FormRenderer, {
...field
})
}, field.name))
});
};
/* -------------------------------------------------------------------------------------------------
* FormRenderer
* -----------------------------------------------------------------------------------------------*/ const FormRenderer = (field)=>{
switch(field.type){
/**
* This will override the default input renderer
* choice for `enumeration`.
*/ case 'enumeration':
return /*#__PURE__*/ jsxRuntime.jsx(EnumerationInput, {
...field
});
default:
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.InputRenderer, {
...field
});
}
};
const EnumerationInput = ({ disabled, hint, label, name, options, placeholder, required })=>{
const { value, error, onChange } = strapiAdmin.useField(name);
const { data: defaultLocales = [] } = locales.useGetDefaultLocalesQuery();
const handleChange = (value)=>{
if (Array.isArray(defaultLocales)) {
// We know it exists because the options are created from the list of default locales
const locale = defaultLocales.find((locale)=>locale.code === value);
onChange(name, value);
// This lets us automatically fill the name field with the locale name
onChange('name', locale.name);
} else {
onChange(name, value);
}
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: error,
hint: hint,
name: name,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelect, {
disabled: disabled,
// @ts-expect-error This will dissapear when the DS removes support for numbers to be returned by SingleSelect.
onChange: handleChange,
placeholder: placeholder,
value: value,
children: options.map((option)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
value: option.value,
children: option.label
}, option.value))
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {})
]
});
};
exports.AdvancedForm = AdvancedForm;
exports.BaseForm = BaseForm;
exports.CreateLocale = CreateLocale;
exports.LOCALE_SCHEMA = LOCALE_SCHEMA;
exports.SubmitButton = SubmitButton;
//# sourceMappingURL=CreateLocale.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,369 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useNotification, useAPIErrorHandler, useAuth, Form, useForm, InputRenderer, useField } from '@strapi/admin/strapi-admin';
import { Modal, Button, useId, Tabs, Flex, Typography, Divider, Box, Grid, Field, SingleSelect, SingleSelectOption } from '@strapi/design-system';
import { Plus, Check } from '@strapi/icons';
import { useIntl } from 'react-intl';
import * as yup from 'yup';
import { useCreateLocaleMutation, useGetDefaultLocalesQuery } from '../services/locales.mjs';
import { isBaseQueryError } from '../utils/baseQuery.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
const CreateLocale = ({ disabled, variant = 'default' })=>{
const { formatMessage } = useIntl();
const [visible, setVisible] = React.useState(false);
return /*#__PURE__*/ jsxs(Modal.Root, {
open: visible,
onOpenChange: setVisible,
children: [
/*#__PURE__*/ jsx(Modal.Trigger, {
children: /*#__PURE__*/ jsx(Button, {
variant: variant,
disabled: disabled,
startIcon: /*#__PURE__*/ jsx(Plus, {}),
onClick: ()=>setVisible(true),
size: "S",
children: formatMessage({
id: getTranslation('Settings.list.actions.add'),
defaultMessage: 'Add new locale'
})
})
}),
/*#__PURE__*/ jsx(CreateModal, {
onClose: ()=>setVisible(false)
})
]
});
};
/* -------------------------------------------------------------------------------------------------
* CreateModal
* -----------------------------------------------------------------------------------------------*/ const LOCALE_SCHEMA = yup.object().shape({
code: yup.string().nullable().required({
id: 'Settings.locales.modal.create.code.error',
defaultMessage: 'Please select a locale'
}),
name: yup.string().nullable().max(50, {
id: 'Settings.locales.modal.create.name.error.min',
defaultMessage: 'The locale display name can only be less than 50 characters.'
}).required({
id: 'Settings.locales.modal.create.name.error.required',
defaultMessage: 'Please give the locale a display name'
}),
isDefault: yup.boolean()
});
const initialFormValues = {
code: '',
name: '',
isDefault: false
};
const CreateModal = ({ onClose })=>{
const titleId = useId();
const { toggleNotification } = useNotification();
const { _unstableFormatAPIError: formatAPIError, _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
const [createLocale] = useCreateLocaleMutation();
const { formatMessage } = useIntl();
const refetchPermissions = useAuth('CreateModal', (state)=>state.refetchPermissions);
const handleSubmit = async (values, helpers)=>{
try {
const res = await createLocale(values);
if ('error' in res) {
if (isBaseQueryError(res.error) && res.error.name === 'ValidationError') {
helpers.setErrors(formatValidationErrors(res.error));
} else {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
}
return;
}
toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation('Settings.locales.modal.create.success'),
defaultMessage: 'Created locale'
})
});
refetchPermissions();
onClose();
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred, please try again'
})
});
}
};
return /*#__PURE__*/ jsx(Modal.Content, {
children: /*#__PURE__*/ jsxs(Form, {
method: "POST",
initialValues: initialFormValues,
validationSchema: LOCALE_SCHEMA,
onSubmit: handleSubmit,
children: [
/*#__PURE__*/ jsx(Modal.Header, {
children: /*#__PURE__*/ jsx(Modal.Title, {
children: formatMessage({
id: getTranslation('Settings.list.actions.add'),
defaultMessage: 'Add new locale'
})
})
}),
/*#__PURE__*/ jsx(Modal.Body, {
children: /*#__PURE__*/ jsxs(Tabs.Root, {
variant: "simple",
defaultValue: "basic",
children: [
/*#__PURE__*/ jsxs(Flex, {
justifyContent: "space-between",
children: [
/*#__PURE__*/ jsx(Typography, {
tag: "h2",
variant: "beta",
id: titleId,
children: formatMessage({
id: getTranslation('Settings.locales.modal.title'),
defaultMessage: 'Configuration'
})
}),
/*#__PURE__*/ jsxs(Tabs.List, {
"aria-labelledby": titleId,
children: [
/*#__PURE__*/ jsx(Tabs.Trigger, {
value: "basic",
children: formatMessage({
id: getTranslation('Settings.locales.modal.base'),
defaultMessage: 'Basic settings'
})
}),
/*#__PURE__*/ jsx(Tabs.Trigger, {
value: "advanced",
children: formatMessage({
id: getTranslation('Settings.locales.modal.advanced'),
defaultMessage: 'Advanced settings'
})
})
]
})
]
}),
/*#__PURE__*/ jsx(Divider, {}),
/*#__PURE__*/ jsxs(Box, {
paddingTop: 7,
paddingBottom: 7,
children: [
/*#__PURE__*/ jsx(Tabs.Content, {
value: "basic",
children: /*#__PURE__*/ jsx(BaseForm, {})
}),
/*#__PURE__*/ jsx(Tabs.Content, {
value: "advanced",
children: /*#__PURE__*/ jsx(AdvancedForm, {})
})
]
})
]
})
}),
/*#__PURE__*/ jsxs(Modal.Footer, {
children: [
/*#__PURE__*/ jsx(Modal.Close, {
children: /*#__PURE__*/ jsx(Button, {
variant: "tertiary",
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
/*#__PURE__*/ jsx(SubmitButton, {})
]
})
]
})
});
};
/* -------------------------------------------------------------------------------------------------
* SubmitButton
* -----------------------------------------------------------------------------------------------*/ const SubmitButton = ()=>{
const { formatMessage } = useIntl();
const isSubmitting = useForm('SubmitButton', (state)=>state.isSubmitting);
const modified = useForm('SubmitButton', (state)=>state.modified);
return /*#__PURE__*/ jsx(Button, {
type: "submit",
startIcon: /*#__PURE__*/ jsx(Check, {}),
disabled: isSubmitting || !modified,
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
});
};
const BaseForm = ({ mode = 'create' })=>{
const { formatMessage } = useIntl();
const { toggleNotification } = useNotification();
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
const { data: defaultLocales, error } = useGetDefaultLocalesQuery();
React.useEffect(()=>{
if (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
}, [
error,
formatAPIError,
toggleNotification
]);
if (!Array.isArray(defaultLocales)) {
return null;
}
const options = defaultLocales.map((locale)=>({
label: locale.name,
value: locale.code
}));
const translatedForm = [
{
disabled: mode !== 'create',
label: {
id: getTranslation('Settings.locales.modal.create.code.label'),
defaultMessage: 'Locales'
},
name: 'code',
options,
placeholder: {
id: 'components.placeholder.select',
defaultMessage: 'Select'
},
required: true,
size: 6,
type: 'enumeration'
},
{
hint: {
id: getTranslation('Settings.locales.modal.create.name.label.description'),
defaultMessage: 'Locale will be displayed under that name in the administration panel'
},
label: {
id: getTranslation('Settings.locales.modal.create.name.label'),
defaultMessage: 'Locale display name'
},
name: 'name',
required: true,
size: 6,
type: 'string'
}
].map((field)=>({
...field,
hint: field.hint ? formatMessage(field.hint) : undefined,
label: formatMessage(field.label),
placeholder: field.placeholder ? formatMessage(field.placeholder) : undefined
}));
return /*#__PURE__*/ jsx(Grid.Root, {
gap: 4,
children: translatedForm.map(({ size, ...field })=>/*#__PURE__*/ jsx(Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsx(FormRenderer, {
...field
})
}, field.name))
});
};
const AdvancedForm = ({ isDefaultLocale })=>{
const { formatMessage } = useIntl();
const form = [
{
disabled: isDefaultLocale,
hint: {
id: getTranslation('Settings.locales.modal.advanced.setAsDefault.hint'),
defaultMessage: 'One default locale is required, change it by selecting another one'
},
label: {
id: getTranslation('Settings.locales.modal.advanced.setAsDefault'),
defaultMessage: 'Set as default locale'
},
name: 'isDefault',
size: 6,
type: 'boolean'
}
].map((field)=>({
...field,
hint: field.hint ? formatMessage(field.hint) : undefined,
label: formatMessage(field.label)
}));
return /*#__PURE__*/ jsx(Grid.Root, {
gap: 4,
children: form.map(({ size, ...field })=>/*#__PURE__*/ jsx(Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsx(FormRenderer, {
...field
})
}, field.name))
});
};
/* -------------------------------------------------------------------------------------------------
* FormRenderer
* -----------------------------------------------------------------------------------------------*/ const FormRenderer = (field)=>{
switch(field.type){
/**
* This will override the default input renderer
* choice for `enumeration`.
*/ case 'enumeration':
return /*#__PURE__*/ jsx(EnumerationInput, {
...field
});
default:
return /*#__PURE__*/ jsx(InputRenderer, {
...field
});
}
};
const EnumerationInput = ({ disabled, hint, label, name, options, placeholder, required })=>{
const { value, error, onChange } = useField(name);
const { data: defaultLocales = [] } = useGetDefaultLocalesQuery();
const handleChange = (value)=>{
if (Array.isArray(defaultLocales)) {
// We know it exists because the options are created from the list of default locales
const locale = defaultLocales.find((locale)=>locale.code === value);
onChange(name, value);
// This lets us automatically fill the name field with the locale name
onChange('name', locale.name);
} else {
onChange(name, value);
}
};
return /*#__PURE__*/ jsxs(Field.Root, {
error: error,
hint: hint,
name: name,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
children: label
}),
/*#__PURE__*/ jsx(SingleSelect, {
disabled: disabled,
// @ts-expect-error This will dissapear when the DS removes support for numbers to be returned by SingleSelect.
onChange: handleChange,
placeholder: placeholder,
value: value,
children: options.map((option)=>/*#__PURE__*/ jsx(SingleSelectOption, {
value: option.value,
children: option.label
}, option.value))
}),
/*#__PURE__*/ jsx(Field.Error, {}),
/*#__PURE__*/ jsx(Field.Hint, {})
]
});
};
export { AdvancedForm, BaseForm, CreateLocale, LOCALE_SCHEMA, SubmitButton };
//# sourceMappingURL=CreateLocale.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,90 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var locales = require('../services/locales.js');
var getTranslation = require('../utils/getTranslation.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const DeleteLocale = ({ id, name })=>{
const { formatMessage } = reactIntl.useIntl();
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
const [visible, setVisible] = React__namespace.useState(false);
const [deleteLocale] = locales.useDeleteLocaleMutation();
const handleConfirm = async ()=>{
try {
const res = await deleteLocale(id);
if ('error' in res) {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
return;
}
toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.delete.success'),
defaultMessage: 'Deleted locale'
})
});
setVisible(false);
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred, please try again'
})
});
}
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Root, {
open: visible,
onOpenChange: setVisible,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Trigger, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
onClick: ()=>setVisible(true),
label: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.delete'),
defaultMessage: 'Delete {name} locale'
}, {
name
}),
variant: "ghost",
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Trash, {})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.ConfirmDialog, {
onConfirm: handleConfirm
})
]
});
};
exports.DeleteLocale = DeleteLocale;
//# sourceMappingURL=DeleteLocale.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DeleteLocale.js","sources":["../../../admin/src/components/DeleteLocale.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { ConfirmDialog, useAPIErrorHandler, useNotification } from '@strapi/admin/strapi-admin';\nimport { Dialog, IconButton } from '@strapi/design-system';\nimport { Trash } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useDeleteLocaleMutation } from '../services/locales';\nimport { getTranslation } from '../utils/getTranslation';\n\nimport type { Locale } from '../../../shared/contracts/locales';\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteLocale\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DeleteLocaleProps extends Locale {}\n\nconst DeleteLocale = ({ id, name }: DeleteLocaleProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n\n const [visible, setVisible] = React.useState(false);\n\n const [deleteLocale] = useDeleteLocaleMutation();\n const handleConfirm = async () => {\n try {\n const res = await deleteLocale(id);\n\n if ('error' in res) {\n toggleNotification({ type: 'danger', message: formatAPIError(res.error) });\n\n return;\n }\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTranslation('Settings.locales.modal.delete.success'),\n defaultMessage: 'Deleted locale',\n }),\n });\n\n setVisible(false);\n } catch (err) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'notification.error',\n defaultMessage: 'An error occurred, please try again',\n }),\n });\n }\n };\n\n return (\n <Dialog.Root open={visible} onOpenChange={setVisible}>\n <Dialog.Trigger>\n <IconButton\n onClick={() => setVisible(true)}\n label={formatMessage(\n {\n id: getTranslation('Settings.list.actions.delete'),\n defaultMessage: 'Delete {name} locale',\n },\n {\n name,\n }\n )}\n variant=\"ghost\"\n >\n <Trash />\n </IconButton>\n </Dialog.Trigger>\n <ConfirmDialog onConfirm={handleConfirm} />\n </Dialog.Root>\n );\n};\n\nexport { DeleteLocale };\n"],"names":["DeleteLocale","id","name","formatMessage","useIntl","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","visible","setVisible","React","useState","deleteLocale","useDeleteLocaleMutation","handleConfirm","res","type","message","error","getTranslation","defaultMessage","err","_jsxs","Dialog","Root","open","onOpenChange","_jsx","Trigger","IconButton","onClick","label","variant","Trash","ConfirmDialog","onConfirm"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,MAAMA,eAAe,CAAC,EAAEC,EAAE,EAAEC,IAAI,EAAqB,GAAA;IACnD,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,2BAAAA,EAAAA;AAC/B,IAAA,MAAM,EAAEC,uBAAAA,EAAyBC,cAAc,EAAE,GAAGC,8BAAAA,EAAAA;AAEpD,IAAA,MAAM,CAACC,OAASC,EAAAA,UAAAA,CAAW,GAAGC,gBAAAA,CAAMC,QAAQ,CAAC,KAAA,CAAA;IAE7C,MAAM,CAACC,aAAa,GAAGC,+BAAAA,EAAAA;AACvB,IAAA,MAAMC,aAAgB,GAAA,UAAA;QACpB,IAAI;YACF,MAAMC,GAAAA,GAAM,MAAMH,YAAab,CAAAA,EAAAA,CAAAA;AAE/B,YAAA,IAAI,WAAWgB,GAAK,EAAA;gBAClBZ,kBAAmB,CAAA;oBAAEa,IAAM,EAAA,QAAA;oBAAUC,OAASX,EAAAA,cAAAA,CAAeS,IAAIG,KAAK;AAAE,iBAAA,CAAA;AAExE,gBAAA;AACF;YAEAf,kBAAmB,CAAA;gBACjBa,IAAM,EAAA,SAAA;AACNC,gBAAAA,OAAAA,EAAShB,aAAc,CAAA;AACrBF,oBAAAA,EAAAA,EAAIoB,6BAAe,CAAA,uCAAA,CAAA;oBACnBC,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;YAEAX,UAAW,CAAA,KAAA,CAAA;AACb,SAAA,CAAE,OAAOY,GAAK,EAAA;YACZlB,kBAAmB,CAAA;gBACjBa,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAAShB,aAAc,CAAA;oBACrBF,EAAI,EAAA,oBAAA;oBACJqB,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;AACF;AACF,KAAA;IAEA,qBACEE,eAAA,CAACC,oBAAOC,IAAI,EAAA;QAACC,IAAMjB,EAAAA,OAAAA;QAASkB,YAAcjB,EAAAA,UAAAA;;AACxC,0BAAAkB,cAAA,CAACJ,oBAAOK,OAAO,EAAA;AACb,gBAAA,QAAA,gBAAAD,cAACE,CAAAA,uBAAAA,EAAAA;AACCC,oBAAAA,OAAAA,EAAS,IAAMrB,UAAW,CAAA,IAAA,CAAA;AAC1BsB,oBAAAA,KAAAA,EAAO9B,aACL,CAAA;AACEF,wBAAAA,EAAAA,EAAIoB,6BAAe,CAAA,8BAAA,CAAA;wBACnBC,cAAgB,EAAA;qBAElB,EAAA;AACEpB,wBAAAA;AACF,qBAAA,CAAA;oBAEFgC,OAAQ,EAAA,OAAA;AAER,oBAAA,QAAA,gBAAAL,cAACM,CAAAA,WAAAA,EAAAA,EAAAA;;;0BAGLN,cAACO,CAAAA,yBAAAA,EAAAA;gBAAcC,SAAWrB,EAAAA;;;;AAGhC;;;;"}

View File

@@ -0,0 +1,69 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useNotification, useAPIErrorHandler, ConfirmDialog } from '@strapi/admin/strapi-admin';
import { Dialog, IconButton } from '@strapi/design-system';
import { Trash } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useDeleteLocaleMutation } from '../services/locales.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
const DeleteLocale = ({ id, name })=>{
const { formatMessage } = useIntl();
const { toggleNotification } = useNotification();
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
const [visible, setVisible] = React.useState(false);
const [deleteLocale] = useDeleteLocaleMutation();
const handleConfirm = async ()=>{
try {
const res = await deleteLocale(id);
if ('error' in res) {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
return;
}
toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation('Settings.locales.modal.delete.success'),
defaultMessage: 'Deleted locale'
})
});
setVisible(false);
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred, please try again'
})
});
}
};
return /*#__PURE__*/ jsxs(Dialog.Root, {
open: visible,
onOpenChange: setVisible,
children: [
/*#__PURE__*/ jsx(Dialog.Trigger, {
children: /*#__PURE__*/ jsx(IconButton, {
onClick: ()=>setVisible(true),
label: formatMessage({
id: getTranslation('Settings.list.actions.delete'),
defaultMessage: 'Delete {name} locale'
}, {
name
}),
variant: "ghost",
children: /*#__PURE__*/ jsx(Trash, {})
})
}),
/*#__PURE__*/ jsx(ConfirmDialog, {
onConfirm: handleConfirm
})
]
});
};
export { DeleteLocale };
//# sourceMappingURL=DeleteLocale.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DeleteLocale.mjs","sources":["../../../admin/src/components/DeleteLocale.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { ConfirmDialog, useAPIErrorHandler, useNotification } from '@strapi/admin/strapi-admin';\nimport { Dialog, IconButton } from '@strapi/design-system';\nimport { Trash } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useDeleteLocaleMutation } from '../services/locales';\nimport { getTranslation } from '../utils/getTranslation';\n\nimport type { Locale } from '../../../shared/contracts/locales';\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteLocale\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DeleteLocaleProps extends Locale {}\n\nconst DeleteLocale = ({ id, name }: DeleteLocaleProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n\n const [visible, setVisible] = React.useState(false);\n\n const [deleteLocale] = useDeleteLocaleMutation();\n const handleConfirm = async () => {\n try {\n const res = await deleteLocale(id);\n\n if ('error' in res) {\n toggleNotification({ type: 'danger', message: formatAPIError(res.error) });\n\n return;\n }\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTranslation('Settings.locales.modal.delete.success'),\n defaultMessage: 'Deleted locale',\n }),\n });\n\n setVisible(false);\n } catch (err) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'notification.error',\n defaultMessage: 'An error occurred, please try again',\n }),\n });\n }\n };\n\n return (\n <Dialog.Root open={visible} onOpenChange={setVisible}>\n <Dialog.Trigger>\n <IconButton\n onClick={() => setVisible(true)}\n label={formatMessage(\n {\n id: getTranslation('Settings.list.actions.delete'),\n defaultMessage: 'Delete {name} locale',\n },\n {\n name,\n }\n )}\n variant=\"ghost\"\n >\n <Trash />\n </IconButton>\n </Dialog.Trigger>\n <ConfirmDialog onConfirm={handleConfirm} />\n </Dialog.Root>\n );\n};\n\nexport { DeleteLocale };\n"],"names":["DeleteLocale","id","name","formatMessage","useIntl","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","visible","setVisible","React","useState","deleteLocale","useDeleteLocaleMutation","handleConfirm","res","type","message","error","getTranslation","defaultMessage","err","_jsxs","Dialog","Root","open","onOpenChange","_jsx","Trigger","IconButton","onClick","label","variant","Trash","ConfirmDialog","onConfirm"],"mappings":";;;;;;;;;AAkBA,MAAMA,eAAe,CAAC,EAAEC,EAAE,EAAEC,IAAI,EAAqB,GAAA;IACnD,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAC1B,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,eAAAA,EAAAA;AAC/B,IAAA,MAAM,EAAEC,uBAAAA,EAAyBC,cAAc,EAAE,GAAGC,kBAAAA,EAAAA;AAEpD,IAAA,MAAM,CAACC,OAASC,EAAAA,UAAAA,CAAW,GAAGC,KAAAA,CAAMC,QAAQ,CAAC,KAAA,CAAA;IAE7C,MAAM,CAACC,aAAa,GAAGC,uBAAAA,EAAAA;AACvB,IAAA,MAAMC,aAAgB,GAAA,UAAA;QACpB,IAAI;YACF,MAAMC,GAAAA,GAAM,MAAMH,YAAab,CAAAA,EAAAA,CAAAA;AAE/B,YAAA,IAAI,WAAWgB,GAAK,EAAA;gBAClBZ,kBAAmB,CAAA;oBAAEa,IAAM,EAAA,QAAA;oBAAUC,OAASX,EAAAA,cAAAA,CAAeS,IAAIG,KAAK;AAAE,iBAAA,CAAA;AAExE,gBAAA;AACF;YAEAf,kBAAmB,CAAA;gBACjBa,IAAM,EAAA,SAAA;AACNC,gBAAAA,OAAAA,EAAShB,aAAc,CAAA;AACrBF,oBAAAA,EAAAA,EAAIoB,cAAe,CAAA,uCAAA,CAAA;oBACnBC,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;YAEAX,UAAW,CAAA,KAAA,CAAA;AACb,SAAA,CAAE,OAAOY,GAAK,EAAA;YACZlB,kBAAmB,CAAA;gBACjBa,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAAShB,aAAc,CAAA;oBACrBF,EAAI,EAAA,oBAAA;oBACJqB,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;AACF;AACF,KAAA;IAEA,qBACEE,IAAA,CAACC,OAAOC,IAAI,EAAA;QAACC,IAAMjB,EAAAA,OAAAA;QAASkB,YAAcjB,EAAAA,UAAAA;;AACxC,0BAAAkB,GAAA,CAACJ,OAAOK,OAAO,EAAA;AACb,gBAAA,QAAA,gBAAAD,GAACE,CAAAA,UAAAA,EAAAA;AACCC,oBAAAA,OAAAA,EAAS,IAAMrB,UAAW,CAAA,IAAA,CAAA;AAC1BsB,oBAAAA,KAAAA,EAAO9B,aACL,CAAA;AACEF,wBAAAA,EAAAA,EAAIoB,cAAe,CAAA,8BAAA,CAAA;wBACnBC,cAAgB,EAAA;qBAElB,EAAA;AACEpB,wBAAAA;AACF,qBAAA,CAAA;oBAEFgC,OAAQ,EAAA,OAAA;AAER,oBAAA,QAAA,gBAAAL,GAACM,CAAAA,KAAAA,EAAAA,EAAAA;;;0BAGLN,GAACO,CAAAA,aAAAA,EAAAA;gBAAcC,SAAWrB,EAAAA;;;;AAGhC;;;;"}

View File

@@ -0,0 +1,212 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var locales = require('../services/locales.js');
var baseQuery = require('../utils/baseQuery.js');
var getTranslation = require('../utils/getTranslation.js');
var CreateLocale = require('./CreateLocale.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const EditLocale = (props)=>{
const { formatMessage } = reactIntl.useIntl();
const [visible, setVisible] = React__namespace.useState(false);
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
onClick: ()=>setVisible(true),
label: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.edit'),
defaultMessage: 'Edit {name} locale'
}, {
name: props.name
}),
variant: "ghost",
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Pencil, {})
}),
/*#__PURE__*/ jsxRuntime.jsx(EditModal, {
...props,
open: visible,
onOpenChange: setVisible
})
]
});
};
/**
* @internal
* @description Exported to be used when someone clicks on a table row.
*/ const EditModal = ({ id, code, isDefault, name, open, onOpenChange })=>{
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError, _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
const refetchPermissions = strapiAdmin.useAuth('EditModal', (state)=>state.refetchPermissions);
const { formatMessage } = reactIntl.useIntl();
const titleId = designSystem.useId();
const [updateLocale] = locales.useUpdateLocaleMutation();
const handleSubmit = async ({ code: _code, ...data }, helpers)=>{
try {
/**
* We don't need to send the code, because the
* code can never be changed.
*/ const res = await updateLocale({
id,
...data
});
if ('error' in res) {
if (baseQuery.isBaseQueryError(res.error) && res.error.name === 'ValidationError') {
helpers.setErrors(formatValidationErrors(res.error));
} else {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
}
return;
}
toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.edit.success'),
defaultMessage: 'Updated locale'
})
});
refetchPermissions();
onOpenChange(false);
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred, please try again'
})
});
}
};
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Root, {
open: open,
onOpenChange: onOpenChange,
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Content, {
children: /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Form, {
method: "PUT",
onSubmit: handleSubmit,
initialValues: {
code,
name,
isDefault
},
validationSchema: CreateLocale.LOCALE_SCHEMA,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Header, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Title, {
children: formatMessage({
id: getTranslation.getTranslation('Settings.list.actions.edit'),
defaultMessage: 'Edit a locale'
}, {
name
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Body, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tabs.Root, {
variant: "simple",
defaultValue: "basic",
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
justifyContent: "space-between",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
tag: "h2",
variant: "beta",
id: titleId,
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.title'),
defaultMessage: 'Configuration'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tabs.List, {
"aria-labelledby": titleId,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Trigger, {
value: "basic",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.base'),
defaultMessage: 'Basic settings'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Trigger, {
value: "advanced",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.modal.advanced'),
defaultMessage: 'Advanced settings'
})
})
]
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Divider, {}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
paddingTop: 7,
paddingBottom: 7,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Content, {
value: "basic",
children: /*#__PURE__*/ jsxRuntime.jsx(CreateLocale.BaseForm, {
mode: "edit"
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Content, {
value: "advanced",
children: /*#__PURE__*/ jsxRuntime.jsx(CreateLocale.AdvancedForm, {
isDefaultLocale: isDefault
})
})
]
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Footer, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Close, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(CreateLocale.SubmitButton, {})
]
})
]
})
})
});
};
exports.EditLocale = EditLocale;
exports.EditModal = EditModal;
//# sourceMappingURL=EditLocale.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,190 @@
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useNotification, useAPIErrorHandler, useAuth, Form } from '@strapi/admin/strapi-admin';
import { IconButton, useId, Modal, Tabs, Flex, Typography, Divider, Box, Button } from '@strapi/design-system';
import { Pencil } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useUpdateLocaleMutation } from '../services/locales.mjs';
import { isBaseQueryError } from '../utils/baseQuery.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
import { LOCALE_SCHEMA, BaseForm, AdvancedForm, SubmitButton } from './CreateLocale.mjs';
const EditLocale = (props)=>{
const { formatMessage } = useIntl();
const [visible, setVisible] = React.useState(false);
return /*#__PURE__*/ jsxs(Fragment, {
children: [
/*#__PURE__*/ jsx(IconButton, {
onClick: ()=>setVisible(true),
label: formatMessage({
id: getTranslation('Settings.list.actions.edit'),
defaultMessage: 'Edit {name} locale'
}, {
name: props.name
}),
variant: "ghost",
children: /*#__PURE__*/ jsx(Pencil, {})
}),
/*#__PURE__*/ jsx(EditModal, {
...props,
open: visible,
onOpenChange: setVisible
})
]
});
};
/**
* @internal
* @description Exported to be used when someone clicks on a table row.
*/ const EditModal = ({ id, code, isDefault, name, open, onOpenChange })=>{
const { toggleNotification } = useNotification();
const { _unstableFormatAPIError: formatAPIError, _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
const refetchPermissions = useAuth('EditModal', (state)=>state.refetchPermissions);
const { formatMessage } = useIntl();
const titleId = useId();
const [updateLocale] = useUpdateLocaleMutation();
const handleSubmit = async ({ code: _code, ...data }, helpers)=>{
try {
/**
* We don't need to send the code, because the
* code can never be changed.
*/ const res = await updateLocale({
id,
...data
});
if ('error' in res) {
if (isBaseQueryError(res.error) && res.error.name === 'ValidationError') {
helpers.setErrors(formatValidationErrors(res.error));
} else {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
}
return;
}
toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation('Settings.locales.modal.edit.success'),
defaultMessage: 'Updated locale'
})
});
refetchPermissions();
onOpenChange(false);
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred, please try again'
})
});
}
};
return /*#__PURE__*/ jsx(Modal.Root, {
open: open,
onOpenChange: onOpenChange,
children: /*#__PURE__*/ jsx(Modal.Content, {
children: /*#__PURE__*/ jsxs(Form, {
method: "PUT",
onSubmit: handleSubmit,
initialValues: {
code,
name,
isDefault
},
validationSchema: LOCALE_SCHEMA,
children: [
/*#__PURE__*/ jsx(Modal.Header, {
children: /*#__PURE__*/ jsx(Modal.Title, {
children: formatMessage({
id: getTranslation('Settings.list.actions.edit'),
defaultMessage: 'Edit a locale'
}, {
name
})
})
}),
/*#__PURE__*/ jsx(Modal.Body, {
children: /*#__PURE__*/ jsxs(Tabs.Root, {
variant: "simple",
defaultValue: "basic",
children: [
/*#__PURE__*/ jsxs(Flex, {
justifyContent: "space-between",
children: [
/*#__PURE__*/ jsx(Typography, {
tag: "h2",
variant: "beta",
id: titleId,
children: formatMessage({
id: getTranslation('Settings.locales.modal.title'),
defaultMessage: 'Configuration'
})
}),
/*#__PURE__*/ jsxs(Tabs.List, {
"aria-labelledby": titleId,
children: [
/*#__PURE__*/ jsx(Tabs.Trigger, {
value: "basic",
children: formatMessage({
id: getTranslation('Settings.locales.modal.base'),
defaultMessage: 'Basic settings'
})
}),
/*#__PURE__*/ jsx(Tabs.Trigger, {
value: "advanced",
children: formatMessage({
id: getTranslation('Settings.locales.modal.advanced'),
defaultMessage: 'Advanced settings'
})
})
]
})
]
}),
/*#__PURE__*/ jsx(Divider, {}),
/*#__PURE__*/ jsxs(Box, {
paddingTop: 7,
paddingBottom: 7,
children: [
/*#__PURE__*/ jsx(Tabs.Content, {
value: "basic",
children: /*#__PURE__*/ jsx(BaseForm, {
mode: "edit"
})
}),
/*#__PURE__*/ jsx(Tabs.Content, {
value: "advanced",
children: /*#__PURE__*/ jsx(AdvancedForm, {
isDefaultLocale: isDefault
})
})
]
})
]
})
}),
/*#__PURE__*/ jsxs(Modal.Footer, {
children: [
/*#__PURE__*/ jsx(Modal.Close, {
children: /*#__PURE__*/ jsx(Button, {
variant: "tertiary",
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
/*#__PURE__*/ jsx(SubmitButton, {})
]
})
]
})
})
});
};
export { EditLocale, EditModal };
//# sourceMappingURL=EditLocale.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,82 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var locales = require('../services/locales.js');
const LocaleListCell = ({ locale: currentLocale, localizations })=>{
const { locale: language } = reactIntl.useIntl();
const { data: locales$1 = [] } = locales.useGetLocalesQuery();
const formatter = designSystem.useCollator(language, {
sensitivity: 'base'
});
if (!Array.isArray(locales$1) || !localizations) {
return null;
}
const availableLocales = localizations.map((loc)=>loc.locale);
const localesForDocument = locales$1.reduce((acc, locale)=>{
const createdLocale = [
currentLocale,
...availableLocales
].find((loc)=>{
return loc === locale.code;
});
if (createdLocale) {
acc.push(locale);
}
return acc;
}, []).map((locale)=>{
if (locale.isDefault) {
return `${locale.name} (default)`;
}
return locale.name;
}).toSorted((a, b)=>formatter.compare(a, b));
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Popover.Root, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "ghost",
type: "button",
onClick: (e)=>e.stopPropagation(),
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
minWidth: "100%",
alignItems: "center",
justifyContent: "center",
fontWeight: "regular",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "neutral800",
ellipsis: true,
marginRight: 2,
children: localesForDocument.join(', ')
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
children: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {
width: "1.2rem",
height: "1.2rem"
})
})
]
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Content, {
sideOffset: 16,
children: /*#__PURE__*/ jsxRuntime.jsx("ul", {
children: localesForDocument.map((name)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
padding: 3,
tag: "li",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: name
})
}, name))
})
})
]
});
};
exports.LocaleListCell = LocaleListCell;
//# sourceMappingURL=LocaleListCell.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,80 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { useCollator, Popover, Button, Flex, Typography, Box } from '@strapi/design-system';
import { CaretDown } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useGetLocalesQuery } from '../services/locales.mjs';
const LocaleListCell = ({ locale: currentLocale, localizations })=>{
const { locale: language } = useIntl();
const { data: locales = [] } = useGetLocalesQuery();
const formatter = useCollator(language, {
sensitivity: 'base'
});
if (!Array.isArray(locales) || !localizations) {
return null;
}
const availableLocales = localizations.map((loc)=>loc.locale);
const localesForDocument = locales.reduce((acc, locale)=>{
const createdLocale = [
currentLocale,
...availableLocales
].find((loc)=>{
return loc === locale.code;
});
if (createdLocale) {
acc.push(locale);
}
return acc;
}, []).map((locale)=>{
if (locale.isDefault) {
return `${locale.name} (default)`;
}
return locale.name;
}).toSorted((a, b)=>formatter.compare(a, b));
return /*#__PURE__*/ jsxs(Popover.Root, {
children: [
/*#__PURE__*/ jsx(Popover.Trigger, {
children: /*#__PURE__*/ jsx(Button, {
variant: "ghost",
type: "button",
onClick: (e)=>e.stopPropagation(),
children: /*#__PURE__*/ jsxs(Flex, {
minWidth: "100%",
alignItems: "center",
justifyContent: "center",
fontWeight: "regular",
children: [
/*#__PURE__*/ jsx(Typography, {
textColor: "neutral800",
ellipsis: true,
marginRight: 2,
children: localesForDocument.join(', ')
}),
/*#__PURE__*/ jsx(Flex, {
children: /*#__PURE__*/ jsx(CaretDown, {
width: "1.2rem",
height: "1.2rem"
})
})
]
})
})
}),
/*#__PURE__*/ jsx(Popover.Content, {
sideOffset: 16,
children: /*#__PURE__*/ jsx("ul", {
children: localesForDocument.map((name)=>/*#__PURE__*/ jsx(Box, {
padding: 3,
tag: "li",
children: /*#__PURE__*/ jsx(Typography, {
children: name
})
}, name))
})
})
]
});
};
export { LocaleListCell };
//# sourceMappingURL=LocaleListCell.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,98 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useI18n = require('../hooks/useI18n.js');
var locales = require('../services/locales.js');
var getTranslation = require('../utils/getTranslation.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const LocalePicker = ()=>{
const { formatMessage } = reactIntl.useIntl();
const [{ query }, setQuery] = strapiAdmin.useQueryParams();
const { hasI18n, canRead, canCreate } = useI18n.useI18n();
const { data: locales$1 = [] } = locales.useGetLocalesQuery(undefined, {
skip: !hasI18n
});
const handleChange = React__namespace.useCallback((code, replace = false)=>{
setQuery({
page: 1,
plugins: {
...query.plugins,
i18n: {
locale: code
}
}
}, 'push', replace);
}, [
query.plugins,
setQuery
]);
React__namespace.useEffect(()=>{
if (!Array.isArray(locales$1) || !hasI18n) {
return;
}
/**
* Handle the case where the current locale query param doesn't exist
* in the list of available locales, so we redirect to the default locale.
*/ const currentDesiredLocale = query.plugins?.i18n?.locale;
const doesLocaleExist = locales$1.find((loc)=>loc.code === currentDesiredLocale);
const defaultLocale = locales$1.find((locale)=>locale.isDefault);
if (!doesLocaleExist && defaultLocale?.code) {
handleChange(defaultLocale.code, true);
}
}, [
hasI18n,
handleChange,
locales$1,
query.plugins?.i18n?.locale
]);
if (!hasI18n || !Array.isArray(locales$1) || locales$1.length === 0) {
return null;
}
const displayedLocales = locales$1.filter((locale)=>{
/**
* If you can create or read we allow you to see the locale exists
* this is because in the ListView, you may be able to create a new entry
* in a locale you can't read.
*/ return canCreate.includes(locale.code) || canRead.includes(locale.code);
});
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelect, {
size: "S",
"aria-label": formatMessage({
id: getTranslation.getTranslation('actions.select-locale'),
defaultMessage: 'Select locale'
}),
value: query.plugins?.i18n?.locale || locales$1.find((locale)=>locale.isDefault)?.code,
// @ts-expect-error This can be removed in V2 of the DS.
onChange: handleChange,
children: displayedLocales.map((locale)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
value: locale.code,
children: locale.name
}, locale.id))
});
};
exports.LocalePicker = LocalePicker;
//# sourceMappingURL=LocalePicker.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
import { jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useQueryParams } from '@strapi/admin/strapi-admin';
import { SingleSelect, SingleSelectOption } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useI18n } from '../hooks/useI18n.mjs';
import { useGetLocalesQuery } from '../services/locales.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
const LocalePicker = ()=>{
const { formatMessage } = useIntl();
const [{ query }, setQuery] = useQueryParams();
const { hasI18n, canRead, canCreate } = useI18n();
const { data: locales = [] } = useGetLocalesQuery(undefined, {
skip: !hasI18n
});
const handleChange = React.useCallback((code, replace = false)=>{
setQuery({
page: 1,
plugins: {
...query.plugins,
i18n: {
locale: code
}
}
}, 'push', replace);
}, [
query.plugins,
setQuery
]);
React.useEffect(()=>{
if (!Array.isArray(locales) || !hasI18n) {
return;
}
/**
* Handle the case where the current locale query param doesn't exist
* in the list of available locales, so we redirect to the default locale.
*/ const currentDesiredLocale = query.plugins?.i18n?.locale;
const doesLocaleExist = locales.find((loc)=>loc.code === currentDesiredLocale);
const defaultLocale = locales.find((locale)=>locale.isDefault);
if (!doesLocaleExist && defaultLocale?.code) {
handleChange(defaultLocale.code, true);
}
}, [
hasI18n,
handleChange,
locales,
query.plugins?.i18n?.locale
]);
if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
return null;
}
const displayedLocales = locales.filter((locale)=>{
/**
* If you can create or read we allow you to see the locale exists
* this is because in the ListView, you may be able to create a new entry
* in a locale you can't read.
*/ return canCreate.includes(locale.code) || canRead.includes(locale.code);
});
return /*#__PURE__*/ jsx(SingleSelect, {
size: "S",
"aria-label": formatMessage({
id: getTranslation('actions.select-locale'),
defaultMessage: 'Select locale'
}),
value: query.plugins?.i18n?.locale || locales.find((locale)=>locale.isDefault)?.code,
// @ts-expect-error This can be removed in V2 of the DS.
onChange: handleChange,
children: displayedLocales.map((locale)=>/*#__PURE__*/ jsx(SingleSelectOption, {
value: locale.code,
children: locale.name
}, locale.id))
});
};
export { LocalePicker };
//# sourceMappingURL=LocalePicker.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,143 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var getTranslation = require('../utils/getTranslation.js');
var DeleteLocale = require('./DeleteLocale.js');
var EditLocale = require('./EditLocale.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const LocaleTable = ({ locales = [], canDelete, canUpdate })=>{
const [editLocaleId, setEditLocaleId] = React__namespace.useState();
const { formatMessage } = reactIntl.useIntl();
const handleClick = (localeId)=>()=>{
if (canUpdate) {
setEditLocaleId(localeId);
}
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Table, {
colCount: 4,
rowCount: locales.length + 1,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Thead, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.row.id'),
defaultMessage: 'ID'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.row.displayName'),
defaultMessage: 'Display name'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTranslation.getTranslation('Settings.locales.row.default-locale'),
defaultMessage: 'Default locale'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
children: "Actions"
})
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tbody, {
children: locales.map((locale)=>/*#__PURE__*/ jsxRuntime.jsxs(React__namespace.Fragment, {
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
onClick: handleClick(locale.id),
style: {
cursor: canUpdate ? 'pointer' : 'default'
},
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "neutral800",
children: locale.id
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "neutral800",
children: locale.name
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "neutral800",
children: locale.isDefault ? formatMessage({
id: getTranslation.getTranslation('Settings.locales.default'),
defaultMessage: 'Default'
}) : null
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
gap: 1,
justifyContent: "flex-end",
onClick: (e)=>e.stopPropagation(),
children: [
canUpdate && /*#__PURE__*/ jsxRuntime.jsx(EditLocale.EditLocale, {
...locale
}),
canDelete && !locale.isDefault && /*#__PURE__*/ jsxRuntime.jsx(DeleteLocale.DeleteLocale, {
...locale
})
]
})
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(EditLocale.EditModal, {
...locale,
onOpenChange: ()=>setEditLocaleId(undefined),
open: editLocaleId === locale.id
})
]
}, locale.id))
})
]
});
};
exports.LocaleTable = LocaleTable;
//# sourceMappingURL=LocaleTable.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,122 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { Table, Thead, Tr, Th, Typography, VisuallyHidden, Tbody, Td, Flex } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { getTranslation } from '../utils/getTranslation.mjs';
import { DeleteLocale } from './DeleteLocale.mjs';
import { EditLocale, EditModal } from './EditLocale.mjs';
const LocaleTable = ({ locales = [], canDelete, canUpdate })=>{
const [editLocaleId, setEditLocaleId] = React.useState();
const { formatMessage } = useIntl();
const handleClick = (localeId)=>()=>{
if (canUpdate) {
setEditLocaleId(localeId);
}
};
return /*#__PURE__*/ jsxs(Table, {
colCount: 4,
rowCount: locales.length + 1,
children: [
/*#__PURE__*/ jsx(Thead, {
children: /*#__PURE__*/ jsxs(Tr, {
children: [
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTranslation('Settings.locales.row.id'),
defaultMessage: 'ID'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTranslation('Settings.locales.row.displayName'),
defaultMessage: 'Display name'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTranslation('Settings.locales.row.default-locale'),
defaultMessage: 'Default locale'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(VisuallyHidden, {
children: "Actions"
})
})
]
})
}),
/*#__PURE__*/ jsx(Tbody, {
children: locales.map((locale)=>/*#__PURE__*/ jsxs(React.Fragment, {
children: [
/*#__PURE__*/ jsxs(Tr, {
onClick: handleClick(locale.id),
style: {
cursor: canUpdate ? 'pointer' : 'default'
},
children: [
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Typography, {
textColor: "neutral800",
children: locale.id
})
}),
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Typography, {
textColor: "neutral800",
children: locale.name
})
}),
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Typography, {
textColor: "neutral800",
children: locale.isDefault ? formatMessage({
id: getTranslation('Settings.locales.default'),
defaultMessage: 'Default'
}) : null
})
}),
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsxs(Flex, {
gap: 1,
justifyContent: "flex-end",
onClick: (e)=>e.stopPropagation(),
children: [
canUpdate && /*#__PURE__*/ jsx(EditLocale, {
...locale
}),
canDelete && !locale.isDefault && /*#__PURE__*/ jsx(DeleteLocale, {
...locale
})
]
})
})
]
}),
/*#__PURE__*/ jsx(EditModal, {
...locale,
onOpenChange: ()=>setEditLocaleId(undefined),
open: editLocaleId === locale.id
})
]
}, locale.id))
})
]
});
};
export { LocaleTable };
//# sourceMappingURL=LocaleTable.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
'use strict';
const PERMISSIONS = {
accessMain: [
{
action: 'plugin::i18n.locale.read',
subject: null
}
],
create: [
{
action: 'plugin::i18n.locale.create',
subject: null
}
],
delete: [
{
action: 'plugin::i18n.locale.delete',
subject: null
}
],
update: [
{
action: 'plugin::i18n.locale.update',
subject: null
}
],
read: [
{
action: 'plugin::i18n.locale.read',
subject: null
}
]
};
exports.PERMISSIONS = PERMISSIONS;
//# sourceMappingURL=constants.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sources":["../../admin/src/constants.ts"],"sourcesContent":["export const PERMISSIONS = {\n accessMain: [{ action: 'plugin::i18n.locale.read', subject: null }],\n create: [{ action: 'plugin::i18n.locale.create', subject: null }],\n delete: [{ action: 'plugin::i18n.locale.delete', subject: null }],\n update: [{ action: 'plugin::i18n.locale.update', subject: null }],\n read: [{ action: 'plugin::i18n.locale.read', subject: null }],\n};\n"],"names":["PERMISSIONS","accessMain","action","subject","create","delete","update","read"],"mappings":";;MAAaA,WAAc,GAAA;IACzBC,UAAY,EAAA;AAAC,QAAA;YAAEC,MAAQ,EAAA,0BAAA;YAA4BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACnEC,MAAQ,EAAA;AAAC,QAAA;YAAEF,MAAQ,EAAA,4BAAA;YAA8BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACjEE,MAAQ,EAAA;AAAC,QAAA;YAAEH,MAAQ,EAAA,4BAAA;YAA8BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACjEG,MAAQ,EAAA;AAAC,QAAA;YAAEJ,MAAQ,EAAA,4BAAA;YAA8BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACjEI,IAAM,EAAA;AAAC,QAAA;YAAEL,MAAQ,EAAA,0BAAA;YAA4BC,OAAS,EAAA;AAAK;AAAE;AAC/D;;;;"}

View File

@@ -0,0 +1,35 @@
const PERMISSIONS = {
accessMain: [
{
action: 'plugin::i18n.locale.read',
subject: null
}
],
create: [
{
action: 'plugin::i18n.locale.create',
subject: null
}
],
delete: [
{
action: 'plugin::i18n.locale.delete',
subject: null
}
],
update: [
{
action: 'plugin::i18n.locale.update',
subject: null
}
],
read: [
{
action: 'plugin::i18n.locale.read',
subject: null
}
]
};
export { PERMISSIONS };
//# sourceMappingURL=constants.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constants.mjs","sources":["../../admin/src/constants.ts"],"sourcesContent":["export const PERMISSIONS = {\n accessMain: [{ action: 'plugin::i18n.locale.read', subject: null }],\n create: [{ action: 'plugin::i18n.locale.create', subject: null }],\n delete: [{ action: 'plugin::i18n.locale.delete', subject: null }],\n update: [{ action: 'plugin::i18n.locale.update', subject: null }],\n read: [{ action: 'plugin::i18n.locale.read', subject: null }],\n};\n"],"names":["PERMISSIONS","accessMain","action","subject","create","delete","update","read"],"mappings":"MAAaA,WAAc,GAAA;IACzBC,UAAY,EAAA;AAAC,QAAA;YAAEC,MAAQ,EAAA,0BAAA;YAA4BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACnEC,MAAQ,EAAA;AAAC,QAAA;YAAEF,MAAQ,EAAA,4BAAA;YAA8BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACjEE,MAAQ,EAAA;AAAC,QAAA;YAAEH,MAAQ,EAAA,4BAAA;YAA8BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACjEG,MAAQ,EAAA;AAAC,QAAA;YAAEJ,MAAQ,EAAA,4BAAA;YAA8BC,OAAS,EAAA;AAAK;AAAE,KAAA;IACjEI,IAAM,EAAA;AAAC,QAAA;YAAEL,MAAQ,EAAA,0BAAA;YAA4BC,OAAS,EAAA;AAAK;AAAE;AAC/D;;;;"}

View File

@@ -0,0 +1,106 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var styledComponents = require('styled-components');
var getTranslation = require('../utils/getTranslation.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const mutateEditViewHook = ({ layout })=>{
// If i18n isn't explicitly enabled on the content type, then no field can be localized
if (!('i18n' in layout.options) || typeof layout.options.i18n === 'object' && layout.options.i18n !== null && 'localized' in layout.options.i18n && !layout.options.i18n.localized) {
return {
layout
};
}
const components = Object.entries(layout.components).reduce((acc, [key, componentLayout])=>{
return {
...acc,
[key]: {
...componentLayout,
layout: componentLayout.layout.map((row)=>row.map(addLabelActionToField))
}
};
}, {});
return {
layout: {
...layout,
components,
layout: layout.layout.map((panel)=>panel.map((row)=>row.map(addLabelActionToField)))
}
};
};
const addLabelActionToField = (field)=>{
const isFieldLocalized = doesFieldHaveI18nPluginOpt(field.attribute.pluginOptions) ? field.attribute.pluginOptions.i18n.localized : true;
const labelActionProps = {
title: {
id: isFieldLocalized ? getTranslation.getTranslation('Field.localized') : getTranslation.getTranslation('Field.not-localized'),
defaultMessage: isFieldLocalized ? 'This value is unique for the selected locale' : 'This value is the same across all locales'
},
icon: isFieldLocalized ? /*#__PURE__*/ jsxRuntime.jsx(icons.Earth, {}) : null
};
return {
...field,
labelAction: isFieldLocalized ? /*#__PURE__*/ jsxRuntime.jsx(LabelAction, {
...labelActionProps
}) : null
};
};
const doesFieldHaveI18nPluginOpt = (pluginOpts)=>{
if (!pluginOpts) {
return false;
}
return 'i18n' in pluginOpts && typeof pluginOpts.i18n === 'object' && pluginOpts.i18n !== null && 'localized' in pluginOpts.i18n;
};
const LabelAction = ({ title, icon })=>{
const { formatMessage } = reactIntl.useIntl();
return /*#__PURE__*/ jsxRuntime.jsxs(Span, {
tag: "span",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
tag: "span",
children: formatMessage(title)
}),
/*#__PURE__*/ React__namespace.cloneElement(icon, {
'aria-hidden': true,
focusable: false
})
]
});
};
const Span = styledComponents.styled(designSystem.Flex)`
svg {
width: 12px;
height: 12px;
fill: ${({ theme })=>theme.colors.neutral500};
path {
fill: ${({ theme })=>theme.colors.neutral500};
}
}
`;
exports.mutateEditViewHook = mutateEditViewHook;
//# sourceMappingURL=editView.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { Flex, VisuallyHidden } from '@strapi/design-system';
import { Earth } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { styled } from 'styled-components';
import { getTranslation } from '../utils/getTranslation.mjs';
const mutateEditViewHook = ({ layout })=>{
// If i18n isn't explicitly enabled on the content type, then no field can be localized
if (!('i18n' in layout.options) || typeof layout.options.i18n === 'object' && layout.options.i18n !== null && 'localized' in layout.options.i18n && !layout.options.i18n.localized) {
return {
layout
};
}
const components = Object.entries(layout.components).reduce((acc, [key, componentLayout])=>{
return {
...acc,
[key]: {
...componentLayout,
layout: componentLayout.layout.map((row)=>row.map(addLabelActionToField))
}
};
}, {});
return {
layout: {
...layout,
components,
layout: layout.layout.map((panel)=>panel.map((row)=>row.map(addLabelActionToField)))
}
};
};
const addLabelActionToField = (field)=>{
const isFieldLocalized = doesFieldHaveI18nPluginOpt(field.attribute.pluginOptions) ? field.attribute.pluginOptions.i18n.localized : true;
const labelActionProps = {
title: {
id: isFieldLocalized ? getTranslation('Field.localized') : getTranslation('Field.not-localized'),
defaultMessage: isFieldLocalized ? 'This value is unique for the selected locale' : 'This value is the same across all locales'
},
icon: isFieldLocalized ? /*#__PURE__*/ jsx(Earth, {}) : null
};
return {
...field,
labelAction: isFieldLocalized ? /*#__PURE__*/ jsx(LabelAction, {
...labelActionProps
}) : null
};
};
const doesFieldHaveI18nPluginOpt = (pluginOpts)=>{
if (!pluginOpts) {
return false;
}
return 'i18n' in pluginOpts && typeof pluginOpts.i18n === 'object' && pluginOpts.i18n !== null && 'localized' in pluginOpts.i18n;
};
const LabelAction = ({ title, icon })=>{
const { formatMessage } = useIntl();
return /*#__PURE__*/ jsxs(Span, {
tag: "span",
children: [
/*#__PURE__*/ jsx(VisuallyHidden, {
tag: "span",
children: formatMessage(title)
}),
/*#__PURE__*/ React.cloneElement(icon, {
'aria-hidden': true,
focusable: false
})
]
});
};
const Span = styled(Flex)`
svg {
width: 12px;
height: 12px;
fill: ${({ theme })=>theme.colors.neutral500};
path {
fill: ${({ theme })=>theme.colors.neutral500};
}
}
`;
export { mutateEditViewHook };
//# sourceMappingURL=editView.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,43 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var LocaleListCell = require('../components/LocaleListCell.js');
var fields = require('../utils/fields.js');
var getTranslation = require('../utils/getTranslation.js');
const addColumnToTableHook = ({ displayedHeaders, layout })=>{
const { options } = layout;
const isFieldLocalized = fields.doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
if (!isFieldLocalized) {
return {
displayedHeaders,
layout
};
}
return {
displayedHeaders: [
...displayedHeaders,
{
attribute: {
type: 'string'
},
label: {
id: getTranslation.getTranslation('list-view.table.header.label'),
defaultMessage: 'Available in'
},
searchable: false,
sortable: false,
name: 'locales',
// @ts-expect-error ID is seen as number | string; this will change when we move the type over.
cellFormatter: (props, _header, meta)=>/*#__PURE__*/ jsxRuntime.jsx(LocaleListCell.LocaleListCell, {
...props,
...meta
})
}
],
layout
};
};
exports.addColumnToTableHook = addColumnToTableHook;
//# sourceMappingURL=listView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"listView.js","sources":["../../../admin/src/contentManagerHooks/listView.tsx"],"sourcesContent":["/* eslint-disable check-file/filename-naming-convention */\nimport { LocaleListCell } from '../components/LocaleListCell';\nimport { doesPluginOptionsHaveI18nLocalized } from '../utils/fields';\nimport { getTranslation } from '../utils/getTranslation';\n\nimport type { ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options)\n ? options.i18n.localized\n : false;\n\n if (!isFieldLocalized) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n attribute: { type: 'string' },\n label: {\n id: getTranslation('list-view.table.header.label'),\n defaultMessage: 'Available in',\n },\n searchable: false,\n sortable: false,\n name: 'locales',\n // @ts-expect-error ID is seen as number | string; this will change when we move the type over.\n cellFormatter: (props, _header, meta) => <LocaleListCell {...props} {...meta} />,\n },\n ],\n layout,\n };\n};\n\nexport { addColumnToTableHook };\n"],"names":["addColumnToTableHook","displayedHeaders","layout","options","isFieldLocalized","doesPluginOptionsHaveI18nLocalized","i18n","localized","attribute","type","label","id","getTranslation","defaultMessage","searchable","sortable","name","cellFormatter","props","_header","meta","_jsx","LocaleListCell"],"mappings":";;;;;;;AAeA,MAAMA,uBAAuB,CAAC,EAAEC,gBAAgB,EAAEC,MAAM,EAA4B,GAAA;IAClF,MAAM,EAAEC,OAAO,EAAE,GAAGD,MAAAA;AAEpB,IAAA,MAAME,mBAAmBC,yCAAmCF,CAAAA,OAAAA,CAAAA,GACxDA,QAAQG,IAAI,CAACC,SAAS,GACtB,KAAA;AAEJ,IAAA,IAAI,CAACH,gBAAkB,EAAA;QACrB,OAAO;AAAEH,YAAAA,gBAAAA;AAAkBC,YAAAA;AAAO,SAAA;AACpC;IAEA,OAAO;QACLD,gBAAkB,EAAA;AACbA,YAAAA,GAAAA,gBAAAA;AACH,YAAA;gBACEO,SAAW,EAAA;oBAAEC,IAAM,EAAA;AAAS,iBAAA;gBAC5BC,KAAO,EAAA;AACLC,oBAAAA,EAAAA,EAAIC,6BAAe,CAAA,8BAAA,CAAA;oBACnBC,cAAgB,EAAA;AAClB,iBAAA;gBACAC,UAAY,EAAA,KAAA;gBACZC,QAAU,EAAA,KAAA;gBACVC,IAAM,EAAA,SAAA;;AAENC,gBAAAA,aAAAA,EAAe,CAACC,KAAAA,EAAOC,OAASC,EAAAA,IAAAA,iBAASC,cAACC,CAAAA,6BAAAA,EAAAA;AAAgB,wBAAA,GAAGJ,KAAK;AAAG,wBAAA,GAAGE;;AAC1E;AACD,SAAA;AACDlB,QAAAA;AACF,KAAA;AACF;;;;"}

View File

@@ -0,0 +1,41 @@
import { jsx } from 'react/jsx-runtime';
import { LocaleListCell } from '../components/LocaleListCell.mjs';
import { doesPluginOptionsHaveI18nLocalized } from '../utils/fields.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
const addColumnToTableHook = ({ displayedHeaders, layout })=>{
const { options } = layout;
const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
if (!isFieldLocalized) {
return {
displayedHeaders,
layout
};
}
return {
displayedHeaders: [
...displayedHeaders,
{
attribute: {
type: 'string'
},
label: {
id: getTranslation('list-view.table.header.label'),
defaultMessage: 'Available in'
},
searchable: false,
sortable: false,
name: 'locales',
// @ts-expect-error ID is seen as number | string; this will change when we move the type over.
cellFormatter: (props, _header, meta)=>/*#__PURE__*/ jsx(LocaleListCell, {
...props,
...meta
})
}
],
layout
};
};
export { addColumnToTableHook };
//# sourceMappingURL=listView.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"listView.mjs","sources":["../../../admin/src/contentManagerHooks/listView.tsx"],"sourcesContent":["/* eslint-disable check-file/filename-naming-convention */\nimport { LocaleListCell } from '../components/LocaleListCell';\nimport { doesPluginOptionsHaveI18nLocalized } from '../utils/fields';\nimport { getTranslation } from '../utils/getTranslation';\n\nimport type { ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options)\n ? options.i18n.localized\n : false;\n\n if (!isFieldLocalized) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n attribute: { type: 'string' },\n label: {\n id: getTranslation('list-view.table.header.label'),\n defaultMessage: 'Available in',\n },\n searchable: false,\n sortable: false,\n name: 'locales',\n // @ts-expect-error ID is seen as number | string; this will change when we move the type over.\n cellFormatter: (props, _header, meta) => <LocaleListCell {...props} {...meta} />,\n },\n ],\n layout,\n };\n};\n\nexport { addColumnToTableHook };\n"],"names":["addColumnToTableHook","displayedHeaders","layout","options","isFieldLocalized","doesPluginOptionsHaveI18nLocalized","i18n","localized","attribute","type","label","id","getTranslation","defaultMessage","searchable","sortable","name","cellFormatter","props","_header","meta","_jsx","LocaleListCell"],"mappings":";;;;;AAeA,MAAMA,uBAAuB,CAAC,EAAEC,gBAAgB,EAAEC,MAAM,EAA4B,GAAA;IAClF,MAAM,EAAEC,OAAO,EAAE,GAAGD,MAAAA;AAEpB,IAAA,MAAME,mBAAmBC,kCAAmCF,CAAAA,OAAAA,CAAAA,GACxDA,QAAQG,IAAI,CAACC,SAAS,GACtB,KAAA;AAEJ,IAAA,IAAI,CAACH,gBAAkB,EAAA;QACrB,OAAO;AAAEH,YAAAA,gBAAAA;AAAkBC,YAAAA;AAAO,SAAA;AACpC;IAEA,OAAO;QACLD,gBAAkB,EAAA;AACbA,YAAAA,GAAAA,gBAAAA;AACH,YAAA;gBACEO,SAAW,EAAA;oBAAEC,IAAM,EAAA;AAAS,iBAAA;gBAC5BC,KAAO,EAAA;AACLC,oBAAAA,EAAAA,EAAIC,cAAe,CAAA,8BAAA,CAAA;oBACnBC,cAAgB,EAAA;AAClB,iBAAA;gBACAC,UAAY,EAAA,KAAA;gBACZC,QAAU,EAAA,KAAA;gBACVC,IAAM,EAAA,SAAA;;AAENC,gBAAAA,aAAAA,EAAe,CAACC,KAAAA,EAAOC,OAASC,EAAAA,IAAAA,iBAASC,GAACC,CAAAA,cAAAA,EAAAA;AAAgB,wBAAA,GAAGJ,KAAK;AAAG,wBAAA,GAAGE;;AAC1E;AACD,SAAA;AACDlB,QAAAA;AACF,KAAA;AACF;;;;"}

View File

@@ -0,0 +1,20 @@
'use strict';
const addLocaleToReleasesHook = ({ displayedHeaders = [] })=>{
return {
displayedHeaders: [
...displayedHeaders,
{
label: {
id: 'content-releases.page.ReleaseDetails.table.header.label.locale',
defaultMessage: 'locale'
},
name: 'locale'
}
],
hasI18nEnabled: true
};
};
exports.addLocaleToReleasesHook = addLocaleToReleasesHook;
//# sourceMappingURL=releaseDetailsView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"releaseDetailsView.js","sources":["../../../admin/src/contentReleasesHooks/releaseDetailsView.ts"],"sourcesContent":["import type { Schema } from '@strapi/types';\n/* -------------------------------------------------------------------------------------------------\n * addLocaleToReleasesHook\n * -----------------------------------------------------------------------------------------------*/\ninterface AddLocaleToReleasesHookArgs {\n displayedHeaders: {\n key: string;\n fieldSchema: Schema.Attribute.Kind | 'custom';\n metadatas: {\n label: { id: string; defaultMessage: string };\n searchable: boolean;\n sortable: boolean;\n };\n name: string;\n }[];\n hasI18nEnabled: boolean;\n}\n\nconst addLocaleToReleasesHook = ({ displayedHeaders = [] }: AddLocaleToReleasesHookArgs) => {\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n label: {\n id: 'content-releases.page.ReleaseDetails.table.header.label.locale',\n defaultMessage: 'locale',\n },\n name: 'locale',\n },\n ],\n hasI18nEnabled: true,\n };\n};\n\nexport { addLocaleToReleasesHook };\n"],"names":["addLocaleToReleasesHook","displayedHeaders","label","id","defaultMessage","name","hasI18nEnabled"],"mappings":";;AAkBA,MAAMA,uBAA0B,GAAA,CAAC,EAAEC,gBAAAA,GAAmB,EAAE,EAA+B,GAAA;IACrF,OAAO;QACLA,gBAAkB,EAAA;AACbA,YAAAA,GAAAA,gBAAAA;AACH,YAAA;gBACEC,KAAO,EAAA;oBACLC,EAAI,EAAA,gEAAA;oBACJC,cAAgB,EAAA;AAClB,iBAAA;gBACAC,IAAM,EAAA;AACR;AACD,SAAA;QACDC,cAAgB,EAAA;AAClB,KAAA;AACF;;;;"}

View File

@@ -0,0 +1,18 @@
const addLocaleToReleasesHook = ({ displayedHeaders = [] })=>{
return {
displayedHeaders: [
...displayedHeaders,
{
label: {
id: 'content-releases.page.ReleaseDetails.table.header.label.locale',
defaultMessage: 'locale'
},
name: 'locale'
}
],
hasI18nEnabled: true
};
};
export { addLocaleToReleasesHook };
//# sourceMappingURL=releaseDetailsView.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"releaseDetailsView.mjs","sources":["../../../admin/src/contentReleasesHooks/releaseDetailsView.ts"],"sourcesContent":["import type { Schema } from '@strapi/types';\n/* -------------------------------------------------------------------------------------------------\n * addLocaleToReleasesHook\n * -----------------------------------------------------------------------------------------------*/\ninterface AddLocaleToReleasesHookArgs {\n displayedHeaders: {\n key: string;\n fieldSchema: Schema.Attribute.Kind | 'custom';\n metadatas: {\n label: { id: string; defaultMessage: string };\n searchable: boolean;\n sortable: boolean;\n };\n name: string;\n }[];\n hasI18nEnabled: boolean;\n}\n\nconst addLocaleToReleasesHook = ({ displayedHeaders = [] }: AddLocaleToReleasesHookArgs) => {\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n label: {\n id: 'content-releases.page.ReleaseDetails.table.header.label.locale',\n defaultMessage: 'locale',\n },\n name: 'locale',\n },\n ],\n hasI18nEnabled: true,\n };\n};\n\nexport { addLocaleToReleasesHook };\n"],"names":["addLocaleToReleasesHook","displayedHeaders","label","id","defaultMessage","name","hasI18nEnabled"],"mappings":"AAkBA,MAAMA,uBAA0B,GAAA,CAAC,EAAEC,gBAAAA,GAAmB,EAAE,EAA+B,GAAA;IACrF,OAAO;QACLA,gBAAkB,EAAA;AACbA,YAAAA,GAAAA,gBAAAA;AACH,YAAA;gBACEC,KAAO,EAAA;oBACLC,EAAI,EAAA,gEAAA;oBACJC,cAAgB,EAAA;AAClB,iBAAA;gBACAC,IAAM,EAAA;AACR;AACD,SAAA;QACDC,cAAgB,EAAA;AAClB,KAAA;AACF;;;;"}

View File

@@ -0,0 +1,78 @@
'use strict';
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var strapiAdmin$1 = require('@strapi/content-manager/strapi-admin');
var reactRouterDom = require('react-router-dom');
var fields = require('../utils/fields.js');
var strings = require('../utils/strings.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
/**
* @alpha
* @description This hook is used to get the i18n status of a content type.
* Also returns the CRUDP permission locale properties for the content type
* so we know which locales the user can perform actions on.
*/ const useI18n = ()=>{
// Extract the params from the URL to pass to our useDocument hook
const params = reactRouterDom.useParams();
const userPermissions = strapiAdmin.useAuth('useI18n', (state)=>state.permissions);
const actions = React__namespace.useMemo(()=>{
const permissions = userPermissions.filter((permission)=>permission.subject === params.slug);
return permissions.reduce((acc, permission)=>{
const [actionShorthand] = permission.action.split('.').slice(-1);
return {
...acc,
[`can${strings.capitalize(actionShorthand)}`]: permission.properties?.locales ?? []
};
}, {
canCreate: [],
canRead: [],
canUpdate: [],
canDelete: [],
canPublish: []
});
}, [
params.slug,
userPermissions
]);
// TODO: use specific hook to get schema only
const { schema } = strapiAdmin$1.unstable_useDocument({
// We can non-null assert these because below we skip the query if they are not present
collectionType: params.collectionType,
model: params.slug
}, {
skip: true
});
if (fields.doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
return {
hasI18n: schema.pluginOptions.i18n.localized,
...actions
};
}
return {
hasI18n: false,
...actions
};
};
exports.useI18n = useI18n;
//# sourceMappingURL=useI18n.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useI18n.js","sources":["../../../admin/src/hooks/useI18n.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useAuth } from '@strapi/admin/strapi-admin';\nimport { unstable_useDocument as useDocument } from '@strapi/content-manager/strapi-admin';\nimport { useParams } from 'react-router-dom';\n\nimport { doesPluginOptionsHaveI18nLocalized } from '../utils/fields';\nimport { capitalize } from '../utils/strings';\n\ntype UseI18n = () => {\n hasI18n: boolean;\n canCreate: string[];\n canRead: string[];\n canUpdate: string[];\n canDelete: string[];\n canPublish: string[];\n};\n\n/**\n * @alpha\n * @description This hook is used to get the i18n status of a content type.\n * Also returns the CRUDP permission locale properties for the content type\n * so we know which locales the user can perform actions on.\n */\nconst useI18n: UseI18n = () => {\n // Extract the params from the URL to pass to our useDocument hook\n const params = useParams<{ collectionType: string; slug: string; model: string }>();\n\n const userPermissions = useAuth('useI18n', (state) => state.permissions);\n const actions = React.useMemo(() => {\n const permissions = userPermissions.filter((permission) => permission.subject === params.slug);\n\n return permissions.reduce<Omit<ReturnType<UseI18n>, 'hasI18n'>>(\n (acc, permission) => {\n const [actionShorthand] = permission.action.split('.').slice(-1);\n\n return {\n ...acc,\n [`can${capitalize(actionShorthand)}`]: permission.properties?.locales ?? [],\n };\n },\n { canCreate: [], canRead: [], canUpdate: [], canDelete: [], canPublish: [] }\n );\n }, [params.slug, userPermissions]);\n\n // TODO: use specific hook to get schema only\n const { schema } = useDocument(\n {\n // We can non-null assert these because below we skip the query if they are not present\n collectionType: params.collectionType!,\n model: params.slug!,\n },\n {\n skip: true,\n }\n );\n\n if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {\n return {\n hasI18n: schema.pluginOptions.i18n.localized,\n ...actions,\n };\n }\n\n return {\n hasI18n: false,\n ...actions,\n };\n};\n\nexport { useI18n };\n"],"names":["useI18n","params","useParams","userPermissions","useAuth","state","permissions","actions","React","useMemo","filter","permission","subject","slug","reduce","acc","actionShorthand","action","split","slice","capitalize","properties","locales","canCreate","canRead","canUpdate","canDelete","canPublish","schema","useDocument","collectionType","model","skip","doesPluginOptionsHaveI18nLocalized","pluginOptions","hasI18n","i18n","localized"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA;;;;;AAKC,UACKA,OAAmB,GAAA,IAAA;;AAEvB,IAAA,MAAMC,MAASC,GAAAA,wBAAAA,EAAAA;AAEf,IAAA,MAAMC,kBAAkBC,mBAAQ,CAAA,SAAA,EAAW,CAACC,KAAAA,GAAUA,MAAMC,WAAW,CAAA;IACvE,MAAMC,OAAAA,GAAUC,gBAAMC,CAAAA,OAAO,CAAC,IAAA;QAC5B,MAAMH,WAAAA,GAAcH,eAAgBO,CAAAA,MAAM,CAAC,CAACC,aAAeA,UAAWC,CAAAA,OAAO,KAAKX,MAAAA,CAAOY,IAAI,CAAA;AAE7F,QAAA,OAAOP,WAAYQ,CAAAA,MAAM,CACvB,CAACC,GAAKJ,EAAAA,UAAAA,GAAAA;YACJ,MAAM,CAACK,eAAgB,CAAA,GAAGL,UAAWM,CAAAA,MAAM,CAACC,KAAK,CAAC,GAAA,CAAA,CAAKC,KAAK,CAAC,CAAC,CAAA,CAAA;YAE9D,OAAO;AACL,gBAAA,GAAGJ,GAAG;AACN,gBAAA,CAAC,CAAC,GAAG,EAAEK,kBAAAA,CAAWJ,eAAiB,CAAA,CAAA,CAAC,GAAGL,UAAWU,CAAAA,UAAU,EAAEC,OAAAA,IAAW;AAC3E,aAAA;SAEF,EAAA;AAAEC,YAAAA,SAAAA,EAAW,EAAE;AAAEC,YAAAA,OAAAA,EAAS,EAAE;AAAEC,YAAAA,SAAAA,EAAW,EAAE;AAAEC,YAAAA,SAAAA,EAAW,EAAE;AAAEC,YAAAA,UAAAA,EAAY;AAAG,SAAA,CAAA;KAE5E,EAAA;AAAC1B,QAAAA,MAAAA,CAAOY,IAAI;AAAEV,QAAAA;AAAgB,KAAA,CAAA;;AAGjC,IAAA,MAAM,EAAEyB,MAAM,EAAE,GAAGC,kCACjB,CAAA;;AAEEC,QAAAA,cAAAA,EAAgB7B,OAAO6B,cAAc;AACrCC,QAAAA,KAAAA,EAAO9B,OAAOY;KAEhB,EAAA;QACEmB,IAAM,EAAA;AACR,KAAA,CAAA;IAGF,IAAIC,yCAAAA,CAAmCL,QAAQM,aAAgB,CAAA,EAAA;QAC7D,OAAO;AACLC,YAAAA,OAAAA,EAASP,MAAOM,CAAAA,aAAa,CAACE,IAAI,CAACC,SAAS;AAC5C,YAAA,GAAG9B;AACL,SAAA;AACF;IAEA,OAAO;QACL4B,OAAS,EAAA,KAAA;AACT,QAAA,GAAG5B;AACL,KAAA;AACF;;;;"}

View File

@@ -0,0 +1,57 @@
import * as React from 'react';
import { useAuth } from '@strapi/admin/strapi-admin';
import { unstable_useDocument } from '@strapi/content-manager/strapi-admin';
import { useParams } from 'react-router-dom';
import { doesPluginOptionsHaveI18nLocalized } from '../utils/fields.mjs';
import { capitalize } from '../utils/strings.mjs';
/**
* @alpha
* @description This hook is used to get the i18n status of a content type.
* Also returns the CRUDP permission locale properties for the content type
* so we know which locales the user can perform actions on.
*/ const useI18n = ()=>{
// Extract the params from the URL to pass to our useDocument hook
const params = useParams();
const userPermissions = useAuth('useI18n', (state)=>state.permissions);
const actions = React.useMemo(()=>{
const permissions = userPermissions.filter((permission)=>permission.subject === params.slug);
return permissions.reduce((acc, permission)=>{
const [actionShorthand] = permission.action.split('.').slice(-1);
return {
...acc,
[`can${capitalize(actionShorthand)}`]: permission.properties?.locales ?? []
};
}, {
canCreate: [],
canRead: [],
canUpdate: [],
canDelete: [],
canPublish: []
});
}, [
params.slug,
userPermissions
]);
// TODO: use specific hook to get schema only
const { schema } = unstable_useDocument({
// We can non-null assert these because below we skip the query if they are not present
collectionType: params.collectionType,
model: params.slug
}, {
skip: true
});
if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
return {
hasI18n: schema.pluginOptions.i18n.localized,
...actions
};
}
return {
hasI18n: false,
...actions
};
};
export { useI18n };
//# sourceMappingURL=useI18n.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useI18n.mjs","sources":["../../../admin/src/hooks/useI18n.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useAuth } from '@strapi/admin/strapi-admin';\nimport { unstable_useDocument as useDocument } from '@strapi/content-manager/strapi-admin';\nimport { useParams } from 'react-router-dom';\n\nimport { doesPluginOptionsHaveI18nLocalized } from '../utils/fields';\nimport { capitalize } from '../utils/strings';\n\ntype UseI18n = () => {\n hasI18n: boolean;\n canCreate: string[];\n canRead: string[];\n canUpdate: string[];\n canDelete: string[];\n canPublish: string[];\n};\n\n/**\n * @alpha\n * @description This hook is used to get the i18n status of a content type.\n * Also returns the CRUDP permission locale properties for the content type\n * so we know which locales the user can perform actions on.\n */\nconst useI18n: UseI18n = () => {\n // Extract the params from the URL to pass to our useDocument hook\n const params = useParams<{ collectionType: string; slug: string; model: string }>();\n\n const userPermissions = useAuth('useI18n', (state) => state.permissions);\n const actions = React.useMemo(() => {\n const permissions = userPermissions.filter((permission) => permission.subject === params.slug);\n\n return permissions.reduce<Omit<ReturnType<UseI18n>, 'hasI18n'>>(\n (acc, permission) => {\n const [actionShorthand] = permission.action.split('.').slice(-1);\n\n return {\n ...acc,\n [`can${capitalize(actionShorthand)}`]: permission.properties?.locales ?? [],\n };\n },\n { canCreate: [], canRead: [], canUpdate: [], canDelete: [], canPublish: [] }\n );\n }, [params.slug, userPermissions]);\n\n // TODO: use specific hook to get schema only\n const { schema } = useDocument(\n {\n // We can non-null assert these because below we skip the query if they are not present\n collectionType: params.collectionType!,\n model: params.slug!,\n },\n {\n skip: true,\n }\n );\n\n if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {\n return {\n hasI18n: schema.pluginOptions.i18n.localized,\n ...actions,\n };\n }\n\n return {\n hasI18n: false,\n ...actions,\n };\n};\n\nexport { useI18n };\n"],"names":["useI18n","params","useParams","userPermissions","useAuth","state","permissions","actions","React","useMemo","filter","permission","subject","slug","reduce","acc","actionShorthand","action","split","slice","capitalize","properties","locales","canCreate","canRead","canUpdate","canDelete","canPublish","schema","useDocument","collectionType","model","skip","doesPluginOptionsHaveI18nLocalized","pluginOptions","hasI18n","i18n","localized"],"mappings":";;;;;;;AAkBA;;;;;AAKC,UACKA,OAAmB,GAAA,IAAA;;AAEvB,IAAA,MAAMC,MAASC,GAAAA,SAAAA,EAAAA;AAEf,IAAA,MAAMC,kBAAkBC,OAAQ,CAAA,SAAA,EAAW,CAACC,KAAAA,GAAUA,MAAMC,WAAW,CAAA;IACvE,MAAMC,OAAAA,GAAUC,KAAMC,CAAAA,OAAO,CAAC,IAAA;QAC5B,MAAMH,WAAAA,GAAcH,eAAgBO,CAAAA,MAAM,CAAC,CAACC,aAAeA,UAAWC,CAAAA,OAAO,KAAKX,MAAAA,CAAOY,IAAI,CAAA;AAE7F,QAAA,OAAOP,WAAYQ,CAAAA,MAAM,CACvB,CAACC,GAAKJ,EAAAA,UAAAA,GAAAA;YACJ,MAAM,CAACK,eAAgB,CAAA,GAAGL,UAAWM,CAAAA,MAAM,CAACC,KAAK,CAAC,GAAA,CAAA,CAAKC,KAAK,CAAC,CAAC,CAAA,CAAA;YAE9D,OAAO;AACL,gBAAA,GAAGJ,GAAG;AACN,gBAAA,CAAC,CAAC,GAAG,EAAEK,UAAAA,CAAWJ,eAAiB,CAAA,CAAA,CAAC,GAAGL,UAAWU,CAAAA,UAAU,EAAEC,OAAAA,IAAW;AAC3E,aAAA;SAEF,EAAA;AAAEC,YAAAA,SAAAA,EAAW,EAAE;AAAEC,YAAAA,OAAAA,EAAS,EAAE;AAAEC,YAAAA,SAAAA,EAAW,EAAE;AAAEC,YAAAA,SAAAA,EAAW,EAAE;AAAEC,YAAAA,UAAAA,EAAY;AAAG,SAAA,CAAA;KAE5E,EAAA;AAAC1B,QAAAA,MAAAA,CAAOY,IAAI;AAAEV,QAAAA;AAAgB,KAAA,CAAA;;AAGjC,IAAA,MAAM,EAAEyB,MAAM,EAAE,GAAGC,oBACjB,CAAA;;AAEEC,QAAAA,cAAAA,EAAgB7B,OAAO6B,cAAc;AACrCC,QAAAA,KAAAA,EAAO9B,OAAOY;KAEhB,EAAA;QACEmB,IAAM,EAAA;AACR,KAAA,CAAA;IAGF,IAAIC,kCAAAA,CAAmCL,QAAQM,aAAgB,CAAA,EAAA;QAC7D,OAAO;AACLC,YAAAA,OAAAA,EAASP,MAAOM,CAAAA,aAAa,CAACE,IAAI,CAACC,SAAS;AAC5C,YAAA,GAAG9B;AACL,SAAA;AACF;IAEA,OAAO;QACL4B,OAAS,EAAA,KAAA;AACT,QAAA,GAAG5B;AACL,KAAA;AACF;;;;"}

227
server/node_modules/@strapi/i18n/dist/admin/index.js generated vendored Normal file
View File

@@ -0,0 +1,227 @@
'use strict';
var get = require('lodash/get');
var yup = require('yup');
var CheckboxConfirmation = require('./components/CheckboxConfirmation.js');
var CMHeaderActions = require('./components/CMHeaderActions.js');
var CMListViewModalsAdditionalInformation = require('./components/CMListViewModalsAdditionalInformation.js');
var LocalePicker = require('./components/LocalePicker.js');
var constants = require('./constants.js');
var editView = require('./contentManagerHooks/editView.js');
var listView = require('./contentManagerHooks/listView.js');
var releaseDetailsView = require('./contentReleasesHooks/releaseDetailsView.js');
var extendCTBAttributeInitialData = require('./middlewares/extendCTBAttributeInitialData.js');
var extendCTBInitialData = require('./middlewares/extendCTBInitialData.js');
var rbacMiddleware = require('./middlewares/rbac-middleware.js');
var pluginId = require('./pluginId.js');
var api = require('./services/api.js');
var fields = require('./utils/fields.js');
var getTranslation = require('./utils/getTranslation.js');
var prefixPluginTranslations = require('./utils/prefixPluginTranslations.js');
var schemas = require('./utils/schemas.js');
function _interopNamespaceDefaultOnly (e) { return Object.freeze({ __proto__: null, default: e }); }
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
function __variableDynamicImportRuntime1__(path) {
switch (path) {
case './translations/de.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/de.json.js')); });
case './translations/dk.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/dk.json.js')); });
case './translations/en.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/en.json.js')); });
case './translations/es.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/es.json.js')); });
case './translations/fr.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/fr.json.js')); });
case './translations/ko.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/ko.json.js')); });
case './translations/pl.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/pl.json.js')); });
case './translations/ru.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/ru.json.js')); });
case './translations/tr.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/tr.json.js')); });
case './translations/uk.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/uk.json.js')); });
case './translations/zh-Hans.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/zh-Hans.json.js')); });
case './translations/zh.json': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/zh.json.js')); });
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
// eslint-disable-next-line import/no-default-export
var index = {
register (app) {
app.addMiddlewares([
extendCTBAttributeInitialData.extendCTBAttributeInitialDataMiddleware,
extendCTBInitialData.extendCTBInitialDataMiddleware
]);
app.addMiddlewares([
()=>api.i18nApi.middleware
]);
app.addReducers({
[api.i18nApi.reducerPath]: api.i18nApi.reducer
});
app.addRBACMiddleware([
rbacMiddleware.localeMiddleware
]);
app.registerPlugin({
id: pluginId.pluginId,
name: pluginId.pluginId
});
},
bootstrap (app) {
// // Hook that adds a column into the CM's LV table
app.registerHook('Admin/CM/pages/ListView/inject-column-in-table', listView.addColumnToTableHook);
app.registerHook('Admin/CM/pages/EditView/mutate-edit-view-layout', editView.mutateEditViewHook);
// Hooks that checks if the locale is present in the release
app.registerHook('ContentReleases/pages/ReleaseDetails/add-locale-in-releases', releaseDetailsView.addLocaleToReleasesHook);
// Add the settings link
app.addSettingsLink('global', {
intlLabel: {
id: getTranslation.getTranslation('plugin.name'),
defaultMessage: 'Internationalization'
},
id: 'internationalization',
to: 'internationalization',
Component: ()=>Promise.resolve().then(function () { return require('./pages/SettingsPage.js'); }).then((mod)=>({
default: mod.ProtectedSettingsPage
})),
permissions: constants.PERMISSIONS.accessMain
});
const contentManager = app.getPlugin('content-manager');
contentManager.apis.addDocumentHeaderAction([
CMHeaderActions.LocalePickerAction,
CMHeaderActions.FillFromAnotherLocaleAction
]);
contentManager.apis.addDocumentAction((actions)=>{
const indexOfDeleteAction = actions.findIndex((action)=>action.type === 'delete');
actions.splice(indexOfDeleteAction, 0, CMHeaderActions.DeleteLocaleAction);
return actions;
});
contentManager.apis.addDocumentAction((actions)=>{
// When enabled the bulk locale publish action should be the first action
// in 'More Document Actions' and therefore the third action in the array
actions.splice(2, 0, CMHeaderActions.BulkLocalePublishAction);
actions.splice(5, 0, CMHeaderActions.BulkLocaleUnpublishAction);
return actions;
});
contentManager.injectComponent('listView', 'actions', {
name: 'i18n-locale-filter',
Component: LocalePicker.LocalePicker
});
contentManager.injectComponent('listView', 'publishModalAdditionalInfos', {
name: 'i18n-publish-bullets-in-modal',
Component: CMListViewModalsAdditionalInformation.PublishModalAdditionalInfo
});
contentManager.injectComponent('listView', 'unpublishModalAdditionalInfos', {
name: 'i18n-unpublish-bullets-in-modal',
Component: CMListViewModalsAdditionalInformation.UnpublishModalAdditionalInfo
});
contentManager.injectComponent('listView', 'deleteModalAdditionalInfos', {
name: 'i18n-delete-bullets-in-modal',
Component: CMListViewModalsAdditionalInformation.DeleteModalAdditionalInfo
});
const ctbPlugin = app.getPlugin('content-type-builder');
if (ctbPlugin) {
const ctbFormsAPI = ctbPlugin.apis.forms;
ctbFormsAPI.addContentTypeSchemaMutation(schemas.mutateCTBContentTypeSchema);
ctbFormsAPI.components.add({
id: 'checkboxConfirmation',
component: CheckboxConfirmation.CheckboxConfirmation
});
ctbFormsAPI.extendContentType({
validator: ()=>({
i18n: yup__namespace.object().shape({
localized: yup__namespace.bool()
})
}),
form: {
advanced () {
return [
{
name: 'pluginOptions.i18n.localized',
description: {
id: getTranslation.getTranslation('plugin.schema.i18n.localized.description-content-type'),
defaultMessage: 'Allows translating an entry into different languages'
},
type: 'checkboxConfirmation',
intlLabel: {
id: getTranslation.getTranslation('plugin.schema.i18n.localized.label-content-type'),
defaultMessage: 'Localization'
}
}
];
}
}
});
ctbFormsAPI.extendFields(fields.LOCALIZED_FIELDS, {
form: {
advanced ({ contentTypeSchema, forTarget, type, step }) {
if (forTarget !== 'contentType') {
return [];
}
const hasI18nEnabled = get(contentTypeSchema, [
'schema',
'pluginOptions',
'i18n',
'localized'
], false);
if (!hasI18nEnabled) {
return [];
}
if (type === 'component' && step === '1') {
return [];
}
return [
{
name: 'pluginOptions.i18n.localized',
description: {
id: getTranslation.getTranslation('plugin.schema.i18n.localized.description-field'),
defaultMessage: 'The field can have different values in each locale'
},
type: 'checkbox',
intlLabel: {
id: getTranslation.getTranslation('plugin.schema.i18n.localized.label-field'),
defaultMessage: 'Enable localization for this field'
}
}
];
}
}
});
}
},
async registerTrads ({ locales }) {
const importedTrads = await Promise.all(locales.map((locale)=>{
return __variableDynamicImportRuntime1__(`./translations/${locale}.json`).then(({ default: data })=>{
return {
data: prefixPluginTranslations.prefixPluginTranslations(data, pluginId.pluginId),
locale
};
}).catch(()=>{
return {
data: {},
locale
};
});
}));
return Promise.resolve(importedTrads);
}
};
module.exports = index;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

204
server/node_modules/@strapi/i18n/dist/admin/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,204 @@
import get from 'lodash/get';
import * as yup from 'yup';
import { CheckboxConfirmation } from './components/CheckboxConfirmation.mjs';
import { LocalePickerAction, FillFromAnotherLocaleAction, DeleteLocaleAction, BulkLocalePublishAction, BulkLocaleUnpublishAction } from './components/CMHeaderActions.mjs';
import { PublishModalAdditionalInfo, UnpublishModalAdditionalInfo, DeleteModalAdditionalInfo } from './components/CMListViewModalsAdditionalInformation.mjs';
import { LocalePicker } from './components/LocalePicker.mjs';
import { PERMISSIONS } from './constants.mjs';
import { mutateEditViewHook } from './contentManagerHooks/editView.mjs';
import { addColumnToTableHook } from './contentManagerHooks/listView.mjs';
import { addLocaleToReleasesHook } from './contentReleasesHooks/releaseDetailsView.mjs';
import { extendCTBAttributeInitialDataMiddleware } from './middlewares/extendCTBAttributeInitialData.mjs';
import { extendCTBInitialDataMiddleware } from './middlewares/extendCTBInitialData.mjs';
import { localeMiddleware } from './middlewares/rbac-middleware.mjs';
import { pluginId } from './pluginId.mjs';
import { i18nApi } from './services/api.mjs';
import { LOCALIZED_FIELDS } from './utils/fields.mjs';
import { getTranslation } from './utils/getTranslation.mjs';
import { prefixPluginTranslations } from './utils/prefixPluginTranslations.mjs';
import { mutateCTBContentTypeSchema } from './utils/schemas.mjs';
function __variableDynamicImportRuntime1__(path) {
switch (path) {
case './translations/de.json': return import('./translations/de.json.mjs');
case './translations/dk.json': return import('./translations/dk.json.mjs');
case './translations/en.json': return import('./translations/en.json.mjs');
case './translations/es.json': return import('./translations/es.json.mjs');
case './translations/fr.json': return import('./translations/fr.json.mjs');
case './translations/ko.json': return import('./translations/ko.json.mjs');
case './translations/pl.json': return import('./translations/pl.json.mjs');
case './translations/ru.json': return import('./translations/ru.json.mjs');
case './translations/tr.json': return import('./translations/tr.json.mjs');
case './translations/uk.json': return import('./translations/uk.json.mjs');
case './translations/zh-Hans.json': return import('./translations/zh-Hans.json.mjs');
case './translations/zh.json': return import('./translations/zh.json.mjs');
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
// eslint-disable-next-line import/no-default-export
var index = {
register (app) {
app.addMiddlewares([
extendCTBAttributeInitialDataMiddleware,
extendCTBInitialDataMiddleware
]);
app.addMiddlewares([
()=>i18nApi.middleware
]);
app.addReducers({
[i18nApi.reducerPath]: i18nApi.reducer
});
app.addRBACMiddleware([
localeMiddleware
]);
app.registerPlugin({
id: pluginId,
name: pluginId
});
},
bootstrap (app) {
// // Hook that adds a column into the CM's LV table
app.registerHook('Admin/CM/pages/ListView/inject-column-in-table', addColumnToTableHook);
app.registerHook('Admin/CM/pages/EditView/mutate-edit-view-layout', mutateEditViewHook);
// Hooks that checks if the locale is present in the release
app.registerHook('ContentReleases/pages/ReleaseDetails/add-locale-in-releases', addLocaleToReleasesHook);
// Add the settings link
app.addSettingsLink('global', {
intlLabel: {
id: getTranslation('plugin.name'),
defaultMessage: 'Internationalization'
},
id: 'internationalization',
to: 'internationalization',
Component: ()=>import('./pages/SettingsPage.mjs').then((mod)=>({
default: mod.ProtectedSettingsPage
})),
permissions: PERMISSIONS.accessMain
});
const contentManager = app.getPlugin('content-manager');
contentManager.apis.addDocumentHeaderAction([
LocalePickerAction,
FillFromAnotherLocaleAction
]);
contentManager.apis.addDocumentAction((actions)=>{
const indexOfDeleteAction = actions.findIndex((action)=>action.type === 'delete');
actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
return actions;
});
contentManager.apis.addDocumentAction((actions)=>{
// When enabled the bulk locale publish action should be the first action
// in 'More Document Actions' and therefore the third action in the array
actions.splice(2, 0, BulkLocalePublishAction);
actions.splice(5, 0, BulkLocaleUnpublishAction);
return actions;
});
contentManager.injectComponent('listView', 'actions', {
name: 'i18n-locale-filter',
Component: LocalePicker
});
contentManager.injectComponent('listView', 'publishModalAdditionalInfos', {
name: 'i18n-publish-bullets-in-modal',
Component: PublishModalAdditionalInfo
});
contentManager.injectComponent('listView', 'unpublishModalAdditionalInfos', {
name: 'i18n-unpublish-bullets-in-modal',
Component: UnpublishModalAdditionalInfo
});
contentManager.injectComponent('listView', 'deleteModalAdditionalInfos', {
name: 'i18n-delete-bullets-in-modal',
Component: DeleteModalAdditionalInfo
});
const ctbPlugin = app.getPlugin('content-type-builder');
if (ctbPlugin) {
const ctbFormsAPI = ctbPlugin.apis.forms;
ctbFormsAPI.addContentTypeSchemaMutation(mutateCTBContentTypeSchema);
ctbFormsAPI.components.add({
id: 'checkboxConfirmation',
component: CheckboxConfirmation
});
ctbFormsAPI.extendContentType({
validator: ()=>({
i18n: yup.object().shape({
localized: yup.bool()
})
}),
form: {
advanced () {
return [
{
name: 'pluginOptions.i18n.localized',
description: {
id: getTranslation('plugin.schema.i18n.localized.description-content-type'),
defaultMessage: 'Allows translating an entry into different languages'
},
type: 'checkboxConfirmation',
intlLabel: {
id: getTranslation('plugin.schema.i18n.localized.label-content-type'),
defaultMessage: 'Localization'
}
}
];
}
}
});
ctbFormsAPI.extendFields(LOCALIZED_FIELDS, {
form: {
advanced ({ contentTypeSchema, forTarget, type, step }) {
if (forTarget !== 'contentType') {
return [];
}
const hasI18nEnabled = get(contentTypeSchema, [
'schema',
'pluginOptions',
'i18n',
'localized'
], false);
if (!hasI18nEnabled) {
return [];
}
if (type === 'component' && step === '1') {
return [];
}
return [
{
name: 'pluginOptions.i18n.localized',
description: {
id: getTranslation('plugin.schema.i18n.localized.description-field'),
defaultMessage: 'The field can have different values in each locale'
},
type: 'checkbox',
intlLabel: {
id: getTranslation('plugin.schema.i18n.localized.label-field'),
defaultMessage: 'Enable localization for this field'
}
}
];
}
}
});
}
},
async registerTrads ({ locales }) {
const importedTrads = await Promise.all(locales.map((locale)=>{
return __variableDynamicImportRuntime1__(`./translations/${locale}.json`).then(({ default: data })=>{
return {
data: prefixPluginTranslations(data, pluginId),
locale
};
}).catch(()=>{
return {
data: {},
locale
};
});
}));
return Promise.resolve(importedTrads);
}
};
export { index as default };
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
'use strict';
var get = require('lodash/get');
const extendCTBAttributeInitialDataMiddleware = ()=>{
return ({ getState })=>(next)=>(action)=>{
const enhanceAction = ()=>{
// the block here is to catch the error when trying to access the state
// of the ctb when the plugin is not mounted
try {
const store = getState();
const hasi18nEnabled = get(store, [
'content-type-builder_dataManagerProvider',
'modifiedData',
'contentType',
'schema',
'pluginOptions',
'i18n',
'localized'
], false);
if (hasi18nEnabled) {
const pluginOptions = action.options ? {
...action.options.pluginOptions,
i18n: {
localized: true
}
} : {
i18n: {
localized: true
}
};
return next({
...action,
options: {
pluginOptions
}
});
}
return next(action);
} catch (err) {
return next(action);
}
};
if (action.type === 'ContentTypeBuilder/FormModal/SET_ATTRIBUTE_DATA_SCHEMA' && action.forTarget === 'contentType' && ![
'relation',
'component'
].includes(action.attributeType) && !action.isEditing) {
return enhanceAction();
}
if (action.type === 'ContentTypeBuilder/FormModal/SET_CUSTOM_FIELD_DATA_SCHEMA' && action.forTarget === 'contentType' && !action.isEditing) {
return enhanceAction();
}
if ((action.type === 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO' || action.type === 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SAVE_CURRENT_DATA') && action.forTarget === 'contentType') {
return enhanceAction();
}
return next(action);
};
};
exports.extendCTBAttributeInitialDataMiddleware = extendCTBAttributeInitialDataMiddleware;
//# sourceMappingURL=extendCTBAttributeInitialData.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extendCTBAttributeInitialData.js","sources":["../../../admin/src/middlewares/extendCTBAttributeInitialData.ts"],"sourcesContent":["import get from 'lodash/get';\n\nimport type { Middleware } from '@reduxjs/toolkit';\nimport type { Store } from '@strapi/admin/strapi-admin';\n\nconst extendCTBAttributeInitialDataMiddleware: () => Middleware<\n object,\n ReturnType<Store['getState']>\n> = () => {\n return ({ getState }) =>\n (next) =>\n (action) => {\n const enhanceAction = () => {\n // the block here is to catch the error when trying to access the state\n // of the ctb when the plugin is not mounted\n try {\n const store = getState();\n\n const hasi18nEnabled = get(\n store,\n [\n 'content-type-builder_dataManagerProvider',\n 'modifiedData',\n 'contentType',\n 'schema',\n 'pluginOptions',\n 'i18n',\n 'localized',\n ],\n false\n );\n\n if (hasi18nEnabled) {\n const pluginOptions = action.options\n ? { ...action.options.pluginOptions, i18n: { localized: true } }\n : { i18n: { localized: true } };\n\n return next({\n ...action,\n options: {\n pluginOptions,\n },\n });\n }\n\n return next(action);\n } catch (err) {\n return next(action);\n }\n };\n\n if (\n action.type === 'ContentTypeBuilder/FormModal/SET_ATTRIBUTE_DATA_SCHEMA' &&\n action.forTarget === 'contentType' &&\n !['relation', 'component'].includes(action.attributeType) &&\n !action.isEditing\n ) {\n return enhanceAction();\n }\n\n if (\n action.type === 'ContentTypeBuilder/FormModal/SET_CUSTOM_FIELD_DATA_SCHEMA' &&\n action.forTarget === 'contentType' &&\n !action.isEditing\n ) {\n return enhanceAction();\n }\n\n if (\n (action.type ===\n 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO' ||\n action.type === 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SAVE_CURRENT_DATA') &&\n action.forTarget === 'contentType'\n ) {\n return enhanceAction();\n }\n\n return next(action);\n };\n};\n\nexport { extendCTBAttributeInitialDataMiddleware };\n"],"names":["extendCTBAttributeInitialDataMiddleware","getState","next","action","enhanceAction","store","hasi18nEnabled","get","pluginOptions","options","i18n","localized","err","type","forTarget","includes","attributeType","isEditing"],"mappings":";;;;AAKA,MAAMA,uCAGF,GAAA,IAAA;AACF,IAAA,OAAO,CAAC,EAAEC,QAAQ,EAAE,GAClB,CAACC,OACD,CAACC,MAAAA,GAAAA;AACC,gBAAA,MAAMC,aAAgB,GAAA,IAAA;;;oBAGpB,IAAI;AACF,wBAAA,MAAMC,KAAQJ,GAAAA,QAAAA,EAAAA;wBAEd,MAAMK,cAAAA,GAAiBC,IACrBF,KACA,EAAA;AACE,4BAAA,0CAAA;AACA,4BAAA,cAAA;AACA,4BAAA,aAAA;AACA,4BAAA,QAAA;AACA,4BAAA,eAAA;AACA,4BAAA,MAAA;AACA,4BAAA;yBACD,EACD,KAAA,CAAA;AAGF,wBAAA,IAAIC,cAAgB,EAAA;4BAClB,MAAME,aAAAA,GAAgBL,MAAOM,CAAAA,OAAO,GAChC;gCAAE,GAAGN,MAAAA,CAAOM,OAAO,CAACD,aAAa;gCAAEE,IAAM,EAAA;oCAAEC,SAAW,EAAA;AAAK;6BAC3D,GAAA;gCAAED,IAAM,EAAA;oCAAEC,SAAW,EAAA;AAAK;AAAE,6BAAA;AAEhC,4BAAA,OAAOT,IAAK,CAAA;AACV,gCAAA,GAAGC,MAAM;gCACTM,OAAS,EAAA;AACPD,oCAAAA;AACF;AACF,6BAAA,CAAA;AACF;AAEA,wBAAA,OAAON,IAAKC,CAAAA,MAAAA,CAAAA;AACd,qBAAA,CAAE,OAAOS,GAAK,EAAA;AACZ,wBAAA,OAAOV,IAAKC,CAAAA,MAAAA,CAAAA;AACd;AACF,iBAAA;gBAEA,IACEA,MAAAA,CAAOU,IAAI,KAAK,wDAAA,IAChBV,OAAOW,SAAS,KAAK,iBACrB,CAAC;AAAC,oBAAA,UAAA;AAAY,oBAAA;iBAAY,CAACC,QAAQ,CAACZ,MAAOa,CAAAA,aAAa,KACxD,CAACb,MAAAA,CAAOc,SAAS,EACjB;oBACA,OAAOb,aAAAA,EAAAA;AACT;gBAEA,IACED,MAAAA,CAAOU,IAAI,KAAK,2DAChBV,IAAAA,MAAAA,CAAOW,SAAS,KAAK,aACrB,IAAA,CAACX,MAAOc,CAAAA,SAAS,EACjB;oBACA,OAAOb,aAAAA,EAAAA;AACT;AAEA,gBAAA,IACE,CAACD,MAAOU,CAAAA,IAAI,KACV,oFACAV,IAAAA,MAAAA,CAAOU,IAAI,KAAK,gEAA+D,KACjFV,MAAOW,CAAAA,SAAS,KAAK,aACrB,EAAA;oBACA,OAAOV,aAAAA,EAAAA;AACT;AAEA,gBAAA,OAAOF,IAAKC,CAAAA,MAAAA,CAAAA;AACd,aAAA;AACJ;;;;"}

View File

@@ -0,0 +1,59 @@
import get from 'lodash/get';
const extendCTBAttributeInitialDataMiddleware = ()=>{
return ({ getState })=>(next)=>(action)=>{
const enhanceAction = ()=>{
// the block here is to catch the error when trying to access the state
// of the ctb when the plugin is not mounted
try {
const store = getState();
const hasi18nEnabled = get(store, [
'content-type-builder_dataManagerProvider',
'modifiedData',
'contentType',
'schema',
'pluginOptions',
'i18n',
'localized'
], false);
if (hasi18nEnabled) {
const pluginOptions = action.options ? {
...action.options.pluginOptions,
i18n: {
localized: true
}
} : {
i18n: {
localized: true
}
};
return next({
...action,
options: {
pluginOptions
}
});
}
return next(action);
} catch (err) {
return next(action);
}
};
if (action.type === 'ContentTypeBuilder/FormModal/SET_ATTRIBUTE_DATA_SCHEMA' && action.forTarget === 'contentType' && ![
'relation',
'component'
].includes(action.attributeType) && !action.isEditing) {
return enhanceAction();
}
if (action.type === 'ContentTypeBuilder/FormModal/SET_CUSTOM_FIELD_DATA_SCHEMA' && action.forTarget === 'contentType' && !action.isEditing) {
return enhanceAction();
}
if ((action.type === 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO' || action.type === 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SAVE_CURRENT_DATA') && action.forTarget === 'contentType') {
return enhanceAction();
}
return next(action);
};
};
export { extendCTBAttributeInitialDataMiddleware };
//# sourceMappingURL=extendCTBAttributeInitialData.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extendCTBAttributeInitialData.mjs","sources":["../../../admin/src/middlewares/extendCTBAttributeInitialData.ts"],"sourcesContent":["import get from 'lodash/get';\n\nimport type { Middleware } from '@reduxjs/toolkit';\nimport type { Store } from '@strapi/admin/strapi-admin';\n\nconst extendCTBAttributeInitialDataMiddleware: () => Middleware<\n object,\n ReturnType<Store['getState']>\n> = () => {\n return ({ getState }) =>\n (next) =>\n (action) => {\n const enhanceAction = () => {\n // the block here is to catch the error when trying to access the state\n // of the ctb when the plugin is not mounted\n try {\n const store = getState();\n\n const hasi18nEnabled = get(\n store,\n [\n 'content-type-builder_dataManagerProvider',\n 'modifiedData',\n 'contentType',\n 'schema',\n 'pluginOptions',\n 'i18n',\n 'localized',\n ],\n false\n );\n\n if (hasi18nEnabled) {\n const pluginOptions = action.options\n ? { ...action.options.pluginOptions, i18n: { localized: true } }\n : { i18n: { localized: true } };\n\n return next({\n ...action,\n options: {\n pluginOptions,\n },\n });\n }\n\n return next(action);\n } catch (err) {\n return next(action);\n }\n };\n\n if (\n action.type === 'ContentTypeBuilder/FormModal/SET_ATTRIBUTE_DATA_SCHEMA' &&\n action.forTarget === 'contentType' &&\n !['relation', 'component'].includes(action.attributeType) &&\n !action.isEditing\n ) {\n return enhanceAction();\n }\n\n if (\n action.type === 'ContentTypeBuilder/FormModal/SET_CUSTOM_FIELD_DATA_SCHEMA' &&\n action.forTarget === 'contentType' &&\n !action.isEditing\n ) {\n return enhanceAction();\n }\n\n if (\n (action.type ===\n 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO' ||\n action.type === 'ContentTypeBuilder/FormModal/RESET_PROPS_AND_SAVE_CURRENT_DATA') &&\n action.forTarget === 'contentType'\n ) {\n return enhanceAction();\n }\n\n return next(action);\n };\n};\n\nexport { extendCTBAttributeInitialDataMiddleware };\n"],"names":["extendCTBAttributeInitialDataMiddleware","getState","next","action","enhanceAction","store","hasi18nEnabled","get","pluginOptions","options","i18n","localized","err","type","forTarget","includes","attributeType","isEditing"],"mappings":";;AAKA,MAAMA,uCAGF,GAAA,IAAA;AACF,IAAA,OAAO,CAAC,EAAEC,QAAQ,EAAE,GAClB,CAACC,OACD,CAACC,MAAAA,GAAAA;AACC,gBAAA,MAAMC,aAAgB,GAAA,IAAA;;;oBAGpB,IAAI;AACF,wBAAA,MAAMC,KAAQJ,GAAAA,QAAAA,EAAAA;wBAEd,MAAMK,cAAAA,GAAiBC,IACrBF,KACA,EAAA;AACE,4BAAA,0CAAA;AACA,4BAAA,cAAA;AACA,4BAAA,aAAA;AACA,4BAAA,QAAA;AACA,4BAAA,eAAA;AACA,4BAAA,MAAA;AACA,4BAAA;yBACD,EACD,KAAA,CAAA;AAGF,wBAAA,IAAIC,cAAgB,EAAA;4BAClB,MAAME,aAAAA,GAAgBL,MAAOM,CAAAA,OAAO,GAChC;gCAAE,GAAGN,MAAAA,CAAOM,OAAO,CAACD,aAAa;gCAAEE,IAAM,EAAA;oCAAEC,SAAW,EAAA;AAAK;6BAC3D,GAAA;gCAAED,IAAM,EAAA;oCAAEC,SAAW,EAAA;AAAK;AAAE,6BAAA;AAEhC,4BAAA,OAAOT,IAAK,CAAA;AACV,gCAAA,GAAGC,MAAM;gCACTM,OAAS,EAAA;AACPD,oCAAAA;AACF;AACF,6BAAA,CAAA;AACF;AAEA,wBAAA,OAAON,IAAKC,CAAAA,MAAAA,CAAAA;AACd,qBAAA,CAAE,OAAOS,GAAK,EAAA;AACZ,wBAAA,OAAOV,IAAKC,CAAAA,MAAAA,CAAAA;AACd;AACF,iBAAA;gBAEA,IACEA,MAAAA,CAAOU,IAAI,KAAK,wDAAA,IAChBV,OAAOW,SAAS,KAAK,iBACrB,CAAC;AAAC,oBAAA,UAAA;AAAY,oBAAA;iBAAY,CAACC,QAAQ,CAACZ,MAAOa,CAAAA,aAAa,KACxD,CAACb,MAAAA,CAAOc,SAAS,EACjB;oBACA,OAAOb,aAAAA,EAAAA;AACT;gBAEA,IACED,MAAAA,CAAOU,IAAI,KAAK,2DAChBV,IAAAA,MAAAA,CAAOW,SAAS,KAAK,aACrB,IAAA,CAACX,MAAOc,CAAAA,SAAS,EACjB;oBACA,OAAOb,aAAAA,EAAAA;AACT;AAEA,gBAAA,IACE,CAACD,MAAOU,CAAAA,IAAI,KACV,oFACAV,IAAAA,MAAAA,CAAOU,IAAI,KAAK,gEAA+D,KACjFV,MAAOW,CAAAA,SAAS,KAAK,aACrB,EAAA;oBACA,OAAOV,aAAAA,EAAAA;AACT;AAEA,gBAAA,OAAOF,IAAKC,CAAAA,MAAAA,CAAAA;AACd,aAAA;AACJ;;;;"}

View File

@@ -0,0 +1,40 @@
'use strict';
const extendCTBInitialDataMiddleware = ()=>{
return ()=>(next)=>(action)=>{
if (action.type === 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT' && action.modalType === 'contentType') {
const i18n = {
localized: false
};
const pluginOptions = action.data.pluginOptions ? {
...action.data.pluginOptions,
i18n
} : {
i18n
};
const data = {
...action.data,
pluginOptions
};
if (action.actionType === 'create') {
return next({
...action,
data
});
}
// Override the action if the pluginOption config does not contain i18n
// In this case we need to set the proper initialData shape
if (!action.data.pluginOptions?.i18n?.localized) {
return next({
...action,
data
});
}
}
// action is not the one we want to override
return next(action);
};
};
exports.extendCTBInitialDataMiddleware = extendCTBInitialDataMiddleware;
//# sourceMappingURL=extendCTBInitialData.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extendCTBInitialData.js","sources":["../../../admin/src/middlewares/extendCTBInitialData.ts"],"sourcesContent":["import type { Middleware } from '@reduxjs/toolkit';\nimport type { Store } from '@strapi/admin/strapi-admin';\n\nconst extendCTBInitialDataMiddleware: () => Middleware<\n object,\n ReturnType<Store['getState']>\n> = () => {\n return () => (next) => (action) => {\n if (\n action.type === 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT' &&\n action.modalType === 'contentType'\n ) {\n const i18n = { localized: false };\n\n const pluginOptions = action.data.pluginOptions\n ? { ...action.data.pluginOptions, i18n }\n : { i18n };\n\n const data = { ...action.data, pluginOptions };\n\n if (action.actionType === 'create') {\n return next({ ...action, data });\n }\n\n // Override the action if the pluginOption config does not contain i18n\n // In this case we need to set the proper initialData shape\n if (!action.data.pluginOptions?.i18n?.localized) {\n return next({ ...action, data });\n }\n }\n\n // action is not the one we want to override\n return next(action);\n };\n};\n\nexport { extendCTBInitialDataMiddleware };\n"],"names":["extendCTBInitialDataMiddleware","next","action","type","modalType","i18n","localized","pluginOptions","data","actionType"],"mappings":";;AAGA,MAAMA,8BAGF,GAAA,IAAA;IACF,OAAO,IAAM,CAACC,IAAAA,GAAS,CAACC,MAAAA,GAAAA;AACtB,gBAAA,IACEA,OAAOC,IAAI,KAAK,mDAChBD,MAAOE,CAAAA,SAAS,KAAK,aACrB,EAAA;AACA,oBAAA,MAAMC,IAAO,GAAA;wBAAEC,SAAW,EAAA;AAAM,qBAAA;AAEhC,oBAAA,MAAMC,aAAgBL,GAAAA,MAAAA,CAAOM,IAAI,CAACD,aAAa,GAC3C;wBAAE,GAAGL,MAAAA,CAAOM,IAAI,CAACD,aAAa;AAAEF,wBAAAA;qBAChC,GAAA;AAAEA,wBAAAA;AAAK,qBAAA;AAEX,oBAAA,MAAMG,IAAO,GAAA;AAAE,wBAAA,GAAGN,OAAOM,IAAI;AAAED,wBAAAA;AAAc,qBAAA;oBAE7C,IAAIL,MAAAA,CAAOO,UAAU,KAAK,QAAU,EAAA;AAClC,wBAAA,OAAOR,IAAK,CAAA;AAAE,4BAAA,GAAGC,MAAM;AAAEM,4BAAAA;AAAK,yBAAA,CAAA;AAChC;;;AAIA,oBAAA,IAAI,CAACN,MAAOM,CAAAA,IAAI,CAACD,aAAa,EAAEF,MAAMC,SAAW,EAAA;AAC/C,wBAAA,OAAOL,IAAK,CAAA;AAAE,4BAAA,GAAGC,MAAM;AAAEM,4BAAAA;AAAK,yBAAA,CAAA;AAChC;AACF;;AAGA,gBAAA,OAAOP,IAAKC,CAAAA,MAAAA,CAAAA;AACd,aAAA;AACF;;;;"}

View File

@@ -0,0 +1,38 @@
const extendCTBInitialDataMiddleware = ()=>{
return ()=>(next)=>(action)=>{
if (action.type === 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT' && action.modalType === 'contentType') {
const i18n = {
localized: false
};
const pluginOptions = action.data.pluginOptions ? {
...action.data.pluginOptions,
i18n
} : {
i18n
};
const data = {
...action.data,
pluginOptions
};
if (action.actionType === 'create') {
return next({
...action,
data
});
}
// Override the action if the pluginOption config does not contain i18n
// In this case we need to set the proper initialData shape
if (!action.data.pluginOptions?.i18n?.localized) {
return next({
...action,
data
});
}
}
// action is not the one we want to override
return next(action);
};
};
export { extendCTBInitialDataMiddleware };
//# sourceMappingURL=extendCTBInitialData.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extendCTBInitialData.mjs","sources":["../../../admin/src/middlewares/extendCTBInitialData.ts"],"sourcesContent":["import type { Middleware } from '@reduxjs/toolkit';\nimport type { Store } from '@strapi/admin/strapi-admin';\n\nconst extendCTBInitialDataMiddleware: () => Middleware<\n object,\n ReturnType<Store['getState']>\n> = () => {\n return () => (next) => (action) => {\n if (\n action.type === 'ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT' &&\n action.modalType === 'contentType'\n ) {\n const i18n = { localized: false };\n\n const pluginOptions = action.data.pluginOptions\n ? { ...action.data.pluginOptions, i18n }\n : { i18n };\n\n const data = { ...action.data, pluginOptions };\n\n if (action.actionType === 'create') {\n return next({ ...action, data });\n }\n\n // Override the action if the pluginOption config does not contain i18n\n // In this case we need to set the proper initialData shape\n if (!action.data.pluginOptions?.i18n?.localized) {\n return next({ ...action, data });\n }\n }\n\n // action is not the one we want to override\n return next(action);\n };\n};\n\nexport { extendCTBInitialDataMiddleware };\n"],"names":["extendCTBInitialDataMiddleware","next","action","type","modalType","i18n","localized","pluginOptions","data","actionType"],"mappings":"AAGA,MAAMA,8BAGF,GAAA,IAAA;IACF,OAAO,IAAM,CAACC,IAAAA,GAAS,CAACC,MAAAA,GAAAA;AACtB,gBAAA,IACEA,OAAOC,IAAI,KAAK,mDAChBD,MAAOE,CAAAA,SAAS,KAAK,aACrB,EAAA;AACA,oBAAA,MAAMC,IAAO,GAAA;wBAAEC,SAAW,EAAA;AAAM,qBAAA;AAEhC,oBAAA,MAAMC,aAAgBL,GAAAA,MAAAA,CAAOM,IAAI,CAACD,aAAa,GAC3C;wBAAE,GAAGL,MAAAA,CAAOM,IAAI,CAACD,aAAa;AAAEF,wBAAAA;qBAChC,GAAA;AAAEA,wBAAAA;AAAK,qBAAA;AAEX,oBAAA,MAAMG,IAAO,GAAA;AAAE,wBAAA,GAAGN,OAAOM,IAAI;AAAED,wBAAAA;AAAc,qBAAA;oBAE7C,IAAIL,MAAAA,CAAOO,UAAU,KAAK,QAAU,EAAA;AAClC,wBAAA,OAAOR,IAAK,CAAA;AAAE,4BAAA,GAAGC,MAAM;AAAEM,4BAAAA;AAAK,yBAAA,CAAA;AAChC;;;AAIA,oBAAA,IAAI,CAACN,MAAOM,CAAAA,IAAI,CAACD,aAAa,EAAEF,MAAMC,SAAW,EAAA;AAC/C,wBAAA,OAAOL,IAAK,CAAA;AAAE,4BAAA,GAAGC,MAAM;AAAEM,4BAAAA;AAAK,yBAAA,CAAA;AAChC;AACF;;AAGA,gBAAA,OAAOP,IAAKC,CAAAA,MAAAA,CAAAA;AACd,aAAA;AACF;;;;"}

View File

@@ -0,0 +1,49 @@
'use strict';
var qs = require('qs');
var reactRouterDom = require('react-router-dom');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var qs__namespace = /*#__PURE__*/_interopNamespaceDefault(qs);
const localeMiddleware = (ctx)=>(next)=>(permissions)=>{
const match = reactRouterDom.matchPath('/content-manager/:collectionType/:model?/:id', ctx.pathname);
if (!match) {
return next(permissions);
}
const search = qs__namespace.parse(ctx.search);
if (typeof search !== 'object') {
return next(permissions);
}
if (!('plugins' in search && typeof search.plugins === 'object')) {
return next(permissions);
}
if (!('i18n' in search.plugins && typeof search.plugins.i18n === 'object' && !Array.isArray(search.plugins.i18n))) {
return next(permissions);
}
const { locale } = search.plugins.i18n;
if (typeof locale !== 'string') {
return next(permissions);
}
const revisedPermissions = permissions.filter((permission)=>!permission.properties?.locales || permission.properties.locales.includes(locale));
return next(revisedPermissions);
};
exports.localeMiddleware = localeMiddleware;
//# sourceMappingURL=rbac-middleware.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rbac-middleware.js","sources":["../../../admin/src/middlewares/rbac-middleware.ts"],"sourcesContent":["/* eslint-disable check-file/filename-naming-convention */\nimport * as qs from 'qs';\nimport { matchPath } from 'react-router-dom';\n\nimport type { RBACMiddleware } from '@strapi/admin/strapi-admin';\n\nconst localeMiddleware: RBACMiddleware = (ctx) => (next) => (permissions) => {\n const match = matchPath('/content-manager/:collectionType/:model?/:id', ctx.pathname);\n\n if (!match) {\n return next(permissions);\n }\n\n const search = qs.parse(ctx.search);\n\n if (typeof search !== 'object') {\n return next(permissions);\n }\n\n if (!('plugins' in search && typeof search.plugins === 'object')) {\n return next(permissions);\n }\n\n if (\n !(\n 'i18n' in search.plugins &&\n typeof search.plugins.i18n === 'object' &&\n !Array.isArray(search.plugins.i18n)\n )\n ) {\n return next(permissions);\n }\n\n const { locale } = search.plugins.i18n;\n\n if (typeof locale !== 'string') {\n return next(permissions);\n }\n\n const revisedPermissions = permissions.filter(\n (permission) =>\n !permission.properties?.locales || permission.properties.locales.includes(locale)\n );\n\n return next(revisedPermissions);\n};\n\nexport { localeMiddleware };\n"],"names":["localeMiddleware","ctx","next","permissions","match","matchPath","pathname","search","qs","parse","plugins","i18n","Array","isArray","locale","revisedPermissions","filter","permission","properties","locales","includes"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAMA,gBAAmC,GAAA,CAACC,GAAQ,GAAA,CAACC,OAAS,CAACC,WAAAA,GAAAA;AAC3D,YAAA,MAAMC,KAAQC,GAAAA,wBAAAA,CAAU,8CAAgDJ,EAAAA,GAAAA,CAAIK,QAAQ,CAAA;AAEpF,YAAA,IAAI,CAACF,KAAO,EAAA;AACV,gBAAA,OAAOF,IAAKC,CAAAA,WAAAA,CAAAA;AACd;AAEA,YAAA,MAAMI,MAASC,GAAAA,aAAAA,CAAGC,KAAK,CAACR,IAAIM,MAAM,CAAA;YAElC,IAAI,OAAOA,WAAW,QAAU,EAAA;AAC9B,gBAAA,OAAOL,IAAKC,CAAAA,WAAAA,CAAAA;AACd;YAEA,IAAI,EAAE,SAAaI,IAAAA,MAAAA,IAAU,OAAOA,MAAOG,CAAAA,OAAO,KAAK,QAAO,CAAI,EAAA;AAChE,gBAAA,OAAOR,IAAKC,CAAAA,WAAAA,CAAAA;AACd;YAEA,IACE,EACE,MAAUI,IAAAA,MAAAA,CAAOG,OAAO,IACxB,OAAOH,MAAOG,CAAAA,OAAO,CAACC,IAAI,KAAK,QAC/B,IAAA,CAACC,MAAMC,OAAO,CAACN,OAAOG,OAAO,CAACC,IAAI,CAAA,CAEpC,EAAA;AACA,gBAAA,OAAOT,IAAKC,CAAAA,WAAAA,CAAAA;AACd;AAEA,YAAA,MAAM,EAAEW,MAAM,EAAE,GAAGP,MAAOG,CAAAA,OAAO,CAACC,IAAI;YAEtC,IAAI,OAAOG,WAAW,QAAU,EAAA;AAC9B,gBAAA,OAAOZ,IAAKC,CAAAA,WAAAA,CAAAA;AACd;AAEA,YAAA,MAAMY,qBAAqBZ,WAAYa,CAAAA,MAAM,CAC3C,CAACC,aACC,CAACA,UAAAA,CAAWC,UAAU,EAAEC,WAAWF,UAAWC,CAAAA,UAAU,CAACC,OAAO,CAACC,QAAQ,CAACN,MAAAA,CAAAA,CAAAA;AAG9E,YAAA,OAAOZ,IAAKa,CAAAA,kBAAAA,CAAAA;AACd;;;;"}

View File

@@ -0,0 +1,28 @@
import * as qs from 'qs';
import { matchPath } from 'react-router-dom';
const localeMiddleware = (ctx)=>(next)=>(permissions)=>{
const match = matchPath('/content-manager/:collectionType/:model?/:id', ctx.pathname);
if (!match) {
return next(permissions);
}
const search = qs.parse(ctx.search);
if (typeof search !== 'object') {
return next(permissions);
}
if (!('plugins' in search && typeof search.plugins === 'object')) {
return next(permissions);
}
if (!('i18n' in search.plugins && typeof search.plugins.i18n === 'object' && !Array.isArray(search.plugins.i18n))) {
return next(permissions);
}
const { locale } = search.plugins.i18n;
if (typeof locale !== 'string') {
return next(permissions);
}
const revisedPermissions = permissions.filter((permission)=>!permission.properties?.locales || permission.properties.locales.includes(locale));
return next(revisedPermissions);
};
export { localeMiddleware };
//# sourceMappingURL=rbac-middleware.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rbac-middleware.mjs","sources":["../../../admin/src/middlewares/rbac-middleware.ts"],"sourcesContent":["/* eslint-disable check-file/filename-naming-convention */\nimport * as qs from 'qs';\nimport { matchPath } from 'react-router-dom';\n\nimport type { RBACMiddleware } from '@strapi/admin/strapi-admin';\n\nconst localeMiddleware: RBACMiddleware = (ctx) => (next) => (permissions) => {\n const match = matchPath('/content-manager/:collectionType/:model?/:id', ctx.pathname);\n\n if (!match) {\n return next(permissions);\n }\n\n const search = qs.parse(ctx.search);\n\n if (typeof search !== 'object') {\n return next(permissions);\n }\n\n if (!('plugins' in search && typeof search.plugins === 'object')) {\n return next(permissions);\n }\n\n if (\n !(\n 'i18n' in search.plugins &&\n typeof search.plugins.i18n === 'object' &&\n !Array.isArray(search.plugins.i18n)\n )\n ) {\n return next(permissions);\n }\n\n const { locale } = search.plugins.i18n;\n\n if (typeof locale !== 'string') {\n return next(permissions);\n }\n\n const revisedPermissions = permissions.filter(\n (permission) =>\n !permission.properties?.locales || permission.properties.locales.includes(locale)\n );\n\n return next(revisedPermissions);\n};\n\nexport { localeMiddleware };\n"],"names":["localeMiddleware","ctx","next","permissions","match","matchPath","pathname","search","qs","parse","plugins","i18n","Array","isArray","locale","revisedPermissions","filter","permission","properties","locales","includes"],"mappings":";;;AAMA,MAAMA,gBAAmC,GAAA,CAACC,GAAQ,GAAA,CAACC,OAAS,CAACC,WAAAA,GAAAA;AAC3D,YAAA,MAAMC,KAAQC,GAAAA,SAAAA,CAAU,8CAAgDJ,EAAAA,GAAAA,CAAIK,QAAQ,CAAA;AAEpF,YAAA,IAAI,CAACF,KAAO,EAAA;AACV,gBAAA,OAAOF,IAAKC,CAAAA,WAAAA,CAAAA;AACd;AAEA,YAAA,MAAMI,MAASC,GAAAA,EAAAA,CAAGC,KAAK,CAACR,IAAIM,MAAM,CAAA;YAElC,IAAI,OAAOA,WAAW,QAAU,EAAA;AAC9B,gBAAA,OAAOL,IAAKC,CAAAA,WAAAA,CAAAA;AACd;YAEA,IAAI,EAAE,SAAaI,IAAAA,MAAAA,IAAU,OAAOA,MAAOG,CAAAA,OAAO,KAAK,QAAO,CAAI,EAAA;AAChE,gBAAA,OAAOR,IAAKC,CAAAA,WAAAA,CAAAA;AACd;YAEA,IACE,EACE,MAAUI,IAAAA,MAAAA,CAAOG,OAAO,IACxB,OAAOH,MAAOG,CAAAA,OAAO,CAACC,IAAI,KAAK,QAC/B,IAAA,CAACC,MAAMC,OAAO,CAACN,OAAOG,OAAO,CAACC,IAAI,CAAA,CAEpC,EAAA;AACA,gBAAA,OAAOT,IAAKC,CAAAA,WAAAA,CAAAA;AACd;AAEA,YAAA,MAAM,EAAEW,MAAM,EAAE,GAAGP,MAAOG,CAAAA,OAAO,CAACC,IAAI;YAEtC,IAAI,OAAOG,WAAW,QAAU,EAAA;AAC9B,gBAAA,OAAOZ,IAAKC,CAAAA,WAAAA,CAAAA;AACd;AAEA,YAAA,MAAMY,qBAAqBZ,WAAYa,CAAAA,MAAM,CAC3C,CAACC,aACC,CAACA,UAAAA,CAAWC,UAAU,EAAEC,WAAWF,UAAWC,CAAAA,UAAU,CAACC,OAAO,CAACC,QAAQ,CAACN,MAAAA,CAAAA,CAAAA;AAG9E,YAAA,OAAOZ,IAAKa,CAAAA,kBAAAA,CAAAA;AACd;;;;"}

View File

@@ -0,0 +1,107 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var symbols = require('@strapi/icons/symbols');
var reactIntl = require('react-intl');
var CreateLocale = require('../components/CreateLocale.js');
var LocaleTable = require('../components/LocaleTable.js');
var constants = require('../constants.js');
var locales = require('../services/locales.js');
var getTranslation = require('../utils/getTranslation.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const SettingsPage = ()=>{
const { formatMessage } = reactIntl.useIntl();
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
const { data: locales$1, isLoading: isLoadingLocales, error } = locales.useGetLocalesQuery();
const { isLoading: isLoadingRBAC, allowedActions: { canUpdate, canCreate, canDelete } } = strapiAdmin.useRBAC(constants.PERMISSIONS);
React__namespace.useEffect(()=>{
if (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
}, [
error,
formatAPIError,
toggleNotification
]);
const isLoading = isLoadingLocales || isLoadingRBAC;
if (isLoading) {
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
}
if (error || !Array.isArray(locales$1)) {
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Page.Error, {});
}
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Page.Main, {
tabIndex: -1,
children: [
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Header, {
primaryAction: /*#__PURE__*/ jsxRuntime.jsx(CreateLocale.CreateLocale, {
disabled: !canCreate
}),
title: formatMessage({
id: getTranslation.getTranslation('plugin.name'),
defaultMessage: 'Internationalization'
}),
subtitle: formatMessage({
id: getTranslation.getTranslation('Settings.list.description'),
defaultMessage: 'Configure the settings'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Content, {
children: locales$1.length > 0 ? /*#__PURE__*/ jsxRuntime.jsx(LocaleTable.LocaleTable, {
locales: locales$1,
canDelete: canDelete,
canUpdate: canUpdate
}) : /*#__PURE__*/ jsxRuntime.jsx(designSystem.EmptyStateLayout, {
icon: /*#__PURE__*/ jsxRuntime.jsx(symbols.EmptyDocuments, {
width: undefined,
height: undefined
}),
content: formatMessage({
id: getTranslation.getTranslation('Settings.list.empty.title'),
defaultMessage: 'There are no locales'
}),
action: /*#__PURE__*/ jsxRuntime.jsx(CreateLocale.CreateLocale, {
disabled: !canCreate,
variant: "secondary"
})
})
})
]
});
};
const ProtectedSettingsPage = ()=>{
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Page.Protect, {
permissions: constants.PERMISSIONS.read,
children: /*#__PURE__*/ jsxRuntime.jsx(SettingsPage, {})
});
};
exports.ProtectedSettingsPage = ProtectedSettingsPage;
exports.SettingsPage = SettingsPage;
//# sourceMappingURL=SettingsPage.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { useNotification, useAPIErrorHandler, useRBAC, Page, Layouts } from '@strapi/admin/strapi-admin';
import { EmptyStateLayout } from '@strapi/design-system';
import { EmptyDocuments } from '@strapi/icons/symbols';
import { useIntl } from 'react-intl';
import { CreateLocale } from '../components/CreateLocale.mjs';
import { LocaleTable } from '../components/LocaleTable.mjs';
import { PERMISSIONS } from '../constants.mjs';
import { useGetLocalesQuery } from '../services/locales.mjs';
import { getTranslation } from '../utils/getTranslation.mjs';
const SettingsPage = ()=>{
const { formatMessage } = useIntl();
const { toggleNotification } = useNotification();
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
const { data: locales, isLoading: isLoadingLocales, error } = useGetLocalesQuery();
const { isLoading: isLoadingRBAC, allowedActions: { canUpdate, canCreate, canDelete } } = useRBAC(PERMISSIONS);
React.useEffect(()=>{
if (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
}, [
error,
formatAPIError,
toggleNotification
]);
const isLoading = isLoadingLocales || isLoadingRBAC;
if (isLoading) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
if (error || !Array.isArray(locales)) {
return /*#__PURE__*/ jsx(Page.Error, {});
}
return /*#__PURE__*/ jsxs(Page.Main, {
tabIndex: -1,
children: [
/*#__PURE__*/ jsx(Layouts.Header, {
primaryAction: /*#__PURE__*/ jsx(CreateLocale, {
disabled: !canCreate
}),
title: formatMessage({
id: getTranslation('plugin.name'),
defaultMessage: 'Internationalization'
}),
subtitle: formatMessage({
id: getTranslation('Settings.list.description'),
defaultMessage: 'Configure the settings'
})
}),
/*#__PURE__*/ jsx(Layouts.Content, {
children: locales.length > 0 ? /*#__PURE__*/ jsx(LocaleTable, {
locales: locales,
canDelete: canDelete,
canUpdate: canUpdate
}) : /*#__PURE__*/ jsx(EmptyStateLayout, {
icon: /*#__PURE__*/ jsx(EmptyDocuments, {
width: undefined,
height: undefined
}),
content: formatMessage({
id: getTranslation('Settings.list.empty.title'),
defaultMessage: 'There are no locales'
}),
action: /*#__PURE__*/ jsx(CreateLocale, {
disabled: !canCreate,
variant: "secondary"
})
})
})
]
});
};
const ProtectedSettingsPage = ()=>{
return /*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.read,
children: /*#__PURE__*/ jsx(SettingsPage, {})
});
};
export { ProtectedSettingsPage, SettingsPage };
//# sourceMappingURL=SettingsPage.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
'use strict';
const pluginId = 'i18n';
exports.pluginId = pluginId;
//# sourceMappingURL=pluginId.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"pluginId.js","sources":["../../admin/src/pluginId.ts"],"sourcesContent":["export const pluginId = 'i18n';\n"],"names":["pluginId"],"mappings":";;AAAO,MAAMA,WAAW;;;;"}

View File

@@ -0,0 +1,4 @@
const pluginId = 'i18n';
export { pluginId };
//# sourceMappingURL=pluginId.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"pluginId.mjs","sources":["../../admin/src/pluginId.ts"],"sourcesContent":["export const pluginId = 'i18n';\n"],"names":["pluginId"],"mappings":"AAAO,MAAMA,WAAW;;;;"}

View File

@@ -0,0 +1,12 @@
'use strict';
var strapiAdmin = require('@strapi/admin/strapi-admin');
const i18nApi = strapiAdmin.adminApi.enhanceEndpoints({
addTagTypes: [
'Locale'
]
});
exports.i18nApi = i18nApi;
//# sourceMappingURL=api.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"api.js","sources":["../../../admin/src/services/api.ts"],"sourcesContent":["import { adminApi } from '@strapi/admin/strapi-admin';\n\nconst i18nApi = adminApi.enhanceEndpoints({\n addTagTypes: ['Locale'],\n});\n\nexport { i18nApi };\n"],"names":["i18nApi","adminApi","enhanceEndpoints","addTagTypes"],"mappings":";;;;AAEMA,MAAAA,OAAAA,GAAUC,oBAASC,CAAAA,gBAAgB,CAAC;IACxCC,WAAa,EAAA;AAAC,QAAA;AAAS;AACzB,CAAA;;;;"}

View File

@@ -0,0 +1,10 @@
import { adminApi } from '@strapi/admin/strapi-admin';
const i18nApi = adminApi.enhanceEndpoints({
addTagTypes: [
'Locale'
]
});
export { i18nApi };
//# sourceMappingURL=api.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"api.mjs","sources":["../../../admin/src/services/api.ts"],"sourcesContent":["import { adminApi } from '@strapi/admin/strapi-admin';\n\nconst i18nApi = adminApi.enhanceEndpoints({\n addTagTypes: ['Locale'],\n});\n\nexport { i18nApi };\n"],"names":["i18nApi","adminApi","enhanceEndpoints","addTagTypes"],"mappings":";;AAEMA,MAAAA,OAAAA,GAAUC,QAASC,CAAAA,gBAAgB,CAAC;IACxCC,WAAa,EAAA;AAAC,QAAA;AAAS;AACzB,CAAA;;;;"}

View File

@@ -0,0 +1,70 @@
'use strict';
var api = require('./api.js');
const localesApi = api.i18nApi.injectEndpoints({
endpoints: (builder)=>({
createLocale: builder.mutation({
query: (data)=>({
url: '/i18n/locales',
method: 'POST',
data
}),
invalidatesTags: [
{
type: 'Locale',
id: 'LIST'
}
]
}),
deleteLocale: builder.mutation({
query: (id)=>({
url: `/i18n/locales/${id}`,
method: 'DELETE'
}),
invalidatesTags: (result, error, id)=>[
{
type: 'Locale',
id
}
]
}),
getLocales: builder.query({
query: ()=>'/i18n/locales',
providesTags: (res)=>[
{
type: 'Locale',
id: 'LIST'
},
...Array.isArray(res) ? res.map((locale)=>({
type: 'Locale',
id: locale.id
})) : []
]
}),
getDefaultLocales: builder.query({
query: ()=>'/i18n/iso-locales'
}),
updateLocale: builder.mutation({
query: ({ id, ...data })=>({
url: `/i18n/locales/${id}`,
method: 'PUT',
data
}),
invalidatesTags: (result, error, { id })=>[
{
type: 'Locale',
id
}
]
})
})
});
const { useCreateLocaleMutation, useDeleteLocaleMutation, useGetLocalesQuery, useGetDefaultLocalesQuery, useUpdateLocaleMutation } = localesApi;
exports.useCreateLocaleMutation = useCreateLocaleMutation;
exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
exports.useGetLocalesQuery = useGetLocalesQuery;
exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
//# sourceMappingURL=locales.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"locales.js","sources":["../../../admin/src/services/locales.ts"],"sourcesContent":["import { i18nApi } from './api';\n\nimport type { GetISOLocales } from '../../../shared/contracts/iso-locales';\nimport type {\n GetLocales,\n CreateLocale,\n DeleteLocale,\n UpdateLocale,\n} from '../../../shared/contracts/locales';\n\nconst localesApi = i18nApi.injectEndpoints({\n endpoints: (builder) => ({\n createLocale: builder.mutation<CreateLocale.Response, CreateLocale.Request['body']>({\n query: (data) => ({\n url: '/i18n/locales',\n method: 'POST',\n data,\n }),\n invalidatesTags: [{ type: 'Locale', id: 'LIST' }],\n }),\n deleteLocale: builder.mutation<DeleteLocale.Response, DeleteLocale.Params['id']>({\n query: (id) => ({\n url: `/i18n/locales/${id}`,\n method: 'DELETE',\n }),\n invalidatesTags: (result, error, id) => [{ type: 'Locale', id }],\n }),\n getLocales: builder.query<GetLocales.Response, void>({\n query: () => '/i18n/locales',\n providesTags: (res) => [\n { type: 'Locale', id: 'LIST' },\n ...(Array.isArray(res)\n ? res.map((locale) => ({\n type: 'Locale' as const,\n id: locale.id,\n }))\n : []),\n ],\n }),\n getDefaultLocales: builder.query<GetISOLocales.Response, void>({\n query: () => '/i18n/iso-locales',\n }),\n updateLocale: builder.mutation<\n UpdateLocale.Response,\n UpdateLocale.Request['body'] & UpdateLocale.Params\n >({\n query: ({ id, ...data }) => ({\n url: `/i18n/locales/${id}`,\n method: 'PUT',\n data,\n }),\n invalidatesTags: (result, error, { id }) => [{ type: 'Locale', id }],\n }),\n }),\n});\n\nconst {\n useCreateLocaleMutation,\n useDeleteLocaleMutation,\n useGetLocalesQuery,\n useGetDefaultLocalesQuery,\n useUpdateLocaleMutation,\n} = localesApi;\n\nexport {\n useCreateLocaleMutation,\n useDeleteLocaleMutation,\n useGetLocalesQuery,\n useGetDefaultLocalesQuery,\n useUpdateLocaleMutation,\n};\n"],"names":["localesApi","i18nApi","injectEndpoints","endpoints","builder","createLocale","mutation","query","data","url","method","invalidatesTags","type","id","deleteLocale","result","error","getLocales","providesTags","res","Array","isArray","map","locale","getDefaultLocales","updateLocale","useCreateLocaleMutation","useDeleteLocaleMutation","useGetLocalesQuery","useGetDefaultLocalesQuery","useUpdateLocaleMutation"],"mappings":";;;;AAUA,MAAMA,UAAAA,GAAaC,WAAQC,CAAAA,eAAe,CAAC;IACzCC,SAAW,EAAA,CAACC,WAAa;YACvBC,YAAcD,EAAAA,OAAAA,CAAQE,QAAQ,CAAsD;gBAClFC,KAAO,EAAA,CAACC,QAAU;wBAChBC,GAAK,EAAA,eAAA;wBACLC,MAAQ,EAAA,MAAA;AACRF,wBAAAA;qBACF,CAAA;gBACAG,eAAiB,EAAA;AAAC,oBAAA;wBAAEC,IAAM,EAAA,QAAA;wBAAUC,EAAI,EAAA;AAAO;AAAE;AACnD,aAAA,CAAA;YACAC,YAAcV,EAAAA,OAAAA,CAAQE,QAAQ,CAAmD;gBAC/EC,KAAO,EAAA,CAACM,MAAQ;AACdJ,wBAAAA,GAAAA,EAAK,CAAC,cAAc,EAAEI,EAAAA,CAAG,CAAC;wBAC1BH,MAAQ,EAAA;qBACV,CAAA;gBACAC,eAAiB,EAAA,CAACI,MAAQC,EAAAA,KAAAA,EAAOH,EAAO,GAAA;AAAC,wBAAA;4BAAED,IAAM,EAAA,QAAA;AAAUC,4BAAAA;AAAG;AAAE;AAClE,aAAA,CAAA;YACAI,UAAYb,EAAAA,OAAAA,CAAQG,KAAK,CAA4B;AACnDA,gBAAAA,KAAAA,EAAO,IAAM,eAAA;AACbW,gBAAAA,YAAAA,EAAc,CAACC,GAAQ,GAAA;AACrB,wBAAA;4BAAEP,IAAM,EAAA,QAAA;4BAAUC,EAAI,EAAA;AAAO,yBAAA;2BACzBO,KAAMC,CAAAA,OAAO,CAACF,GACdA,CAAAA,GAAAA,GAAAA,CAAIG,GAAG,CAAC,CAACC,UAAY;gCACnBX,IAAM,EAAA,QAAA;AACNC,gCAAAA,EAAAA,EAAIU,OAAOV;AACb,6BAAA,KACA;AACL;AACH,aAAA,CAAA;YACAW,iBAAmBpB,EAAAA,OAAAA,CAAQG,KAAK,CAA+B;AAC7DA,gBAAAA,KAAAA,EAAO,IAAM;AACf,aAAA,CAAA;YACAkB,YAAcrB,EAAAA,OAAAA,CAAQE,QAAQ,CAG5B;AACAC,gBAAAA,KAAAA,EAAO,CAAC,EAAEM,EAAE,EAAE,GAAGL,IAAAA,EAAM,IAAM;AAC3BC,wBAAAA,GAAAA,EAAK,CAAC,cAAc,EAAEI,EAAAA,CAAG,CAAC;wBAC1BH,MAAQ,EAAA,KAAA;AACRF,wBAAAA;qBACF,CAAA;AACAG,gBAAAA,eAAAA,EAAiB,CAACI,MAAQC,EAAAA,KAAAA,EAAO,EAAEH,EAAE,EAAE,GAAK;AAAC,wBAAA;4BAAED,IAAM,EAAA,QAAA;AAAUC,4BAAAA;AAAG;AAAE;AACtE,aAAA;SACF;AACF,CAAA,CAAA;AAEM,MAAA,EACJa,uBAAuB,EACvBC,uBAAuB,EACvBC,kBAAkB,EAClBC,yBAAyB,EACzBC,uBAAuB,EACxB,GAAG9B;;;;;;;;"}

View File

@@ -0,0 +1,64 @@
import { i18nApi } from './api.mjs';
const localesApi = i18nApi.injectEndpoints({
endpoints: (builder)=>({
createLocale: builder.mutation({
query: (data)=>({
url: '/i18n/locales',
method: 'POST',
data
}),
invalidatesTags: [
{
type: 'Locale',
id: 'LIST'
}
]
}),
deleteLocale: builder.mutation({
query: (id)=>({
url: `/i18n/locales/${id}`,
method: 'DELETE'
}),
invalidatesTags: (result, error, id)=>[
{
type: 'Locale',
id
}
]
}),
getLocales: builder.query({
query: ()=>'/i18n/locales',
providesTags: (res)=>[
{
type: 'Locale',
id: 'LIST'
},
...Array.isArray(res) ? res.map((locale)=>({
type: 'Locale',
id: locale.id
})) : []
]
}),
getDefaultLocales: builder.query({
query: ()=>'/i18n/iso-locales'
}),
updateLocale: builder.mutation({
query: ({ id, ...data })=>({
url: `/i18n/locales/${id}`,
method: 'PUT',
data
}),
invalidatesTags: (result, error, { id })=>[
{
type: 'Locale',
id
}
]
})
})
});
const { useCreateLocaleMutation, useDeleteLocaleMutation, useGetLocalesQuery, useGetDefaultLocalesQuery, useUpdateLocaleMutation } = localesApi;
export { useCreateLocaleMutation, useDeleteLocaleMutation, useGetDefaultLocalesQuery, useGetLocalesQuery, useUpdateLocaleMutation };
//# sourceMappingURL=locales.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"locales.mjs","sources":["../../../admin/src/services/locales.ts"],"sourcesContent":["import { i18nApi } from './api';\n\nimport type { GetISOLocales } from '../../../shared/contracts/iso-locales';\nimport type {\n GetLocales,\n CreateLocale,\n DeleteLocale,\n UpdateLocale,\n} from '../../../shared/contracts/locales';\n\nconst localesApi = i18nApi.injectEndpoints({\n endpoints: (builder) => ({\n createLocale: builder.mutation<CreateLocale.Response, CreateLocale.Request['body']>({\n query: (data) => ({\n url: '/i18n/locales',\n method: 'POST',\n data,\n }),\n invalidatesTags: [{ type: 'Locale', id: 'LIST' }],\n }),\n deleteLocale: builder.mutation<DeleteLocale.Response, DeleteLocale.Params['id']>({\n query: (id) => ({\n url: `/i18n/locales/${id}`,\n method: 'DELETE',\n }),\n invalidatesTags: (result, error, id) => [{ type: 'Locale', id }],\n }),\n getLocales: builder.query<GetLocales.Response, void>({\n query: () => '/i18n/locales',\n providesTags: (res) => [\n { type: 'Locale', id: 'LIST' },\n ...(Array.isArray(res)\n ? res.map((locale) => ({\n type: 'Locale' as const,\n id: locale.id,\n }))\n : []),\n ],\n }),\n getDefaultLocales: builder.query<GetISOLocales.Response, void>({\n query: () => '/i18n/iso-locales',\n }),\n updateLocale: builder.mutation<\n UpdateLocale.Response,\n UpdateLocale.Request['body'] & UpdateLocale.Params\n >({\n query: ({ id, ...data }) => ({\n url: `/i18n/locales/${id}`,\n method: 'PUT',\n data,\n }),\n invalidatesTags: (result, error, { id }) => [{ type: 'Locale', id }],\n }),\n }),\n});\n\nconst {\n useCreateLocaleMutation,\n useDeleteLocaleMutation,\n useGetLocalesQuery,\n useGetDefaultLocalesQuery,\n useUpdateLocaleMutation,\n} = localesApi;\n\nexport {\n useCreateLocaleMutation,\n useDeleteLocaleMutation,\n useGetLocalesQuery,\n useGetDefaultLocalesQuery,\n useUpdateLocaleMutation,\n};\n"],"names":["localesApi","i18nApi","injectEndpoints","endpoints","builder","createLocale","mutation","query","data","url","method","invalidatesTags","type","id","deleteLocale","result","error","getLocales","providesTags","res","Array","isArray","map","locale","getDefaultLocales","updateLocale","useCreateLocaleMutation","useDeleteLocaleMutation","useGetLocalesQuery","useGetDefaultLocalesQuery","useUpdateLocaleMutation"],"mappings":";;AAUA,MAAMA,UAAAA,GAAaC,OAAQC,CAAAA,eAAe,CAAC;IACzCC,SAAW,EAAA,CAACC,WAAa;YACvBC,YAAcD,EAAAA,OAAAA,CAAQE,QAAQ,CAAsD;gBAClFC,KAAO,EAAA,CAACC,QAAU;wBAChBC,GAAK,EAAA,eAAA;wBACLC,MAAQ,EAAA,MAAA;AACRF,wBAAAA;qBACF,CAAA;gBACAG,eAAiB,EAAA;AAAC,oBAAA;wBAAEC,IAAM,EAAA,QAAA;wBAAUC,EAAI,EAAA;AAAO;AAAE;AACnD,aAAA,CAAA;YACAC,YAAcV,EAAAA,OAAAA,CAAQE,QAAQ,CAAmD;gBAC/EC,KAAO,EAAA,CAACM,MAAQ;AACdJ,wBAAAA,GAAAA,EAAK,CAAC,cAAc,EAAEI,EAAAA,CAAG,CAAC;wBAC1BH,MAAQ,EAAA;qBACV,CAAA;gBACAC,eAAiB,EAAA,CAACI,MAAQC,EAAAA,KAAAA,EAAOH,EAAO,GAAA;AAAC,wBAAA;4BAAED,IAAM,EAAA,QAAA;AAAUC,4BAAAA;AAAG;AAAE;AAClE,aAAA,CAAA;YACAI,UAAYb,EAAAA,OAAAA,CAAQG,KAAK,CAA4B;AACnDA,gBAAAA,KAAAA,EAAO,IAAM,eAAA;AACbW,gBAAAA,YAAAA,EAAc,CAACC,GAAQ,GAAA;AACrB,wBAAA;4BAAEP,IAAM,EAAA,QAAA;4BAAUC,EAAI,EAAA;AAAO,yBAAA;2BACzBO,KAAMC,CAAAA,OAAO,CAACF,GACdA,CAAAA,GAAAA,GAAAA,CAAIG,GAAG,CAAC,CAACC,UAAY;gCACnBX,IAAM,EAAA,QAAA;AACNC,gCAAAA,EAAAA,EAAIU,OAAOV;AACb,6BAAA,KACA;AACL;AACH,aAAA,CAAA;YACAW,iBAAmBpB,EAAAA,OAAAA,CAAQG,KAAK,CAA+B;AAC7DA,gBAAAA,KAAAA,EAAO,IAAM;AACf,aAAA,CAAA;YACAkB,YAAcrB,EAAAA,OAAAA,CAAQE,QAAQ,CAG5B;AACAC,gBAAAA,KAAAA,EAAO,CAAC,EAAEM,EAAE,EAAE,GAAGL,IAAAA,EAAM,IAAM;AAC3BC,wBAAAA,GAAAA,EAAK,CAAC,cAAc,EAAEI,EAAAA,CAAG,CAAC;wBAC1BH,MAAQ,EAAA,KAAA;AACRF,wBAAAA;qBACF,CAAA;AACAG,gBAAAA,eAAAA,EAAiB,CAACI,MAAQC,EAAAA,KAAAA,EAAO,EAAEH,EAAE,EAAE,GAAK;AAAC,wBAAA;4BAAED,IAAM,EAAA,QAAA;AAAUC,4BAAAA;AAAG;AAAE;AACtE,aAAA;SACF;AACF,CAAA,CAAA;AAEM,MAAA,EACJa,uBAAuB,EACvBC,uBAAuB,EACvBC,kBAAkB,EAClBC,yBAAyB,EACzBC,uBAAuB,EACxB,GAAG9B;;;;"}

View File

@@ -0,0 +1,23 @@
'use strict';
var api = require('./api.js');
const relationsApi = api.i18nApi.injectEndpoints({
overrideExisting: true,
endpoints: (builder)=>({
getManyDraftRelationCount: builder.query({
query: ({ model, ...params })=>({
url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
method: 'GET',
config: {
params
}
}),
transformResponse: (response)=>response.data
})
})
});
const { useGetManyDraftRelationCountQuery } = relationsApi;
exports.useGetManyDraftRelationCountQuery = useGetManyDraftRelationCountQuery;
//# sourceMappingURL=relations.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"relations.js","sources":["../../../admin/src/services/relations.ts"],"sourcesContent":["import { i18nApi } from './api';\n\nimport type { CountManyEntriesDraftRelations } from '../../../shared/contracts/content-manager';\n\nconst relationsApi = i18nApi.injectEndpoints({\n overrideExisting: true,\n endpoints: (builder) => ({\n getManyDraftRelationCount: builder.query<\n CountManyEntriesDraftRelations.Response['data'],\n CountManyEntriesDraftRelations.Request['query'] & {\n model: string;\n }\n >({\n query: ({ model, ...params }) => ({\n url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,\n method: 'GET',\n config: {\n params,\n },\n }),\n transformResponse: (response: CountManyEntriesDraftRelations.Response) => response.data,\n }),\n }),\n});\n\nconst { useGetManyDraftRelationCountQuery } = relationsApi;\n\nexport { useGetManyDraftRelationCountQuery };\n"],"names":["relationsApi","i18nApi","injectEndpoints","overrideExisting","endpoints","builder","getManyDraftRelationCount","query","model","params","url","method","config","transformResponse","response","data","useGetManyDraftRelationCountQuery"],"mappings":";;;;AAIA,MAAMA,YAAAA,GAAeC,WAAQC,CAAAA,eAAe,CAAC;IAC3CC,gBAAkB,EAAA,IAAA;IAClBC,SAAW,EAAA,CAACC,WAAa;YACvBC,yBAA2BD,EAAAA,OAAAA,CAAQE,KAAK,CAKtC;AACAA,gBAAAA,KAAAA,EAAO,CAAC,EAAEC,KAAK,EAAE,GAAGC,MAAAA,EAAQ,IAAM;AAChCC,wBAAAA,GAAAA,EAAK,CAAC,kCAAkC,EAAEF,KAAAA,CAAM,uCAAuC,CAAC;wBACxFG,MAAQ,EAAA,KAAA;wBACRC,MAAQ,EAAA;AACNH,4BAAAA;AACF;qBACF,CAAA;gBACAI,iBAAmB,EAAA,CAACC,QAAsDA,GAAAA,QAAAA,CAASC;AACrF,aAAA;SACF;AACF,CAAA,CAAA;AAEM,MAAA,EAAEC,iCAAiC,EAAE,GAAGhB;;;;"}

View File

@@ -0,0 +1,21 @@
import { i18nApi } from './api.mjs';
const relationsApi = i18nApi.injectEndpoints({
overrideExisting: true,
endpoints: (builder)=>({
getManyDraftRelationCount: builder.query({
query: ({ model, ...params })=>({
url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
method: 'GET',
config: {
params
}
}),
transformResponse: (response)=>response.data
})
})
});
const { useGetManyDraftRelationCountQuery } = relationsApi;
export { useGetManyDraftRelationCountQuery };
//# sourceMappingURL=relations.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"relations.mjs","sources":["../../../admin/src/services/relations.ts"],"sourcesContent":["import { i18nApi } from './api';\n\nimport type { CountManyEntriesDraftRelations } from '../../../shared/contracts/content-manager';\n\nconst relationsApi = i18nApi.injectEndpoints({\n overrideExisting: true,\n endpoints: (builder) => ({\n getManyDraftRelationCount: builder.query<\n CountManyEntriesDraftRelations.Response['data'],\n CountManyEntriesDraftRelations.Request['query'] & {\n model: string;\n }\n >({\n query: ({ model, ...params }) => ({\n url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,\n method: 'GET',\n config: {\n params,\n },\n }),\n transformResponse: (response: CountManyEntriesDraftRelations.Response) => response.data,\n }),\n }),\n});\n\nconst { useGetManyDraftRelationCountQuery } = relationsApi;\n\nexport { useGetManyDraftRelationCountQuery };\n"],"names":["relationsApi","i18nApi","injectEndpoints","overrideExisting","endpoints","builder","getManyDraftRelationCount","query","model","params","url","method","config","transformResponse","response","data","useGetManyDraftRelationCountQuery"],"mappings":";;AAIA,MAAMA,YAAAA,GAAeC,OAAQC,CAAAA,eAAe,CAAC;IAC3CC,gBAAkB,EAAA,IAAA;IAClBC,SAAW,EAAA,CAACC,WAAa;YACvBC,yBAA2BD,EAAAA,OAAAA,CAAQE,KAAK,CAKtC;AACAA,gBAAAA,KAAAA,EAAO,CAAC,EAAEC,KAAK,EAAE,GAAGC,MAAAA,EAAQ,IAAM;AAChCC,wBAAAA,GAAAA,EAAK,CAAC,kCAAkC,EAAEF,KAAAA,CAAM,uCAAuC,CAAC;wBACxFG,MAAQ,EAAA,KAAA;wBACRC,MAAQ,EAAA;AACNH,4BAAAA;AACF;qBACF,CAAA;gBACAI,iBAAmB,EAAA,CAACC,QAAsDA,GAAAA,QAAAA,CAASC;AACrF,aAAA;SACF;AACF,CAAA,CAAA;AAEM,MAAA,EAAEC,iCAAiC,EAAE,GAAGhB;;;;"}

View File

@@ -0,0 +1,16 @@
import { FormErrors } from '@strapi/admin/strapi-admin';
import { Locale } from '../../../shared/contracts/locales';
import { LocaleStatus } from './CMHeaderActions';
interface BulkLocaleActionModalProps {
rows: LocaleStatus[];
headers: {
label: string;
name: string;
}[];
localesMetadata: Locale[];
validationErrors?: FormErrors;
action: 'bulk-publish' | 'bulk-unpublish';
}
declare const BulkLocaleActionModal: ({ headers, rows, localesMetadata, validationErrors, action, }: BulkLocaleActionModalProps) => import("react/jsx-runtime").JSX.Element;
export { BulkLocaleActionModal };
export type { BulkLocaleActionModalProps };

View File

@@ -0,0 +1,36 @@
import { type DocumentActionComponent, HeaderActionProps } from '@strapi/content-manager/strapi-admin';
import type { Locale } from '../../../shared/contracts/locales';
import type { Modules } from '@strapi/types';
declare const LocalePickerAction: ({ document, meta, model, collectionType, documentId, }: HeaderActionProps) => {
label: string;
options: {
disabled: boolean;
value: string;
label: import("react/jsx-runtime").JSX.Element;
startIcon: import("react/jsx-runtime").JSX.Element | null;
}[];
customizeContent: () => string | undefined;
onSelect: (value: string) => void;
value: Locale | undefined;
} | null;
declare const FillFromAnotherLocaleAction: ({ documentId, meta, model, collectionType, }: HeaderActionProps) => {
type: string;
icon: import("react/jsx-runtime").JSX.Element;
disabled: boolean;
label: string;
dialog: {
type: string;
title: string;
content: ({ onClose }: {
onClose: () => void;
}) => import("react/jsx-runtime").JSX.Element;
};
} | null;
declare const DeleteLocaleAction: DocumentActionComponent;
export type LocaleStatus = {
locale: string;
status: Modules.Documents.Params.PublicationStatus.Kind | 'modified';
};
declare const BulkLocalePublishAction: DocumentActionComponent;
declare const BulkLocaleUnpublishAction: DocumentActionComponent;
export { BulkLocalePublishAction, BulkLocaleUnpublishAction, DeleteLocaleAction, LocalePickerAction, FillFromAnotherLocaleAction, };

Some files were not shown because too many files have changed in this diff Show More