@strapi/content-releases 0.0.0-next.c5f067b5650921187770124e9b6c8186e805e242 → 0.0.0-next.cfecf3ad808761571ce11e528113e5c1ea5f87fd
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-5PsAyVt2.js → App-HjWtUYmc.js} +728 -459
- package/dist/_chunks/App-HjWtUYmc.js.map +1 -0
- package/dist/_chunks/{App-3ycH2d3s.mjs → App-gu1aiP6i.mjs} +738 -470
- 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-D57Rztnc.js → index-ZNwxYN8H.js} +437 -32
- package/dist/_chunks/index-ZNwxYN8H.js.map +1 -0
- package/dist/_chunks/{index-4gUWuCQV.mjs → index-mvj9PSKd.mjs} +453 -48
- 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 +1037 -421
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1036 -421
- package/dist/server/index.mjs.map +1 -1
- package/package.json +15 -12
- package/dist/_chunks/App-3ycH2d3s.mjs.map +0 -1
- package/dist/_chunks/App-5PsAyVt2.js.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-4gUWuCQV.mjs.map +0 -1
- package/dist/_chunks/index-D57Rztnc.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
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";
|
|
@@ -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,7 +808,7 @@ 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,
|
|
@@ -768,7 +864,7 @@ const CMReleasesContainer = () => {
|
|
|
768
864
|
alignItems: "start",
|
|
769
865
|
borderWidth: "1px",
|
|
770
866
|
borderStyle: "solid",
|
|
771
|
-
borderColor: getReleaseColorVariant(release.
|
|
867
|
+
borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
|
|
772
868
|
overflow: "hidden",
|
|
773
869
|
hasRadius: true,
|
|
774
870
|
children: [
|
|
@@ -779,34 +875,59 @@ const CMReleasesContainer = () => {
|
|
|
779
875
|
paddingBottom: 3,
|
|
780
876
|
paddingLeft: 4,
|
|
781
877
|
paddingRight: 4,
|
|
782
|
-
background: getReleaseColorVariant(release.
|
|
878
|
+
background: getReleaseColorVariant(release.actions[0].type, "100"),
|
|
783
879
|
width: "100%",
|
|
784
880
|
children: /* @__PURE__ */ jsx(
|
|
785
881
|
Typography,
|
|
786
882
|
{
|
|
787
883
|
fontSize: 1,
|
|
788
884
|
variant: "pi",
|
|
789
|
-
textColor: getReleaseColorVariant(release.
|
|
885
|
+
textColor: getReleaseColorVariant(release.actions[0].type, "600"),
|
|
790
886
|
children: formatMessage(
|
|
791
887
|
{
|
|
792
888
|
id: "content-releases.content-manager-edit-view.list-releases.title",
|
|
793
889
|
defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
|
|
794
890
|
},
|
|
795
|
-
{ isPublish: release.
|
|
891
|
+
{ isPublish: release.actions[0].type === "publish" }
|
|
796
892
|
)
|
|
797
893
|
}
|
|
798
894
|
)
|
|
799
895
|
}
|
|
800
896
|
),
|
|
801
|
-
/* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap:
|
|
897
|
+
/* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
|
|
802
898
|
/* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
|
|
803
|
-
|
|
804
|
-
|
|
899
|
+
release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
|
|
900
|
+
{
|
|
901
|
+
id: "content-releases.content-manager-edit-view.scheduled.date",
|
|
902
|
+
defaultMessage: "{date} at {time} ({offset})"
|
|
903
|
+
},
|
|
805
904
|
{
|
|
806
|
-
|
|
807
|
-
|
|
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
|
+
)
|
|
808
919
|
}
|
|
809
|
-
) })
|
|
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
|
+
] }) })
|
|
810
931
|
] })
|
|
811
932
|
]
|
|
812
933
|
},
|
|
@@ -814,7 +935,7 @@ const CMReleasesContainer = () => {
|
|
|
814
935
|
);
|
|
815
936
|
}),
|
|
816
937
|
/* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.createAction, children: /* @__PURE__ */ jsx(
|
|
817
|
-
Button,
|
|
938
|
+
Button$1,
|
|
818
939
|
{
|
|
819
940
|
justifyContent: "center",
|
|
820
941
|
paddingLeft: 4,
|
|
@@ -842,9 +963,272 @@ const CMReleasesContainer = () => {
|
|
|
842
963
|
}
|
|
843
964
|
) });
|
|
844
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
|
+
};
|
|
845
1228
|
const admin = {
|
|
846
1229
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
847
1230
|
register(app) {
|
|
1231
|
+
app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
|
|
848
1232
|
if (window.strapi.features.isEnabled("cms-content-releases")) {
|
|
849
1233
|
app.addMenuLink({
|
|
850
1234
|
to: `/plugins/${pluginId}`,
|
|
@@ -854,7 +1238,7 @@ const admin = {
|
|
|
854
1238
|
defaultMessage: "Releases"
|
|
855
1239
|
},
|
|
856
1240
|
async Component() {
|
|
857
|
-
const { App } = await import("./App-
|
|
1241
|
+
const { App } = await import("./App-gu1aiP6i.mjs");
|
|
858
1242
|
return App;
|
|
859
1243
|
},
|
|
860
1244
|
permissions: PERMISSIONS.main
|
|
@@ -867,12 +1251,32 @@ const admin = {
|
|
|
867
1251
|
name: `${pluginId}-link`,
|
|
868
1252
|
Component: CMReleasesContainer
|
|
869
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
|
+
});
|
|
870
1274
|
}
|
|
871
1275
|
},
|
|
872
1276
|
async registerTrads({ locales }) {
|
|
873
1277
|
const importedTrads = await Promise.all(
|
|
874
1278
|
locales.map((locale) => {
|
|
875
|
-
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 }) => {
|
|
876
1280
|
return {
|
|
877
1281
|
data: prefixPluginTranslations(data, "content-releases"),
|
|
878
1282
|
locale
|
|
@@ -891,19 +1295,20 @@ const admin = {
|
|
|
891
1295
|
export {
|
|
892
1296
|
PERMISSIONS as P,
|
|
893
1297
|
ReleaseActionOptions as R,
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
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,
|
|
902
1306
|
isAxiosError as i,
|
|
903
|
-
|
|
904
|
-
|
|
1307
|
+
useUpdateReleaseActionMutation as j,
|
|
1308
|
+
ReleaseActionMenu as k,
|
|
1309
|
+
admin as l,
|
|
905
1310
|
pluginId as p,
|
|
906
1311
|
releaseApi as r,
|
|
907
|
-
|
|
1312
|
+
useGetReleasesQuery as u
|
|
908
1313
|
};
|
|
909
|
-
//# sourceMappingURL=index-
|
|
1314
|
+
//# sourceMappingURL=index-mvj9PSKd.mjs.map
|