@strapi/content-releases 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.e8d8fc824d0f6a695b2a9ebaa4680ed21c3645ca
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -1
- package/dist/_chunks/{App-BsUSTHVD.mjs → App-CiZCkScI.mjs} +643 -428
- package/dist/_chunks/App-CiZCkScI.mjs.map +1 -0
- package/dist/_chunks/{App-CXRpb2hi.js → App-SGjO5UPV.js} +682 -470
- package/dist/_chunks/App-SGjO5UPV.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-Be3acS2L.js → PurchaseContentReleases--qQepXpP.js} +2 -2
- package/dist/_chunks/PurchaseContentReleases--qQepXpP.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-_MxP6-Dt.mjs → PurchaseContentReleases-D-n-w-st.mjs} +2 -2
- package/dist/_chunks/{PurchaseContentReleases-_MxP6-Dt.mjs.map → PurchaseContentReleases-D-n-w-st.mjs.map} +1 -1
- package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js +178 -0
- package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js.map +1 -0
- package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs +178 -0
- package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs.map +1 -0
- package/dist/_chunks/{en-DtFJ5ViE.js → en-BWPPsSH-.js} +18 -2
- package/dist/_chunks/en-BWPPsSH-.js.map +1 -0
- package/dist/_chunks/{en-B9Ur3VsE.mjs → en-D9Q4YW03.mjs} +18 -2
- package/dist/_chunks/en-D9Q4YW03.mjs.map +1 -0
- package/dist/_chunks/{index-DJLIZdZv.mjs → index-BjvFfTtA.mjs} +751 -605
- package/dist/_chunks/index-BjvFfTtA.mjs.map +1 -0
- package/dist/_chunks/{index-B6-lic1Q.js → index-CyU534vL.js} +739 -596
- package/dist/_chunks/index-CyU534vL.js.map +1 -0
- package/dist/_chunks/schemas-DBYv9gK8.js +61 -0
- package/dist/_chunks/schemas-DBYv9gK8.js.map +1 -0
- package/dist/_chunks/schemas-DdA2ic2U.mjs +44 -0
- package/dist/_chunks/schemas-DdA2ic2U.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/admin/src/components/EntryValidationPopover.d.ts +13 -0
- package/dist/admin/src/components/ReleaseActionMenu.d.ts +3 -3
- package/dist/admin/src/components/{CMReleasesContainer.d.ts → ReleaseActionModal.d.ts} +3 -1
- package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
- package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
- package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
- package/dist/admin/src/constants.d.ts +18 -0
- package/dist/admin/src/modules/hooks.d.ts +7 -0
- package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
- package/dist/admin/src/services/release.d.ts +53 -370
- package/dist/admin/src/utils/api.d.ts +6 -0
- package/dist/admin/src/utils/time.d.ts +9 -0
- package/dist/admin/src/validation/schemas.d.ts +6 -0
- package/dist/server/index.js +889 -614
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +889 -613
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +11 -2
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +3 -5
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/release-action/index.d.ts +3 -5
- package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
- package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
- package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +6 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/release-action.d.ts.map +1 -1
- package/dist/server/src/controllers/release.d.ts +7 -1
- package/dist/server/src/controllers/release.d.ts.map +1 -1
- package/dist/server/src/controllers/settings.d.ts +11 -0
- package/dist/server/src/controllers/settings.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/release-action.d.ts +7 -1
- package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/release.d.ts +2 -0
- package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/settings.d.ts +3 -0
- package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
- package/dist/server/src/index.d.ts +64 -49
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/documents.d.ts +6 -0
- package/dist/server/src/middlewares/documents.d.ts.map +1 -0
- package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
- package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
- package/dist/server/src/migrations/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts +16 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/routes/release.d.ts.map +1 -1
- package/dist/server/src/routes/settings.d.ts +18 -0
- package/dist/server/src/routes/settings.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +36 -38
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/release-action.d.ts +34 -0
- package/dist/server/src/services/release-action.d.ts.map +1 -0
- package/dist/server/src/services/release.d.ts +6 -41
- package/dist/server/src/services/release.d.ts.map +1 -1
- package/dist/server/src/services/settings.d.ts +13 -0
- package/dist/server/src/services/settings.d.ts.map +1 -0
- package/dist/server/src/services/validation.d.ts +1 -1
- package/dist/server/src/services/validation.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +29 -8
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/release-actions.d.ts +17 -11
- package/dist/shared/contracts/release-actions.d.ts.map +1 -1
- package/dist/shared/contracts/releases.d.ts +9 -7
- package/dist/shared/contracts/releases.d.ts.map +1 -1
- package/dist/shared/contracts/settings.d.ts +39 -0
- package/dist/shared/contracts/settings.d.ts.map +1 -0
- package/package.json +24 -23
- package/dist/_chunks/App-BsUSTHVD.mjs.map +0 -1
- package/dist/_chunks/App-CXRpb2hi.js.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +0 -1
- package/dist/_chunks/en-B9Ur3VsE.mjs.map +0 -1
- package/dist/_chunks/en-DtFJ5ViE.js.map +0 -1
- package/dist/_chunks/index-B6-lic1Q.js.map +0 -1
- package/dist/_chunks/index-DJLIZdZv.mjs.map +0 -1
- package/dist/admin/src/services/axios.d.ts +0 -29
- package/dist/shared/validation-schemas.d.ts +0 -2
- package/dist/shared/validation-schemas.d.ts.map +0 -1
- package/strapi-server.js +0 -3
|
@@ -1,25 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { unstable_useDocument } from "@strapi/content-manager/strapi-admin";
|
|
7
|
-
import { Menu, IconButton, Flex, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button, EmptyStateLayout, LinkButton, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter } from "@strapi/design-system";
|
|
8
|
-
import { EmptyDocuments } from "@strapi/icons/symbols";
|
|
9
|
-
import { isAxiosError as isAxiosError$1 } from "axios";
|
|
10
|
-
import { Formik, Form } from "formik";
|
|
1
|
+
import { PaperPlane, CaretDown, Cross, Pencil, More } from "@strapi/icons";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { adminApi, useRBAC, useNotification, useAPIErrorHandler, useQueryParams, isFetchError, useTable, useAuth } from "@strapi/admin/strapi-admin";
|
|
4
|
+
import { Field, Flex, VisuallyHidden, Modal, Button, EmptyStateLayout, LinkButton, Box, SingleSelect, SingleSelectOption, Popover, Typography, Link as Link$1, Menu, AccessibleIcon } from "@strapi/design-system";
|
|
5
|
+
import { useFormik, Formik, Form } from "formik";
|
|
11
6
|
import { useIntl } from "react-intl";
|
|
12
|
-
import {
|
|
7
|
+
import { unstable_useDocumentLayout } from "@strapi/content-manager/strapi-admin";
|
|
8
|
+
import { EmptyDocuments } from "@strapi/icons/symbols";
|
|
9
|
+
import { Link, NavLink } from "react-router-dom";
|
|
13
10
|
import * as yup from "yup";
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
|
11
|
+
import { styled } from "styled-components";
|
|
12
|
+
import * as React from "react";
|
|
13
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
17
14
|
const v = glob[path];
|
|
18
15
|
if (v) {
|
|
19
16
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
20
17
|
}
|
|
21
18
|
return new Promise((_, reject) => {
|
|
22
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
19
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
20
|
+
reject.bind(
|
|
21
|
+
null,
|
|
22
|
+
new Error(
|
|
23
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
);
|
|
23
27
|
});
|
|
24
28
|
};
|
|
25
29
|
const PERMISSIONS = {
|
|
@@ -94,55 +98,70 @@ const PERMISSIONS = {
|
|
|
94
98
|
}
|
|
95
99
|
]
|
|
96
100
|
};
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
method,
|
|
101
|
-
data,
|
|
102
|
-
config
|
|
103
|
-
}) => {
|
|
104
|
-
try {
|
|
105
|
-
const { get, post, del, put } = getFetchClient();
|
|
106
|
-
if (method === "POST") {
|
|
107
|
-
const result2 = await post(url, data, config);
|
|
108
|
-
return { data: result2.data };
|
|
109
|
-
}
|
|
110
|
-
if (method === "DELETE") {
|
|
111
|
-
const result2 = await del(url, config);
|
|
112
|
-
return { data: result2.data };
|
|
113
|
-
}
|
|
114
|
-
if (method === "PUT") {
|
|
115
|
-
const result2 = await put(url, data, config);
|
|
116
|
-
return { data: result2.data };
|
|
117
|
-
}
|
|
118
|
-
const result = await get(url, config);
|
|
119
|
-
return { data: result.data };
|
|
120
|
-
} catch (error) {
|
|
121
|
-
const err = error;
|
|
122
|
-
return {
|
|
123
|
-
error: {
|
|
124
|
-
status: err.response?.status,
|
|
125
|
-
code: err.code,
|
|
126
|
-
response: {
|
|
127
|
-
data: err.response?.data
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
};
|
|
101
|
+
const extendInvalidatesTags = (endpoint, extraTags) => {
|
|
102
|
+
if (!endpoint) {
|
|
103
|
+
return;
|
|
131
104
|
}
|
|
105
|
+
const originalInvalidatesTags = endpoint.invalidatesTags;
|
|
106
|
+
const newInvalidatesTags = (result, err, args, meta) => {
|
|
107
|
+
const originalTags = typeof originalInvalidatesTags === "function" ? originalInvalidatesTags(result, err, args, meta) : originalInvalidatesTags;
|
|
108
|
+
return [...originalTags ?? [], ...extraTags];
|
|
109
|
+
};
|
|
110
|
+
Object.assign(endpoint, { invalidatesTags: newInvalidatesTags });
|
|
132
111
|
};
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
112
|
+
const releaseApi = adminApi.enhanceEndpoints({
|
|
113
|
+
addTagTypes: ["Release", "ReleaseAction", "EntriesInRelease", "ReleaseSettings", "Document"],
|
|
114
|
+
endpoints: {
|
|
115
|
+
updateDocument(endpoint) {
|
|
116
|
+
extendInvalidatesTags(endpoint, [
|
|
117
|
+
{ type: "Release", id: "LIST" },
|
|
118
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
119
|
+
]);
|
|
120
|
+
},
|
|
121
|
+
deleteDocument(endpoint) {
|
|
122
|
+
extendInvalidatesTags(endpoint, [
|
|
123
|
+
{ type: "Release", id: "LIST" },
|
|
124
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
125
|
+
]);
|
|
126
|
+
},
|
|
127
|
+
deleteManyDocuments(endpoint) {
|
|
128
|
+
extendInvalidatesTags(endpoint, [
|
|
129
|
+
{ type: "Release", id: "LIST" },
|
|
130
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
131
|
+
]);
|
|
132
|
+
},
|
|
133
|
+
discardDocument(endpoint) {
|
|
134
|
+
extendInvalidatesTags(endpoint, [
|
|
135
|
+
{ type: "Release", id: "LIST" },
|
|
136
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
137
|
+
]);
|
|
138
|
+
},
|
|
139
|
+
createWorkflow(endpoint) {
|
|
140
|
+
extendInvalidatesTags(endpoint, [
|
|
141
|
+
{ type: "Release", id: "LIST" },
|
|
142
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
143
|
+
]);
|
|
144
|
+
},
|
|
145
|
+
updateWorkflow(endpoint) {
|
|
146
|
+
extendInvalidatesTags(endpoint, [
|
|
147
|
+
{ type: "Release", id: "LIST" },
|
|
148
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
149
|
+
]);
|
|
150
|
+
},
|
|
151
|
+
deleteWorkflow(endpoint) {
|
|
152
|
+
extendInvalidatesTags(endpoint, [
|
|
153
|
+
{ type: "Release", id: "LIST" },
|
|
154
|
+
{ type: "ReleaseAction", id: "LIST" }
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}).injectEndpoints({
|
|
140
159
|
endpoints: (build) => {
|
|
141
160
|
return {
|
|
142
161
|
getReleasesForEntry: build.query({
|
|
143
162
|
query(params) {
|
|
144
163
|
return {
|
|
145
|
-
url: "/content-releases",
|
|
164
|
+
url: "/content-releases/getByDocumentAttached",
|
|
146
165
|
method: "GET",
|
|
147
166
|
config: {
|
|
148
167
|
params
|
|
@@ -204,7 +223,10 @@ const releaseApi = createApi({
|
|
|
204
223
|
method: "GET"
|
|
205
224
|
};
|
|
206
225
|
},
|
|
207
|
-
providesTags: (result, error, arg) => [
|
|
226
|
+
providesTags: (result, error, arg) => [
|
|
227
|
+
{ type: "Release", id: "LIST" },
|
|
228
|
+
{ type: "Release", id: arg.id }
|
|
229
|
+
]
|
|
208
230
|
}),
|
|
209
231
|
getReleaseActions: build.query({
|
|
210
232
|
query({ releaseId, ...params }) {
|
|
@@ -273,20 +295,28 @@ const releaseApi = createApi({
|
|
|
273
295
|
data: body
|
|
274
296
|
};
|
|
275
297
|
},
|
|
276
|
-
invalidatesTags: () => [
|
|
298
|
+
invalidatesTags: (res, error, arg) => [
|
|
299
|
+
{ type: "ReleaseAction", id: "LIST" },
|
|
300
|
+
{ type: "Release", id: "LIST" },
|
|
301
|
+
{ type: "Release", id: arg.params.releaseId }
|
|
302
|
+
],
|
|
277
303
|
async onQueryStarted({ body, params, query, actionPath }, { dispatch, queryFulfilled }) {
|
|
278
304
|
const paramsWithoutActionId = {
|
|
279
305
|
releaseId: params.releaseId,
|
|
280
306
|
...query
|
|
281
307
|
};
|
|
282
308
|
const patchResult = dispatch(
|
|
283
|
-
releaseApi.util.updateQueryData(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
309
|
+
releaseApi.util.updateQueryData(
|
|
310
|
+
"getReleaseActions",
|
|
311
|
+
paramsWithoutActionId,
|
|
312
|
+
(draft) => {
|
|
313
|
+
const [key, index] = actionPath;
|
|
314
|
+
const action = draft.data[key][index];
|
|
315
|
+
if (action) {
|
|
316
|
+
action.type = body.type;
|
|
317
|
+
}
|
|
288
318
|
}
|
|
289
|
-
|
|
319
|
+
)
|
|
290
320
|
);
|
|
291
321
|
try {
|
|
292
322
|
await queryFulfilled;
|
|
@@ -316,7 +346,10 @@ const releaseApi = createApi({
|
|
|
316
346
|
method: "POST"
|
|
317
347
|
};
|
|
318
348
|
},
|
|
319
|
-
invalidatesTags: (result, error, arg) => [
|
|
349
|
+
invalidatesTags: (result, error, arg) => [
|
|
350
|
+
{ type: "Release", id: arg.id },
|
|
351
|
+
{ type: "Document", id: `ALL_LIST` }
|
|
352
|
+
]
|
|
320
353
|
}),
|
|
321
354
|
deleteRelease: build.mutation({
|
|
322
355
|
query({ id }) {
|
|
@@ -341,6 +374,20 @@ const releaseApi = createApi({
|
|
|
341
374
|
return response.data;
|
|
342
375
|
},
|
|
343
376
|
providesTags: [{ type: "EntriesInRelease" }]
|
|
377
|
+
}),
|
|
378
|
+
getReleaseSettings: build.query({
|
|
379
|
+
query: () => "/content-releases/settings",
|
|
380
|
+
providesTags: [{ type: "ReleaseSettings" }]
|
|
381
|
+
}),
|
|
382
|
+
updateReleaseSettings: build.mutation({
|
|
383
|
+
query(data) {
|
|
384
|
+
return {
|
|
385
|
+
url: "/content-releases/settings",
|
|
386
|
+
method: "PUT",
|
|
387
|
+
data
|
|
388
|
+
};
|
|
389
|
+
},
|
|
390
|
+
invalidatesTags: [{ type: "ReleaseSettings" }]
|
|
344
391
|
})
|
|
345
392
|
};
|
|
346
393
|
}
|
|
@@ -358,199 +405,21 @@ const {
|
|
|
358
405
|
usePublishReleaseMutation,
|
|
359
406
|
useDeleteReleaseActionMutation,
|
|
360
407
|
useDeleteReleaseMutation,
|
|
361
|
-
useGetMappedEntriesInReleasesQuery
|
|
408
|
+
useGetMappedEntriesInReleasesQuery,
|
|
409
|
+
useGetReleaseSettingsQuery,
|
|
410
|
+
useUpdateReleaseSettingsMutation
|
|
362
411
|
} = releaseApi;
|
|
363
|
-
const getTimezoneOffset = (timezone, date) => {
|
|
364
|
-
try {
|
|
365
|
-
const offsetPart = new Intl.DateTimeFormat("en", {
|
|
366
|
-
timeZone: timezone,
|
|
367
|
-
timeZoneName: "longOffset"
|
|
368
|
-
}).formatToParts(date).find((part) => part.type === "timeZoneName");
|
|
369
|
-
const offset = offsetPart ? offsetPart.value : "";
|
|
370
|
-
let utcOffset = offset.replace("GMT", "UTC");
|
|
371
|
-
if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
|
|
372
|
-
utcOffset = `${utcOffset}+00:00`;
|
|
373
|
-
}
|
|
374
|
-
return utcOffset;
|
|
375
|
-
} catch (error) {
|
|
376
|
-
return "";
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
const StyledMenuItem = styled(Menu.Item)`
|
|
380
|
-
&:hover {
|
|
381
|
-
background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
|
|
382
|
-
|
|
383
|
-
svg {
|
|
384
|
-
fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
a {
|
|
388
|
-
color: ${({ theme }) => theme.colors.neutral800};
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
svg {
|
|
393
|
-
fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
a {
|
|
397
|
-
color: ${({ theme }) => theme.colors.neutral800};
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
span,
|
|
401
|
-
a {
|
|
402
|
-
width: 100%;
|
|
403
|
-
}
|
|
404
|
-
`;
|
|
405
|
-
const StyledIconButton = styled(IconButton)`
|
|
406
|
-
/* Setting this style inline with borderColor will not apply the style */
|
|
407
|
-
border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
|
|
408
|
-
`;
|
|
409
|
-
const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
|
|
410
|
-
const { formatMessage } = useIntl();
|
|
411
|
-
const { toggleNotification } = useNotification();
|
|
412
|
-
const { formatAPIError } = useAPIErrorHandler();
|
|
413
|
-
const [deleteReleaseAction] = useDeleteReleaseActionMutation();
|
|
414
|
-
const {
|
|
415
|
-
allowedActions: { canDeleteAction }
|
|
416
|
-
} = useRBAC(PERMISSIONS);
|
|
417
|
-
const handleDeleteAction = async () => {
|
|
418
|
-
const response = await deleteReleaseAction({
|
|
419
|
-
params: { releaseId, actionId }
|
|
420
|
-
});
|
|
421
|
-
if ("data" in response) {
|
|
422
|
-
toggleNotification({
|
|
423
|
-
type: "success",
|
|
424
|
-
message: formatMessage({
|
|
425
|
-
id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
|
|
426
|
-
defaultMessage: "Entry removed from release"
|
|
427
|
-
})
|
|
428
|
-
});
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
if ("error" in response) {
|
|
432
|
-
if (isAxiosError$1(response.error)) {
|
|
433
|
-
toggleNotification({
|
|
434
|
-
type: "danger",
|
|
435
|
-
message: formatAPIError(response.error)
|
|
436
|
-
});
|
|
437
|
-
} else {
|
|
438
|
-
toggleNotification({
|
|
439
|
-
type: "danger",
|
|
440
|
-
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
if (!canDeleteAction) {
|
|
446
|
-
return null;
|
|
447
|
-
}
|
|
448
|
-
return /* @__PURE__ */ jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
449
|
-
/* @__PURE__ */ jsx(Cross, { width: "1.6rem", height: "1.6rem" }),
|
|
450
|
-
/* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
|
|
451
|
-
id: "content-releases.content-manager-edit-view.remove-from-release",
|
|
452
|
-
defaultMessage: "Remove from release"
|
|
453
|
-
}) })
|
|
454
|
-
] }) });
|
|
455
|
-
};
|
|
456
|
-
const ReleaseActionEntryLinkItem = ({
|
|
457
|
-
contentTypeUid,
|
|
458
|
-
entryId,
|
|
459
|
-
locale
|
|
460
|
-
}) => {
|
|
461
|
-
const { formatMessage } = useIntl();
|
|
462
|
-
const userPermissions = useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
|
|
463
|
-
const canUpdateEntryForLocale = React.useMemo(() => {
|
|
464
|
-
const updatePermissions = userPermissions.find(
|
|
465
|
-
(permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
|
|
466
|
-
);
|
|
467
|
-
if (!updatePermissions) {
|
|
468
|
-
return false;
|
|
469
|
-
}
|
|
470
|
-
return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
|
|
471
|
-
}, [contentTypeUid, locale, userPermissions]);
|
|
472
|
-
const {
|
|
473
|
-
allowedActions: { canUpdate: canUpdateContentType }
|
|
474
|
-
} = useRBAC({
|
|
475
|
-
updateContentType: [
|
|
476
|
-
{
|
|
477
|
-
action: "plugin::content-manager.explorer.update",
|
|
478
|
-
subject: contentTypeUid
|
|
479
|
-
}
|
|
480
|
-
]
|
|
481
|
-
});
|
|
482
|
-
if (!canUpdateContentType || !canUpdateEntryForLocale) {
|
|
483
|
-
return null;
|
|
484
|
-
}
|
|
485
|
-
return /* @__PURE__ */ jsx(
|
|
486
|
-
StyledMenuItem,
|
|
487
|
-
{
|
|
488
|
-
forwardedAs: Link,
|
|
489
|
-
isLink: true,
|
|
490
|
-
to: {
|
|
491
|
-
pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
|
|
492
|
-
search: locale && `?plugins[i18n][locale]=${locale}`
|
|
493
|
-
},
|
|
494
|
-
children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
495
|
-
/* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" }),
|
|
496
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
|
|
497
|
-
id: "content-releases.content-manager-edit-view.edit-entry",
|
|
498
|
-
defaultMessage: "Edit entry"
|
|
499
|
-
}) })
|
|
500
|
-
] })
|
|
501
|
-
}
|
|
502
|
-
);
|
|
503
|
-
};
|
|
504
|
-
const EditReleaseItem = ({ releaseId }) => {
|
|
505
|
-
const { formatMessage } = useIntl();
|
|
506
|
-
return /* @__PURE__ */ jsx(StyledMenuItem, { forwardedAs: Link, isLink: true, to: `/plugins/content-releases/${releaseId}`, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
507
|
-
/* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" }),
|
|
508
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
|
|
509
|
-
id: "content-releases.content-manager-edit-view.edit-release",
|
|
510
|
-
defaultMessage: "Edit release"
|
|
511
|
-
}) })
|
|
512
|
-
] }) });
|
|
513
|
-
};
|
|
514
|
-
const Root = ({ children, hasTriggerBorder = false }) => {
|
|
515
|
-
const { formatMessage } = useIntl();
|
|
516
|
-
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
517
|
-
return (
|
|
518
|
-
// A user can access the dropdown if they have permissions to delete a release-action OR update a release
|
|
519
|
-
allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxs(Menu.Root, { children: [
|
|
520
|
-
/* @__PURE__ */ jsx(
|
|
521
|
-
Menu.Trigger,
|
|
522
|
-
{
|
|
523
|
-
as: hasTriggerBorder ? StyledIconButton : IconButton,
|
|
524
|
-
paddingLeft: 2,
|
|
525
|
-
paddingRight: 2,
|
|
526
|
-
"aria-label": formatMessage({
|
|
527
|
-
id: "content-releases.content-manager-edit-view.release-action-menu",
|
|
528
|
-
defaultMessage: "Release action options"
|
|
529
|
-
}),
|
|
530
|
-
icon: /* @__PURE__ */ jsx(More, {})
|
|
531
|
-
}
|
|
532
|
-
),
|
|
533
|
-
/* @__PURE__ */ jsx(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
|
|
534
|
-
] }) : null
|
|
535
|
-
);
|
|
536
|
-
};
|
|
537
|
-
const ReleaseActionMenu = {
|
|
538
|
-
Root,
|
|
539
|
-
EditReleaseItem,
|
|
540
|
-
DeleteReleaseActionItem,
|
|
541
|
-
ReleaseActionEntryLinkItem
|
|
542
|
-
};
|
|
543
412
|
const getBorderLeftRadiusValue = (actionType) => {
|
|
544
413
|
return actionType === "publish" ? 1 : 0;
|
|
545
414
|
};
|
|
546
415
|
const getBorderRightRadiusValue = (actionType) => {
|
|
547
416
|
return actionType === "publish" ? 0 : 1;
|
|
548
417
|
};
|
|
549
|
-
const FieldWrapper = styled(Field)`
|
|
550
|
-
border-top-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
|
|
551
|
-
border-bottom-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
|
|
552
|
-
border-top-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
|
|
553
|
-
border-bottom-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
|
|
418
|
+
const FieldWrapper = styled(Field.Root)`
|
|
419
|
+
border-top-left-radius: ${({ $actionType, theme }) => theme.spaces[getBorderLeftRadiusValue($actionType)]};
|
|
420
|
+
border-bottom-left-radius: ${({ $actionType, theme }) => theme.spaces[getBorderLeftRadiusValue($actionType)]};
|
|
421
|
+
border-top-right-radius: ${({ $actionType, theme }) => theme.spaces[getBorderRightRadiusValue($actionType)]};
|
|
422
|
+
border-bottom-right-radius: ${({ $actionType, theme }) => theme.spaces[getBorderRightRadiusValue($actionType)]};
|
|
554
423
|
|
|
555
424
|
> label {
|
|
556
425
|
color: inherit;
|
|
@@ -561,14 +430,14 @@ const FieldWrapper = styled(Field)`
|
|
|
561
430
|
}
|
|
562
431
|
|
|
563
432
|
&[data-checked='true'] {
|
|
564
|
-
color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
|
|
565
|
-
background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
|
|
566
|
-
border-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
|
|
433
|
+
color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
|
|
434
|
+
background-color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
|
|
435
|
+
border-color: ${({ theme, $actionType }) => $actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
|
|
567
436
|
}
|
|
568
437
|
|
|
569
438
|
&[data-checked='false'] {
|
|
570
|
-
border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
|
|
571
|
-
border-right: ${({ actionType }) => actionType === "publish" && "none"};
|
|
439
|
+
border-left: ${({ $actionType }) => $actionType === "unpublish" && "none"};
|
|
440
|
+
border-right: ${({ $actionType }) => $actionType === "publish" && "none"};
|
|
572
441
|
}
|
|
573
442
|
|
|
574
443
|
&[data-checked='false'][data-disabled='false']:hover {
|
|
@@ -597,7 +466,7 @@ const ActionOption = ({
|
|
|
597
466
|
return /* @__PURE__ */ jsx(
|
|
598
467
|
FieldWrapper,
|
|
599
468
|
{
|
|
600
|
-
actionType,
|
|
469
|
+
$actionType: actionType,
|
|
601
470
|
background: "primary0",
|
|
602
471
|
borderColor: "neutral200",
|
|
603
472
|
color: selected === actionType ? "primary600" : "neutral600",
|
|
@@ -605,12 +474,11 @@ const ActionOption = ({
|
|
|
605
474
|
cursor: "pointer",
|
|
606
475
|
"data-checked": selected === actionType,
|
|
607
476
|
"data-disabled": disabled && selected !== actionType,
|
|
608
|
-
children: /* @__PURE__ */ jsxs(
|
|
477
|
+
children: /* @__PURE__ */ jsxs(Field.Label, { children: [
|
|
609
478
|
/* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
|
|
610
|
-
|
|
479
|
+
Field.Input,
|
|
611
480
|
{
|
|
612
481
|
type: "radio",
|
|
613
|
-
id: `${name}-${actionType}`,
|
|
614
482
|
name,
|
|
615
483
|
checked: selected === actionType,
|
|
616
484
|
onChange: handleChange,
|
|
@@ -676,302 +544,192 @@ const NoReleases = () => {
|
|
|
676
544
|
to: {
|
|
677
545
|
pathname: "/plugins/content-releases"
|
|
678
546
|
},
|
|
679
|
-
|
|
547
|
+
tag: Link,
|
|
680
548
|
variant: "secondary",
|
|
681
549
|
children: formatMessage({
|
|
682
550
|
id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
|
|
683
551
|
defaultMessage: "Open the list of releases"
|
|
684
552
|
})
|
|
685
553
|
}
|
|
686
|
-
)
|
|
554
|
+
),
|
|
555
|
+
shadow: "none"
|
|
687
556
|
}
|
|
688
557
|
);
|
|
689
558
|
};
|
|
690
559
|
const AddActionToReleaseModal = ({
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
560
|
+
contentType,
|
|
561
|
+
documentId,
|
|
562
|
+
onInputChange,
|
|
563
|
+
values
|
|
694
564
|
}) => {
|
|
695
|
-
const releaseHeaderId = React.useId();
|
|
696
565
|
const { formatMessage } = useIntl();
|
|
697
|
-
const { toggleNotification } = useNotification();
|
|
698
|
-
const { formatAPIError } = useAPIErrorHandler();
|
|
699
566
|
const [{ query }] = useQueryParams();
|
|
700
567
|
const locale = query.plugins?.i18n?.locale;
|
|
701
568
|
const response = useGetReleasesForEntryQuery({
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
hasEntryAttached: false
|
|
569
|
+
contentType,
|
|
570
|
+
entryDocumentId: documentId,
|
|
571
|
+
hasEntryAttached: false,
|
|
572
|
+
locale
|
|
705
573
|
});
|
|
706
574
|
const releases = response.data?.data;
|
|
575
|
+
if (releases?.length === 0) {
|
|
576
|
+
return /* @__PURE__ */ jsx(NoReleases, {});
|
|
577
|
+
}
|
|
578
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
579
|
+
/* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxs(Field.Root, { required: true, children: [
|
|
580
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
581
|
+
id: "content-releases.content-manager-edit-view.add-to-release.select-label",
|
|
582
|
+
defaultMessage: "Select a release"
|
|
583
|
+
}) }),
|
|
584
|
+
/* @__PURE__ */ jsx(
|
|
585
|
+
SingleSelect,
|
|
586
|
+
{
|
|
587
|
+
required: true,
|
|
588
|
+
placeholder: formatMessage({
|
|
589
|
+
id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
|
|
590
|
+
defaultMessage: "Select"
|
|
591
|
+
}),
|
|
592
|
+
name: "releaseId",
|
|
593
|
+
onChange: (value) => onInputChange("releaseId", value),
|
|
594
|
+
value: values.releaseId,
|
|
595
|
+
children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
|
|
596
|
+
}
|
|
597
|
+
)
|
|
598
|
+
] }) }),
|
|
599
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
600
|
+
id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
|
|
601
|
+
defaultMessage: "What do you want to do with this entry?"
|
|
602
|
+
}) }),
|
|
603
|
+
/* @__PURE__ */ jsx(
|
|
604
|
+
ReleaseActionOptions,
|
|
605
|
+
{
|
|
606
|
+
selected: values.type,
|
|
607
|
+
handleChange: (e) => onInputChange("type", e.target.value),
|
|
608
|
+
name: "type"
|
|
609
|
+
}
|
|
610
|
+
)
|
|
611
|
+
] });
|
|
612
|
+
};
|
|
613
|
+
const ReleaseActionModalForm = ({
|
|
614
|
+
documentId,
|
|
615
|
+
document,
|
|
616
|
+
model,
|
|
617
|
+
collectionType
|
|
618
|
+
}) => {
|
|
619
|
+
const { formatMessage } = useIntl();
|
|
620
|
+
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
621
|
+
const { canCreateAction } = allowedActions;
|
|
707
622
|
const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
if ("data" in response2) {
|
|
719
|
-
toggleNotification({
|
|
720
|
-
type: "success",
|
|
721
|
-
message: formatMessage({
|
|
722
|
-
id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
|
|
723
|
-
defaultMessage: "Entry added to release"
|
|
724
|
-
})
|
|
725
|
-
});
|
|
726
|
-
handleClose();
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
if ("error" in response2) {
|
|
730
|
-
if (isAxiosError$1(response2.error)) {
|
|
623
|
+
const { toggleNotification } = useNotification();
|
|
624
|
+
const { formatAPIError } = useAPIErrorHandler();
|
|
625
|
+
const [{ query }] = useQueryParams();
|
|
626
|
+
const locale = query.plugins?.i18n?.locale;
|
|
627
|
+
const handleSubmit = async (e, onClose) => {
|
|
628
|
+
try {
|
|
629
|
+
await formik.handleSubmit(e);
|
|
630
|
+
onClose();
|
|
631
|
+
} catch (error) {
|
|
632
|
+
if (isFetchError(error)) {
|
|
731
633
|
toggleNotification({
|
|
732
634
|
type: "danger",
|
|
733
|
-
message: formatAPIError(
|
|
635
|
+
message: formatAPIError(error)
|
|
734
636
|
});
|
|
735
637
|
} else {
|
|
736
638
|
toggleNotification({
|
|
737
639
|
type: "danger",
|
|
738
|
-
message: formatMessage({
|
|
640
|
+
message: formatMessage({
|
|
641
|
+
id: "notification.error",
|
|
642
|
+
defaultMessage: "An error occurred"
|
|
643
|
+
})
|
|
739
644
|
});
|
|
740
645
|
}
|
|
741
646
|
}
|
|
742
647
|
};
|
|
743
|
-
|
|
744
|
-
|
|
648
|
+
const formik = useFormik({
|
|
649
|
+
initialValues: INITIAL_VALUES,
|
|
650
|
+
validationSchema: RELEASE_ACTION_FORM_SCHEMA,
|
|
651
|
+
onSubmit: async (values) => {
|
|
652
|
+
if (collectionType === "collection-types" && !documentId) {
|
|
653
|
+
throw new Error("Document id is required");
|
|
654
|
+
}
|
|
655
|
+
const response = await createReleaseAction({
|
|
656
|
+
body: {
|
|
657
|
+
type: values.type,
|
|
658
|
+
contentType: model,
|
|
659
|
+
entryDocumentId: documentId,
|
|
660
|
+
locale
|
|
661
|
+
},
|
|
662
|
+
params: { releaseId: values.releaseId }
|
|
663
|
+
});
|
|
664
|
+
if ("data" in response) {
|
|
665
|
+
toggleNotification({
|
|
666
|
+
type: "success",
|
|
667
|
+
message: formatMessage({
|
|
668
|
+
id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
|
|
669
|
+
defaultMessage: "Entry added to release"
|
|
670
|
+
})
|
|
671
|
+
});
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
if ("error" in response) {
|
|
675
|
+
throw response.error;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
const {
|
|
680
|
+
edit: { options }
|
|
681
|
+
} = unstable_useDocumentLayout(model);
|
|
682
|
+
if (!window.strapi.isEE || !options?.draftAndPublish || !canCreateAction) {
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
return {
|
|
689
|
+
label: formatMessage({
|
|
745
690
|
id: "content-releases.content-manager-edit-view.add-to-release",
|
|
746
691
|
defaultMessage: "Add to release"
|
|
747
|
-
})
|
|
748
|
-
/* @__PURE__ */ jsx(
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
/* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsx(
|
|
758
|
-
SingleSelect,
|
|
759
|
-
{
|
|
760
|
-
required: true,
|
|
761
|
-
label: formatMessage({
|
|
762
|
-
id: "content-releases.content-manager-edit-view.add-to-release.select-label",
|
|
763
|
-
defaultMessage: "Select a release"
|
|
764
|
-
}),
|
|
765
|
-
placeholder: formatMessage({
|
|
766
|
-
id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
|
|
767
|
-
defaultMessage: "Select"
|
|
768
|
-
}),
|
|
769
|
-
onChange: (value) => setFieldValue("releaseId", value),
|
|
770
|
-
value: values.releaseId,
|
|
771
|
-
children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
|
|
772
|
-
}
|
|
773
|
-
) }),
|
|
774
|
-
/* @__PURE__ */ jsx(FieldLabel, { children: formatMessage({
|
|
775
|
-
id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
|
|
776
|
-
defaultMessage: "What do you want to do with this entry?"
|
|
777
|
-
}) }),
|
|
778
|
-
/* @__PURE__ */ jsx(
|
|
779
|
-
ReleaseActionOptions,
|
|
780
|
-
{
|
|
781
|
-
selected: values.type,
|
|
782
|
-
handleChange: (e) => setFieldValue("type", e.target.value),
|
|
783
|
-
name: "type"
|
|
784
|
-
}
|
|
785
|
-
)
|
|
786
|
-
] }) }),
|
|
787
|
-
/* @__PURE__ */ jsx(
|
|
788
|
-
ModalFooter,
|
|
789
|
-
{
|
|
790
|
-
startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
|
|
791
|
-
id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
|
|
792
|
-
defaultMessage: "Cancel"
|
|
793
|
-
}) }),
|
|
794
|
-
endActions: (
|
|
795
|
-
/**
|
|
796
|
-
* TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
|
|
797
|
-
* for yup.string().required(), even when the value is falsy (including empty string)
|
|
798
|
-
*/
|
|
799
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
|
|
800
|
-
id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
|
|
801
|
-
defaultMessage: "Continue"
|
|
802
|
-
}) })
|
|
803
|
-
)
|
|
804
|
-
}
|
|
805
|
-
)
|
|
806
|
-
] });
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
)
|
|
810
|
-
] });
|
|
811
|
-
};
|
|
812
|
-
const CMReleasesContainer = () => {
|
|
813
|
-
const [isModalOpen, setIsModalOpen] = React.useState(false);
|
|
814
|
-
const { formatMessage, formatDate, formatTime } = useIntl();
|
|
815
|
-
const { id, slug, collectionType } = useParams();
|
|
816
|
-
const isCreatingEntry = id === "create";
|
|
817
|
-
const entryId = parseInt(id, 10);
|
|
818
|
-
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
819
|
-
const { canCreateAction, canRead: canMain, canDeleteAction } = allowedActions;
|
|
820
|
-
const { schema } = unstable_useDocument({
|
|
821
|
-
collectionType,
|
|
822
|
-
model: slug
|
|
823
|
-
});
|
|
824
|
-
const hasDraftAndPublish = schema?.options?.draftAndPublish;
|
|
825
|
-
const contentTypeUid = slug;
|
|
826
|
-
const canFetch = id != null && contentTypeUid != null;
|
|
827
|
-
const fetchParams = canFetch ? {
|
|
828
|
-
contentTypeUid,
|
|
829
|
-
entryId,
|
|
830
|
-
hasEntryAttached: true
|
|
831
|
-
} : skipToken;
|
|
832
|
-
const response = useGetReleasesForEntryQuery(fetchParams);
|
|
833
|
-
const releases = response.data?.data;
|
|
834
|
-
if (!canFetch) {
|
|
835
|
-
return null;
|
|
836
|
-
}
|
|
837
|
-
if (isCreatingEntry || !hasDraftAndPublish) {
|
|
838
|
-
return null;
|
|
839
|
-
}
|
|
840
|
-
const toggleModal = () => setIsModalOpen((prev) => !prev);
|
|
841
|
-
const getReleaseColorVariant = (actionType, shade) => {
|
|
842
|
-
if (actionType === "unpublish") {
|
|
843
|
-
return `secondary${shade}`;
|
|
844
|
-
}
|
|
845
|
-
return `success${shade}`;
|
|
846
|
-
};
|
|
847
|
-
if (!canMain) {
|
|
848
|
-
return null;
|
|
849
|
-
}
|
|
850
|
-
return /* @__PURE__ */ jsxs(
|
|
851
|
-
Box,
|
|
852
|
-
{
|
|
853
|
-
as: "aside",
|
|
854
|
-
"aria-label": formatMessage({
|
|
855
|
-
id: "content-releases.plugin.name",
|
|
856
|
-
defaultMessage: "Releases"
|
|
692
|
+
}),
|
|
693
|
+
icon: /* @__PURE__ */ jsx(PaperPlane, {}),
|
|
694
|
+
// Entry is creating so we don't want to allow adding it to a release
|
|
695
|
+
disabled: !document,
|
|
696
|
+
position: ["panel", "table-row"],
|
|
697
|
+
dialog: {
|
|
698
|
+
type: "modal",
|
|
699
|
+
title: formatMessage({
|
|
700
|
+
id: "content-releases.content-manager-edit-view.add-to-release",
|
|
701
|
+
defaultMessage: "Add to release"
|
|
857
702
|
}),
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
releases
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
alignItems: "start",
|
|
875
|
-
borderWidth: "1px",
|
|
876
|
-
borderStyle: "solid",
|
|
877
|
-
borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
|
|
878
|
-
overflow: "hidden",
|
|
879
|
-
hasRadius: true,
|
|
880
|
-
children: [
|
|
881
|
-
/* @__PURE__ */ jsx(
|
|
882
|
-
Box,
|
|
883
|
-
{
|
|
884
|
-
paddingTop: 3,
|
|
885
|
-
paddingBottom: 3,
|
|
886
|
-
paddingLeft: 4,
|
|
887
|
-
paddingRight: 4,
|
|
888
|
-
background: getReleaseColorVariant(release.actions[0].type, "100"),
|
|
889
|
-
width: "100%",
|
|
890
|
-
children: /* @__PURE__ */ jsx(
|
|
891
|
-
Typography,
|
|
892
|
-
{
|
|
893
|
-
fontSize: 1,
|
|
894
|
-
variant: "pi",
|
|
895
|
-
textColor: getReleaseColorVariant(release.actions[0].type, "600"),
|
|
896
|
-
children: formatMessage(
|
|
897
|
-
{
|
|
898
|
-
id: "content-releases.content-manager-edit-view.list-releases.title",
|
|
899
|
-
defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
|
|
900
|
-
},
|
|
901
|
-
{ isPublish: release.actions[0].type === "publish" }
|
|
902
|
-
)
|
|
903
|
-
}
|
|
904
|
-
)
|
|
905
|
-
}
|
|
906
|
-
),
|
|
907
|
-
/* @__PURE__ */ jsx(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: /* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
|
|
908
|
-
/* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
|
|
909
|
-
release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
|
|
910
|
-
{
|
|
911
|
-
id: "content-releases.content-manager-edit-view.scheduled.date",
|
|
912
|
-
defaultMessage: "{date} at {time} ({offset})"
|
|
913
|
-
},
|
|
914
|
-
{
|
|
915
|
-
date: formatDate(new Date(release.scheduledAt), {
|
|
916
|
-
day: "2-digit",
|
|
917
|
-
month: "2-digit",
|
|
918
|
-
year: "numeric",
|
|
919
|
-
timeZone: release.timezone
|
|
920
|
-
}),
|
|
921
|
-
time: formatTime(new Date(release.scheduledAt), {
|
|
922
|
-
hourCycle: "h23",
|
|
923
|
-
timeZone: release.timezone
|
|
924
|
-
}),
|
|
925
|
-
offset: getTimezoneOffset(
|
|
926
|
-
release.timezone,
|
|
927
|
-
new Date(release.scheduledAt)
|
|
928
|
-
)
|
|
929
|
-
}
|
|
930
|
-
) }),
|
|
931
|
-
canDeleteAction ? /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
|
|
932
|
-
/* @__PURE__ */ jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
|
|
933
|
-
/* @__PURE__ */ jsx(
|
|
934
|
-
ReleaseActionMenu.DeleteReleaseActionItem,
|
|
935
|
-
{
|
|
936
|
-
releaseId: release.id,
|
|
937
|
-
actionId: release.actions[0].id
|
|
938
|
-
}
|
|
939
|
-
)
|
|
940
|
-
] }) : null
|
|
941
|
-
] }) })
|
|
942
|
-
]
|
|
943
|
-
},
|
|
944
|
-
release.id
|
|
945
|
-
);
|
|
946
|
-
}),
|
|
947
|
-
canCreateAction ? /* @__PURE__ */ jsx(
|
|
948
|
-
Button,
|
|
949
|
-
{
|
|
950
|
-
justifyContent: "center",
|
|
951
|
-
paddingLeft: 4,
|
|
952
|
-
paddingRight: 4,
|
|
953
|
-
color: "neutral700",
|
|
954
|
-
variant: "tertiary",
|
|
955
|
-
startIcon: /* @__PURE__ */ jsx(Plus, {}),
|
|
956
|
-
onClick: toggleModal,
|
|
957
|
-
children: formatMessage({
|
|
958
|
-
id: "content-releases.content-manager-edit-view.add-to-release",
|
|
959
|
-
defaultMessage: "Add to release"
|
|
960
|
-
})
|
|
961
|
-
}
|
|
962
|
-
) : null
|
|
963
|
-
] }),
|
|
964
|
-
isModalOpen && /* @__PURE__ */ jsx(
|
|
965
|
-
AddActionToReleaseModal,
|
|
703
|
+
content: /* @__PURE__ */ jsx(
|
|
704
|
+
AddActionToReleaseModal,
|
|
705
|
+
{
|
|
706
|
+
contentType: model,
|
|
707
|
+
documentId,
|
|
708
|
+
onInputChange: formik.setFieldValue,
|
|
709
|
+
values: formik.values
|
|
710
|
+
}
|
|
711
|
+
),
|
|
712
|
+
footer: ({ onClose }) => /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
713
|
+
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
|
|
714
|
+
id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
|
|
715
|
+
defaultMessage: "Cancel"
|
|
716
|
+
}) }),
|
|
717
|
+
/* @__PURE__ */ jsx(
|
|
718
|
+
Button,
|
|
966
719
|
{
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
720
|
+
type: "submit",
|
|
721
|
+
onClick: (e) => handleSubmit(e, onClose),
|
|
722
|
+
disabled: !formik.values.releaseId,
|
|
723
|
+
loading: isLoading,
|
|
724
|
+
children: formatMessage({
|
|
725
|
+
id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
|
|
726
|
+
defaultMessage: "Continue"
|
|
727
|
+
})
|
|
970
728
|
}
|
|
971
729
|
)
|
|
972
|
-
]
|
|
730
|
+
] })
|
|
973
731
|
}
|
|
974
|
-
|
|
732
|
+
};
|
|
975
733
|
};
|
|
976
734
|
const getContentPermissions = (subject) => {
|
|
977
735
|
const permissions = {
|
|
@@ -988,7 +746,7 @@ const getContentPermissions = (subject) => {
|
|
|
988
746
|
};
|
|
989
747
|
return permissions;
|
|
990
748
|
};
|
|
991
|
-
const ReleaseAction = ({
|
|
749
|
+
const ReleaseAction = ({ documents, model }) => {
|
|
992
750
|
const { formatMessage } = useIntl();
|
|
993
751
|
const { toggleNotification } = useNotification();
|
|
994
752
|
const { formatAPIError } = useAPIErrorHandler();
|
|
@@ -1003,16 +761,15 @@ const ReleaseAction = ({ documentIds, model }) => {
|
|
|
1003
761
|
const response = useGetReleasesQuery();
|
|
1004
762
|
const releases = response.data?.data;
|
|
1005
763
|
const [createManyReleaseActions, { isLoading }] = useCreateManyReleaseActionsMutation();
|
|
764
|
+
const documentIds = documents.map((doc) => doc.documentId);
|
|
1006
765
|
const handleSubmit = async (values) => {
|
|
1007
766
|
const locale = query.plugins?.i18n?.locale;
|
|
1008
767
|
const releaseActionEntries = documentIds.map(
|
|
1009
|
-
(
|
|
768
|
+
(entryDocumentId) => ({
|
|
1010
769
|
type: values.type,
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
locale
|
|
1015
|
-
}
|
|
770
|
+
contentType: model,
|
|
771
|
+
entryDocumentId,
|
|
772
|
+
locale
|
|
1016
773
|
})
|
|
1017
774
|
);
|
|
1018
775
|
const response2 = await createManyReleaseActions({
|
|
@@ -1048,7 +805,7 @@ const ReleaseAction = ({ documentIds, model }) => {
|
|
|
1048
805
|
return true;
|
|
1049
806
|
}
|
|
1050
807
|
if ("error" in response2) {
|
|
1051
|
-
if (
|
|
808
|
+
if (isFetchError(response2.error)) {
|
|
1052
809
|
toggleNotification({
|
|
1053
810
|
type: "warning",
|
|
1054
811
|
message: formatAPIError(response2.error)
|
|
@@ -1061,8 +818,7 @@ const ReleaseAction = ({ documentIds, model }) => {
|
|
|
1061
818
|
}
|
|
1062
819
|
}
|
|
1063
820
|
};
|
|
1064
|
-
if (!canCreate || !canPublish)
|
|
1065
|
-
return null;
|
|
821
|
+
if (!canCreate || !canPublish) return null;
|
|
1066
822
|
return {
|
|
1067
823
|
actionType: "release",
|
|
1068
824
|
variant: "tertiary",
|
|
@@ -1089,25 +845,26 @@ const ReleaseAction = ({ documentIds, model }) => {
|
|
|
1089
845
|
validationSchema: RELEASE_ACTION_FORM_SCHEMA,
|
|
1090
846
|
initialValues: INITIAL_VALUES,
|
|
1091
847
|
children: ({ values, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
|
|
1092
|
-
releases?.length === 0 ? /* @__PURE__ */ jsx(NoReleases, {}) : /* @__PURE__ */ jsx(
|
|
1093
|
-
/* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
848
|
+
releases?.length === 0 ? /* @__PURE__ */ jsx(NoReleases, {}) : /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
849
|
+
/* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxs(Field.Root, { required: true, children: [
|
|
850
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
851
|
+
id: "content-releases.content-manager-list-view.add-to-release.select-label",
|
|
852
|
+
defaultMessage: "Select a release"
|
|
853
|
+
}) }),
|
|
854
|
+
/* @__PURE__ */ jsx(
|
|
855
|
+
SingleSelect,
|
|
856
|
+
{
|
|
857
|
+
placeholder: formatMessage({
|
|
858
|
+
id: "content-releases.content-manager-list-view.add-to-release.select-placeholder",
|
|
859
|
+
defaultMessage: "Select"
|
|
860
|
+
}),
|
|
861
|
+
onChange: (value) => setFieldValue("releaseId", value),
|
|
862
|
+
value: values.releaseId,
|
|
863
|
+
children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
] }) }),
|
|
867
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
1111
868
|
id: "content-releases.content-manager-list-view.add-to-release.action-type-label",
|
|
1112
869
|
defaultMessage: "What do you want to do with these entries?"
|
|
1113
870
|
}) }),
|
|
@@ -1120,25 +877,16 @@ const ReleaseAction = ({ documentIds, model }) => {
|
|
|
1120
877
|
}
|
|
1121
878
|
)
|
|
1122
879
|
] }) }),
|
|
1123
|
-
/* @__PURE__ */
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
* for yup.string().required(), even when the value is falsy (including empty string)
|
|
1134
|
-
*/
|
|
1135
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
|
|
1136
|
-
id: "content-releases.content-manager-list-view.add-to-release.continue-button",
|
|
1137
|
-
defaultMessage: "Continue"
|
|
1138
|
-
}) })
|
|
1139
|
-
)
|
|
1140
|
-
}
|
|
1141
|
-
)
|
|
880
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
881
|
+
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", name: "cancel", children: formatMessage({
|
|
882
|
+
id: "content-releases.content-manager-list-view.add-to-release.cancel-button",
|
|
883
|
+
defaultMessage: "Cancel"
|
|
884
|
+
}) }),
|
|
885
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
|
|
886
|
+
id: "content-releases.content-manager-list-view.add-to-release.continue-button",
|
|
887
|
+
defaultMessage: "Continue"
|
|
888
|
+
}) })
|
|
889
|
+
] })
|
|
1142
890
|
] })
|
|
1143
891
|
}
|
|
1144
892
|
);
|
|
@@ -1146,10 +894,386 @@ const ReleaseAction = ({ documentIds, model }) => {
|
|
|
1146
894
|
}
|
|
1147
895
|
};
|
|
1148
896
|
};
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
897
|
+
const useReleasesList = (contentTypeUid, documentId) => {
|
|
898
|
+
const listViewData = useTable("ListView", (state) => state.rows);
|
|
899
|
+
const documentIds = listViewData.map((entry) => entry.documentId);
|
|
900
|
+
const [{ query }] = useQueryParams();
|
|
901
|
+
const locale = query?.plugins?.i18n?.locale || void 0;
|
|
902
|
+
const response = useGetMappedEntriesInReleasesQuery(
|
|
903
|
+
{ contentTypeUid, documentIds, locale },
|
|
904
|
+
{ skip: !documentIds || !contentTypeUid || documentIds.length === 0 }
|
|
905
|
+
);
|
|
906
|
+
const mappedEntriesInReleases = response.data || {};
|
|
907
|
+
return mappedEntriesInReleases?.[documentId] || [];
|
|
908
|
+
};
|
|
909
|
+
const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
|
910
|
+
const { options } = layout;
|
|
911
|
+
if (!options?.draftAndPublish) {
|
|
912
|
+
return { displayedHeaders, layout };
|
|
1152
913
|
}
|
|
914
|
+
return {
|
|
915
|
+
displayedHeaders: [
|
|
916
|
+
...displayedHeaders,
|
|
917
|
+
{
|
|
918
|
+
searchable: false,
|
|
919
|
+
sortable: false,
|
|
920
|
+
name: "releases",
|
|
921
|
+
label: {
|
|
922
|
+
id: "content-releases.content-manager.list-view.releases.header",
|
|
923
|
+
defaultMessage: "To be released in"
|
|
924
|
+
},
|
|
925
|
+
cellFormatter: (props, _, { model }) => /* @__PURE__ */ jsx(ReleaseListCell, { ...props, model })
|
|
926
|
+
}
|
|
927
|
+
],
|
|
928
|
+
layout
|
|
929
|
+
};
|
|
930
|
+
};
|
|
931
|
+
const ReleaseListCell = ({ documentId, model }) => {
|
|
932
|
+
const releases = useReleasesList(model, documentId);
|
|
933
|
+
const { formatMessage } = useIntl();
|
|
934
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { children: [
|
|
935
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(
|
|
936
|
+
Button,
|
|
937
|
+
{
|
|
938
|
+
variant: "ghost",
|
|
939
|
+
onClick: (e) => e.stopPropagation(),
|
|
940
|
+
endIcon: releases.length > 0 ? /* @__PURE__ */ jsx(CaretDown, { width: "1.2rem", height: "1.2rem" }) : null,
|
|
941
|
+
children: /* @__PURE__ */ jsx(
|
|
942
|
+
Typography,
|
|
943
|
+
{
|
|
944
|
+
style: { maxWidth: "252px", cursor: "pointer" },
|
|
945
|
+
textColor: "neutral800",
|
|
946
|
+
fontWeight: "regular",
|
|
947
|
+
children: releases.length > 0 ? formatMessage(
|
|
948
|
+
{
|
|
949
|
+
id: "content-releases.content-manager.list-view.releases-number",
|
|
950
|
+
defaultMessage: "{number} {number, plural, one {release} other {releases}}"
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
number: releases.length
|
|
954
|
+
}
|
|
955
|
+
) : "-"
|
|
956
|
+
}
|
|
957
|
+
)
|
|
958
|
+
}
|
|
959
|
+
) }),
|
|
960
|
+
/* @__PURE__ */ jsx(Popover.Content, { children: /* @__PURE__ */ jsx("ul", { children: releases.map(({ id, name }) => /* @__PURE__ */ jsx(Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsx(Link$1, { href: `/admin/plugins/content-releases/${id}`, isExternal: false, children: name }) }, id)) }) })
|
|
961
|
+
] });
|
|
962
|
+
};
|
|
963
|
+
const getTimezoneOffset = (timezone, date) => {
|
|
964
|
+
try {
|
|
965
|
+
const offsetPart = new Intl.DateTimeFormat("en", {
|
|
966
|
+
timeZone: timezone,
|
|
967
|
+
timeZoneName: "longOffset"
|
|
968
|
+
}).formatToParts(date).find((part) => part.type === "timeZoneName");
|
|
969
|
+
const offset = offsetPart ? offsetPart.value : "";
|
|
970
|
+
let utcOffset = offset.replace("GMT", "UTC");
|
|
971
|
+
if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
|
|
972
|
+
utcOffset = `${utcOffset}+00:00`;
|
|
973
|
+
}
|
|
974
|
+
return utcOffset;
|
|
975
|
+
} catch (error) {
|
|
976
|
+
return "";
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
const getTimezones = (selectedDate) => {
|
|
980
|
+
const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
|
|
981
|
+
const utcOffset = getTimezoneOffset(timezone, selectedDate);
|
|
982
|
+
return { offset: utcOffset, value: `${utcOffset}&${timezone}` };
|
|
983
|
+
});
|
|
984
|
+
const systemTimezone = timezoneList.find(
|
|
985
|
+
(timezone) => timezone.value.split("&")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
986
|
+
);
|
|
987
|
+
return { timezoneList, systemTimezone };
|
|
988
|
+
};
|
|
989
|
+
const StyledMenuItem = styled(Menu.Item)`
|
|
990
|
+
&:hover {
|
|
991
|
+
background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
|
|
992
|
+
|
|
993
|
+
svg {
|
|
994
|
+
fill: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}600`]};
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
a {
|
|
998
|
+
color: ${({ theme }) => theme.colors.neutral800};
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
svg {
|
|
1003
|
+
color: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}500`]};
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
span {
|
|
1007
|
+
color: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}800`]};
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
span,
|
|
1011
|
+
a {
|
|
1012
|
+
width: 100%;
|
|
1013
|
+
}
|
|
1014
|
+
`;
|
|
1015
|
+
const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
|
|
1016
|
+
const { formatMessage } = useIntl();
|
|
1017
|
+
const { toggleNotification } = useNotification();
|
|
1018
|
+
const { formatAPIError } = useAPIErrorHandler();
|
|
1019
|
+
const [deleteReleaseAction] = useDeleteReleaseActionMutation();
|
|
1020
|
+
const {
|
|
1021
|
+
allowedActions: { canDeleteAction }
|
|
1022
|
+
} = useRBAC(PERMISSIONS);
|
|
1023
|
+
const handleDeleteAction = async () => {
|
|
1024
|
+
const response = await deleteReleaseAction({
|
|
1025
|
+
params: { releaseId, actionId }
|
|
1026
|
+
});
|
|
1027
|
+
if ("data" in response) {
|
|
1028
|
+
toggleNotification({
|
|
1029
|
+
type: "success",
|
|
1030
|
+
message: formatMessage({
|
|
1031
|
+
id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
|
|
1032
|
+
defaultMessage: "Entry removed from release"
|
|
1033
|
+
})
|
|
1034
|
+
});
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
if ("error" in response) {
|
|
1038
|
+
if (isFetchError(response.error)) {
|
|
1039
|
+
toggleNotification({
|
|
1040
|
+
type: "danger",
|
|
1041
|
+
message: formatAPIError(response.error)
|
|
1042
|
+
});
|
|
1043
|
+
} else {
|
|
1044
|
+
toggleNotification({
|
|
1045
|
+
type: "danger",
|
|
1046
|
+
message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
if (!canDeleteAction) {
|
|
1052
|
+
return null;
|
|
1053
|
+
}
|
|
1054
|
+
return /* @__PURE__ */ jsx(StyledMenuItem, { $variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
1055
|
+
/* @__PURE__ */ jsx(Cross, { width: "1.6rem", height: "1.6rem" }),
|
|
1056
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
|
|
1057
|
+
id: "content-releases.content-manager-edit-view.remove-from-release",
|
|
1058
|
+
defaultMessage: "Remove from release"
|
|
1059
|
+
}) })
|
|
1060
|
+
] }) });
|
|
1061
|
+
};
|
|
1062
|
+
const ReleaseActionEntryLinkItem = ({
|
|
1063
|
+
contentTypeUid,
|
|
1064
|
+
documentId,
|
|
1065
|
+
locale
|
|
1066
|
+
}) => {
|
|
1067
|
+
const { formatMessage } = useIntl();
|
|
1068
|
+
const userPermissions = useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
|
|
1069
|
+
const canUpdateEntryForLocale = React.useMemo(() => {
|
|
1070
|
+
const updatePermissions = userPermissions.find(
|
|
1071
|
+
(permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
|
|
1072
|
+
);
|
|
1073
|
+
if (!updatePermissions) {
|
|
1074
|
+
return false;
|
|
1075
|
+
}
|
|
1076
|
+
return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
|
|
1077
|
+
}, [contentTypeUid, locale, userPermissions]);
|
|
1078
|
+
const {
|
|
1079
|
+
allowedActions: { canUpdate: canUpdateContentType }
|
|
1080
|
+
} = useRBAC({
|
|
1081
|
+
updateContentType: [
|
|
1082
|
+
{
|
|
1083
|
+
action: "plugin::content-manager.explorer.update",
|
|
1084
|
+
subject: contentTypeUid
|
|
1085
|
+
}
|
|
1086
|
+
]
|
|
1087
|
+
});
|
|
1088
|
+
if (!canUpdateContentType || !canUpdateEntryForLocale) {
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
return /* @__PURE__ */ jsx(
|
|
1092
|
+
StyledMenuItem,
|
|
1093
|
+
{
|
|
1094
|
+
tag: NavLink,
|
|
1095
|
+
isLink: true,
|
|
1096
|
+
to: {
|
|
1097
|
+
pathname: `/content-manager/collection-types/${contentTypeUid}/${documentId}`,
|
|
1098
|
+
search: locale && `?plugins[i18n][locale]=${locale}`
|
|
1099
|
+
},
|
|
1100
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
1101
|
+
/* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" }),
|
|
1102
|
+
/* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
|
|
1103
|
+
id: "content-releases.content-manager-edit-view.edit-entry",
|
|
1104
|
+
defaultMessage: "Edit entry"
|
|
1105
|
+
}) })
|
|
1106
|
+
] })
|
|
1107
|
+
}
|
|
1108
|
+
);
|
|
1109
|
+
};
|
|
1110
|
+
const EditReleaseItem = ({ releaseId }) => {
|
|
1111
|
+
const { formatMessage } = useIntl();
|
|
1112
|
+
return (
|
|
1113
|
+
/* @ts-expect-error inference isn't working in DS */
|
|
1114
|
+
/* @__PURE__ */ jsx(StyledMenuItem, { tag: NavLink, isLink: true, to: `/plugins/content-releases/${releaseId}`, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
1115
|
+
/* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" }),
|
|
1116
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", variant: "omega", children: formatMessage({
|
|
1117
|
+
id: "content-releases.content-manager-edit-view.edit-release",
|
|
1118
|
+
defaultMessage: "Edit release"
|
|
1119
|
+
}) })
|
|
1120
|
+
] }) })
|
|
1121
|
+
);
|
|
1122
|
+
};
|
|
1123
|
+
const Root = ({ children }) => {
|
|
1124
|
+
const { formatMessage } = useIntl();
|
|
1125
|
+
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
1126
|
+
return (
|
|
1127
|
+
// A user can access the dropdown if they have permissions to delete a release-action OR update a release
|
|
1128
|
+
allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxs(Menu.Root, { children: [
|
|
1129
|
+
/* @__PURE__ */ jsx(StyledMoreButton, { variant: "tertiary", endIcon: null, paddingLeft: "7px", paddingRight: "7px", children: /* @__PURE__ */ jsx(
|
|
1130
|
+
AccessibleIcon,
|
|
1131
|
+
{
|
|
1132
|
+
label: formatMessage({
|
|
1133
|
+
id: "content-releases.content-manager-edit-view.release-action-menu",
|
|
1134
|
+
defaultMessage: "Release action options"
|
|
1135
|
+
}),
|
|
1136
|
+
children: /* @__PURE__ */ jsx(More, {})
|
|
1137
|
+
}
|
|
1138
|
+
) }),
|
|
1139
|
+
/* @__PURE__ */ jsx(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
|
|
1140
|
+
] }) : null
|
|
1141
|
+
);
|
|
1142
|
+
};
|
|
1143
|
+
const StyledMoreButton = styled(Menu.Trigger)`
|
|
1144
|
+
& > span {
|
|
1145
|
+
display: flex;
|
|
1146
|
+
}
|
|
1147
|
+
`;
|
|
1148
|
+
const ReleaseActionMenu = {
|
|
1149
|
+
Root,
|
|
1150
|
+
EditReleaseItem,
|
|
1151
|
+
DeleteReleaseActionItem,
|
|
1152
|
+
ReleaseActionEntryLinkItem
|
|
1153
|
+
};
|
|
1154
|
+
const Panel = ({
|
|
1155
|
+
model,
|
|
1156
|
+
document,
|
|
1157
|
+
documentId,
|
|
1158
|
+
collectionType
|
|
1159
|
+
}) => {
|
|
1160
|
+
const [{ query }] = useQueryParams();
|
|
1161
|
+
const locale = query.plugins?.i18n?.locale;
|
|
1162
|
+
const {
|
|
1163
|
+
edit: { options }
|
|
1164
|
+
} = unstable_useDocumentLayout(model);
|
|
1165
|
+
const { formatMessage, formatDate, formatTime } = useIntl();
|
|
1166
|
+
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
1167
|
+
const { canRead, canDeleteAction } = allowedActions;
|
|
1168
|
+
const response = useGetReleasesForEntryQuery(
|
|
1169
|
+
{
|
|
1170
|
+
contentType: model,
|
|
1171
|
+
entryDocumentId: documentId,
|
|
1172
|
+
locale,
|
|
1173
|
+
hasEntryAttached: true
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
skip: !document
|
|
1177
|
+
}
|
|
1178
|
+
);
|
|
1179
|
+
const releases = response.data?.data;
|
|
1180
|
+
const getReleaseColorVariant = (actionType, shade) => {
|
|
1181
|
+
if (actionType === "unpublish") {
|
|
1182
|
+
return `secondary${shade}`;
|
|
1183
|
+
}
|
|
1184
|
+
return `success${shade}`;
|
|
1185
|
+
};
|
|
1186
|
+
if (!window.strapi.isEE || !options?.draftAndPublish || !canRead) {
|
|
1187
|
+
return null;
|
|
1188
|
+
}
|
|
1189
|
+
if (collectionType === "collection-types" && (!documentId || documentId === "create")) {
|
|
1190
|
+
return null;
|
|
1191
|
+
}
|
|
1192
|
+
if (!releases || releases.length === 0) {
|
|
1193
|
+
return null;
|
|
1194
|
+
}
|
|
1195
|
+
return {
|
|
1196
|
+
title: formatMessage({
|
|
1197
|
+
id: "content-releases.plugin.name",
|
|
1198
|
+
defaultMessage: "Releases"
|
|
1199
|
+
}),
|
|
1200
|
+
content: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 3, width: "100%", children: releases?.map((release) => /* @__PURE__ */ jsxs(
|
|
1201
|
+
Flex,
|
|
1202
|
+
{
|
|
1203
|
+
direction: "column",
|
|
1204
|
+
alignItems: "start",
|
|
1205
|
+
borderWidth: "1px",
|
|
1206
|
+
borderStyle: "solid",
|
|
1207
|
+
borderColor: getReleaseColorVariant(release.actions[0].type, "200"),
|
|
1208
|
+
overflow: "hidden",
|
|
1209
|
+
hasRadius: true,
|
|
1210
|
+
children: [
|
|
1211
|
+
/* @__PURE__ */ jsx(
|
|
1212
|
+
Box,
|
|
1213
|
+
{
|
|
1214
|
+
paddingTop: 3,
|
|
1215
|
+
paddingBottom: 3,
|
|
1216
|
+
paddingLeft: 4,
|
|
1217
|
+
paddingRight: 4,
|
|
1218
|
+
background: getReleaseColorVariant(release.actions[0].type, "100"),
|
|
1219
|
+
width: "100%",
|
|
1220
|
+
children: /* @__PURE__ */ jsx(
|
|
1221
|
+
Typography,
|
|
1222
|
+
{
|
|
1223
|
+
fontSize: 1,
|
|
1224
|
+
variant: "pi",
|
|
1225
|
+
textColor: getReleaseColorVariant(release.actions[0].type, "600"),
|
|
1226
|
+
children: formatMessage(
|
|
1227
|
+
{
|
|
1228
|
+
id: "content-releases.content-manager-edit-view.list-releases.title",
|
|
1229
|
+
defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
|
|
1230
|
+
},
|
|
1231
|
+
{ isPublish: release.actions[0].type === "publish" }
|
|
1232
|
+
)
|
|
1233
|
+
}
|
|
1234
|
+
)
|
|
1235
|
+
}
|
|
1236
|
+
),
|
|
1237
|
+
/* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
|
|
1238
|
+
/* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
|
|
1239
|
+
release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
|
|
1240
|
+
{
|
|
1241
|
+
id: "content-releases.content-manager-edit-view.scheduled.date",
|
|
1242
|
+
defaultMessage: "{date} at {time} ({offset})"
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
date: formatDate(new Date(release.scheduledAt), {
|
|
1246
|
+
day: "2-digit",
|
|
1247
|
+
month: "2-digit",
|
|
1248
|
+
year: "numeric",
|
|
1249
|
+
timeZone: release.timezone
|
|
1250
|
+
}),
|
|
1251
|
+
time: formatTime(new Date(release.scheduledAt), {
|
|
1252
|
+
hourCycle: "h23",
|
|
1253
|
+
timeZone: release.timezone
|
|
1254
|
+
}),
|
|
1255
|
+
offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
|
|
1256
|
+
}
|
|
1257
|
+
) }),
|
|
1258
|
+
canDeleteAction ? /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
|
|
1259
|
+
/* @__PURE__ */ jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
|
|
1260
|
+
/* @__PURE__ */ jsx(
|
|
1261
|
+
ReleaseActionMenu.DeleteReleaseActionItem,
|
|
1262
|
+
{
|
|
1263
|
+
releaseId: release.id,
|
|
1264
|
+
actionId: release.actions[0].id
|
|
1265
|
+
}
|
|
1266
|
+
)
|
|
1267
|
+
] }) : null
|
|
1268
|
+
] })
|
|
1269
|
+
]
|
|
1270
|
+
},
|
|
1271
|
+
release.id
|
|
1272
|
+
)) })
|
|
1273
|
+
};
|
|
1274
|
+
};
|
|
1275
|
+
const pluginId = "content-releases";
|
|
1276
|
+
const prefixPluginTranslations = (trad, pluginId2) => {
|
|
1153
1277
|
return Object.keys(trad).reduce((acc, current) => {
|
|
1154
1278
|
acc[`${pluginId2}.${current}`] = trad[current];
|
|
1155
1279
|
return acc;
|
|
@@ -1167,43 +1291,63 @@ const admin = {
|
|
|
1167
1291
|
id: `${pluginId}.plugin.name`,
|
|
1168
1292
|
defaultMessage: "Releases"
|
|
1169
1293
|
},
|
|
1170
|
-
Component: () => import("./App-
|
|
1171
|
-
permissions: PERMISSIONS.main
|
|
1172
|
-
|
|
1173
|
-
app.addMiddlewares([() => releaseApi.middleware]);
|
|
1174
|
-
app.addReducers({
|
|
1175
|
-
[releaseApi.reducerPath]: releaseApi.reducer
|
|
1294
|
+
Component: () => import("./App-CiZCkScI.mjs").then((mod) => ({ default: mod.App })),
|
|
1295
|
+
permissions: PERMISSIONS.main,
|
|
1296
|
+
position: 2
|
|
1176
1297
|
});
|
|
1177
|
-
app.getPlugin("content-manager").
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1298
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
|
1299
|
+
if ("addEditViewSidePanel" in contentManagerPluginApis && typeof contentManagerPluginApis.addEditViewSidePanel === "function") {
|
|
1300
|
+
contentManagerPluginApis.addEditViewSidePanel([Panel]);
|
|
1301
|
+
}
|
|
1302
|
+
if ("addDocumentAction" in contentManagerPluginApis && typeof contentManagerPluginApis.addDocumentAction === "function") {
|
|
1303
|
+
contentManagerPluginApis.addDocumentAction((actions) => {
|
|
1304
|
+
const indexOfDeleteAction = actions.findIndex((action) => action.type === "unpublish");
|
|
1305
|
+
actions.splice(indexOfDeleteAction, 0, ReleaseActionModalForm);
|
|
1306
|
+
return actions;
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
app.addSettingsLink("global", {
|
|
1310
|
+
id: pluginId,
|
|
1311
|
+
to: "releases",
|
|
1312
|
+
intlLabel: {
|
|
1313
|
+
id: `${pluginId}.plugin.name`,
|
|
1314
|
+
defaultMessage: "Releases"
|
|
1315
|
+
},
|
|
1316
|
+
permissions: [],
|
|
1317
|
+
async Component() {
|
|
1318
|
+
const { ProtectedReleasesSettingsPage } = await import("./ReleasesSettingsPage-DQT8N3A-.mjs");
|
|
1319
|
+
return { default: ProtectedReleasesSettingsPage };
|
|
1320
|
+
}
|
|
1185
1321
|
});
|
|
1322
|
+
if ("addBulkAction" in contentManagerPluginApis && typeof contentManagerPluginApis.addBulkAction === "function") {
|
|
1323
|
+
contentManagerPluginApis.addBulkAction((actions) => {
|
|
1324
|
+
const deleteActionIndex = actions.findIndex((action) => action.type === "delete");
|
|
1325
|
+
actions.splice(deleteActionIndex, 0, ReleaseAction);
|
|
1326
|
+
return actions;
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
app.registerHook("Admin/CM/pages/ListView/inject-column-in-table", addColumnToTableHook);
|
|
1186
1330
|
} else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
|
|
1187
|
-
app.
|
|
1188
|
-
|
|
1189
|
-
|
|
1331
|
+
app.addSettingsLink("global", {
|
|
1332
|
+
id: pluginId,
|
|
1333
|
+
to: "/plugins/purchase-content-releases",
|
|
1190
1334
|
intlLabel: {
|
|
1191
1335
|
id: `${pluginId}.plugin.name`,
|
|
1192
1336
|
defaultMessage: "Releases"
|
|
1193
1337
|
},
|
|
1194
1338
|
permissions: [],
|
|
1195
1339
|
async Component() {
|
|
1196
|
-
const { PurchaseContentReleases } = await import("./PurchaseContentReleases-
|
|
1340
|
+
const { PurchaseContentReleases } = await import("./PurchaseContentReleases-D-n-w-st.mjs");
|
|
1197
1341
|
return { default: PurchaseContentReleases };
|
|
1198
1342
|
},
|
|
1199
|
-
|
|
1343
|
+
licenseOnly: true
|
|
1200
1344
|
});
|
|
1201
1345
|
}
|
|
1202
1346
|
},
|
|
1203
1347
|
async registerTrads({ locales }) {
|
|
1204
1348
|
const importedTrads = await Promise.all(
|
|
1205
1349
|
locales.map((locale) => {
|
|
1206
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-
|
|
1350
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-D9Q4YW03.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
|
1207
1351
|
return {
|
|
1208
1352
|
data: prefixPluginTranslations(data, "content-releases"),
|
|
1209
1353
|
locale
|
|
@@ -1222,19 +1366,21 @@ const admin = {
|
|
|
1222
1366
|
export {
|
|
1223
1367
|
PERMISSIONS as P,
|
|
1224
1368
|
ReleaseActionOptions as R,
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1369
|
+
useGetReleaseSettingsQuery as a,
|
|
1370
|
+
useCreateReleaseMutation as b,
|
|
1371
|
+
useGetReleaseQuery as c,
|
|
1372
|
+
useUpdateReleaseMutation as d,
|
|
1373
|
+
useDeleteReleaseMutation as e,
|
|
1374
|
+
usePublishReleaseMutation as f,
|
|
1375
|
+
getTimezones as g,
|
|
1376
|
+
getTimezoneOffset as h,
|
|
1377
|
+
useGetReleaseActionsQuery as i,
|
|
1378
|
+
useUpdateReleaseActionMutation as j,
|
|
1379
|
+
ReleaseActionMenu as k,
|
|
1380
|
+
useUpdateReleaseSettingsMutation as l,
|
|
1381
|
+
admin as m,
|
|
1236
1382
|
pluginId as p,
|
|
1237
1383
|
releaseApi as r,
|
|
1238
1384
|
useGetReleasesQuery as u
|
|
1239
1385
|
};
|
|
1240
|
-
//# sourceMappingURL=index-
|
|
1386
|
+
//# sourceMappingURL=index-BjvFfTtA.mjs.map
|