@strapi/content-releases 0.0.0-experimental.cb311d9fcfbd8e441f790aea232f0a39bdd90e16 → 0.0.0-experimental.cb74730ce5154c26404d4dccca14976a22319002

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 (55) hide show
  1. package/dist/_chunks/{App-DdxsZcmK.js → App-BogHVHwI.js} +352 -146
  2. package/dist/_chunks/App-BogHVHwI.js.map +1 -0
  3. package/dist/_chunks/{App-CZe9wueI.mjs → App-Ckb7_0Kj.mjs} +312 -105
  4. package/dist/_chunks/App-Ckb7_0Kj.mjs.map +1 -0
  5. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -1
  6. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -1
  7. package/dist/_chunks/{ReleasesSettingsPage-DWc3H14U.mjs → ReleasesSettingsPage-CFWj9DKn.mjs} +4 -4
  8. package/dist/_chunks/ReleasesSettingsPage-CFWj9DKn.mjs.map +1 -0
  9. package/dist/_chunks/{ReleasesSettingsPage-CwsExK2M.js → ReleasesSettingsPage-DhhwsfOv.js} +4 -4
  10. package/dist/_chunks/ReleasesSettingsPage-DhhwsfOv.js.map +1 -0
  11. package/dist/_chunks/{en-CmYoEnA7.js → en-BWPPsSH-.js} +11 -2
  12. package/dist/_chunks/en-BWPPsSH-.js.map +1 -0
  13. package/dist/_chunks/{en-D0yVZFqf.mjs → en-D9Q4YW03.mjs} +11 -2
  14. package/dist/_chunks/en-D9Q4YW03.mjs.map +1 -0
  15. package/dist/_chunks/{index-DtQIl4fm.js → index-CBRMnJQ5.js} +91 -40
  16. package/dist/_chunks/index-CBRMnJQ5.js.map +1 -0
  17. package/dist/_chunks/{index-CPq3qdIv.mjs → index-RcSLPK74.mjs} +90 -38
  18. package/dist/_chunks/index-RcSLPK74.mjs.map +1 -0
  19. package/dist/_chunks/{schemas-z5zp-_Gd.js → schemas-DBYv9gK8.js} +3 -4
  20. package/dist/_chunks/schemas-DBYv9gK8.js.map +1 -0
  21. package/dist/_chunks/{schemas-63pFihNF.mjs → schemas-DdA2ic2U.mjs} +2 -2
  22. package/dist/_chunks/schemas-DdA2ic2U.mjs.map +1 -0
  23. package/dist/admin/index.js +1 -1
  24. package/dist/admin/index.mjs +1 -1
  25. package/dist/admin/src/components/EntryValidationPopover.d.ts +13 -0
  26. package/dist/admin/src/services/release.d.ts +28 -28
  27. package/dist/server/index.js +119 -17
  28. package/dist/server/index.js.map +1 -1
  29. package/dist/server/index.mjs +118 -15
  30. package/dist/server/index.mjs.map +1 -1
  31. package/dist/server/src/controllers/release-action.d.ts.map +1 -1
  32. package/dist/server/src/controllers/release.d.ts.map +1 -1
  33. package/dist/server/src/index.d.ts +4 -6
  34. package/dist/server/src/index.d.ts.map +1 -1
  35. package/dist/server/src/middlewares/documents.d.ts.map +1 -1
  36. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -1
  37. package/dist/server/src/services/index.d.ts +4 -6
  38. package/dist/server/src/services/index.d.ts.map +1 -1
  39. package/dist/server/src/services/release-action.d.ts +6 -8
  40. package/dist/server/src/services/release-action.d.ts.map +1 -1
  41. package/dist/server/src/utils/index.d.ts.map +1 -1
  42. package/dist/shared/contracts/release-actions.d.ts +8 -1
  43. package/dist/shared/contracts/release-actions.d.ts.map +1 -1
  44. package/package.json +18 -16
  45. package/dist/_chunks/App-CZe9wueI.mjs.map +0 -1
  46. package/dist/_chunks/App-DdxsZcmK.js.map +0 -1
  47. package/dist/_chunks/ReleasesSettingsPage-CwsExK2M.js.map +0 -1
  48. package/dist/_chunks/ReleasesSettingsPage-DWc3H14U.mjs.map +0 -1
  49. package/dist/_chunks/en-CmYoEnA7.js.map +0 -1
  50. package/dist/_chunks/en-D0yVZFqf.mjs.map +0 -1
  51. package/dist/_chunks/index-CPq3qdIv.mjs.map +0 -1
  52. package/dist/_chunks/index-DtQIl4fm.js.map +0 -1
  53. package/dist/_chunks/schemas-63pFihNF.mjs.map +0 -1
  54. package/dist/_chunks/schemas-z5zp-_Gd.js.map +0 -1
  55. package/strapi-server.js +0 -3
@@ -12,8 +12,7 @@ const yup = require("yup");
12
12
  const styledComponents = require("styled-components");
13
13
  const React = require("react");
14
14
  function _interopNamespace(e) {
15
- if (e && e.__esModule)
16
- return e;
15
+ if (e && e.__esModule) return e;
17
16
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
18
17
  if (e) {
19
18
  for (const k in e) {
@@ -31,13 +30,20 @@ function _interopNamespace(e) {
31
30
  }
32
31
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
33
32
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
34
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
33
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
35
34
  const v = glob[path];
36
35
  if (v) {
37
36
  return typeof v === "function" ? v() : Promise.resolve(v);
38
37
  }
39
38
  return new Promise((_, reject) => {
40
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
39
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
40
+ reject.bind(
41
+ null,
42
+ new Error(
43
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
44
+ )
45
+ )
46
+ );
41
47
  });
42
48
  };
43
49
  const PERMISSIONS = {
@@ -124,7 +130,7 @@ const extendInvalidatesTags = (endpoint, extraTags) => {
124
130
  Object.assign(endpoint, { invalidatesTags: newInvalidatesTags });
125
131
  };
126
132
  const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
127
- addTagTypes: ["Release", "ReleaseAction", "EntriesInRelease", "ReleaseSettings"],
133
+ addTagTypes: ["Release", "ReleaseAction", "EntriesInRelease", "ReleaseSettings", "Document"],
128
134
  endpoints: {
129
135
  updateDocument(endpoint) {
130
136
  extendInvalidatesTags(endpoint, [
@@ -149,6 +155,24 @@ const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
149
155
  { type: "Release", id: "LIST" },
150
156
  { type: "ReleaseAction", id: "LIST" }
151
157
  ]);
158
+ },
159
+ createWorkflow(endpoint) {
160
+ extendInvalidatesTags(endpoint, [
161
+ { type: "Release", id: "LIST" },
162
+ { type: "ReleaseAction", id: "LIST" }
163
+ ]);
164
+ },
165
+ updateWorkflow(endpoint) {
166
+ extendInvalidatesTags(endpoint, [
167
+ { type: "Release", id: "LIST" },
168
+ { type: "ReleaseAction", id: "LIST" }
169
+ ]);
170
+ },
171
+ deleteWorkflow(endpoint) {
172
+ extendInvalidatesTags(endpoint, [
173
+ { type: "Release", id: "LIST" },
174
+ { type: "ReleaseAction", id: "LIST" }
175
+ ]);
152
176
  }
153
177
  }
154
178
  }).injectEndpoints({
@@ -219,7 +243,10 @@ const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
219
243
  method: "GET"
220
244
  };
221
245
  },
222
- providesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
246
+ providesTags: (result, error, arg) => [
247
+ { type: "Release", id: "LIST" },
248
+ { type: "Release", id: arg.id }
249
+ ]
223
250
  }),
224
251
  getReleaseActions: build.query({
225
252
  query({ releaseId, ...params }) {
@@ -288,7 +315,11 @@ const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
288
315
  data: body
289
316
  };
290
317
  },
291
- invalidatesTags: () => [{ type: "ReleaseAction", id: "LIST" }],
318
+ invalidatesTags: (res, error, arg) => [
319
+ { type: "ReleaseAction", id: "LIST" },
320
+ { type: "Release", id: "LIST" },
321
+ { type: "Release", id: arg.params.releaseId }
322
+ ],
292
323
  async onQueryStarted({ body, params, query, actionPath }, { dispatch, queryFulfilled }) {
293
324
  const paramsWithoutActionId = {
294
325
  releaseId: params.releaseId,
@@ -335,7 +366,10 @@ const releaseApi = strapiAdmin.adminApi.enhanceEndpoints({
335
366
  method: "POST"
336
367
  };
337
368
  },
338
- invalidatesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
369
+ invalidatesTags: (result, error, arg) => [
370
+ { type: "Release", id: arg.id },
371
+ { type: "Document", id: `ALL_LIST` }
372
+ ]
339
373
  }),
340
374
  deleteRelease: build.mutation({
341
375
  query({ id }) {
@@ -598,6 +632,7 @@ const AddActionToReleaseModal = ({
598
632
  };
599
633
  const ReleaseActionModalForm = ({
600
634
  documentId,
635
+ document,
601
636
  model,
602
637
  collectionType
603
638
  }) => {
@@ -676,6 +711,8 @@ const ReleaseActionModalForm = ({
676
711
  defaultMessage: "Add to release"
677
712
  }),
678
713
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
714
+ // Entry is creating so we don't want to allow adding it to a release
715
+ disabled: !document,
679
716
  position: ["panel", "table-row"],
680
717
  dialog: {
681
718
  type: "modal",
@@ -801,8 +838,7 @@ const ReleaseAction = ({ documents, model }) => {
801
838
  }
802
839
  }
803
840
  };
804
- if (!canCreate || !canPublish)
805
- return null;
841
+ if (!canCreate || !canPublish) return null;
806
842
  return {
807
843
  actionType: "release",
808
844
  variant: "tertiary",
@@ -878,11 +914,6 @@ const ReleaseAction = ({ documents, model }) => {
878
914
  }
879
915
  };
880
916
  };
881
- const StyledButton = styledComponents.styled(designSystem.Button)`
882
- span {
883
- font-weight: 400;
884
- }
885
- `;
886
917
  const useReleasesList = (contentTypeUid, documentId) => {
887
918
  const listViewData = strapiAdmin.useTable("ListView", (state) => state.rows);
888
919
  const documentIds = listViewData.map((entry) => entry.documentId);
@@ -922,20 +953,28 @@ const ReleaseListCell = ({ documentId, model }) => {
922
953
  const { formatMessage } = reactIntl.useIntl();
923
954
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
924
955
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
925
- StyledButton,
956
+ designSystem.Button,
926
957
  {
927
958
  variant: "ghost",
928
959
  onClick: (e) => e.stopPropagation(),
929
- endIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, {}),
930
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { style: { maxWidth: "252px", cursor: "pointer" }, textColor: "neutral800", children: releases.length > 0 ? formatMessage(
960
+ endIcon: releases.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) : null,
961
+ children: /* @__PURE__ */ jsxRuntime.jsx(
962
+ designSystem.Typography,
931
963
  {
932
- id: "content-releases.content-manager.list-view.releases-number",
933
- defaultMessage: "{number} {number, plural, one {release} other {releases}}"
934
- },
935
- {
936
- number: releases.length
964
+ style: { maxWidth: "252px", cursor: "pointer" },
965
+ textColor: "neutral800",
966
+ fontWeight: "regular",
967
+ children: releases.length > 0 ? formatMessage(
968
+ {
969
+ id: "content-releases.content-manager.list-view.releases-number",
970
+ defaultMessage: "{number} {number, plural, one {release} other {releases}}"
971
+ },
972
+ {
973
+ number: releases.length
974
+ }
975
+ ) : "-"
937
976
  }
938
- ) : "-" })
977
+ )
939
978
  }
940
979
  ) }),
941
980
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Content, { children: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: releases.map(({ id, name }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { href: `/admin/plugins/content-releases/${id}`, isExternal: false, children: name }) }, id)) }) })
@@ -1107,7 +1146,7 @@ const Root = ({ children }) => {
1107
1146
  return (
1108
1147
  // A user can access the dropdown if they have permissions to delete a release-action OR update a release
1109
1148
  allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
1110
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Trigger, { variant: "tertiary", endIcon: null, paddingLeft: "7px", paddingRight: "7px", children: /* @__PURE__ */ jsxRuntime.jsx(
1149
+ /* @__PURE__ */ jsxRuntime.jsx(StyledMoreButton, { variant: "tertiary", endIcon: null, paddingLeft: "7px", paddingRight: "7px", children: /* @__PURE__ */ jsxRuntime.jsx(
1111
1150
  designSystem.AccessibleIcon,
1112
1151
  {
1113
1152
  label: formatMessage({
@@ -1121,13 +1160,23 @@ const Root = ({ children }) => {
1121
1160
  ] }) : null
1122
1161
  );
1123
1162
  };
1163
+ const StyledMoreButton = styledComponents.styled(designSystem.Menu.Trigger)`
1164
+ & > span {
1165
+ display: flex;
1166
+ }
1167
+ `;
1124
1168
  const ReleaseActionMenu = {
1125
1169
  Root,
1126
1170
  EditReleaseItem,
1127
1171
  DeleteReleaseActionItem,
1128
1172
  ReleaseActionEntryLinkItem
1129
1173
  };
1130
- const Panel = ({ model, documentId, collectionType }) => {
1174
+ const Panel = ({
1175
+ model,
1176
+ document,
1177
+ documentId,
1178
+ collectionType
1179
+ }) => {
1131
1180
  const [{ query }] = strapiAdmin.useQueryParams();
1132
1181
  const locale = query.plugins?.i18n?.locale;
1133
1182
  const {
@@ -1136,12 +1185,17 @@ const Panel = ({ model, documentId, collectionType }) => {
1136
1185
  const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
1137
1186
  const { allowedActions } = strapiAdmin.useRBAC(PERMISSIONS);
1138
1187
  const { canRead, canDeleteAction } = allowedActions;
1139
- const response = useGetReleasesForEntryQuery({
1140
- contentType: model,
1141
- entryDocumentId: documentId,
1142
- locale,
1143
- hasEntryAttached: true
1144
- });
1188
+ const response = useGetReleasesForEntryQuery(
1189
+ {
1190
+ contentType: model,
1191
+ entryDocumentId: documentId,
1192
+ locale,
1193
+ hasEntryAttached: true
1194
+ },
1195
+ {
1196
+ skip: !document
1197
+ }
1198
+ );
1145
1199
  const releases = response.data?.data;
1146
1200
  const getReleaseColorVariant = (actionType, shade) => {
1147
1201
  if (actionType === "unpublish") {
@@ -1155,7 +1209,7 @@ const Panel = ({ model, documentId, collectionType }) => {
1155
1209
  if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
1156
1210
  return null;
1157
1211
  }
1158
- if (releases && releases.length === 0) {
1212
+ if (!releases || releases.length === 0) {
1159
1213
  return null;
1160
1214
  }
1161
1215
  return {
@@ -1240,9 +1294,6 @@ const Panel = ({ model, documentId, collectionType }) => {
1240
1294
  };
1241
1295
  const pluginId = "content-releases";
1242
1296
  const prefixPluginTranslations = (trad, pluginId2) => {
1243
- if (!pluginId2) {
1244
- throw new TypeError("pluginId can't be empty");
1245
- }
1246
1297
  return Object.keys(trad).reduce((acc, current) => {
1247
1298
  acc[`${pluginId2}.${current}`] = trad[current];
1248
1299
  return acc;
@@ -1260,7 +1311,7 @@ const admin = {
1260
1311
  id: `${pluginId}.plugin.name`,
1261
1312
  defaultMessage: "Releases"
1262
1313
  },
1263
- Component: () => Promise.resolve().then(() => require("./App-DdxsZcmK.js")).then((mod) => ({ default: mod.App })),
1314
+ Component: () => Promise.resolve().then(() => require("./App-BogHVHwI.js")).then((mod) => ({ default: mod.App })),
1264
1315
  permissions: PERMISSIONS.main,
1265
1316
  position: 2
1266
1317
  });
@@ -1284,7 +1335,7 @@ const admin = {
1284
1335
  },
1285
1336
  permissions: [],
1286
1337
  async Component() {
1287
- const { ProtectedReleasesSettingsPage } = await Promise.resolve().then(() => require("./ReleasesSettingsPage-CwsExK2M.js"));
1338
+ const { ProtectedReleasesSettingsPage } = await Promise.resolve().then(() => require("./ReleasesSettingsPage-DhhwsfOv.js"));
1288
1339
  return { default: ProtectedReleasesSettingsPage };
1289
1340
  }
1290
1341
  });
@@ -1316,7 +1367,7 @@ const admin = {
1316
1367
  async registerTrads({ locales }) {
1317
1368
  const importedTrads = await Promise.all(
1318
1369
  locales.map((locale) => {
1319
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-CmYoEnA7.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1370
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-BWPPsSH-.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
1320
1371
  return {
1321
1372
  data: prefixPluginTranslations(data, "content-releases"),
1322
1373
  locale
@@ -1350,4 +1401,4 @@ exports.usePublishReleaseMutation = usePublishReleaseMutation;
1350
1401
  exports.useUpdateReleaseActionMutation = useUpdateReleaseActionMutation;
1351
1402
  exports.useUpdateReleaseMutation = useUpdateReleaseMutation;
1352
1403
  exports.useUpdateReleaseSettingsMutation = useUpdateReleaseSettingsMutation;
1353
- //# sourceMappingURL=index-DtQIl4fm.js.map
1404
+ //# sourceMappingURL=index-CBRMnJQ5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CBRMnJQ5.js","sources":["../../admin/src/constants.ts","../../admin/src/services/release.ts","../../admin/src/components/ReleaseActionOptions.tsx","../../admin/src/components/ReleaseActionModal.tsx","../../admin/src/components/ReleaseAction.tsx","../../admin/src/components/ReleaseListCell.tsx","../../admin/src/utils/time.ts","../../admin/src/components/ReleaseActionMenu.tsx","../../admin/src/components/ReleasesPanel.tsx","../../admin/src/pluginId.ts","../../admin/src/utils/prefixPluginTranslations.ts","../../admin/src/index.ts"],"sourcesContent":["import type { Permission as StrapiPermission } from '@strapi/admin/strapi-admin';\n\nexport const PERMISSIONS = {\n main: [\n {\n action: 'plugin::content-releases.read',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n create: [\n {\n action: 'plugin::content-releases.create',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n update: [\n {\n action: 'plugin::content-releases.update',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n delete: [\n {\n action: 'plugin::content-releases.delete',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n createAction: [\n {\n action: 'plugin::content-releases.create-action',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n deleteAction: [\n {\n action: 'plugin::content-releases.delete-action',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n publish: [\n {\n action: 'plugin::content-releases.publish',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n} satisfies Record<string, StrapiPermission[]>;\n\nexport const PERMISSIONS_SETTINGS = {\n read: [\n {\n action: 'plugin::content-releases.settings.read',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n update: [\n {\n action: 'plugin::content-releases.settings.update',\n subject: null,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n} satisfies Record<string, StrapiPermission[]>;\n","import { adminApi } from '@strapi/admin/strapi-admin';\n\nimport {\n CreateReleaseAction,\n CreateManyReleaseActions,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\n\nimport type {\n GetReleaseActions,\n UpdateReleaseAction,\n ReleaseActionGroupBy,\n} from '../../../shared/contracts/release-actions';\nimport type {\n CreateRelease,\n DeleteRelease,\n GetReleases,\n GetReleasesByDocumentAttached,\n UpdateRelease,\n GetRelease,\n PublishRelease,\n MapEntriesToReleases,\n} from '../../../shared/contracts/releases';\nimport type { GetSettings, UpdateSettings } from '../../../shared/contracts/settings';\nimport type { EndpointDefinition } from '@reduxjs/toolkit/query';\n\nexport interface GetReleasesQueryParams {\n page?: number;\n pageSize?: number;\n filters?: {\n releasedAt?: {\n // TODO: this should be a boolean, find a way to avoid strings\n $notNull?: boolean | 'true' | 'false';\n };\n };\n}\n\nexport interface GetReleaseActionsQueryParams {\n page?: number;\n pageSize?: number;\n groupBy?: ReleaseActionGroupBy;\n}\n\ntype GetReleasesTabResponse = GetReleases.Response & {\n meta: {\n activeTab: 'pending' | 'done';\n };\n};\n\ntype AnyEndpointDefinition = EndpointDefinition<any, any, any, any>;\n\n// TODO: move this into the admin code & expose an improved version of enhanceEndpoints or a new function\nconst extendInvalidatesTags = (\n endpoint: AnyEndpointDefinition,\n extraTags: string[] | { type: string; id: string }[]\n) => {\n if (!endpoint) {\n return;\n }\n\n const originalInvalidatesTags = endpoint.invalidatesTags;\n\n const newInvalidatesTags: AnyEndpointDefinition['invalidatesTags'] = (\n result,\n err,\n args,\n meta\n ) => {\n const originalTags =\n typeof originalInvalidatesTags === 'function'\n ? originalInvalidatesTags(result, err, args, meta)\n : originalInvalidatesTags;\n\n return [...(originalTags ?? []), ...extraTags];\n };\n\n Object.assign(endpoint, { invalidatesTags: newInvalidatesTags });\n};\n\nconst releaseApi = adminApi\n .enhanceEndpoints({\n addTagTypes: ['Release', 'ReleaseAction', 'EntriesInRelease', 'ReleaseSettings', 'Document'],\n endpoints: {\n updateDocument(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n deleteDocument(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n deleteManyDocuments(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n discardDocument(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n createWorkflow(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n updateWorkflow(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n deleteWorkflow(endpoint: AnyEndpointDefinition) {\n extendInvalidatesTags(endpoint, [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ]);\n },\n },\n })\n .injectEndpoints({\n endpoints: (build) => {\n return {\n getReleasesForEntry: build.query<\n GetReleasesByDocumentAttached.Response,\n Partial<GetReleasesByDocumentAttached.Request['query']>\n >({\n query(params) {\n return {\n url: '/content-releases/getByDocumentAttached',\n method: 'GET',\n config: {\n params,\n },\n };\n },\n providesTags: (result) =>\n result\n ? [\n ...result.data.map(({ id }) => ({ type: 'Release' as const, id })),\n { type: 'Release', id: 'LIST' },\n ]\n : [],\n }),\n getReleases: build.query<GetReleasesTabResponse, GetReleasesQueryParams | void>({\n query(\n { page, pageSize, filters } = {\n page: 1,\n pageSize: 16,\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n }\n ) {\n return {\n url: '/content-releases',\n method: 'GET',\n config: {\n params: {\n page: page || 1,\n pageSize: pageSize || 16,\n filters: filters || {\n releasedAt: {\n $notNull: false,\n },\n },\n },\n },\n };\n },\n transformResponse(response: GetReleasesTabResponse, meta, arg) {\n const releasedAtValue = arg?.filters?.releasedAt?.$notNull;\n const isActiveDoneTab = releasedAtValue === 'true';\n const newResponse: GetReleasesTabResponse = {\n ...response,\n meta: {\n ...response.meta,\n activeTab: isActiveDoneTab ? 'done' : 'pending',\n },\n };\n\n return newResponse;\n },\n providesTags: (result) =>\n result\n ? [\n ...result.data.map(({ id }) => ({ type: 'Release' as const, id })),\n { type: 'Release', id: 'LIST' },\n ]\n : [{ type: 'Release', id: 'LIST' }],\n }),\n getRelease: build.query<GetRelease.Response, GetRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}`,\n method: 'GET',\n };\n },\n providesTags: (result, error, arg) => [\n { type: 'Release', id: 'LIST' },\n { type: 'Release' as const, id: arg.id },\n ],\n }),\n getReleaseActions: build.query<\n GetReleaseActions.Response,\n GetReleaseActions.Request['params'] & GetReleaseActions.Request['query']\n >({\n query({ releaseId, ...params }) {\n return {\n url: `/content-releases/${releaseId}/actions`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n providesTags: [{ type: 'ReleaseAction', id: 'LIST' }],\n }),\n createRelease: build.mutation<CreateRelease.Response, CreateRelease.Request['body']>({\n query(data) {\n return {\n url: '/content-releases',\n method: 'POST',\n data,\n };\n },\n invalidatesTags: [{ type: 'Release', id: 'LIST' }],\n }),\n updateRelease: build.mutation<\n void,\n UpdateRelease.Request['params'] & UpdateRelease.Request['body']\n >({\n query({ id, ...data }) {\n return {\n url: `/content-releases/${id}`,\n method: 'PUT',\n data,\n };\n },\n invalidatesTags: (result, error, arg) => [{ type: 'Release', id: arg.id }],\n }),\n createReleaseAction: build.mutation<\n CreateReleaseAction.Response,\n CreateReleaseAction.Request\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions`,\n method: 'POST',\n data: body,\n };\n },\n invalidatesTags: [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n ],\n }),\n createManyReleaseActions: build.mutation<\n CreateManyReleaseActions.Response,\n CreateManyReleaseActions.Request\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/bulk`,\n method: 'POST',\n data: body,\n };\n },\n invalidatesTags: [\n { type: 'Release', id: 'LIST' },\n { type: 'ReleaseAction', id: 'LIST' },\n { type: 'EntriesInRelease' },\n ],\n }),\n updateReleaseAction: build.mutation<\n UpdateReleaseAction.Response,\n UpdateReleaseAction.Request & { query: GetReleaseActions.Request['query'] } & {\n actionPath: [string, number];\n }\n >({\n query({ body, params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,\n method: 'PUT',\n data: body,\n };\n },\n invalidatesTags: (res, error, arg) => [\n { type: 'ReleaseAction', id: 'LIST' },\n { type: 'Release', id: 'LIST' },\n { type: 'Release', id: arg.params.releaseId },\n ],\n async onQueryStarted({ body, params, query, actionPath }, { dispatch, queryFulfilled }) {\n // We need to mimic the same params received by the getReleaseActions query\n const paramsWithoutActionId = {\n releaseId: params.releaseId,\n ...query,\n };\n\n const patchResult = dispatch(\n releaseApi.util.updateQueryData(\n 'getReleaseActions',\n paramsWithoutActionId,\n (draft) => {\n const [key, index] = actionPath;\n const action = draft.data[key][index];\n\n if (action) {\n action.type = body.type;\n }\n }\n )\n );\n\n try {\n await queryFulfilled;\n } catch {\n patchResult.undo();\n }\n },\n }),\n deleteReleaseAction: build.mutation<\n DeleteReleaseAction.Response,\n DeleteReleaseAction.Request\n >({\n query({ params }) {\n return {\n url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,\n method: 'DELETE',\n };\n },\n invalidatesTags: (result, error, arg) => [\n { type: 'Release', id: 'LIST' },\n { type: 'Release', id: arg.params.releaseId },\n { type: 'ReleaseAction', id: 'LIST' },\n { type: 'EntriesInRelease' },\n ],\n }),\n publishRelease: build.mutation<PublishRelease.Response, PublishRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}/publish`,\n method: 'POST',\n };\n },\n invalidatesTags: (result, error, arg) => [\n { type: 'Release', id: arg.id },\n { type: 'Document', id: `ALL_LIST` },\n ],\n }),\n deleteRelease: build.mutation<DeleteRelease.Response, DeleteRelease.Request['params']>({\n query({ id }) {\n return {\n url: `/content-releases/${id}`,\n method: 'DELETE',\n };\n },\n invalidatesTags: () => [{ type: 'Release', id: 'LIST' }, { type: 'EntriesInRelease' }],\n }),\n getMappedEntriesInReleases: build.query<\n MapEntriesToReleases.Response['data'],\n MapEntriesToReleases.Request['query']\n >({\n query(params) {\n return {\n url: '/content-releases/mapEntriesToReleases',\n method: 'GET',\n config: {\n params,\n },\n };\n },\n transformResponse(response: MapEntriesToReleases.Response) {\n return response.data;\n },\n providesTags: [{ type: 'EntriesInRelease' }],\n }),\n getReleaseSettings: build.query<GetSettings.Response, GetSettings.Request | void>({\n query: () => '/content-releases/settings',\n providesTags: [{ type: 'ReleaseSettings' }],\n }),\n updateReleaseSettings: build.mutation<void, UpdateSettings.Request['body']>({\n query(data) {\n return {\n url: '/content-releases/settings',\n method: 'PUT',\n data,\n };\n },\n invalidatesTags: [{ type: 'ReleaseSettings' }],\n }),\n };\n },\n });\n\nconst {\n useGetReleasesQuery,\n useGetReleasesForEntryQuery,\n useGetReleaseQuery,\n useGetReleaseActionsQuery,\n useCreateReleaseMutation,\n useCreateReleaseActionMutation,\n useCreateManyReleaseActionsMutation,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseActionMutation,\n useDeleteReleaseMutation,\n useGetMappedEntriesInReleasesQuery,\n useGetReleaseSettingsQuery,\n useUpdateReleaseSettingsMutation,\n} = releaseApi;\n\nexport {\n useGetReleasesQuery,\n useGetReleasesForEntryQuery,\n useGetReleaseQuery,\n useGetReleaseActionsQuery,\n useCreateReleaseMutation,\n useCreateReleaseActionMutation,\n useCreateManyReleaseActionsMutation,\n useUpdateReleaseMutation,\n useUpdateReleaseActionMutation,\n usePublishReleaseMutation,\n useDeleteReleaseActionMutation,\n useDeleteReleaseMutation,\n useGetMappedEntriesInReleasesQuery,\n useGetReleaseSettingsQuery,\n useUpdateReleaseSettingsMutation,\n releaseApi,\n};\n","import * as React from 'react';\n\nimport { VisuallyHidden, Field, Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface FieldWrapperProps extends Field.Props {\n actionType: 'publish' | 'unpublish';\n}\n\nconst getBorderLeftRadiusValue = (actionType: FieldWrapperProps['actionType']) => {\n return actionType === 'publish' ? 1 : 0;\n};\n\nconst getBorderRightRadiusValue = (actionType: FieldWrapperProps['actionType']) => {\n return actionType === 'publish' ? 0 : 1;\n};\n\nconst FieldWrapper = styled(Field.Root)<{\n $actionType: 'publish' | 'unpublish';\n}>`\n border-top-left-radius: ${({ $actionType, theme }) =>\n theme.spaces[getBorderLeftRadiusValue($actionType)]};\n border-bottom-left-radius: ${({ $actionType, theme }) =>\n theme.spaces[getBorderLeftRadiusValue($actionType)]};\n border-top-right-radius: ${({ $actionType, theme }) =>\n theme.spaces[getBorderRightRadiusValue($actionType)]};\n border-bottom-right-radius: ${({ $actionType, theme }) =>\n theme.spaces[getBorderRightRadiusValue($actionType)]};\n\n > label {\n color: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n text-align: center;\n vertical-align: middle;\n text-transform: capitalize;\n }\n\n &[data-checked='true'] {\n color: ${({ theme, $actionType }) =>\n $actionType === 'publish' ? theme.colors.primary700 : theme.colors.danger600};\n background-color: ${({ theme, $actionType }) =>\n $actionType === 'publish' ? theme.colors.primary100 : theme.colors.danger100};\n border-color: ${({ theme, $actionType }) =>\n $actionType === 'publish' ? theme.colors.primary700 : theme.colors.danger600};\n }\n\n &[data-checked='false'] {\n border-left: ${({ $actionType }) => $actionType === 'unpublish' && 'none'};\n border-right: ${({ $actionType }) => $actionType === 'publish' && 'none'};\n }\n\n &[data-checked='false'][data-disabled='false']:hover {\n color: ${({ theme }) => theme.colors.neutral700};\n background-color: ${({ theme }) => theme.colors.neutral100};\n border-color: ${({ theme }) => theme.colors.neutral200};\n\n & > label {\n cursor: pointer;\n }\n }\n\n &[data-disabled='true'] {\n color: ${({ theme }) => theme.colors.neutral600};\n background-color: ${({ theme }) => theme.colors.neutral150};\n border-color: ${({ theme }) => theme.colors.neutral300};\n }\n`;\n\ninterface ActionOptionProps {\n selected: 'publish' | 'unpublish';\n handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n name: string;\n disabled?: boolean;\n}\n\ninterface OptionProps extends ActionOptionProps {\n actionType: 'publish' | 'unpublish';\n}\n\nconst ActionOption = ({\n selected,\n actionType,\n handleChange,\n name,\n disabled = false,\n}: OptionProps) => {\n return (\n <FieldWrapper\n $actionType={actionType}\n background=\"primary0\"\n borderColor=\"neutral200\"\n color={selected === actionType ? 'primary600' : 'neutral600'}\n position=\"relative\"\n cursor=\"pointer\"\n data-checked={selected === actionType}\n data-disabled={disabled && selected !== actionType}\n >\n <Field.Label>\n <VisuallyHidden>\n <Field.Input\n type=\"radio\"\n name={name}\n checked={selected === actionType}\n onChange={handleChange}\n value={actionType}\n disabled={disabled}\n />\n </VisuallyHidden>\n {actionType}\n </Field.Label>\n </FieldWrapper>\n );\n};\n\nexport const ReleaseActionOptions = ({\n selected,\n handleChange,\n name,\n disabled = false,\n}: ActionOptionProps) => {\n return (\n <Flex>\n <ActionOption\n actionType=\"publish\"\n selected={selected}\n handleChange={handleChange}\n name={name}\n disabled={disabled}\n />\n <ActionOption\n actionType=\"unpublish\"\n selected={selected}\n handleChange={handleChange}\n name={name}\n disabled={disabled}\n />\n </Flex>\n );\n};\n","import * as React from 'react';\n\nimport {\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n isFetchError,\n} from '@strapi/admin/strapi-admin';\nimport { unstable_useDocumentLayout as useDocumentLayout } from '@strapi/content-manager/strapi-admin';\nimport {\n Box,\n Button,\n Flex,\n SingleSelect,\n SingleSelectOption,\n EmptyStateLayout,\n LinkButton,\n Field,\n Modal,\n} from '@strapi/design-system';\nimport { PaperPlane } from '@strapi/icons';\nimport { EmptyDocuments } from '@strapi/icons/symbols';\nimport { useFormik } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { Link as ReactRouterLink } from 'react-router-dom';\nimport * as yup from 'yup';\n\nimport { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { PERMISSIONS } from '../constants';\nimport { useCreateReleaseActionMutation, useGetReleasesForEntryQuery } from '../services/release';\n\nimport { ReleaseActionOptions } from './ReleaseActionOptions';\n\nimport type {\n DocumentActionComponent,\n DocumentActionProps,\n} from '@strapi/content-manager/strapi-admin';\nimport type { UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * AddActionToReleaseModal\n * -----------------------------------------------------------------------------------------------*/\nexport const RELEASE_ACTION_FORM_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n releaseId: yup.string().required(),\n});\n\nexport interface FormValues {\n type: CreateReleaseAction.Request['body']['type'];\n releaseId: CreateReleaseAction.Request['params']['releaseId'];\n}\n\nexport const INITIAL_VALUES = {\n type: 'publish',\n releaseId: '',\n} satisfies FormValues;\n\ninterface AddActionToReleaseModalProps {\n contentType: string;\n documentId?: string;\n onInputChange: (field: keyof FormValues, value: string | number) => void;\n values: FormValues;\n}\n\nexport const NoReleases = () => {\n const { formatMessage } = useIntl();\n return (\n <EmptyStateLayout\n icon={<EmptyDocuments width=\"16rem\" />}\n content={formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.no-releases-message',\n defaultMessage:\n 'No available releases. Open the list of releases and create a new one from there.',\n })}\n action={\n <LinkButton\n to={{\n pathname: '/plugins/content-releases',\n }}\n tag={ReactRouterLink}\n variant=\"secondary\"\n >\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.redirect-button',\n defaultMessage: 'Open the list of releases',\n })}\n </LinkButton>\n }\n shadow=\"none\"\n />\n );\n};\n\nconst AddActionToReleaseModal = ({\n contentType,\n documentId,\n onInputChange,\n values,\n}: AddActionToReleaseModalProps) => {\n const { formatMessage } = useIntl();\n const [{ query }] = useQueryParams<{ plugins?: { i18n?: { locale?: string } } }>();\n const locale = query.plugins?.i18n?.locale;\n\n // Get all 'pending' releases that do not have the entry attached\n const response = useGetReleasesForEntryQuery({\n contentType,\n entryDocumentId: documentId,\n hasEntryAttached: false,\n locale,\n });\n\n const releases = response.data?.data;\n\n if (releases?.length === 0) {\n return <NoReleases />;\n }\n\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Box paddingBottom={6}>\n <Field.Root required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.select-label',\n defaultMessage: 'Select a release',\n })}\n </Field.Label>\n <SingleSelect\n required\n placeholder={formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.select-placeholder',\n defaultMessage: 'Select',\n })}\n name=\"releaseId\"\n onChange={(value) => onInputChange('releaseId', value)}\n value={values.releaseId}\n >\n {releases?.map((release) => (\n <SingleSelectOption key={release.id} value={release.id}>\n {release.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Field.Root>\n </Box>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.action-type-label',\n defaultMessage: 'What do you want to do with this entry?',\n })}\n </Field.Label>\n <ReleaseActionOptions\n selected={values.type}\n handleChange={(e) => onInputChange('type', e.target.value)}\n name=\"type\"\n />\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseActionModalForm\n * -----------------------------------------------------------------------------------------------*/\n\nconst ReleaseActionModalForm: DocumentActionComponent = ({\n documentId,\n document,\n model,\n collectionType,\n}: DocumentActionProps) => {\n const { formatMessage } = useIntl();\n const { allowedActions } = useRBAC(PERMISSIONS);\n const { canCreateAction } = allowedActions;\n const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const [{ query }] = useQueryParams<{ plugins?: { i18n?: { locale?: string } } }>();\n const locale = query.plugins?.i18n?.locale;\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>, onClose: () => void) => {\n try {\n await formik.handleSubmit(e);\n onClose();\n } catch (error) {\n if (isFetchError(error)) {\n // Handle axios error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'notification.error',\n defaultMessage: 'An error occurred',\n }),\n });\n }\n }\n };\n\n const formik = useFormik({\n initialValues: INITIAL_VALUES,\n validationSchema: RELEASE_ACTION_FORM_SCHEMA,\n onSubmit: async (values: FormValues) => {\n if (collectionType === 'collection-types' && !documentId) {\n throw new Error('Document id is required');\n }\n\n const response = await createReleaseAction({\n body: {\n type: values.type,\n contentType: model as UID.ContentType,\n entryDocumentId: documentId,\n locale,\n },\n params: { releaseId: values.releaseId },\n });\n\n if ('data' in response) {\n // Handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.notification.success',\n defaultMessage: 'Entry added to release',\n }),\n });\n\n return;\n }\n\n if ('error' in response) {\n throw response.error;\n }\n },\n });\n\n const {\n edit: { options },\n } = useDocumentLayout(model);\n\n // Project is not EE or contentType does not have draftAndPublish enabled\n if (!window.strapi.isEE || !options?.draftAndPublish || !canCreateAction) {\n return null;\n }\n\n if (collectionType === 'collection-types' && (!documentId || documentId === 'create')) {\n return null;\n }\n\n return {\n label: formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release',\n defaultMessage: 'Add to release',\n }),\n icon: <PaperPlane />,\n // Entry is creating so we don't want to allow adding it to a release\n disabled: !document,\n position: ['panel', 'table-row'],\n dialog: {\n type: 'modal',\n title: formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release',\n defaultMessage: 'Add to release',\n }),\n content: (\n <AddActionToReleaseModal\n contentType={model}\n documentId={documentId}\n onInputChange={formik.setFieldValue}\n values={formik.values}\n />\n ),\n footer: ({ onClose }) => (\n <Modal.Footer>\n <Button onClick={onClose} variant=\"tertiary\" name=\"cancel\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.cancel-button',\n defaultMessage: 'Cancel',\n })}\n </Button>\n <Button\n type=\"submit\"\n // @ts-expect-error - formik ReactEvent types don't match button onClick types as they expect a MouseEvent\n onClick={(e) => handleSubmit(e, onClose)}\n disabled={!formik.values.releaseId}\n loading={isLoading}\n >\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.add-to-release.continue-button',\n defaultMessage: 'Continue',\n })}\n </Button>\n </Modal.Footer>\n ),\n },\n };\n};\n\nexport { ReleaseActionModalForm };\n","import * as React from 'react';\n\nimport {\n useAPIErrorHandler,\n useNotification,\n useQueryParams,\n useRBAC,\n isFetchError,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Flex,\n SingleSelect,\n SingleSelectOption,\n Modal,\n Field,\n} from '@strapi/design-system';\nimport { UID } from '@strapi/types';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\n\nimport { CreateManyReleaseActions } from '../../../shared/contracts/release-actions';\nimport { PERMISSIONS as releasePermissions } from '../constants';\nimport { useCreateManyReleaseActionsMutation, useGetReleasesQuery } from '../services/release';\n\nimport {\n type FormValues,\n INITIAL_VALUES,\n RELEASE_ACTION_FORM_SCHEMA,\n NoReleases,\n} from './ReleaseActionModal';\nimport { ReleaseActionOptions } from './ReleaseActionOptions';\n\nimport type { BulkActionComponent } from '@strapi/content-manager/strapi-admin';\n\nconst getContentPermissions = (subject: string) => {\n const permissions = {\n publish: [\n {\n action: 'plugin::content-manager.explorer.publish',\n subject,\n id: '',\n actionParameters: {},\n properties: {},\n conditions: [],\n },\n ],\n };\n\n return permissions;\n};\n\nconst ReleaseAction: BulkActionComponent = ({ documents, model }) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const [{ query }] = useQueryParams<{ plugins?: { i18n?: { locale?: string } } }>();\n const contentPermissions = getContentPermissions(model);\n const {\n allowedActions: { canPublish },\n } = useRBAC(contentPermissions);\n const {\n allowedActions: { canCreate },\n } = useRBAC(releasePermissions);\n\n // Get all the releases not published\n const response = useGetReleasesQuery();\n const releases = response.data?.data;\n const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();\n const documentIds = documents.map((doc) => doc.documentId);\n\n const handleSubmit = async (values: FormValues) => {\n const locale = query.plugins?.i18n?.locale;\n\n const releaseActionEntries: CreateManyReleaseActions.Request['body'] = documentIds.map(\n (entryDocumentId) => ({\n type: values.type,\n contentType: model as UID.ContentType,\n entryDocumentId,\n locale,\n })\n );\n\n const response = await createManyReleaseActions({\n body: releaseActionEntries,\n params: { releaseId: values.releaseId },\n });\n\n if ('data' in response) {\n // Handle success\n\n const notificationMessage = formatMessage(\n {\n id: 'content-releases.content-manager-list-view.add-to-release.notification.success.message',\n defaultMessage:\n '{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release.',\n },\n {\n entriesAlreadyInRelease: response.data.meta.entriesAlreadyInRelease,\n totalEntries: response.data.meta.totalEntries,\n }\n );\n\n const notification = {\n type: 'success' as const,\n title: formatMessage(\n {\n id: 'content-releases.content-manager-list-view.add-to-release.notification.success.title',\n defaultMessage: 'Successfully added to release.',\n },\n {\n entriesAlreadyInRelease: response.data.meta.entriesAlreadyInRelease,\n totalEntries: response.data.meta.totalEntries,\n }\n ),\n message: response.data.meta.entriesAlreadyInRelease ? notificationMessage : '',\n };\n\n toggleNotification(notification);\n\n return true;\n }\n\n if ('error' in response) {\n if (isFetchError(response.error)) {\n // Handle fetch error\n toggleNotification({\n type: 'warning',\n message: formatAPIError(response.error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'warning',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n if (!canCreate || !canPublish) return null;\n\n return {\n actionType: 'release',\n variant: 'tertiary',\n label: formatMessage({\n id: 'content-manager-list-view.add-to-release',\n defaultMessage: 'Add to Release',\n }),\n dialog: {\n type: 'modal',\n title: formatMessage({\n id: 'content-manager-list-view.add-to-release',\n defaultMessage: 'Add to Release',\n }),\n content: ({ onClose }) => {\n return (\n <Formik\n onSubmit={async (values) => {\n const data = await handleSubmit(values);\n if (data) {\n return onClose();\n }\n }}\n validationSchema={RELEASE_ACTION_FORM_SCHEMA}\n initialValues={INITIAL_VALUES}\n >\n {({ values, setFieldValue }) => (\n <Form>\n {releases?.length === 0 ? (\n <NoReleases />\n ) : (\n <Modal.Body>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n <Box paddingBottom={6}>\n <Field.Root required>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.content-manager-list-view.add-to-release.select-label',\n defaultMessage: 'Select a release',\n })}\n </Field.Label>\n <SingleSelect\n placeholder={formatMessage({\n id: 'content-releases.content-manager-list-view.add-to-release.select-placeholder',\n defaultMessage: 'Select',\n })}\n onChange={(value) => setFieldValue('releaseId', value)}\n value={values.releaseId}\n >\n {releases?.map((release) => (\n <SingleSelectOption key={release.id} value={release.id}>\n {release.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Field.Root>\n </Box>\n <Field.Label>\n {formatMessage({\n id: 'content-releases.content-manager-list-view.add-to-release.action-type-label',\n defaultMessage: 'What do you want to do with these entries?',\n })}\n </Field.Label>\n <ReleaseActionOptions\n selected={values.type}\n handleChange={(e) => setFieldValue('type', e.target.value)}\n name=\"type\"\n />\n </Flex>\n </Modal.Body>\n )}\n <Modal.Footer>\n <Button onClick={onClose} variant=\"tertiary\" name=\"cancel\">\n {formatMessage({\n id: 'content-releases.content-manager-list-view.add-to-release.cancel-button',\n defaultMessage: 'Cancel',\n })}\n </Button>\n {/** * TODO: Ideally we would use isValid from Formik to disable the button,\n however currently it always returns true * for yup.string().required(), even when\n the value is falsy (including empty string) */}\n <Button type=\"submit\" disabled={!values.releaseId} loading={isLoading}>\n {formatMessage({\n id: 'content-releases.content-manager-list-view.add-to-release.continue-button',\n defaultMessage: 'Continue',\n })}\n </Button>\n </Modal.Footer>\n </Form>\n )}\n </Formik>\n );\n },\n },\n };\n};\n\nexport { ReleaseAction };\n","import * as React from 'react';\n\nimport { useTable, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { ListFieldLayout, ListLayout } from '@strapi/content-manager/strapi-admin';\nimport { Box, Popover, Typography, Button, Link } from '@strapi/design-system';\nimport { CaretDown } from '@strapi/icons';\nimport { Modules, UID } from '@strapi/types';\nimport { useIntl } from 'react-intl';\n\nimport { useGetMappedEntriesInReleasesQuery } from '../services/release';\n\n/* -------------------------------------------------------------------------------------------------\n * useReleasesList\n * -----------------------------------------------------------------------------------------------*/\ninterface QueryParams {\n plugins?: {\n i18n?: {\n locale: string;\n };\n };\n}\n\nconst useReleasesList = (contentTypeUid: UID.ContentType, documentId: Modules.Documents.ID) => {\n const listViewData = useTable('ListView', (state) => state.rows);\n const documentIds = listViewData.map((entry) => entry.documentId);\n const [{ query }] = useQueryParams();\n const locale = (query as QueryParams)?.plugins?.i18n?.locale || undefined;\n\n const response = useGetMappedEntriesInReleasesQuery(\n { contentTypeUid, documentIds, locale },\n { skip: !documentIds || !contentTypeUid || documentIds.length === 0 }\n );\n\n const mappedEntriesInReleases = response.data || {};\n\n return mappedEntriesInReleases?.[documentId] || [];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * addColumnToTableHook\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AddColumnToTableHookArgs {\n layout: ListLayout;\n displayedHeaders: ListFieldLayout[];\n}\n\nconst addColumnToTableHook = ({ displayedHeaders, layout }: AddColumnToTableHookArgs) => {\n const { options } = layout;\n\n if (!options?.draftAndPublish) {\n return { displayedHeaders, layout };\n }\n\n return {\n displayedHeaders: [\n ...displayedHeaders,\n {\n searchable: false,\n sortable: false,\n name: 'releases',\n label: {\n id: 'content-releases.content-manager.list-view.releases.header',\n defaultMessage: 'To be released in',\n },\n cellFormatter: (\n props: Modules.Documents.AnyDocument,\n _: any,\n { model }: { model: UID.ContentType }\n ) => <ReleaseListCell {...props} model={model} />,\n },\n ],\n layout,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseListCell\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ReleaseListCellProps extends Modules.Documents.AnyDocument {\n documentId: Modules.Documents.ID;\n model: UID.ContentType;\n}\n\nconst ReleaseListCell = ({ documentId, model }: ReleaseListCellProps) => {\n const releases = useReleasesList(model, documentId);\n const { formatMessage } = useIntl();\n\n return (\n <Popover.Root>\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n onClick={(e: React.MouseEvent<HTMLElement>) => e.stopPropagation()}\n // TODO: find a way in the DS to define the widht and height of the icon\n endIcon={releases.length > 0 ? <CaretDown width=\"1.2rem\" height=\"1.2rem\" /> : null}\n >\n <Typography\n style={{ maxWidth: '252px', cursor: 'pointer' }}\n textColor=\"neutral800\"\n fontWeight=\"regular\"\n >\n {releases.length > 0\n ? formatMessage(\n {\n id: 'content-releases.content-manager.list-view.releases-number',\n defaultMessage: '{number} {number, plural, one {release} other {releases}}',\n },\n {\n number: releases.length,\n }\n )\n : '-'}\n </Typography>\n </Button>\n </Popover.Trigger>\n <Popover.Content>\n <ul>\n {releases.map(({ id, name }) => (\n <Box key={id} padding={3} tag=\"li\">\n <Link href={`/admin/plugins/content-releases/${id}`} isExternal={false}>\n {name}\n </Link>\n </Box>\n ))}\n </ul>\n </Popover.Content>\n </Popover.Root>\n );\n};\n\nexport { ReleaseListCell, addColumnToTableHook };\nexport type { ReleaseListCellProps };\n","export const getTimezoneOffset = (timezone: string, date: Date) => {\n try {\n const offsetPart = new Intl.DateTimeFormat('en', {\n timeZone: timezone,\n timeZoneName: 'longOffset',\n })\n .formatToParts(date)\n .find((part) => part.type === 'timeZoneName');\n\n const offset = offsetPart ? offsetPart.value : '';\n\n // We want to show time based on UTC, not GMT so we swap that.\n let utcOffset = offset.replace('GMT', 'UTC');\n\n // For perfect UTC (UTC+0:00) we only get the string UTC, So we need to append the 0's.\n if (!utcOffset.includes('+') && !utcOffset.includes('-')) {\n utcOffset = `${utcOffset}+00:00`;\n }\n\n return utcOffset;\n } catch (error) {\n // When timezone is invalid we catch the error and return empty to don't break the app\n return '';\n }\n};\n\ninterface ITimezoneOption {\n offset: string;\n value: string;\n}\n\nexport const getTimezones = (selectedDate: Date) => {\n const timezoneList: ITimezoneOption[] = Intl.supportedValuesOf('timeZone').map((timezone) => {\n // Timezone will be in the format GMT${OFFSET} where offset could be nothing,\n // a four digit string e.g. +05:00 or -08:00\n const utcOffset = getTimezoneOffset(timezone, selectedDate);\n\n // Offset and timezone are concatenated with '&', so to split and save the required timezone in DB\n return { offset: utcOffset, value: `${utcOffset}&${timezone}` } satisfies ITimezoneOption;\n });\n\n const systemTimezone = timezoneList.find(\n (timezone) => timezone.value.split('&')[1] === Intl.DateTimeFormat().resolvedOptions().timeZone\n );\n\n return { timezoneList, systemTimezone };\n};\n","import * as React from 'react';\n\nimport {\n useAPIErrorHandler,\n useNotification,\n useAuth,\n useRBAC,\n isFetchError,\n} from '@strapi/admin/strapi-admin';\nimport { Flex, Typography, Menu, AccessibleIcon } from '@strapi/design-system';\nimport { Cross, More, Pencil } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { NavLink } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { DeleteReleaseAction, ReleaseAction } from '../../../shared/contracts/release-actions';\nimport { Release } from '../../../shared/contracts/releases';\nimport { PERMISSIONS } from '../constants';\nimport { useDeleteReleaseActionMutation } from '../services/release';\n\nconst StyledMenuItem = styled(Menu.Item)<{ $variant?: 'neutral' | 'danger' }>`\n &:hover {\n background: ${({ theme, $variant = 'neutral' }) => theme.colors[`${$variant}100`]};\n\n svg {\n fill: ${({ theme, $variant = 'neutral' }) => theme.colors[`${$variant}600`]};\n }\n\n a {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n }\n\n svg {\n color: ${({ theme, $variant = 'neutral' }) => theme.colors[`${$variant}500`]};\n }\n\n span {\n color: ${({ theme, $variant = 'neutral' }) => theme.colors[`${$variant}800`]};\n }\n\n span,\n a {\n width: 100%;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteReleaseActionItemProps\n * -----------------------------------------------------------------------------------------------*/\ninterface DeleteReleaseActionItemProps {\n releaseId: DeleteReleaseAction.Request['params']['releaseId'];\n actionId: DeleteReleaseAction.Request['params']['actionId'];\n}\n\nconst DeleteReleaseActionItem = ({ releaseId, actionId }: DeleteReleaseActionItemProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { formatAPIError } = useAPIErrorHandler();\n const [deleteReleaseAction] = useDeleteReleaseActionMutation();\n const {\n allowedActions: { canDeleteAction },\n } = useRBAC(PERMISSIONS);\n\n const handleDeleteAction = async () => {\n const response = await deleteReleaseAction({\n params: { releaseId, actionId },\n });\n\n if ('data' in response) {\n // Handle success\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.content-manager-edit-view.remove-from-release.notification.success',\n defaultMessage: 'Entry removed from release',\n }),\n });\n\n return;\n }\n\n if ('error' in response) {\n if (isFetchError(response.error)) {\n // Handle fetch error\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n // Handle generic error\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n if (!canDeleteAction) {\n return null;\n }\n\n return (\n <StyledMenuItem $variant=\"danger\" onSelect={handleDeleteAction}>\n <Flex gap={2}>\n <Cross width=\"1.6rem\" height=\"1.6rem\" />\n <Typography textColor=\"danger600\" variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.remove-from-release',\n defaultMessage: 'Remove from release',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReleaseActionEntryLinkItem\n * -----------------------------------------------------------------------------------------------*/\ninterface ReleaseActionEntryLinkItemProps {\n contentTypeUid: ReleaseAction['contentType'];\n documentId: ReleaseAction['entry']['documentId'];\n locale: ReleaseAction['locale'];\n}\n\nconst ReleaseActionEntryLinkItem = ({\n contentTypeUid,\n documentId,\n locale,\n}: ReleaseActionEntryLinkItemProps) => {\n const { formatMessage } = useIntl();\n const userPermissions = useAuth('ReleaseActionEntryLinkItem', (state) => state.permissions);\n\n // Confirm user has permissions to access the entry for the given locale\n const canUpdateEntryForLocale = React.useMemo(() => {\n const updatePermissions = userPermissions.find(\n (permission) =>\n permission.subject === contentTypeUid &&\n permission.action === 'plugin::content-manager.explorer.update'\n );\n\n if (!updatePermissions) {\n return false;\n }\n\n return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));\n }, [contentTypeUid, locale, userPermissions]);\n\n const {\n allowedActions: { canUpdate: canUpdateContentType },\n } = useRBAC({\n updateContentType: [\n {\n action: 'plugin::content-manager.explorer.update',\n subject: contentTypeUid,\n },\n ],\n });\n\n if (!canUpdateContentType || !canUpdateEntryForLocale) {\n return null;\n }\n\n return (\n <StyledMenuItem\n /* @ts-expect-error inference isn't working in DS */\n tag={NavLink}\n isLink\n to={{\n pathname: `/content-manager/collection-types/${contentTypeUid}/${documentId}`,\n search: locale && `?plugins[i18n][locale]=${locale}`,\n }}\n >\n <Flex gap={2}>\n <Pencil width=\"1.6rem\" height=\"1.6rem\" />\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.edit-entry',\n defaultMessage: 'Edit entry',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * EditReleaseItem\n * -----------------------------------------------------------------------------------------------*/\ninterface EditReleaseItemProps {\n releaseId: Release['id'];\n}\n\nconst EditReleaseItem = ({ releaseId }: EditReleaseItemProps) => {\n const { formatMessage } = useIntl();\n\n return (\n /* @ts-expect-error inference isn't working in DS */\n <StyledMenuItem tag={NavLink} isLink to={`/plugins/content-releases/${releaseId}`}>\n <Flex gap={2}>\n <Pencil width=\"1.6rem\" height=\"1.6rem\" />\n <Typography textColor=\"neutral800\" variant=\"omega\">\n {formatMessage({\n id: 'content-releases.content-manager-edit-view.edit-release',\n defaultMessage: 'Edit release',\n })}\n </Typography>\n </Flex>\n </StyledMenuItem>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasTriggerBorder?: boolean;\n}\n\nconst Root = ({ children }: RootProps) => {\n const { formatMessage } = useIntl();\n\n const { allowedActions } = useRBAC(PERMISSIONS);\n\n return (\n // A user can access the dropdown if they have permissions to delete a release-action OR update a release\n allowedActions.canDeleteAction || allowedActions.canUpdate ? (\n <Menu.Root>\n <StyledMoreButton variant=\"tertiary\" endIcon={null} paddingLeft=\"7px\" paddingRight=\"7px\">\n <AccessibleIcon\n label={formatMessage({\n id: 'content-releases.content-manager-edit-view.release-action-menu',\n defaultMessage: 'Release action options',\n })}\n >\n <More />\n </AccessibleIcon>\n </StyledMoreButton>\n <Menu.Content top={1} popoverPlacement=\"bottom-end\">\n {children}\n </Menu.Content>\n </Menu.Root>\n ) : null\n );\n};\n\nconst StyledMoreButton = styled(Menu.Trigger)`\n & > span {\n display: flex;\n }\n`;\n\nexport const ReleaseActionMenu = {\n Root,\n EditReleaseItem,\n DeleteReleaseActionItem,\n ReleaseActionEntryLinkItem,\n};\n","import { useRBAC, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { unstable_useDocumentLayout as useDocumentLayout } from '@strapi/content-manager/strapi-admin';\nimport { Box, Flex, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { PERMISSIONS } from '../constants';\nimport { useGetReleasesForEntryQuery } from '../services/release';\nimport { getTimezoneOffset } from '../utils/time';\n\nimport { ReleaseActionMenu } from './ReleaseActionMenu';\n\nimport type { PanelComponent, PanelComponentProps } from '@strapi/content-manager/strapi-admin';\n\nconst Panel: PanelComponent = ({\n model,\n document,\n documentId,\n collectionType,\n}: PanelComponentProps) => {\n const [{ query }] = useQueryParams<{ plugins: { i18n: { locale: string } } }>();\n const locale = query.plugins?.i18n?.locale;\n\n const {\n edit: { options },\n } = useDocumentLayout(model);\n const { formatMessage, formatDate, formatTime } = useIntl();\n\n const { allowedActions } = useRBAC(PERMISSIONS);\n const { canRead, canDeleteAction } = allowedActions;\n\n const response = useGetReleasesForEntryQuery(\n {\n contentType: model,\n entryDocumentId: documentId,\n locale,\n hasEntryAttached: true,\n },\n {\n skip: !document,\n }\n );\n const releases = response.data?.data;\n\n const getReleaseColorVariant = (\n actionType: 'publish' | 'unpublish',\n shade: '100' | '200' | '600'\n ) => {\n if (actionType === 'unpublish') {\n return `secondary${shade}`;\n }\n\n return `success${shade}`;\n };\n\n // Project is not EE or contentType does not have draftAndPublish enabled\n if (!window.strapi.isEE || !options?.draftAndPublish || !canRead) {\n return null;\n }\n\n if (collectionType === 'collection-types' && (!documentId || documentId === 'create')) {\n return null;\n }\n\n if (!releases || releases.length === 0) {\n return null;\n }\n\n return {\n title: formatMessage({\n id: 'content-releases.plugin.name',\n defaultMessage: 'Releases',\n }),\n content: (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={3} width=\"100%\">\n {releases?.map((release) => (\n <Flex\n key={release.id}\n direction=\"column\"\n alignItems=\"start\"\n borderWidth=\"1px\"\n borderStyle=\"solid\"\n borderColor={getReleaseColorVariant(release.actions[0].type, '200')}\n overflow=\"hidden\"\n hasRadius\n >\n <Box\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n background={getReleaseColorVariant(release.actions[0].type, '100')}\n width=\"100%\"\n >\n <Typography\n fontSize={1}\n variant=\"pi\"\n textColor={getReleaseColorVariant(release.actions[0].type, '600')}\n >\n {formatMessage(\n {\n id: 'content-releases.content-manager-edit-view.list-releases.title',\n defaultMessage:\n '{isPublish, select, true {Will be published in} other {Will be unpublished in}}',\n },\n { isPublish: release.actions[0].type === 'publish' }\n )}\n </Typography>\n </Box>\n <Flex padding={4} direction=\"column\" gap={2} width=\"100%\" alignItems=\"flex-start\">\n <Typography fontSize={2} fontWeight=\"bold\" variant=\"omega\" textColor=\"neutral700\">\n {release.name}\n </Typography>\n {release.scheduledAt && release.timezone && (\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage(\n {\n id: 'content-releases.content-manager-edit-view.scheduled.date',\n defaultMessage: '{date} at {time} ({offset})',\n },\n {\n date: formatDate(new Date(release.scheduledAt), {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n timeZone: release.timezone,\n }),\n time: formatTime(new Date(release.scheduledAt), {\n hourCycle: 'h23',\n timeZone: release.timezone,\n }),\n offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt)),\n }\n )}\n </Typography>\n )}\n {canDeleteAction ? (\n <ReleaseActionMenu.Root hasTriggerBorder>\n <ReleaseActionMenu.EditReleaseItem releaseId={release.id} />\n <ReleaseActionMenu.DeleteReleaseActionItem\n releaseId={release.id}\n actionId={release.actions[0].id}\n />\n </ReleaseActionMenu.Root>\n ) : null}\n </Flex>\n </Flex>\n ))}\n </Flex>\n ),\n };\n};\n\nexport { Panel };\n","export const pluginId = 'content-releases';\n","type TradOptions = Record<string, string>;\n\nconst prefixPluginTranslations = (trad: TradOptions, pluginId: string): TradOptions => {\n if (!pluginId) {\n throw new TypeError(\"pluginId can't be empty\");\n }\n return Object.keys(trad).reduce((acc, current) => {\n acc[`${pluginId}.${current}`] = trad[current];\n return acc;\n }, {} as TradOptions);\n};\n\nexport { prefixPluginTranslations };\n","import { PaperPlane } from '@strapi/icons';\n\nimport { ReleaseAction } from './components/ReleaseAction';\nimport { ReleaseActionModalForm } from './components/ReleaseActionModal';\nimport { addColumnToTableHook } from './components/ReleaseListCell';\nimport { Panel as ReleasesPanel } from './components/ReleasesPanel';\nimport { PERMISSIONS } from './constants';\nimport { pluginId } from './pluginId';\nimport { prefixPluginTranslations } from './utils/prefixPluginTranslations';\n\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type {\n DocumentActionComponent,\n BulkActionComponent,\n} from '@strapi/content-manager/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\n// eslint-disable-next-line import/no-default-export\nconst admin: Plugin.Config.AdminInput = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n register(app: StrapiApp) {\n /**\n * Hook that adds the locale column in the Release Details table\n * @constant\n * @type {string}\n */\n app.createHook('ContentReleases/pages/ReleaseDetails/add-locale-in-releases');\n\n if (window.strapi.features.isEnabled('cms-content-releases')) {\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: PaperPlane,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Releases',\n },\n Component: () => import('./pages/App').then((mod) => ({ default: mod.App })),\n permissions: PERMISSIONS.main,\n position: 2,\n });\n\n // Insert the releases container into the CM's sidebar on the Edit View\n const contentManagerPluginApis = app.getPlugin('content-manager').apis;\n if (\n 'addEditViewSidePanel' in contentManagerPluginApis &&\n typeof contentManagerPluginApis.addEditViewSidePanel === 'function'\n ) {\n contentManagerPluginApis.addEditViewSidePanel([ReleasesPanel]);\n }\n\n // Insert the \"add to release\" action into the CM's Edit View\n if (\n 'addDocumentAction' in contentManagerPluginApis &&\n typeof contentManagerPluginApis.addDocumentAction === 'function'\n ) {\n contentManagerPluginApis.addDocumentAction((actions: DocumentActionComponent[]) => {\n const indexOfDeleteAction = actions.findIndex((action) => action.type === 'unpublish');\n actions.splice(indexOfDeleteAction, 0, ReleaseActionModalForm);\n return actions;\n });\n }\n\n app.addSettingsLink('global', {\n id: pluginId,\n to: 'releases',\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Releases',\n },\n permissions: [],\n async Component() {\n const { ProtectedReleasesSettingsPage } = await import('./pages/ReleasesSettingsPage');\n return { default: ProtectedReleasesSettingsPage };\n },\n });\n\n if (\n 'addBulkAction' in contentManagerPluginApis &&\n typeof contentManagerPluginApis.addBulkAction === 'function'\n ) {\n contentManagerPluginApis.addBulkAction((actions: BulkActionComponent[]) => {\n // We want to add this action to just before the delete action all the time\n const deleteActionIndex = actions.findIndex((action) => action.type === 'delete');\n\n actions.splice(deleteActionIndex, 0, ReleaseAction);\n return actions;\n });\n }\n\n // Hook that adds a column into the CM's LV table\n app.registerHook('Admin/CM/pages/ListView/inject-column-in-table', addColumnToTableHook);\n } else if (\n !window.strapi.features.isEnabled('cms-content-releases') &&\n window.strapi?.flags?.promoteEE\n ) {\n app.addSettingsLink('global', {\n id: pluginId,\n to: '/plugins/purchase-content-releases',\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Releases',\n },\n permissions: [],\n async Component() {\n const { PurchaseContentReleases } = await import('./pages/PurchaseContentReleases');\n return { default: PurchaseContentReleases };\n },\n licenseOnly: true,\n });\n }\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, 'content-releases'),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["adminApi","styled","Field","jsx","jsxs","VisuallyHidden","Flex","yup","useIntl","EmptyStateLayout","EmptyDocuments","LinkButton","ReactRouterLink","useQueryParams","Box","SingleSelect","SingleSelectOption","useRBAC","useNotification","useAPIErrorHandler","formik","isFetchError","useFormik","useDocumentLayout","PaperPlane","Modal","Button","releasePermissions","response","Formik","Form","useTable","Popover","CaretDown","Typography","Link","Menu","Cross","useAuth","React","NavLink","Pencil","AccessibleIcon","More","pluginId","ReleasesPanel"],"mappings":"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"}