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

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, };

View File

@@ -0,0 +1,4 @@
declare const DeleteModalAdditionalInfo: () => import("react/jsx-runtime").JSX.Element | null;
declare const PublishModalAdditionalInfo: () => import("react/jsx-runtime").JSX.Element | null;
declare const UnpublishModalAdditionalInfo: () => import("react/jsx-runtime").JSX.Element | null;
export { DeleteModalAdditionalInfo, PublishModalAdditionalInfo, UnpublishModalAdditionalInfo };

View File

@@ -0,0 +1,20 @@
import { MessageDescriptor } from 'react-intl';
interface IntlMessage extends MessageDescriptor {
values: object;
}
interface CheckboxConfirmationProps {
description: IntlMessage;
intlLabel: IntlMessage;
isCreating?: boolean;
name: string;
onChange: (event: {
target: {
name: string;
value: boolean;
type: string;
};
}) => void;
value: boolean;
}
declare const CheckboxConfirmation: ({ description, isCreating, intlLabel, name, onChange, value, }: CheckboxConfirmationProps) => import("react/jsx-runtime").JSX.Element;
export { CheckboxConfirmation };

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