@strapi/content-releases 0.0.0-next.0a7843dbfbff3628c1a547e687ca05eefe4ae611 → 0.0.0-next.0c9f2e7cee619866963b738b5c18348f5d021a90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App--nWfPfW0.js → App-HjWtUYmc.js} +730 -461
- package/dist/_chunks/App-HjWtUYmc.js.map +1 -0
- package/dist/_chunks/{App-LLQiZULE.mjs → App-gu1aiP6i.mjs} +735 -467
- package/dist/_chunks/App-gu1aiP6i.mjs.map +1 -0
- package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs +51 -0
- package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +1 -0
- package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js +51 -0
- package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +1 -0
- package/dist/_chunks/{en-2DuPv5k0.js → en-HrREghh3.js} +27 -7
- package/dist/_chunks/en-HrREghh3.js.map +1 -0
- package/dist/_chunks/{en-SOqjCdyh.mjs → en-ltT1TlKQ.mjs} +27 -7
- package/dist/_chunks/en-ltT1TlKQ.mjs.map +1 -0
- package/dist/_chunks/{index-kxiJMcBr.js → index-ZNwxYN8H.js} +447 -40
- package/dist/_chunks/index-ZNwxYN8H.js.map +1 -0
- package/dist/_chunks/{index-5zt6Fms0.mjs → index-mvj9PSKd.mjs} +464 -57
- package/dist/_chunks/index-mvj9PSKd.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/server/index.js +1039 -397
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1035 -394
- package/dist/server/index.mjs.map +1 -1
- package/package.json +15 -12
- package/dist/_chunks/App--nWfPfW0.js.map +0 -1
- package/dist/_chunks/App-LLQiZULE.mjs.map +0 -1
- package/dist/_chunks/en-2DuPv5k0.js.map +0 -1
- package/dist/_chunks/en-SOqjCdyh.mjs.map +0 -1
- package/dist/_chunks/index-5zt6Fms0.mjs.map +0 -1
- package/dist/_chunks/index-kxiJMcBr.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { getFetchClient, useNotification, useAPIErrorHandler, CheckPermissions, useCMEditViewDataManager, NoContent, prefixPluginTranslations } from "@strapi/helper-plugin";
|
|
1
|
+
import { getFetchClient, useNotification, useAPIErrorHandler, CheckPermissions, useCMEditViewDataManager, NoContent, useRBAC, SortIcon, prefixPluginTranslations } from "@strapi/helper-plugin";
|
|
2
2
|
import { Cross, Pencil, More, Plus, PaperPlane } from "@strapi/icons";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { skipToken } from "@reduxjs/toolkit/query";
|
|
6
|
-
import { IconButton, Flex, Icon, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter } from "@strapi/design-system";
|
|
6
|
+
import { IconButton, Flex, Icon, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button as Button$1, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter, Popover } from "@strapi/design-system";
|
|
7
7
|
import { Menu, Link, LinkButton } from "@strapi/design-system/v2";
|
|
8
8
|
import { isAxiosError as isAxiosError$1 } from "axios";
|
|
9
9
|
import { Formik, Form } from "formik";
|
|
10
10
|
import { useIntl } from "react-intl";
|
|
11
|
-
import { NavLink,
|
|
11
|
+
import { NavLink, Link as Link$1 } from "react-router-dom";
|
|
12
12
|
import * as yup from "yup";
|
|
13
13
|
import { createApi } from "@reduxjs/toolkit/query/react";
|
|
14
14
|
import styled from "styled-components";
|
|
@@ -136,7 +136,7 @@ const isAxiosError = (err) => {
|
|
|
136
136
|
const releaseApi = createApi({
|
|
137
137
|
reducerPath: pluginId,
|
|
138
138
|
baseQuery: axiosBaseQuery,
|
|
139
|
-
tagTypes: ["Release", "ReleaseAction"],
|
|
139
|
+
tagTypes: ["Release", "ReleaseAction", "EntriesInRelease"],
|
|
140
140
|
endpoints: (build) => {
|
|
141
141
|
return {
|
|
142
142
|
getReleasesForEntry: build.query({
|
|
@@ -251,6 +251,20 @@ const releaseApi = createApi({
|
|
|
251
251
|
{ type: "ReleaseAction", id: "LIST" }
|
|
252
252
|
]
|
|
253
253
|
}),
|
|
254
|
+
createManyReleaseActions: build.mutation({
|
|
255
|
+
query({ body, params }) {
|
|
256
|
+
return {
|
|
257
|
+
url: `/content-releases/${params.releaseId}/actions/bulk`,
|
|
258
|
+
method: "POST",
|
|
259
|
+
data: body
|
|
260
|
+
};
|
|
261
|
+
},
|
|
262
|
+
invalidatesTags: [
|
|
263
|
+
{ type: "Release", id: "LIST" },
|
|
264
|
+
{ type: "ReleaseAction", id: "LIST" },
|
|
265
|
+
{ type: "EntriesInRelease" }
|
|
266
|
+
]
|
|
267
|
+
}),
|
|
254
268
|
updateReleaseAction: build.mutation({
|
|
255
269
|
query({ body, params }) {
|
|
256
270
|
return {
|
|
@@ -288,9 +302,11 @@ const releaseApi = createApi({
|
|
|
288
302
|
method: "DELETE"
|
|
289
303
|
};
|
|
290
304
|
},
|
|
291
|
-
invalidatesTags: [
|
|
305
|
+
invalidatesTags: (result, error, arg) => [
|
|
292
306
|
{ type: "Release", id: "LIST" },
|
|
293
|
-
{ type: "
|
|
307
|
+
{ type: "Release", id: arg.params.releaseId },
|
|
308
|
+
{ type: "ReleaseAction", id: "LIST" },
|
|
309
|
+
{ type: "EntriesInRelease" }
|
|
294
310
|
]
|
|
295
311
|
}),
|
|
296
312
|
publishRelease: build.mutation({
|
|
@@ -309,7 +325,22 @@ const releaseApi = createApi({
|
|
|
309
325
|
method: "DELETE"
|
|
310
326
|
};
|
|
311
327
|
},
|
|
312
|
-
invalidatesTags: (
|
|
328
|
+
invalidatesTags: () => [{ type: "Release", id: "LIST" }, { type: "EntriesInRelease" }]
|
|
329
|
+
}),
|
|
330
|
+
getMappedEntriesInReleases: build.query({
|
|
331
|
+
query(params) {
|
|
332
|
+
return {
|
|
333
|
+
url: "/content-releases/mapEntriesToReleases",
|
|
334
|
+
method: "GET",
|
|
335
|
+
config: {
|
|
336
|
+
params
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
},
|
|
340
|
+
transformResponse(response) {
|
|
341
|
+
return response.data;
|
|
342
|
+
},
|
|
343
|
+
providesTags: [{ type: "EntriesInRelease" }]
|
|
313
344
|
})
|
|
314
345
|
};
|
|
315
346
|
}
|
|
@@ -321,12 +352,30 @@ const {
|
|
|
321
352
|
useGetReleaseActionsQuery,
|
|
322
353
|
useCreateReleaseMutation,
|
|
323
354
|
useCreateReleaseActionMutation,
|
|
355
|
+
useCreateManyReleaseActionsMutation,
|
|
324
356
|
useUpdateReleaseMutation,
|
|
325
357
|
useUpdateReleaseActionMutation,
|
|
326
358
|
usePublishReleaseMutation,
|
|
327
359
|
useDeleteReleaseActionMutation,
|
|
328
|
-
useDeleteReleaseMutation
|
|
360
|
+
useDeleteReleaseMutation,
|
|
361
|
+
useGetMappedEntriesInReleasesQuery
|
|
329
362
|
} = releaseApi;
|
|
363
|
+
const getTimezoneOffset = (timezone, date) => {
|
|
364
|
+
try {
|
|
365
|
+
const offsetPart = new Intl.DateTimeFormat("en", {
|
|
366
|
+
timeZone: timezone,
|
|
367
|
+
timeZoneName: "longOffset"
|
|
368
|
+
}).formatToParts(date).find((part) => part.type === "timeZoneName");
|
|
369
|
+
const offset = offsetPart ? offsetPart.value : "";
|
|
370
|
+
let utcOffset = offset.replace("GMT", "UTC");
|
|
371
|
+
if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
|
|
372
|
+
utcOffset = `${utcOffset}+00:00`;
|
|
373
|
+
}
|
|
374
|
+
return utcOffset;
|
|
375
|
+
} catch (error) {
|
|
376
|
+
return "";
|
|
377
|
+
}
|
|
378
|
+
};
|
|
330
379
|
const useTypedDispatch = useDispatch;
|
|
331
380
|
const useTypedSelector = useSelector;
|
|
332
381
|
const StyledMenuItem = styled(Menu.Item)`
|
|
@@ -397,7 +446,7 @@ const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
|
|
|
397
446
|
}
|
|
398
447
|
};
|
|
399
448
|
return /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
400
|
-
/* @__PURE__ */ jsx(Icon, { as: Cross,
|
|
449
|
+
/* @__PURE__ */ jsx(Icon, { as: Cross, width: 3, height: 3 }),
|
|
401
450
|
/* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
|
|
402
451
|
id: "content-releases.content-manager-edit-view.remove-from-release",
|
|
403
452
|
defaultMessage: "Remove from release"
|
|
@@ -436,7 +485,7 @@ const ReleaseActionEntryLinkItem = ({
|
|
|
436
485
|
pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
|
|
437
486
|
search: locale && `?plugins[i18n][locale]=${locale}`
|
|
438
487
|
},
|
|
439
|
-
startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil,
|
|
488
|
+
startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, width: 3, height: 3 }),
|
|
440
489
|
children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
|
|
441
490
|
id: "content-releases.content-manager-edit-view.edit-entry",
|
|
442
491
|
defaultMessage: "Edit entry"
|
|
@@ -446,6 +495,21 @@ const ReleaseActionEntryLinkItem = ({
|
|
|
446
495
|
}
|
|
447
496
|
);
|
|
448
497
|
};
|
|
498
|
+
const EditReleaseItem = ({ releaseId }) => {
|
|
499
|
+
const { formatMessage } = useIntl();
|
|
500
|
+
return /* @__PURE__ */ jsx(StyledMenuItem, { children: /* @__PURE__ */ jsx(
|
|
501
|
+
Link,
|
|
502
|
+
{
|
|
503
|
+
href: `/admin/plugins/content-releases/${releaseId}`,
|
|
504
|
+
startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, width: 3, height: 3 }),
|
|
505
|
+
isExternal: false,
|
|
506
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
|
|
507
|
+
id: "content-releases.content-manager-edit-view.edit-release",
|
|
508
|
+
defaultMessage: "Edit release"
|
|
509
|
+
}) })
|
|
510
|
+
}
|
|
511
|
+
) });
|
|
512
|
+
};
|
|
449
513
|
const Root = ({ children, hasTriggerBorder = false }) => {
|
|
450
514
|
const { formatMessage } = useIntl();
|
|
451
515
|
return (
|
|
@@ -470,6 +534,7 @@ const Root = ({ children, hasTriggerBorder = false }) => {
|
|
|
470
534
|
};
|
|
471
535
|
const ReleaseActionMenu = {
|
|
472
536
|
Root,
|
|
537
|
+
EditReleaseItem,
|
|
473
538
|
DeleteReleaseActionItem,
|
|
474
539
|
ReleaseActionEntryLinkItem
|
|
475
540
|
};
|
|
@@ -493,19 +558,40 @@ const FieldWrapper = styled(Field)`
|
|
|
493
558
|
text-transform: capitalize;
|
|
494
559
|
}
|
|
495
560
|
|
|
496
|
-
&:active,
|
|
497
561
|
&[data-checked='true'] {
|
|
498
|
-
color: ${({ theme }) => theme.colors.primary700};
|
|
499
|
-
background-color: ${({ theme }) => theme.colors.primary100};
|
|
500
|
-
border-color: ${({ theme }) => theme.colors.primary700};
|
|
562
|
+
color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
|
|
563
|
+
background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
|
|
564
|
+
border-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
|
|
501
565
|
}
|
|
502
566
|
|
|
503
567
|
&[data-checked='false'] {
|
|
504
568
|
border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
|
|
505
569
|
border-right: ${({ actionType }) => actionType === "publish" && "none"};
|
|
506
570
|
}
|
|
571
|
+
|
|
572
|
+
&[data-checked='false'][data-disabled='false']:hover {
|
|
573
|
+
color: ${({ theme }) => theme.colors.neutral700};
|
|
574
|
+
background-color: ${({ theme }) => theme.colors.neutral100};
|
|
575
|
+
border-color: ${({ theme }) => theme.colors.neutral200};
|
|
576
|
+
|
|
577
|
+
& > label {
|
|
578
|
+
cursor: pointer;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
&[data-disabled='true'] {
|
|
583
|
+
color: ${({ theme }) => theme.colors.neutral600};
|
|
584
|
+
background-color: ${({ theme }) => theme.colors.neutral150};
|
|
585
|
+
border-color: ${({ theme }) => theme.colors.neutral300};
|
|
586
|
+
}
|
|
507
587
|
`;
|
|
508
|
-
const ActionOption = ({
|
|
588
|
+
const ActionOption = ({
|
|
589
|
+
selected,
|
|
590
|
+
actionType,
|
|
591
|
+
handleChange,
|
|
592
|
+
name,
|
|
593
|
+
disabled = false
|
|
594
|
+
}) => {
|
|
509
595
|
return /* @__PURE__ */ jsx(
|
|
510
596
|
FieldWrapper,
|
|
511
597
|
{
|
|
@@ -516,6 +602,7 @@ const ActionOption = ({ selected, actionType, handleChange, name }) => {
|
|
|
516
602
|
position: "relative",
|
|
517
603
|
cursor: "pointer",
|
|
518
604
|
"data-checked": selected === actionType,
|
|
605
|
+
"data-disabled": disabled && selected !== actionType,
|
|
519
606
|
children: /* @__PURE__ */ jsxs(FieldLabel, { htmlFor: `${name}-${actionType}`, children: [
|
|
520
607
|
/* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
|
|
521
608
|
FieldInput,
|
|
@@ -525,7 +612,8 @@ const ActionOption = ({ selected, actionType, handleChange, name }) => {
|
|
|
525
612
|
name,
|
|
526
613
|
checked: selected === actionType,
|
|
527
614
|
onChange: handleChange,
|
|
528
|
-
value: actionType
|
|
615
|
+
value: actionType,
|
|
616
|
+
disabled
|
|
529
617
|
}
|
|
530
618
|
) }),
|
|
531
619
|
actionType
|
|
@@ -533,7 +621,12 @@ const ActionOption = ({ selected, actionType, handleChange, name }) => {
|
|
|
533
621
|
}
|
|
534
622
|
);
|
|
535
623
|
};
|
|
536
|
-
const ReleaseActionOptions = ({
|
|
624
|
+
const ReleaseActionOptions = ({
|
|
625
|
+
selected,
|
|
626
|
+
handleChange,
|
|
627
|
+
name,
|
|
628
|
+
disabled = false
|
|
629
|
+
}) => {
|
|
537
630
|
return /* @__PURE__ */ jsxs(Flex, { children: [
|
|
538
631
|
/* @__PURE__ */ jsx(
|
|
539
632
|
ActionOption,
|
|
@@ -541,7 +634,8 @@ const ReleaseActionOptions = ({ selected, handleChange, name }) => {
|
|
|
541
634
|
actionType: "publish",
|
|
542
635
|
selected,
|
|
543
636
|
handleChange,
|
|
544
|
-
name
|
|
637
|
+
name,
|
|
638
|
+
disabled
|
|
545
639
|
}
|
|
546
640
|
),
|
|
547
641
|
/* @__PURE__ */ jsx(
|
|
@@ -550,7 +644,8 @@ const ReleaseActionOptions = ({ selected, handleChange, name }) => {
|
|
|
550
644
|
actionType: "unpublish",
|
|
551
645
|
selected,
|
|
552
646
|
handleChange,
|
|
553
|
-
name
|
|
647
|
+
name,
|
|
648
|
+
disabled
|
|
554
649
|
}
|
|
555
650
|
)
|
|
556
651
|
] });
|
|
@@ -594,6 +689,7 @@ const AddActionToReleaseModal = ({
|
|
|
594
689
|
contentTypeUid,
|
|
595
690
|
entryId
|
|
596
691
|
}) => {
|
|
692
|
+
const releaseHeaderId = React.useId();
|
|
597
693
|
const { formatMessage } = useIntl();
|
|
598
694
|
const toggleNotification = useNotification();
|
|
599
695
|
const { formatAPIError } = useAPIErrorHandler();
|
|
@@ -641,8 +737,8 @@ const AddActionToReleaseModal = ({
|
|
|
641
737
|
}
|
|
642
738
|
}
|
|
643
739
|
};
|
|
644
|
-
return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy:
|
|
645
|
-
/* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id:
|
|
740
|
+
return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: releaseHeaderId, children: [
|
|
741
|
+
/* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: releaseHeaderId, fontWeight: "bold", textColor: "neutral800", children: formatMessage({
|
|
646
742
|
id: "content-releases.content-manager-edit-view.add-to-release",
|
|
647
743
|
defaultMessage: "Add to release"
|
|
648
744
|
}) }) }),
|
|
@@ -688,7 +784,7 @@ const AddActionToReleaseModal = ({
|
|
|
688
784
|
/* @__PURE__ */ jsx(
|
|
689
785
|
ModalFooter,
|
|
690
786
|
{
|
|
691
|
-
startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
|
|
787
|
+
startActions: /* @__PURE__ */ jsx(Button$1, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
|
|
692
788
|
id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
|
|
693
789
|
defaultMessage: "Cancel"
|
|
694
790
|
}) }),
|
|
@@ -697,7 +793,7 @@ const AddActionToReleaseModal = ({
|
|
|
697
793
|
* TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
|
|
698
794
|
* for yup.string().required(), even when the value is falsy (including empty string)
|
|
699
795
|
*/
|
|
700
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
|
|
796
|
+
/* @__PURE__ */ jsx(Button$1, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
|
|
701
797
|
id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
|
|
702
798
|
defaultMessage: "Continue"
|
|
703
799
|
}) })
|
|
@@ -712,16 +808,18 @@ const AddActionToReleaseModal = ({
|
|
|
712
808
|
};
|
|
713
809
|
const CMReleasesContainer = () => {
|
|
714
810
|
const [isModalOpen, setIsModalOpen] = React.useState(false);
|
|
715
|
-
const { formatMessage } = useIntl();
|
|
811
|
+
const { formatMessage, formatDate, formatTime } = useIntl();
|
|
716
812
|
const {
|
|
717
813
|
isCreatingEntry,
|
|
718
|
-
|
|
814
|
+
hasDraftAndPublish,
|
|
815
|
+
initialData: { id: entryId },
|
|
816
|
+
slug
|
|
719
817
|
} = useCMEditViewDataManager();
|
|
720
|
-
const
|
|
721
|
-
const canFetch =
|
|
818
|
+
const contentTypeUid = slug;
|
|
819
|
+
const canFetch = entryId != null && contentTypeUid != null;
|
|
722
820
|
const fetchParams = canFetch ? {
|
|
723
|
-
contentTypeUid
|
|
724
|
-
entryId
|
|
821
|
+
contentTypeUid,
|
|
822
|
+
entryId,
|
|
725
823
|
hasEntryAttached: true
|
|
726
824
|
} : skipToken;
|
|
727
825
|
const response = useGetReleasesForEntryQuery(fetchParams);
|
|
@@ -729,7 +827,7 @@ const CMReleasesContainer = () => {
|
|
|
729
827
|
if (!canFetch) {
|
|
730
828
|
return null;
|
|
731
829
|
}
|
|
732
|
-
if (isCreatingEntry || !
|
|
830
|
+
if (isCreatingEntry || !hasDraftAndPublish) {
|
|
733
831
|
return null;
|
|
734
832
|
}
|
|
735
833
|
const toggleModal = () => setIsModalOpen((prev) => !prev);
|
|
@@ -766,7 +864,7 @@ const CMReleasesContainer = () => {
|
|
|
766
864
|
alignItems: "start",
|
|
767
865
|
borderWidth: "1px",
|
|
768
866
|
borderStyle: "solid",
|
|
769
|
-
borderColor: getReleaseColorVariant(release.
|
|
867
|
+
borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
|
|
770
868
|
overflow: "hidden",
|
|
771
869
|
hasRadius: true,
|
|
772
870
|
children: [
|
|
@@ -777,34 +875,59 @@ const CMReleasesContainer = () => {
|
|
|
777
875
|
paddingBottom: 3,
|
|
778
876
|
paddingLeft: 4,
|
|
779
877
|
paddingRight: 4,
|
|
780
|
-
background: getReleaseColorVariant(release.
|
|
878
|
+
background: getReleaseColorVariant(release.actions[0].type, "100"),
|
|
781
879
|
width: "100%",
|
|
782
880
|
children: /* @__PURE__ */ jsx(
|
|
783
881
|
Typography,
|
|
784
882
|
{
|
|
785
883
|
fontSize: 1,
|
|
786
884
|
variant: "pi",
|
|
787
|
-
textColor: getReleaseColorVariant(release.
|
|
885
|
+
textColor: getReleaseColorVariant(release.actions[0].type, "600"),
|
|
788
886
|
children: formatMessage(
|
|
789
887
|
{
|
|
790
888
|
id: "content-releases.content-manager-edit-view.list-releases.title",
|
|
791
889
|
defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
|
|
792
890
|
},
|
|
793
|
-
{ isPublish: release.
|
|
891
|
+
{ isPublish: release.actions[0].type === "publish" }
|
|
794
892
|
)
|
|
795
893
|
}
|
|
796
894
|
)
|
|
797
895
|
}
|
|
798
896
|
),
|
|
799
|
-
/* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap:
|
|
897
|
+
/* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
|
|
800
898
|
/* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
|
|
801
|
-
|
|
802
|
-
ReleaseActionMenu.DeleteReleaseActionItem,
|
|
899
|
+
release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
|
|
803
900
|
{
|
|
804
|
-
|
|
805
|
-
|
|
901
|
+
id: "content-releases.content-manager-edit-view.scheduled.date",
|
|
902
|
+
defaultMessage: "{date} at {time} ({offset})"
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
date: formatDate(new Date(release.scheduledAt), {
|
|
906
|
+
day: "2-digit",
|
|
907
|
+
month: "2-digit",
|
|
908
|
+
year: "numeric",
|
|
909
|
+
timeZone: release.timezone
|
|
910
|
+
}),
|
|
911
|
+
time: formatTime(new Date(release.scheduledAt), {
|
|
912
|
+
hourCycle: "h23",
|
|
913
|
+
timeZone: release.timezone
|
|
914
|
+
}),
|
|
915
|
+
offset: getTimezoneOffset(
|
|
916
|
+
release.timezone,
|
|
917
|
+
new Date(release.scheduledAt)
|
|
918
|
+
)
|
|
806
919
|
}
|
|
807
|
-
) })
|
|
920
|
+
) }),
|
|
921
|
+
/* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
|
|
922
|
+
/* @__PURE__ */ jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
|
|
923
|
+
/* @__PURE__ */ jsx(
|
|
924
|
+
ReleaseActionMenu.DeleteReleaseActionItem,
|
|
925
|
+
{
|
|
926
|
+
releaseId: release.id,
|
|
927
|
+
actionId: release.actions[0].id
|
|
928
|
+
}
|
|
929
|
+
)
|
|
930
|
+
] }) })
|
|
808
931
|
] })
|
|
809
932
|
]
|
|
810
933
|
},
|
|
@@ -812,7 +935,7 @@ const CMReleasesContainer = () => {
|
|
|
812
935
|
);
|
|
813
936
|
}),
|
|
814
937
|
/* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.createAction, children: /* @__PURE__ */ jsx(
|
|
815
|
-
Button,
|
|
938
|
+
Button$1,
|
|
816
939
|
{
|
|
817
940
|
justifyContent: "center",
|
|
818
941
|
paddingLeft: 4,
|
|
@@ -832,17 +955,280 @@ const CMReleasesContainer = () => {
|
|
|
832
955
|
AddActionToReleaseModal,
|
|
833
956
|
{
|
|
834
957
|
handleClose: toggleModal,
|
|
835
|
-
contentTypeUid
|
|
836
|
-
entryId
|
|
958
|
+
contentTypeUid,
|
|
959
|
+
entryId
|
|
837
960
|
}
|
|
838
961
|
)
|
|
839
962
|
]
|
|
840
963
|
}
|
|
841
964
|
) });
|
|
842
965
|
};
|
|
966
|
+
const getContentPermissions = (subject) => {
|
|
967
|
+
const permissions = {
|
|
968
|
+
publish: [
|
|
969
|
+
{
|
|
970
|
+
action: "plugin::content-manager.explorer.publish",
|
|
971
|
+
subject,
|
|
972
|
+
id: "",
|
|
973
|
+
actionParameters: {},
|
|
974
|
+
properties: {},
|
|
975
|
+
conditions: []
|
|
976
|
+
}
|
|
977
|
+
]
|
|
978
|
+
};
|
|
979
|
+
return permissions;
|
|
980
|
+
};
|
|
981
|
+
const ReleaseAction = ({ ids, model }) => {
|
|
982
|
+
const { formatMessage } = useIntl();
|
|
983
|
+
const toggleNotification = useNotification();
|
|
984
|
+
const { formatAPIError } = useAPIErrorHandler();
|
|
985
|
+
const { modifiedData } = useCMEditViewDataManager();
|
|
986
|
+
const contentPermissions = getContentPermissions(model);
|
|
987
|
+
const {
|
|
988
|
+
allowedActions: { canPublish }
|
|
989
|
+
} = useRBAC(contentPermissions);
|
|
990
|
+
const {
|
|
991
|
+
allowedActions: { canCreate }
|
|
992
|
+
} = useRBAC(PERMISSIONS);
|
|
993
|
+
const response = useGetReleasesQuery();
|
|
994
|
+
const releases = response.data?.data;
|
|
995
|
+
const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
|
|
996
|
+
const handleSubmit = async (values) => {
|
|
997
|
+
const locale = modifiedData.locale;
|
|
998
|
+
const releaseActionEntries = ids.map((id) => ({
|
|
999
|
+
type: values.type,
|
|
1000
|
+
entry: {
|
|
1001
|
+
contentType: model,
|
|
1002
|
+
id,
|
|
1003
|
+
locale
|
|
1004
|
+
}
|
|
1005
|
+
}));
|
|
1006
|
+
const response2 = await createManyReleaseActions({
|
|
1007
|
+
body: releaseActionEntries,
|
|
1008
|
+
params: { releaseId: values.releaseId }
|
|
1009
|
+
});
|
|
1010
|
+
if ("data" in response2) {
|
|
1011
|
+
const notificationMessage = formatMessage(
|
|
1012
|
+
{
|
|
1013
|
+
id: "content-releases.content-manager-list-view.add-to-release.notification.success.message",
|
|
1014
|
+
defaultMessage: "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release."
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
entriesAlreadyInRelease: response2.data.meta.entriesAlreadyInRelease,
|
|
1018
|
+
totalEntries: response2.data.meta.totalEntries
|
|
1019
|
+
}
|
|
1020
|
+
);
|
|
1021
|
+
const notification = {
|
|
1022
|
+
type: "success",
|
|
1023
|
+
title: formatMessage(
|
|
1024
|
+
{
|
|
1025
|
+
id: "content-releases.content-manager-list-view.add-to-release.notification.success.title",
|
|
1026
|
+
defaultMessage: "Successfully added to release."
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
entriesAlreadyInRelease: response2.data.meta.entriesAlreadyInRelease,
|
|
1030
|
+
totalEntries: response2.data.meta.totalEntries
|
|
1031
|
+
}
|
|
1032
|
+
),
|
|
1033
|
+
message: response2.data.meta.entriesAlreadyInRelease ? notificationMessage : ""
|
|
1034
|
+
};
|
|
1035
|
+
toggleNotification(notification);
|
|
1036
|
+
return true;
|
|
1037
|
+
}
|
|
1038
|
+
if ("error" in response2) {
|
|
1039
|
+
if (isAxiosError$1(response2.error)) {
|
|
1040
|
+
toggleNotification({
|
|
1041
|
+
type: "warning",
|
|
1042
|
+
message: formatAPIError(response2.error)
|
|
1043
|
+
});
|
|
1044
|
+
} else {
|
|
1045
|
+
toggleNotification({
|
|
1046
|
+
type: "warning",
|
|
1047
|
+
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
if (!canCreate || !canPublish)
|
|
1053
|
+
return null;
|
|
1054
|
+
return {
|
|
1055
|
+
actionType: "release",
|
|
1056
|
+
variant: "tertiary",
|
|
1057
|
+
label: formatMessage({
|
|
1058
|
+
id: "content-manager-list-view.add-to-release",
|
|
1059
|
+
defaultMessage: "Add to Release"
|
|
1060
|
+
}),
|
|
1061
|
+
dialog: {
|
|
1062
|
+
type: "modal",
|
|
1063
|
+
title: formatMessage({
|
|
1064
|
+
id: "content-manager-list-view.add-to-release",
|
|
1065
|
+
defaultMessage: "Add to Release"
|
|
1066
|
+
}),
|
|
1067
|
+
content: ({ onClose }) => {
|
|
1068
|
+
return /* @__PURE__ */ jsx(
|
|
1069
|
+
Formik,
|
|
1070
|
+
{
|
|
1071
|
+
onSubmit: async (values) => {
|
|
1072
|
+
const data = await handleSubmit(values);
|
|
1073
|
+
if (data) {
|
|
1074
|
+
return onClose();
|
|
1075
|
+
}
|
|
1076
|
+
},
|
|
1077
|
+
validationSchema: RELEASE_ACTION_FORM_SCHEMA,
|
|
1078
|
+
initialValues: INITIAL_VALUES,
|
|
1079
|
+
children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
|
|
1080
|
+
releases?.length === 0 ? /* @__PURE__ */ jsx(NoReleases, {}) : /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
1081
|
+
/* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsx(
|
|
1082
|
+
SingleSelect,
|
|
1083
|
+
{
|
|
1084
|
+
required: true,
|
|
1085
|
+
label: formatMessage({
|
|
1086
|
+
id: "content-releases.content-manager-list-view.add-to-release.select-label",
|
|
1087
|
+
defaultMessage: "Select a release"
|
|
1088
|
+
}),
|
|
1089
|
+
placeholder: formatMessage({
|
|
1090
|
+
id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
|
|
1091
|
+
defaultMessage: "Select"
|
|
1092
|
+
}),
|
|
1093
|
+
onChange: (value) => setFieldValue("releaseId", value),
|
|
1094
|
+
value: values.releaseId,
|
|
1095
|
+
children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
|
|
1096
|
+
}
|
|
1097
|
+
) }),
|
|
1098
|
+
/* @__PURE__ */ jsx(FieldLabel, { children: formatMessage({
|
|
1099
|
+
id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
|
|
1100
|
+
defaultMessage: "What do you want to do with these entries?"
|
|
1101
|
+
}) }),
|
|
1102
|
+
/* @__PURE__ */ jsx(
|
|
1103
|
+
ReleaseActionOptions,
|
|
1104
|
+
{
|
|
1105
|
+
selected: values.type,
|
|
1106
|
+
handleChange: (e) => setFieldValue("type", e.target.value),
|
|
1107
|
+
name: "type"
|
|
1108
|
+
}
|
|
1109
|
+
)
|
|
1110
|
+
] }) }),
|
|
1111
|
+
/* @__PURE__ */ jsx(
|
|
1112
|
+
ModalFooter,
|
|
1113
|
+
{
|
|
1114
|
+
startActions: /* @__PURE__ */ jsx(Button$1, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
|
|
1115
|
+
id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
|
|
1116
|
+
defaultMessage: "Cancel"
|
|
1117
|
+
}) }),
|
|
1118
|
+
endActions: (
|
|
1119
|
+
/**
|
|
1120
|
+
* TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
|
|
1121
|
+
* for yup.string().required(), even when the value is falsy (including empty string)
|
|
1122
|
+
*/
|
|
1123
|
+
/* @__PURE__ */ jsx(Button$1, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
|
|
1124
|
+
id: "content-releases.content-manager-list-view.add-to-release.continue-button",
|
|
1125
|
+
defaultMessage: "Continue"
|
|
1126
|
+
}) })
|
|
1127
|
+
)
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] })
|
|
1131
|
+
}
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
};
|
|
1137
|
+
const Button = styled.button`
|
|
1138
|
+
svg {
|
|
1139
|
+
> g,
|
|
1140
|
+
path {
|
|
1141
|
+
fill: ${({ theme }) => theme.colors.neutral500};
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
&:hover {
|
|
1145
|
+
svg {
|
|
1146
|
+
> g,
|
|
1147
|
+
path {
|
|
1148
|
+
fill: ${({ theme }) => theme.colors.neutral600};
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
&:active {
|
|
1153
|
+
svg {
|
|
1154
|
+
> g,
|
|
1155
|
+
path {
|
|
1156
|
+
fill: ${({ theme }) => theme.colors.neutral400};
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
`;
|
|
1161
|
+
const ActionWrapper = styled(Flex)`
|
|
1162
|
+
svg {
|
|
1163
|
+
height: ${4 / 16}rem;
|
|
1164
|
+
}
|
|
1165
|
+
`;
|
|
1166
|
+
const useReleasesList = (entryId) => {
|
|
1167
|
+
const { uid: contentTypeUid } = useTypedSelector(
|
|
1168
|
+
(state) => state["content-manager_listView"].contentType
|
|
1169
|
+
);
|
|
1170
|
+
const listViewData = useTypedSelector((state) => state["content-manager_listView"].data);
|
|
1171
|
+
const entriesIds = listViewData.map((entry) => entry.id);
|
|
1172
|
+
const response = useGetMappedEntriesInReleasesQuery(
|
|
1173
|
+
{ contentTypeUid, entriesIds },
|
|
1174
|
+
{ skip: !entriesIds || !contentTypeUid || entriesIds.length === 0 }
|
|
1175
|
+
);
|
|
1176
|
+
const mappedEntriesInReleases = response.data || {};
|
|
1177
|
+
return mappedEntriesInReleases?.[entryId] || [];
|
|
1178
|
+
};
|
|
1179
|
+
const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
|
1180
|
+
const { contentType } = layout;
|
|
1181
|
+
if (!contentType.options?.draftAndPublish) {
|
|
1182
|
+
return { displayedHeaders, layout };
|
|
1183
|
+
}
|
|
1184
|
+
return {
|
|
1185
|
+
displayedHeaders: [
|
|
1186
|
+
...displayedHeaders,
|
|
1187
|
+
{
|
|
1188
|
+
key: "__release_key__",
|
|
1189
|
+
fieldSchema: { type: "string" },
|
|
1190
|
+
metadatas: { label: "To be released in", searchable: true, sortable: false },
|
|
1191
|
+
name: "releasedAt",
|
|
1192
|
+
cellFormatter: (props) => /* @__PURE__ */ jsx(ReleaseListCell, { ...props })
|
|
1193
|
+
}
|
|
1194
|
+
],
|
|
1195
|
+
layout
|
|
1196
|
+
};
|
|
1197
|
+
};
|
|
1198
|
+
const ReleaseListCell = ({ id }) => {
|
|
1199
|
+
const releases = useReleasesList(id);
|
|
1200
|
+
const [visible, setVisible] = React.useState(false);
|
|
1201
|
+
const buttonRef = React.useRef(null);
|
|
1202
|
+
const { formatMessage } = useIntl();
|
|
1203
|
+
const handleTogglePopover = () => setVisible((prev) => !prev);
|
|
1204
|
+
return /* @__PURE__ */ jsx(Flex, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx(Button, { type: "button", onClick: handleTogglePopover, ref: buttonRef, children: /* @__PURE__ */ jsxs(ActionWrapper, { height: "2rem", width: "2rem", children: [
|
|
1205
|
+
/* @__PURE__ */ jsx(Typography, { style: { maxWidth: "252px", cursor: "pointer" }, textColor: "neutral800", children: releases.length > 0 ? formatMessage(
|
|
1206
|
+
{
|
|
1207
|
+
id: "content-releases.content-manager.list-view.releases-number",
|
|
1208
|
+
defaultMessage: "{number} {number, plural, one {release} other {releases}}"
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
number: releases.length
|
|
1212
|
+
}
|
|
1213
|
+
) : "-" }),
|
|
1214
|
+
/* @__PURE__ */ jsxs(Flex, { children: [
|
|
1215
|
+
releases.length > 0 && /* @__PURE__ */ jsx(SortIcon, {}),
|
|
1216
|
+
visible && /* @__PURE__ */ jsx(
|
|
1217
|
+
Popover,
|
|
1218
|
+
{
|
|
1219
|
+
onDismiss: handleTogglePopover,
|
|
1220
|
+
source: buttonRef,
|
|
1221
|
+
spacing: 16,
|
|
1222
|
+
children: /* @__PURE__ */ jsx("ul", { children: releases.map(({ id: id2, name }) => /* @__PURE__ */ jsx(Box, { padding: 3, as: "li", children: /* @__PURE__ */ jsx(Link, { href: `/admin/plugins/content-releases/${id2}`, isExternal: false, children: name }) }, id2)) })
|
|
1223
|
+
}
|
|
1224
|
+
)
|
|
1225
|
+
] })
|
|
1226
|
+
] }) }) });
|
|
1227
|
+
};
|
|
843
1228
|
const admin = {
|
|
844
1229
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
845
1230
|
register(app) {
|
|
1231
|
+
app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
|
|
846
1232
|
if (window.strapi.features.isEnabled("cms-content-releases")) {
|
|
847
1233
|
app.addMenuLink({
|
|
848
1234
|
to: `/plugins/${pluginId}`,
|
|
@@ -852,7 +1238,7 @@ const admin = {
|
|
|
852
1238
|
defaultMessage: "Releases"
|
|
853
1239
|
},
|
|
854
1240
|
async Component() {
|
|
855
|
-
const { App } = await import("./App-
|
|
1241
|
+
const { App } = await import("./App-gu1aiP6i.mjs");
|
|
856
1242
|
return App;
|
|
857
1243
|
},
|
|
858
1244
|
permissions: PERMISSIONS.main
|
|
@@ -865,12 +1251,32 @@ const admin = {
|
|
|
865
1251
|
name: `${pluginId}-link`,
|
|
866
1252
|
Component: CMReleasesContainer
|
|
867
1253
|
});
|
|
1254
|
+
app.plugins["content-manager"].apis.addBulkAction((actions) => {
|
|
1255
|
+
const deleteActionIndex = actions.findIndex((action) => action.name === "DeleteAction");
|
|
1256
|
+
actions.splice(deleteActionIndex, 0, ReleaseAction);
|
|
1257
|
+
return actions;
|
|
1258
|
+
});
|
|
1259
|
+
app.registerHook("Admin/CM/pages/ListView/inject-column-in-table", addColumnToTableHook);
|
|
1260
|
+
} else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
|
|
1261
|
+
app.addMenuLink({
|
|
1262
|
+
to: `/plugins/purchase-content-releases`,
|
|
1263
|
+
icon: PaperPlane,
|
|
1264
|
+
intlLabel: {
|
|
1265
|
+
id: `${pluginId}.plugin.name`,
|
|
1266
|
+
defaultMessage: "Releases"
|
|
1267
|
+
},
|
|
1268
|
+
async Component() {
|
|
1269
|
+
const { PurchaseContentReleases } = await import("./PurchaseContentReleases-3tRbmbY3.mjs");
|
|
1270
|
+
return PurchaseContentReleases;
|
|
1271
|
+
},
|
|
1272
|
+
lockIcon: true
|
|
1273
|
+
});
|
|
868
1274
|
}
|
|
869
1275
|
},
|
|
870
1276
|
async registerTrads({ locales }) {
|
|
871
1277
|
const importedTrads = await Promise.all(
|
|
872
1278
|
locales.map((locale) => {
|
|
873
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-
|
|
1279
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-ltT1TlKQ.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
|
|
874
1280
|
return {
|
|
875
1281
|
data: prefixPluginTranslations(data, "content-releases"),
|
|
876
1282
|
locale
|
|
@@ -889,19 +1295,20 @@ const admin = {
|
|
|
889
1295
|
export {
|
|
890
1296
|
PERMISSIONS as P,
|
|
891
1297
|
ReleaseActionOptions as R,
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1298
|
+
useCreateReleaseMutation as a,
|
|
1299
|
+
useGetReleaseQuery as b,
|
|
1300
|
+
useUpdateReleaseMutation as c,
|
|
1301
|
+
useDeleteReleaseMutation as d,
|
|
1302
|
+
usePublishReleaseMutation as e,
|
|
1303
|
+
useTypedDispatch as f,
|
|
1304
|
+
getTimezoneOffset as g,
|
|
1305
|
+
useGetReleaseActionsQuery as h,
|
|
900
1306
|
isAxiosError as i,
|
|
901
|
-
|
|
902
|
-
|
|
1307
|
+
useUpdateReleaseActionMutation as j,
|
|
1308
|
+
ReleaseActionMenu as k,
|
|
1309
|
+
admin as l,
|
|
903
1310
|
pluginId as p,
|
|
904
1311
|
releaseApi as r,
|
|
905
|
-
|
|
1312
|
+
useGetReleasesQuery as u
|
|
906
1313
|
};
|
|
907
|
-
//# sourceMappingURL=index-
|
|
1314
|
+
//# sourceMappingURL=index-mvj9PSKd.mjs.map
|