@strapi/content-releases 0.0.0-next.2a816cdadd2ece37767550b2a249c03ef2b53aeb → 0.0.0-next.2c18b0da94ecfad7e25c7a17ed408b9eccc259e9

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.
Files changed (32) hide show
  1. package/LICENSE +17 -1
  2. package/dist/_chunks/{App-oGnTffWo.js → App-dLXY5ei3.js} +678 -640
  3. package/dist/_chunks/App-dLXY5ei3.js.map +1 -0
  4. package/dist/_chunks/{App-eVYKuxUc.mjs → App-jrh58sXY.mjs} +691 -653
  5. package/dist/_chunks/App-jrh58sXY.mjs.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-3tRbmbY3.mjs} +2 -2
  7. package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-bpIYXOfu.js} +2 -2
  9. package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +1 -0
  10. package/dist/_chunks/{en-r0otWaln.js → en-HrREghh3.js} +14 -5
  11. package/dist/_chunks/en-HrREghh3.js.map +1 -0
  12. package/dist/_chunks/{en-veqvqeEr.mjs → en-ltT1TlKQ.mjs} +14 -5
  13. package/dist/_chunks/en-ltT1TlKQ.mjs.map +1 -0
  14. package/dist/_chunks/{index-ABxBBqzg.js → index-CVO0Rqdm.js} +348 -23
  15. package/dist/_chunks/index-CVO0Rqdm.js.map +1 -0
  16. package/dist/_chunks/{index-8XT9UxC5.mjs → index-PiOGBETy.mjs} +363 -38
  17. package/dist/_chunks/index-PiOGBETy.mjs.map +1 -0
  18. package/dist/admin/index.js +1 -1
  19. package/dist/admin/index.mjs +1 -1
  20. package/dist/server/index.js +621 -175
  21. package/dist/server/index.js.map +1 -1
  22. package/dist/server/index.mjs +620 -175
  23. package/dist/server/index.mjs.map +1 -1
  24. package/package.json +12 -12
  25. package/dist/_chunks/App-eVYKuxUc.mjs.map +0 -1
  26. package/dist/_chunks/App-oGnTffWo.js.map +0 -1
  27. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
  28. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
  29. package/dist/_chunks/en-r0otWaln.js.map +0 -1
  30. package/dist/_chunks/en-veqvqeEr.mjs.map +0 -1
  31. package/dist/_chunks/index-8XT9UxC5.mjs.map +0 -1
  32. package/dist/_chunks/index-ABxBBqzg.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: "ReleaseAction", id: "LIST" }
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: (result, error, arg) => [{ type: "Release", id: arg.id }]
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,11 +352,13 @@ 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;
330
363
  const getTimezoneOffset = (timezone, date) => {
331
364
  try {
@@ -462,6 +495,21 @@ const ReleaseActionEntryLinkItem = ({
462
495
  }
463
496
  );
464
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
+ };
465
513
  const Root = ({ children, hasTriggerBorder = false }) => {
466
514
  const { formatMessage } = useIntl();
467
515
  return (
@@ -486,6 +534,7 @@ const Root = ({ children, hasTriggerBorder = false }) => {
486
534
  };
487
535
  const ReleaseActionMenu = {
488
536
  Root,
537
+ EditReleaseItem,
489
538
  DeleteReleaseActionItem,
490
539
  ReleaseActionEntryLinkItem
491
540
  };
@@ -524,6 +573,10 @@ const FieldWrapper = styled(Field)`
524
573
  color: ${({ theme }) => theme.colors.neutral700};
525
574
  background-color: ${({ theme }) => theme.colors.neutral100};
526
575
  border-color: ${({ theme }) => theme.colors.neutral200};
576
+
577
+ & > label {
578
+ cursor: pointer;
579
+ }
527
580
  }
528
581
 
529
582
  &[data-disabled='true'] {
@@ -731,7 +784,7 @@ const AddActionToReleaseModal = ({
731
784
  /* @__PURE__ */ jsx(
732
785
  ModalFooter,
733
786
  {
734
- 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({
735
788
  id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
736
789
  defaultMessage: "Cancel"
737
790
  }) }),
@@ -740,7 +793,7 @@ const AddActionToReleaseModal = ({
740
793
  * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
741
794
  * for yup.string().required(), even when the value is falsy (including empty string)
742
795
  */
743
- /* @__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({
744
797
  id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
745
798
  defaultMessage: "Continue"
746
799
  }) })
@@ -763,7 +816,6 @@ const CMReleasesContainer = () => {
763
816
  slug
764
817
  } = useCMEditViewDataManager();
765
818
  const contentTypeUid = slug;
766
- const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
767
819
  const canFetch = entryId != null && contentTypeUid != null;
768
820
  const fetchParams = canFetch ? {
769
821
  contentTypeUid,
@@ -812,7 +864,7 @@ const CMReleasesContainer = () => {
812
864
  alignItems: "start",
813
865
  borderWidth: "1px",
814
866
  borderStyle: "solid",
815
- borderColor: getReleaseColorVariant(release.action.type, "200"),
867
+ borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
816
868
  overflow: "hidden",
817
869
  hasRadius: true,
818
870
  children: [
@@ -823,20 +875,20 @@ const CMReleasesContainer = () => {
823
875
  paddingBottom: 3,
824
876
  paddingLeft: 4,
825
877
  paddingRight: 4,
826
- background: getReleaseColorVariant(release.action.type, "100"),
878
+ background: getReleaseColorVariant(release.actions[0].type, "100"),
827
879
  width: "100%",
828
880
  children: /* @__PURE__ */ jsx(
829
881
  Typography,
830
882
  {
831
883
  fontSize: 1,
832
884
  variant: "pi",
833
- textColor: getReleaseColorVariant(release.action.type, "600"),
885
+ textColor: getReleaseColorVariant(release.actions[0].type, "600"),
834
886
  children: formatMessage(
835
887
  {
836
888
  id: "content-releases.content-manager-edit-view.list-releases.title",
837
889
  defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
838
890
  },
839
- { isPublish: release.action.type === "publish" }
891
+ { isPublish: release.actions[0].type === "publish" }
840
892
  )
841
893
  }
842
894
  )
@@ -844,7 +896,7 @@ const CMReleasesContainer = () => {
844
896
  ),
845
897
  /* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
846
898
  /* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
847
- IsSchedulingEnabled && release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
899
+ release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
848
900
  {
849
901
  id: "content-releases.content-manager-edit-view.scheduled.date",
850
902
  defaultMessage: "{date} at {time} ({offset})"
@@ -857,7 +909,7 @@ const CMReleasesContainer = () => {
857
909
  timeZone: release.timezone
858
910
  }),
859
911
  time: formatTime(new Date(release.scheduledAt), {
860
- hour12: false,
912
+ hourCycle: "h23",
861
913
  timeZone: release.timezone
862
914
  }),
863
915
  offset: getTimezoneOffset(
@@ -866,13 +918,16 @@ const CMReleasesContainer = () => {
866
918
  )
867
919
  }
868
920
  ) }),
869
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.deleteAction, children: /* @__PURE__ */ jsx(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: /* @__PURE__ */ jsx(
870
- ReleaseActionMenu.DeleteReleaseActionItem,
871
- {
872
- releaseId: release.id,
873
- actionId: release.action.id
874
- }
875
- ) }) })
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
+ ] }) })
876
931
  ] })
877
932
  ]
878
933
  },
@@ -880,7 +935,7 @@ const CMReleasesContainer = () => {
880
935
  );
881
936
  }),
882
937
  /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.createAction, children: /* @__PURE__ */ jsx(
883
- Button,
938
+ Button$1,
884
939
  {
885
940
  justifyContent: "center",
886
941
  paddingLeft: 4,
@@ -908,9 +963,272 @@ const CMReleasesContainer = () => {
908
963
  }
909
964
  ) });
910
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
+ };
911
1228
  const admin = {
912
1229
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
913
1230
  register(app) {
1231
+ app.createHook("ContentReleases/pages/ReleaseDetails/add-locale-in-releases");
914
1232
  if (window.strapi.features.isEnabled("cms-content-releases")) {
915
1233
  app.addMenuLink({
916
1234
  to: `/plugins/${pluginId}`,
@@ -920,7 +1238,7 @@ const admin = {
920
1238
  defaultMessage: "Releases"
921
1239
  },
922
1240
  async Component() {
923
- const { App } = await import("./App-eVYKuxUc.mjs");
1241
+ const { App } = await import("./App-jrh58sXY.mjs");
924
1242
  return App;
925
1243
  },
926
1244
  permissions: PERMISSIONS.main
@@ -933,6 +1251,12 @@ const admin = {
933
1251
  name: `${pluginId}-link`,
934
1252
  Component: CMReleasesContainer
935
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);
936
1260
  } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
937
1261
  app.addMenuLink({
938
1262
  to: `/plugins/purchase-content-releases`,
@@ -942,17 +1266,18 @@ const admin = {
942
1266
  defaultMessage: "Releases"
943
1267
  },
944
1268
  async Component() {
945
- const { PurchaseContentReleases } = await import("./PurchaseContentReleases-Clm0iACO.mjs");
1269
+ const { PurchaseContentReleases } = await import("./PurchaseContentReleases-3tRbmbY3.mjs");
946
1270
  return PurchaseContentReleases;
947
1271
  },
948
1272
  lockIcon: true
1273
+ // TODO: to replace with another name in v5
949
1274
  });
950
1275
  }
951
1276
  },
952
1277
  async registerTrads({ locales }) {
953
1278
  const importedTrads = await Promise.all(
954
1279
  locales.map((locale) => {
955
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-veqvqeEr.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
1280
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-ltT1TlKQ.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
956
1281
  return {
957
1282
  data: prefixPluginTranslations(data, "content-releases"),
958
1283
  locale
@@ -971,20 +1296,20 @@ const admin = {
971
1296
  export {
972
1297
  PERMISSIONS as P,
973
1298
  ReleaseActionOptions as R,
974
- useUpdateReleaseMutation as a,
975
- useDeleteReleaseMutation as b,
976
- usePublishReleaseMutation as c,
977
- useTypedDispatch as d,
978
- useGetReleaseActionsQuery as e,
979
- useUpdateReleaseActionMutation as f,
1299
+ useCreateReleaseMutation as a,
1300
+ useGetReleaseQuery as b,
1301
+ useUpdateReleaseMutation as c,
1302
+ useDeleteReleaseMutation as d,
1303
+ usePublishReleaseMutation as e,
1304
+ useTypedDispatch as f,
980
1305
  getTimezoneOffset as g,
981
- ReleaseActionMenu as h,
1306
+ useGetReleaseActionsQuery as h,
982
1307
  isAxiosError as i,
983
- useGetReleasesQuery as j,
984
- useCreateReleaseMutation as k,
1308
+ useUpdateReleaseActionMutation as j,
1309
+ ReleaseActionMenu as k,
985
1310
  admin as l,
986
1311
  pluginId as p,
987
1312
  releaseApi as r,
988
- useGetReleaseQuery as u
1313
+ useGetReleasesQuery as u
989
1314
  };
990
- //# sourceMappingURL=index-8XT9UxC5.mjs.map
1315
+ //# sourceMappingURL=index-PiOGBETy.mjs.map