@webiny/app-headless-cms-scheduler 6.4.12-beta.5 → 6.5.0-beta.0

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 (63) hide show
  1. package/components/Browser/BrowserConfig.js +12 -1
  2. package/components/Browser/BrowserConfig.js.map +1 -1
  3. package/components/Browser/CellLive.d.ts +11 -0
  4. package/components/Browser/CellLive.js +37 -0
  5. package/components/Browser/CellLive.js.map +1 -0
  6. package/components/Browser/LiveTag.d.ts +7 -0
  7. package/components/Browser/LiveTag.js +19 -0
  8. package/components/Browser/LiveTag.js.map +1 -0
  9. package/components/Browser/MenuItem.d.ts +3 -1
  10. package/components/Browser/MenuItem.js +12 -10
  11. package/components/Browser/MenuItem.js.map +1 -1
  12. package/components/Browser/ScheduledTag.d.ts +5 -0
  13. package/components/Browser/ScheduledTag.js +24 -0
  14. package/components/Browser/ScheduledTag.js.map +1 -0
  15. package/components/{Sidebar → Browser}/SchedulerButton.js.map +1 -1
  16. package/components/Browser/SchedulerMenuItem.d.ts +2 -0
  17. package/components/Browser/SchedulerMenuItem.js +26 -0
  18. package/components/Browser/SchedulerMenuItem.js.map +1 -0
  19. package/components/Browser/isScheduleRedundant.d.ts +12 -0
  20. package/components/Browser/isScheduleRedundant.js +8 -0
  21. package/components/Browser/isScheduleRedundant.js.map +1 -0
  22. package/components/Dialogs/PublishScheduleNotice.d.ts +6 -0
  23. package/components/Dialogs/PublishScheduleNotice.js +17 -0
  24. package/components/Dialogs/PublishScheduleNotice.js.map +1 -0
  25. package/components/Dialogs/ScheduleNoticeAlert.d.ts +14 -0
  26. package/components/Dialogs/ScheduleNoticeAlert.js +22 -0
  27. package/components/Dialogs/ScheduleNoticeAlert.js.map +1 -0
  28. package/components/Dialogs/UnpublishScheduleNotice.d.ts +6 -0
  29. package/components/Dialogs/UnpublishScheduleNotice.js +17 -0
  30. package/components/Dialogs/UnpublishScheduleNotice.js.map +1 -0
  31. package/components/Editor/EditorConfig.js +4 -4
  32. package/components/Editor/EditorConfig.js.map +1 -1
  33. package/components/Editor/MenuItem.d.ts +3 -1
  34. package/components/Editor/MenuItem.js +27 -21
  35. package/components/Editor/MenuItem.js.map +1 -1
  36. package/components/Editor/ScheduledActionAlert.d.ts +6 -0
  37. package/components/Editor/ScheduledActionAlert.js +43 -0
  38. package/components/Editor/ScheduledActionAlert.js.map +1 -0
  39. package/components/index.d.ts +3 -1
  40. package/components/index.js +3 -1
  41. package/hooks/useScheduledActionsPresenter.d.ts +6 -0
  42. package/hooks/useScheduledActionsPresenter.js +12 -0
  43. package/hooks/useScheduledActionsPresenter.js.map +1 -0
  44. package/index.js +6 -2
  45. package/index.js.map +1 -1
  46. package/package.json +13 -9
  47. package/presentation/scheduledActions/ContentEntriesPresenterSchedulingDecorator.d.ts +30 -0
  48. package/presentation/scheduledActions/ContentEntriesPresenterSchedulingDecorator.js +67 -0
  49. package/presentation/scheduledActions/ContentEntriesPresenterSchedulingDecorator.js.map +1 -0
  50. package/presentation/scheduledActions/ScheduledActionsPresenter.d.ts +28 -0
  51. package/presentation/scheduledActions/ScheduledActionsPresenter.js +90 -0
  52. package/presentation/scheduledActions/ScheduledActionsPresenter.js.map +1 -0
  53. package/presentation/scheduledActions/abstractions.d.ts +16 -0
  54. package/presentation/scheduledActions/abstractions.js +5 -0
  55. package/presentation/scheduledActions/abstractions.js.map +1 -0
  56. package/presentation/scheduledActions/feature.d.ts +3 -0
  57. package/presentation/scheduledActions/feature.js +19 -0
  58. package/presentation/scheduledActions/feature.js.map +1 -0
  59. package/components/Sidebar/Sidebar.d.ts +0 -2
  60. package/components/Sidebar/Sidebar.js +0 -27
  61. package/components/Sidebar/Sidebar.js.map +0 -1
  62. /package/components/{Sidebar → Browser}/SchedulerButton.d.ts +0 -0
  63. /package/components/{Sidebar → Browser}/SchedulerButton.js +0 -0
@@ -2,10 +2,21 @@ import react from "react";
2
2
  import { IsModelPublishable } from "@webiny/app-headless-cms/exports/admin/cms.js";
3
3
  import { ContentEntryListConfig } from "@webiny/app-headless-cms/admin/config/contentEntries/index.js";
4
4
  import { MenuItem } from "./MenuItem.js";
5
+ import { SchedulerMenuItem } from "./SchedulerMenuItem.js";
6
+ import { CellLive } from "./CellLive.js";
5
7
  const { Browser: Browser } = ContentEntryListConfig;
6
- const BrowserConfig = ()=>/*#__PURE__*/ react.createElement(ContentEntryListConfig, null, /*#__PURE__*/ react.createElement(IsModelPublishable, null, /*#__PURE__*/ react.createElement(Browser.Entry.Action, {
8
+ const BrowserConfig = ()=>/*#__PURE__*/ react.createElement(ContentEntryListConfig, null, /*#__PURE__*/ react.createElement(IsModelPublishable, null, /*#__PURE__*/ react.createElement(Browser.Sidebar.Footer, {
9
+ name: "scheduler",
10
+ element: /*#__PURE__*/ react.createElement(SchedulerMenuItem, null)
11
+ }), /*#__PURE__*/ react.createElement(Browser.Entry.Action, {
7
12
  name: "schedule",
8
13
  element: /*#__PURE__*/ react.createElement(MenuItem, null)
14
+ }), /*#__PURE__*/ react.createElement(Browser.Table.Column, {
15
+ name: "live",
16
+ header: "Live",
17
+ truncate: false,
18
+ sortable: true,
19
+ cell: /*#__PURE__*/ react.createElement(CellLive, null)
9
20
  })));
10
21
  export { BrowserConfig };
11
22
 
@@ -1 +1 @@
1
- {"version":3,"file":"components/Browser/BrowserConfig.js","sources":["../../../src/components/Browser/BrowserConfig.tsx"],"sourcesContent":["import React from \"react\";\nimport { IsModelPublishable } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { ContentEntryListConfig } from \"@webiny/app-headless-cms/admin/config/contentEntries/index.js\";\nimport { MenuItem } from \"./MenuItem.js\";\n\nconst { Browser } = ContentEntryListConfig;\n\nexport const BrowserConfig = () => {\n return (\n <ContentEntryListConfig>\n <IsModelPublishable>\n <Browser.Entry.Action name={\"schedule\"} element={<MenuItem />} />\n </IsModelPublishable>\n </ContentEntryListConfig>\n );\n};\n"],"names":["Browser","ContentEntryListConfig","BrowserConfig","IsModelPublishable","MenuItem"],"mappings":";;;;AAKA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAEb,MAAMC,gBAAgB,IAClB,WAAP,GACI,oBAACD,wBAAsBA,MAAAA,WAAAA,GACnB,oBAACE,oBAAkBA,MAAAA,WAAAA,GACf,oBAACH,QAAQ,KAAK,CAAC,MAAM;QAAC,MAAM;QAAY,uBAAS,oBAACI,UAAQA"}
1
+ {"version":3,"file":"components/Browser/BrowserConfig.js","sources":["../../../src/components/Browser/BrowserConfig.tsx"],"sourcesContent":["import React from \"react\";\nimport { IsModelPublishable } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { ContentEntryListConfig } from \"@webiny/app-headless-cms/admin/config/contentEntries/index.js\";\nimport { MenuItem } from \"./MenuItem.js\";\nimport { SchedulerMenuItem } from \"./SchedulerMenuItem.js\";\nimport { CellLive } from \"./CellLive.js\";\n\nconst { Browser } = ContentEntryListConfig;\n\nexport const BrowserConfig = () => {\n return (\n <ContentEntryListConfig>\n <IsModelPublishable>\n <Browser.Sidebar.Footer name={\"scheduler\"} element={<SchedulerMenuItem />} />\n <Browser.Entry.Action name={\"schedule\"} element={<MenuItem />} />\n {/* Override the core \"Live\" column cell to surface scheduled actions. Same column\n name merges over the core (primary) definition from the public (secondary)\n config, replacing only the cell. */}\n <Browser.Table.Column\n name={\"live\"}\n header={\"Live\"}\n truncate={false}\n sortable={true}\n cell={<CellLive />}\n />\n </IsModelPublishable>\n </ContentEntryListConfig>\n );\n};\n"],"names":["Browser","ContentEntryListConfig","BrowserConfig","IsModelPublishable","SchedulerMenuItem","MenuItem","CellLive"],"mappings":";;;;;;AAOA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAEb,MAAMC,gBAAgB,IAClB,WAAP,GACI,oBAACD,wBAAsBA,MAAAA,WAAAA,GACnB,oBAACE,oBAAkBA,MAAAA,WAAAA,GACf,oBAACH,QAAQ,OAAO,CAAC,MAAM;QAAC,MAAM;QAAa,uBAAS,oBAACI,mBAAiBA;sBACtE,oBAACJ,QAAQ,KAAK,CAAC,MAAM;QAAC,MAAM;QAAY,uBAAS,oBAACK,UAAQA;sBAI1D,oBAACL,QAAQ,KAAK,CAAC,MAAM;QACjB,MAAM;QACN,QAAQ;QACR,UAAU;QACV,UAAU;QACV,oBAAM,oBAACM,UAAQA"}
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ /**
3
+ * Overrides the CMS "Live" column cell to surface scheduled publish/unpublish actions.
4
+ *
5
+ * The data comes from ScheduledActionsPresenter, which the content-entries list presenter decorator
6
+ * keeps loaded for the current model. An entry can be live AND have a scheduled action (e.g. a new
7
+ * revision scheduled to publish), so both are shown when both apply.
8
+ */
9
+ export declare const CellLive: (() => React.JSX.Element) & {
10
+ displayName: string;
11
+ };
@@ -0,0 +1,37 @@
1
+ import react from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { ContentEntryListConfig } from "@webiny/app-headless-cms/admin/config/contentEntries/index.js";
4
+ import { useScheduledActionsPresenter } from "../../hooks/useScheduledActionsPresenter.js";
5
+ import { LiveTag } from "./LiveTag.js";
6
+ import { ScheduledTag } from "./ScheduledTag.js";
7
+ import { isScheduleRedundant } from "./isScheduleRedundant.js";
8
+ const CellLive = observer(()=>{
9
+ const { useTableRow, isFolderRow } = ContentEntryListConfig.Browser.Table.Column;
10
+ const { row } = useTableRow();
11
+ const presenter = useScheduledActionsPresenter();
12
+ if (isFolderRow(row)) return /*#__PURE__*/ react.createElement(react.Fragment, null, "-");
13
+ const entry = row.data;
14
+ const liveVersion = entry.live?.version;
15
+ const rawScheduled = presenter.getScheduledAction(entry.id);
16
+ const scheduled = rawScheduled && !isScheduleRedundant(rawScheduled, liveVersion, entry.meta?.version) ? rawScheduled : void 0;
17
+ const lastPublishedOn = entry.lastPublishedOn;
18
+ if (liveVersion && scheduled) return /*#__PURE__*/ react.createElement("div", {
19
+ className: "flex flex-wrap items-center gap-xs"
20
+ }, /*#__PURE__*/ react.createElement(LiveTag, {
21
+ version: liveVersion,
22
+ lastPublishedOn: lastPublishedOn
23
+ }), /*#__PURE__*/ react.createElement(ScheduledTag, {
24
+ scheduled: scheduled
25
+ }));
26
+ if (scheduled) return /*#__PURE__*/ react.createElement(ScheduledTag, {
27
+ scheduled: scheduled
28
+ });
29
+ if (!liveVersion) return /*#__PURE__*/ react.createElement(react.Fragment, null, "No");
30
+ return /*#__PURE__*/ react.createElement(LiveTag, {
31
+ version: liveVersion,
32
+ lastPublishedOn: lastPublishedOn
33
+ });
34
+ });
35
+ export { CellLive };
36
+
37
+ //# sourceMappingURL=CellLive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Browser/CellLive.js","sources":["../../../src/components/Browser/CellLive.tsx"],"sourcesContent":["import React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { ContentEntryListConfig } from \"@webiny/app-headless-cms/admin/config/contentEntries/index.js\";\nimport { useScheduledActionsPresenter } from \"~/hooks/useScheduledActionsPresenter.js\";\nimport { LiveTag } from \"./LiveTag.js\";\nimport { ScheduledTag } from \"./ScheduledTag.js\";\nimport { isScheduleRedundant } from \"./isScheduleRedundant.js\";\n\n/**\n * Overrides the CMS \"Live\" column cell to surface scheduled publish/unpublish actions.\n *\n * The data comes from ScheduledActionsPresenter, which the content-entries list presenter decorator\n * keeps loaded for the current model. An entry can be live AND have a scheduled action (e.g. a new\n * revision scheduled to publish), so both are shown when both apply.\n */\nexport const CellLive = observer(() => {\n const { useTableRow, isFolderRow } = ContentEntryListConfig.Browser.Table.Column;\n const { row } = useTableRow();\n const presenter = useScheduledActionsPresenter();\n\n if (isFolderRow(row)) {\n return <>{\"-\"}</>;\n }\n\n const entry = row.data;\n const liveVersion = entry.live?.version;\n\n const rawScheduled = presenter.getScheduledAction(entry.id);\n // Ignore a scheduled action the entry's current state has already made redundant (see helper).\n const scheduled =\n rawScheduled && !isScheduleRedundant(rawScheduled, liveVersion, entry.meta?.version)\n ? rawScheduled\n : undefined;\n\n const lastPublishedOn = entry.lastPublishedOn;\n\n // Live now AND a change scheduled — show both, wrapping to a second line if the column is narrow.\n if (liveVersion && scheduled) {\n return (\n <div className={\"flex flex-wrap items-center gap-xs\"}>\n <LiveTag version={liveVersion} lastPublishedOn={lastPublishedOn} />\n <ScheduledTag scheduled={scheduled} />\n </div>\n );\n }\n\n if (scheduled) {\n return <ScheduledTag scheduled={scheduled} />;\n }\n\n if (!liveVersion) {\n return <>No</>;\n }\n\n return <LiveTag version={liveVersion} lastPublishedOn={lastPublishedOn} />;\n});\n"],"names":["CellLive","observer","useTableRow","isFolderRow","ContentEntryListConfig","row","presenter","useScheduledActionsPresenter","entry","liveVersion","rawScheduled","scheduled","isScheduleRedundant","undefined","lastPublishedOn","LiveTag","ScheduledTag"],"mappings":";;;;;;;AAeO,MAAMA,WAAWC,SAAS;IAC7B,MAAM,EAAEC,WAAW,EAAEC,WAAW,EAAE,GAAGC,uBAAuB,OAAO,CAAC,KAAK,CAAC,MAAM;IAChF,MAAM,EAAEC,GAAG,EAAE,GAAGH;IAChB,MAAMI,YAAYC;IAElB,IAAIJ,YAAYE,MACZ,OAAO,WAAP,GAAO,0CAAG;IAGd,MAAMG,QAAQH,IAAI,IAAI;IACtB,MAAMI,cAAcD,MAAM,IAAI,EAAE;IAEhC,MAAME,eAAeJ,UAAU,kBAAkB,CAACE,MAAM,EAAE;IAE1D,MAAMG,YACFD,gBAAgB,CAACE,oBAAoBF,cAAcD,aAAaD,MAAM,IAAI,EAAE,WACtEE,eACAG;IAEV,MAAMC,kBAAkBN,MAAM,eAAe;IAG7C,IAAIC,eAAeE,WACf,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACI,SAAOA;QAAC,SAASN;QAAa,iBAAiBK;sBAChD,oBAACE,cAAYA;QAAC,WAAWL;;IAKrC,IAAIA,WACA,OAAO,WAAP,GAAO,oBAACK,cAAYA;QAAC,WAAWL;;IAGpC,IAAI,CAACF,aACD,OAAO,WAAP,GAAO,0CAAE;IAGb,OAAO,WAAP,GAAO,oBAACM,SAAOA;QAAC,SAASN;QAAa,iBAAiBK;;AAC3D"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ interface LiveTagProps {
3
+ version: number;
4
+ lastPublishedOn?: string | null;
5
+ }
6
+ export declare const LiveTag: ({ version, lastPublishedOn }: LiveTagProps) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,19 @@
1
+ import react from "react";
2
+ import { Tag, Tooltip } from "@webiny/admin-ui";
3
+ import { formatUtcOffset, useDateFormatter } from "@webiny/app-admin";
4
+ const LiveTag = ({ version, lastPublishedOn })=>{
5
+ const dateFormatter = useDateFormatter();
6
+ const tag = /*#__PURE__*/ react.createElement(Tag, {
7
+ swatchColor: "#5AC84C",
8
+ variant: "success-light",
9
+ content: `Live (v${version})`
10
+ });
11
+ if (lastPublishedOn) return /*#__PURE__*/ react.createElement(Tooltip, {
12
+ content: `Published ${dateFormatter.format(lastPublishedOn)} (${formatUtcOffset()})`,
13
+ trigger: tag
14
+ });
15
+ return tag;
16
+ };
17
+ export { LiveTag };
18
+
19
+ //# sourceMappingURL=LiveTag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Browser/LiveTag.js","sources":["../../../src/components/Browser/LiveTag.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tag, Tooltip } from \"@webiny/admin-ui\";\nimport { formatUtcOffset, useDateFormatter } from \"@webiny/app-admin\";\n\ninterface LiveTagProps {\n version: number;\n lastPublishedOn?: string | null;\n}\n\nexport const LiveTag = ({ version, lastPublishedOn }: LiveTagProps) => {\n const dateFormatter = useDateFormatter();\n\n const tag = (\n <Tag swatchColor={\"#5AC84C\"} variant={\"success-light\"} content={`Live (v${version})`} />\n );\n\n if (lastPublishedOn) {\n return (\n <Tooltip\n content={`Published ${dateFormatter.format(lastPublishedOn)} (${formatUtcOffset()})`}\n trigger={tag}\n />\n );\n }\n\n return tag;\n};\n"],"names":["LiveTag","version","lastPublishedOn","dateFormatter","useDateFormatter","tag","Tag","Tooltip","formatUtcOffset"],"mappings":";;;AASO,MAAMA,UAAU,CAAC,EAAEC,OAAO,EAAEC,eAAe,EAAgB;IAC9D,MAAMC,gBAAgBC;IAEtB,MAAMC,MAAM,WAANA,GACF,oBAACC,KAAGA;QAAC,aAAa;QAAW,SAAS;QAAiB,SAAS,CAAC,OAAO,EAAEL,QAAQ,CAAC,CAAC;;IAGxF,IAAIC,iBACA,OAAO,WAAP,GACI,oBAACK,SAAOA;QACJ,SAAS,CAAC,UAAU,EAAEJ,cAAc,MAAM,CAACD,iBAAiB,EAAE,EAAEM,kBAAkB,CAAC,CAAC;QACpF,SAASH;;IAKrB,OAAOA;AACX"}
@@ -1,2 +1,4 @@
1
1
  import React from "react";
2
- export declare const MenuItem: () => React.JSX.Element | null;
2
+ export declare const MenuItem: (() => React.JSX.Element | null) & {
3
+ displayName: string;
4
+ };
@@ -1,26 +1,28 @@
1
1
  import react, { useCallback } from "react";
2
+ import { observer } from "mobx-react-lite";
2
3
  import { ReactComponent } from "@webiny/icons/cell_tower.svg";
3
- import { useApolloClient } from "@apollo/react-hooks";
4
4
  import { useScheduleDialog } from "@webiny/app-scheduler";
5
+ import { ContentEntryListConfig } from "@webiny/app-headless-cms/exports/admin/cms/entry/list.js";
6
+ import { useEntry } from "@webiny/app-headless-cms";
7
+ import { useModel } from "@webiny/app-headless-cms/exports/admin/cms.js";
5
8
  import { usePermissions } from "../../hooks/usePermissions.js";
6
9
  import { createNamespace } from "../../utils/index.js";
7
- import { ContentEntryListConfig, useContentEntriesList } from "@webiny/app-headless-cms/exports/admin/cms/entry/list.js";
8
- import { useEntry } from "@webiny/app-headless-cms";
9
- const MenuItem = ()=>{
10
- const { modelId } = useContentEntriesList();
10
+ import { useScheduledActionsPresenter } from "../../hooks/useScheduledActionsPresenter.js";
11
+ const MenuItem = observer(()=>{
12
+ const { model } = useModel();
11
13
  const { entry } = useEntry();
14
+ const scheduledActions = useScheduledActionsPresenter();
12
15
  const { canPublish, canUnpublish } = usePermissions();
13
- const client = useApolloClient();
14
16
  const { showDialog: showSchedulerDialog } = useScheduleDialog({
15
- client,
16
17
  namespace: createNamespace({
17
- modelId
18
+ modelId: model.modelId
18
19
  }),
19
20
  target: {
20
21
  id: entry.id,
21
22
  title: entry.meta.title,
22
23
  status: entry.meta.status
23
- }
24
+ },
25
+ onCompleted: ()=>scheduledActions.reload()
24
26
  });
25
27
  const { OptionsMenuItem } = ContentEntryListConfig.Browser.Entry.Action;
26
28
  const showDialog = useCallback(()=>{
@@ -37,7 +39,7 @@ const MenuItem = ()=>{
37
39
  disabled: !entry?.meta?.status,
38
40
  "data-testid": "cms.content-form.header.schedule"
39
41
  });
40
- };
42
+ });
41
43
  export { MenuItem };
42
44
 
43
45
  //# sourceMappingURL=MenuItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"components/Browser/MenuItem.js","sources":["../../../src/components/Browser/MenuItem.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { ReactComponent as ScheduleIcon } from \"@webiny/icons/cell_tower.svg\";\nimport { useApolloClient } from \"@apollo/react-hooks\";\nimport { useScheduleDialog } from \"@webiny/app-scheduler\";\nimport { usePermissions } from \"~/hooks/usePermissions.js\";\nimport { createNamespace } from \"~/utils/index.js\";\nimport {\n ContentEntryListConfig,\n useContentEntriesList\n} from \"@webiny/app-headless-cms/exports/admin/cms/entry/list.js\";\nimport { useEntry } from \"@webiny/app-headless-cms\";\n\nexport const MenuItem = () => {\n const { modelId } = useContentEntriesList();\n const { entry } = useEntry();\n\n const { canPublish, canUnpublish } = usePermissions();\n const client = useApolloClient();\n\n const { showDialog: showSchedulerDialog } = useScheduleDialog({\n client,\n namespace: createNamespace({\n modelId\n }),\n target: {\n id: entry.id,\n title: entry.meta.title,\n status: entry.meta.status\n }\n });\n\n const { OptionsMenuItem } = ContentEntryListConfig.Browser.Entry.Action;\n\n const showDialog = useCallback(() => {\n showSchedulerDialog();\n }, [showSchedulerDialog]);\n\n if (!canPublish && !canUnpublish) {\n return null;\n }\n\n const action = entry.meta?.status === \"published\" ? \"unpublish\" : \"publish\";\n\n return (\n <OptionsMenuItem\n icon={<ScheduleIcon />}\n label={`Schedule ${action}`}\n onAction={showDialog}\n disabled={!entry?.meta?.status}\n data-testid={\"cms.content-form.header.schedule\"}\n />\n );\n};\n"],"names":["MenuItem","modelId","useContentEntriesList","entry","useEntry","canPublish","canUnpublish","usePermissions","client","useApolloClient","showSchedulerDialog","useScheduleDialog","createNamespace","OptionsMenuItem","ContentEntryListConfig","showDialog","useCallback","action","ScheduleIcon"],"mappings":";;;;;;;;AAYO,MAAMA,WAAW;IACpB,MAAM,EAAEC,OAAO,EAAE,GAAGC;IACpB,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAElB,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC;IACrC,MAAMC,SAASC;IAEf,MAAM,EAAE,YAAYC,mBAAmB,EAAE,GAAGC,kBAAkB;QAC1DH;QACA,WAAWI,gBAAgB;YACvBX;QACJ;QACA,QAAQ;YACJ,IAAIE,MAAM,EAAE;YACZ,OAAOA,MAAM,IAAI,CAAC,KAAK;YACvB,QAAQA,MAAM,IAAI,CAAC,MAAM;QAC7B;IACJ;IAEA,MAAM,EAAEU,eAAe,EAAE,GAAGC,uBAAuB,OAAO,CAAC,KAAK,CAAC,MAAM;IAEvE,MAAMC,aAAaC,YAAY;QAC3BN;IACJ,GAAG;QAACA;KAAoB;IAExB,IAAI,CAACL,cAAc,CAACC,cAChB,OAAO;IAGX,MAAMW,SAASd,MAAM,IAAI,EAAE,WAAW,cAAc,cAAc;IAElE,OAAO,WAAP,GACI,oBAACU,iBAAAA;QACG,oBAAM,oBAACK,gBAAYA;QACnB,OAAO,CAAC,SAAS,EAAED,QAAQ;QAC3B,UAAUF;QACV,UAAU,CAACZ,OAAO,MAAM;QACxB,eAAa;;AAGzB"}
1
+ {"version":3,"file":"components/Browser/MenuItem.js","sources":["../../../src/components/Browser/MenuItem.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { ReactComponent as ScheduleIcon } from \"@webiny/icons/cell_tower.svg\";\nimport { useScheduleDialog } from \"@webiny/app-scheduler\";\nimport { ContentEntryListConfig } from \"@webiny/app-headless-cms/exports/admin/cms/entry/list.js\";\nimport { useEntry } from \"@webiny/app-headless-cms\";\nimport { useModel } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { usePermissions } from \"~/hooks/usePermissions.js\";\nimport { createNamespace } from \"~/utils/index.js\";\nimport { useScheduledActionsPresenter } from \"~/hooks/useScheduledActionsPresenter.js\";\n\nexport const MenuItem = observer(() => {\n const { model } = useModel();\n const { entry } = useEntry();\n const scheduledActions = useScheduledActionsPresenter();\n\n const { canPublish, canUnpublish } = usePermissions();\n\n const { showDialog: showSchedulerDialog } = useScheduleDialog({\n namespace: createNamespace({ modelId: model.modelId }),\n target: {\n id: entry.id,\n title: entry.meta.title,\n status: entry.meta.status\n },\n onCompleted: () => scheduledActions.reload()\n });\n\n const { OptionsMenuItem } = ContentEntryListConfig.Browser.Entry.Action;\n\n const showDialog = useCallback(() => {\n showSchedulerDialog();\n }, [showSchedulerDialog]);\n\n if (!canPublish && !canUnpublish) {\n return null;\n }\n\n const action = entry.meta?.status === \"published\" ? \"unpublish\" : \"publish\";\n\n return (\n <OptionsMenuItem\n icon={<ScheduleIcon />}\n label={`Schedule ${action}`}\n onAction={showDialog}\n disabled={!entry?.meta?.status}\n data-testid={\"cms.content-form.header.schedule\"}\n />\n );\n});\n"],"names":["MenuItem","observer","model","useModel","entry","useEntry","scheduledActions","useScheduledActionsPresenter","canPublish","canUnpublish","usePermissions","showSchedulerDialog","useScheduleDialog","createNamespace","OptionsMenuItem","ContentEntryListConfig","showDialog","useCallback","action","ScheduleIcon"],"mappings":";;;;;;;;;;AAWO,MAAMA,WAAWC,SAAS;IAC7B,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAClB,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAClB,MAAMC,mBAAmBC;IAEzB,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC;IAErC,MAAM,EAAE,YAAYC,mBAAmB,EAAE,GAAGC,kBAAkB;QAC1D,WAAWC,gBAAgB;YAAE,SAASX,MAAM,OAAO;QAAC;QACpD,QAAQ;YACJ,IAAIE,MAAM,EAAE;YACZ,OAAOA,MAAM,IAAI,CAAC,KAAK;YACvB,QAAQA,MAAM,IAAI,CAAC,MAAM;QAC7B;QACA,aAAa,IAAME,iBAAiB,MAAM;IAC9C;IAEA,MAAM,EAAEQ,eAAe,EAAE,GAAGC,uBAAuB,OAAO,CAAC,KAAK,CAAC,MAAM;IAEvE,MAAMC,aAAaC,YAAY;QAC3BN;IACJ,GAAG;QAACA;KAAoB;IAExB,IAAI,CAACH,cAAc,CAACC,cAChB,OAAO;IAGX,MAAMS,SAASd,MAAM,IAAI,EAAE,WAAW,cAAc,cAAc;IAElE,OAAO,WAAP,GACI,oBAACU,iBAAAA;QACG,oBAAM,oBAACK,gBAAYA;QACnB,OAAO,CAAC,SAAS,EAAED,QAAQ;QAC3B,UAAUF;QACV,UAAU,CAACZ,OAAO,MAAM;QACxB,eAAa;;AAGzB"}
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import type { SchedulerEntry } from "@webiny/app-scheduler/types.js";
3
+ export declare const ScheduledTag: ({ scheduled }: {
4
+ scheduled: SchedulerEntry;
5
+ }) => React.JSX.Element;
@@ -0,0 +1,24 @@
1
+ import react from "react";
2
+ import { ReactComponent } from "@webiny/icons/access_time.svg";
3
+ import { Tag, Tooltip } from "@webiny/admin-ui";
4
+ import { ScheduleActionType } from "@webiny/app-scheduler/types.js";
5
+ import { formatUtcOffset, useDateFormatter } from "@webiny/app-admin";
6
+ const scheduledTooltip = (scheduled, dateFormatter)=>{
7
+ const goLiveOn = scheduled.publishOn || scheduled.unpublishOn;
8
+ const actionLabel = scheduled.actionType === ScheduleActionType.unpublish ? "unpublish" : "publish";
9
+ return goLiveOn ? `Scheduled to ${actionLabel} on ${dateFormatter.format(goLiveOn)} (${formatUtcOffset()})` : `Scheduled to ${actionLabel}`;
10
+ };
11
+ const ScheduledTag = ({ scheduled })=>{
12
+ const dateFormatter = useDateFormatter();
13
+ return /*#__PURE__*/ react.createElement(Tooltip, {
14
+ content: scheduledTooltip(scheduled, dateFormatter),
15
+ trigger: /*#__PURE__*/ react.createElement(Tag, {
16
+ variant: "warning",
17
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
18
+ content: "Scheduled"
19
+ })
20
+ });
21
+ };
22
+ export { ScheduledTag };
23
+
24
+ //# sourceMappingURL=ScheduledTag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Browser/ScheduledTag.js","sources":["../../../src/components/Browser/ScheduledTag.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as ScheduledIcon } from \"@webiny/icons/access_time.svg\";\nimport { Tag, Tooltip } from \"@webiny/admin-ui\";\nimport { ScheduleActionType } from \"@webiny/app-scheduler/types.js\";\nimport type { SchedulerEntry } from \"@webiny/app-scheduler/types.js\";\nimport { useDateFormatter } from \"@webiny/app-admin\";\nimport type { DateFormatter } from \"@webiny/app-admin\";\nimport { formatUtcOffset } from \"@webiny/app-admin\";\n\nconst scheduledTooltip = (\n scheduled: SchedulerEntry,\n dateFormatter: DateFormatter.Interface\n): string => {\n const goLiveOn = scheduled.publishOn || scheduled.unpublishOn;\n const actionLabel =\n scheduled.actionType === ScheduleActionType.unpublish ? \"unpublish\" : \"publish\";\n return goLiveOn\n ? `Scheduled to ${actionLabel} on ${dateFormatter.format(goLiveOn)} (${formatUtcOffset()})`\n : `Scheduled to ${actionLabel}`;\n};\n\nexport const ScheduledTag = ({ scheduled }: { scheduled: SchedulerEntry }) => {\n const dateFormatter = useDateFormatter();\n return (\n <Tooltip\n content={scheduledTooltip(scheduled, dateFormatter)}\n trigger={<Tag variant={\"warning\"} icon={<ScheduledIcon />} content={\"Scheduled\"} />}\n />\n );\n};\n"],"names":["scheduledTooltip","scheduled","dateFormatter","goLiveOn","actionLabel","ScheduleActionType","formatUtcOffset","ScheduledTag","useDateFormatter","Tooltip","Tag","ScheduledIcon"],"mappings":";;;;;AASA,MAAMA,mBAAmB,CACrBC,WACAC;IAEA,MAAMC,WAAWF,UAAU,SAAS,IAAIA,UAAU,WAAW;IAC7D,MAAMG,cACFH,UAAU,UAAU,KAAKI,mBAAmB,SAAS,GAAG,cAAc;IAC1E,OAAOF,WACD,CAAC,aAAa,EAAEC,YAAY,IAAI,EAAEF,cAAc,MAAM,CAACC,UAAU,EAAE,EAAEG,kBAAkB,CAAC,CAAC,GACzF,CAAC,aAAa,EAAEF,aAAa;AACvC;AAEO,MAAMG,eAAe,CAAC,EAAEN,SAAS,EAAiC;IACrE,MAAMC,gBAAgBM;IACtB,OAAO,WAAP,GACI,oBAACC,SAAOA;QACJ,SAAST,iBAAiBC,WAAWC;QACrC,uBAAS,oBAACQ,KAAGA;YAAC,SAAS;YAAW,oBAAM,oBAACC,gBAAaA;YAAK,SAAS;;;AAGhF"}
@@ -1 +1 @@
1
- {"version":3,"file":"components/Sidebar/SchedulerButton.js","sources":["../../../src/components/Sidebar/SchedulerButton.tsx"],"sourcesContent":["import React from \"react\";\nimport { Sidebar } from \"@webiny/admin-ui\";\nimport { ReactComponent as ScheduleIcon } from \"@webiny/icons/cell_tower.svg\";\n\nexport interface ScheduleButtonProps {\n onClick: () => void;\n}\n\nexport const SchedulerButton = (props: ScheduleButtonProps) => {\n return (\n <div className={\"list-none\"}>\n <Sidebar.Item\n onClick={props.onClick}\n text={\"Schedule\"}\n icon={<Sidebar.Item.Icon element={<ScheduleIcon />} label={\"Schedule\"} />}\n />\n </div>\n );\n};\n"],"names":["SchedulerButton","props","Sidebar","ScheduleIcon"],"mappings":";;;AAQO,MAAMA,kBAAkB,CAACC,QACrB,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACC,QAAQ,IAAI;QACT,SAASD,MAAM,OAAO;QACtB,MAAM;QACN,oBAAM,oBAACC,QAAQ,IAAI,CAAC,IAAI;YAAC,uBAAS,oBAACC,gBAAYA;YAAK,OAAO"}
1
+ {"version":3,"file":"components/Browser/SchedulerButton.js","sources":["../../../src/components/Browser/SchedulerButton.tsx"],"sourcesContent":["import React from \"react\";\nimport { Sidebar } from \"@webiny/admin-ui\";\nimport { ReactComponent as ScheduleIcon } from \"@webiny/icons/cell_tower.svg\";\n\nexport interface ScheduleButtonProps {\n onClick: () => void;\n}\n\nexport const SchedulerButton = (props: ScheduleButtonProps) => {\n return (\n <div className={\"list-none\"}>\n <Sidebar.Item\n onClick={props.onClick}\n text={\"Schedule\"}\n icon={<Sidebar.Item.Icon element={<ScheduleIcon />} label={\"Schedule\"} />}\n />\n </div>\n );\n};\n"],"names":["SchedulerButton","props","Sidebar","ScheduleIcon"],"mappings":";;;AAQO,MAAMA,kBAAkB,CAACC,QACrB,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACC,QAAQ,IAAI;QACT,SAASD,MAAM,OAAO;QACtB,MAAM;QACN,oBAAM,oBAACC,QAAQ,IAAI,CAAC,IAAI;YAAC,uBAAS,oBAACC,gBAAYA;YAAK,OAAO"}
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare const SchedulerMenuItem: () => React.JSX.Element | null;
@@ -0,0 +1,26 @@
1
+ import react from "react";
2
+ import { useModel } from "@webiny/app-headless-cms/exports/admin/cms.js";
3
+ import { usePermissions } from "../../hooks/usePermissions.js";
4
+ import { Scheduler } from "@webiny/app-scheduler";
5
+ import { SchedulerButton } from "./SchedulerButton.js";
6
+ import { useScheduledActionsPresenter } from "../../hooks/useScheduledActionsPresenter.js";
7
+ import { createNamespace } from "../../utils/index.js";
8
+ const SchedulerMenuItem = ()=>{
9
+ const { model } = useModel();
10
+ const { canPublish, canUnpublish } = usePermissions();
11
+ const scheduledActions = useScheduledActionsPresenter();
12
+ const namespace = createNamespace(model);
13
+ if (!canPublish && !canUnpublish) return null;
14
+ return /*#__PURE__*/ react.createElement(Scheduler, {
15
+ namespace: namespace,
16
+ canPublish: canPublish,
17
+ canUnpublish: canUnpublish,
18
+ onClose: ()=>scheduledActions.loadForModel(model.modelId),
19
+ render: ({ showScheduler })=>/*#__PURE__*/ react.createElement(SchedulerButton, {
20
+ onClick: showScheduler
21
+ })
22
+ });
23
+ };
24
+ export { SchedulerMenuItem };
25
+
26
+ //# sourceMappingURL=SchedulerMenuItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Browser/SchedulerMenuItem.js","sources":["../../../src/components/Browser/SchedulerMenuItem.tsx"],"sourcesContent":["import React from \"react\";\nimport { useModel } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { usePermissions } from \"~/hooks/usePermissions.js\";\nimport { Scheduler as BaseScheduler } from \"@webiny/app-scheduler\";\nimport { SchedulerButton } from \"./SchedulerButton.js\";\nimport { useScheduledActionsPresenter } from \"~/hooks/useScheduledActionsPresenter.js\";\nimport { createNamespace } from \"~/utils/index.js\";\n\nexport const SchedulerMenuItem = () => {\n const { model } = useModel();\n const { canPublish, canUnpublish } = usePermissions();\n const scheduledActions = useScheduledActionsPresenter();\n\n const namespace = createNamespace(model);\n\n if (!canPublish && !canUnpublish) {\n return null;\n }\n\n return (\n <BaseScheduler\n namespace={namespace}\n canPublish={canPublish}\n canUnpublish={canUnpublish}\n // The scheduler overlay opens on top of the entries list, so the list stays mounted and\n // its cached scheduled actions go stale when one is cancelled here. Reload on close so the\n // \"Live\" column reflects any cancellations before the user sees the list again.\n onClose={() => scheduledActions.loadForModel(model.modelId)}\n render={({ showScheduler }) => {\n return <SchedulerButton onClick={showScheduler} />;\n }}\n />\n );\n};\n"],"names":["SchedulerMenuItem","model","useModel","canPublish","canUnpublish","usePermissions","scheduledActions","useScheduledActionsPresenter","namespace","createNamespace","BaseScheduler","showScheduler","SchedulerButton"],"mappings":";;;;;;;AAQO,MAAMA,oBAAoB;IAC7B,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAClB,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC;IACrC,MAAMC,mBAAmBC;IAEzB,MAAMC,YAAYC,gBAAgBR;IAElC,IAAI,CAACE,cAAc,CAACC,cAChB,OAAO;IAGX,OAAO,WAAP,GACI,oBAACM,WAAaA;QACV,WAAWF;QACX,YAAYL;QACZ,cAAcC;QAId,SAAS,IAAME,iBAAiB,YAAY,CAACL,MAAM,OAAO;QAC1D,QAAQ,CAAC,EAAEU,aAAa,EAAE,GACf,WAAP,GAAO,oBAACC,iBAAeA;gBAAC,SAASD;;;AAIjD"}
@@ -0,0 +1,12 @@
1
+ import type { SchedulerEntry } from "@webiny/app-scheduler/types.js";
2
+ /**
3
+ * A scheduled action is made redundant by a direct publish/unpublish. The API cancels it, but that
4
+ * happens asynchronously, so reconcile against the entry's current state to clear the badge
5
+ * immediately instead of waiting for the backend cancellation to propagate:
6
+ *
7
+ * - Scheduled PUBLISH is redundant once the latest revision is already live
8
+ * (`live.version === version`). It is NOT redundant when an older revision is live and a newer one
9
+ * is queued (live.version < version) — that is the legitimate "live and scheduled" case.
10
+ * - Scheduled UNPUBLISH is redundant once nothing is live.
11
+ */
12
+ export declare const isScheduleRedundant: (scheduled: SchedulerEntry, liveVersion: number | undefined, currentVersion: number | undefined) => boolean;
@@ -0,0 +1,8 @@
1
+ import { ScheduleActionType } from "@webiny/app-scheduler/types.js";
2
+ const isScheduleRedundant = (scheduled, liveVersion, currentVersion)=>{
3
+ if (scheduled.actionType === ScheduleActionType.unpublish) return void 0 === liveVersion;
4
+ return void 0 !== liveVersion && liveVersion === currentVersion;
5
+ };
6
+ export { isScheduleRedundant };
7
+
8
+ //# sourceMappingURL=isScheduleRedundant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Browser/isScheduleRedundant.js","sources":["../../../src/components/Browser/isScheduleRedundant.ts"],"sourcesContent":["import { ScheduleActionType } from \"@webiny/app-scheduler/types.js\";\nimport type { SchedulerEntry } from \"@webiny/app-scheduler/types.js\";\n\n/**\n * A scheduled action is made redundant by a direct publish/unpublish. The API cancels it, but that\n * happens asynchronously, so reconcile against the entry's current state to clear the badge\n * immediately instead of waiting for the backend cancellation to propagate:\n *\n * - Scheduled PUBLISH is redundant once the latest revision is already live\n * (`live.version === version`). It is NOT redundant when an older revision is live and a newer one\n * is queued (live.version < version) — that is the legitimate \"live and scheduled\" case.\n * - Scheduled UNPUBLISH is redundant once nothing is live.\n */\nexport const isScheduleRedundant = (\n scheduled: SchedulerEntry,\n liveVersion: number | undefined,\n currentVersion: number | undefined\n): boolean => {\n if (scheduled.actionType === ScheduleActionType.unpublish) {\n return liveVersion === undefined;\n }\n return liveVersion !== undefined && liveVersion === currentVersion;\n};\n"],"names":["isScheduleRedundant","scheduled","liveVersion","currentVersion","ScheduleActionType","undefined"],"mappings":";AAaO,MAAMA,sBAAsB,CAC/BC,WACAC,aACAC;IAEA,IAAIF,UAAU,UAAU,KAAKG,mBAAmB,SAAS,EACrD,OAAOF,AAAgBG,WAAhBH;IAEX,OAAOA,AAAgBG,WAAhBH,eAA6BA,gBAAgBC;AACxD"}
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ /**
3
+ * Decorates the "Publish entry" dialog to warn (via its `intro` prop) that publishing now will
4
+ * cancel an existing scheduled action for the entry.
5
+ */
6
+ export declare const PublishScheduleNoticeDecorator: (props: unknown) => React.JSX.Element;
@@ -0,0 +1,17 @@
1
+ import react from "react";
2
+ import { useNamedConfirmationDialog } from "@webiny/app-admin";
3
+ import { PublishEntryConfirmDialog } from "@webiny/app-headless-cms/exports/admin/cms.js";
4
+ import { ScheduleNoticeAlert } from "./ScheduleNoticeAlert.js";
5
+ const PublishScheduleNoticeDecorator = PublishEntryConfirmDialog.createDecorator((Original)=>function(props) {
6
+ const { params } = useNamedConfirmationDialog();
7
+ return /*#__PURE__*/ react.createElement(Original, {
8
+ ...props,
9
+ intro: /*#__PURE__*/ react.createElement(react.Fragment, null, props.intro, /*#__PURE__*/ react.createElement(ScheduleNoticeAlert, {
10
+ targetId: params.entry?.id,
11
+ verb: "Publishing"
12
+ }))
13
+ });
14
+ });
15
+ export { PublishScheduleNoticeDecorator };
16
+
17
+ //# sourceMappingURL=PublishScheduleNotice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Dialogs/PublishScheduleNotice.js","sources":["../../../src/components/Dialogs/PublishScheduleNotice.tsx"],"sourcesContent":["import React from \"react\";\nimport { useNamedConfirmationDialog } from \"@webiny/app-admin\";\nimport { PublishEntryConfirmDialog } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport type { CmsContentEntry } from \"@webiny/app-headless-cms-common/types/index.js\";\nimport { ScheduleNoticeAlert } from \"./ScheduleNoticeAlert.js\";\n\n/**\n * Decorates the \"Publish entry\" dialog to warn (via its `intro` prop) that publishing now will\n * cancel an existing scheduled action for the entry.\n */\nexport const PublishScheduleNoticeDecorator = PublishEntryConfirmDialog.createDecorator(\n Original => {\n return function PublishEntryConfirmDialogWithNotice(props) {\n const { params } = useNamedConfirmationDialog<{ entry: CmsContentEntry }>();\n return (\n <Original\n {...props}\n intro={\n <>\n {props.intro}\n <ScheduleNoticeAlert targetId={params.entry?.id} verb={\"Publishing\"} />\n </>\n }\n />\n );\n };\n }\n);\n"],"names":["PublishScheduleNoticeDecorator","PublishEntryConfirmDialog","Original","props","params","useNamedConfirmationDialog","ScheduleNoticeAlert"],"mappings":";;;;AAUO,MAAMA,iCAAiCC,0BAA0B,eAAe,CACnFC,CAAAA,WACW,SAA6CC,KAAK;QACrD,MAAM,EAAEC,MAAM,EAAE,GAAGC;QACnB,OAAO,WAAP,GACI,oBAACH,UAAAA;YACI,GAAGC,KAAK;YACT,qBACI,0CACKA,MAAM,KAAK,gBACZ,oBAACG,qBAAmBA;gBAAC,UAAUF,OAAO,KAAK,EAAE;gBAAI,MAAM;;;IAK3E"}
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ interface ScheduleNoticeAlertProps {
3
+ targetId: string | undefined;
4
+ verb: "Publishing" | "Unpublishing";
5
+ }
6
+ /**
7
+ * Warns that an about-to-happen publish/unpublish will cancel an existing scheduled action for the
8
+ * entry (the API cancels it). Reads from ScheduledActionsPresenter, already populated by the list
9
+ * (or the entry form). Renders nothing when there is no scheduled action.
10
+ */
11
+ export declare const ScheduleNoticeAlert: (({ targetId, verb }: ScheduleNoticeAlertProps) => React.JSX.Element | null) & {
12
+ displayName: string;
13
+ };
14
+ export {};
@@ -0,0 +1,22 @@
1
+ import react from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { Alert } from "@webiny/admin-ui";
4
+ import { ScheduleActionType } from "@webiny/app-scheduler/types.js";
5
+ import { useDateFormatter } from "@webiny/app-admin";
6
+ import { useScheduledActionsPresenter } from "../../hooks/useScheduledActionsPresenter.js";
7
+ const ScheduleNoticeAlert = observer(({ targetId, verb })=>{
8
+ const presenter = useScheduledActionsPresenter();
9
+ const dateFormatter = useDateFormatter();
10
+ const scheduled = targetId ? presenter.getScheduledAction(targetId) : void 0;
11
+ if (!scheduled) return null;
12
+ const goLiveOn = scheduled.publishOn || scheduled.unpublishOn;
13
+ const actionLabel = scheduled.actionType === ScheduleActionType.unpublish ? "unpublish" : "publish";
14
+ return /*#__PURE__*/ react.createElement(Alert, {
15
+ type: "warning",
16
+ variant: "subtle",
17
+ className: "mb-md"
18
+ }, "This entry has a ", actionLabel, " scheduled", goLiveOn ? ` for ${dateFormatter.format(goLiveOn)}` : "", ". ", verb, " now will cancel it.");
19
+ });
20
+ export { ScheduleNoticeAlert };
21
+
22
+ //# sourceMappingURL=ScheduleNoticeAlert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Dialogs/ScheduleNoticeAlert.js","sources":["../../../src/components/Dialogs/ScheduleNoticeAlert.tsx"],"sourcesContent":["import React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Alert } from \"@webiny/admin-ui\";\nimport { ScheduleActionType } from \"@webiny/app-scheduler/types.js\";\nimport { useDateFormatter } from \"@webiny/app-admin\";\nimport { useScheduledActionsPresenter } from \"~/hooks/useScheduledActionsPresenter.js\";\n\ninterface ScheduleNoticeAlertProps {\n targetId: string | undefined;\n // The action the user is about to take, used in the warning (\"Publishing now will cancel it.\").\n verb: \"Publishing\" | \"Unpublishing\";\n}\n\n/**\n * Warns that an about-to-happen publish/unpublish will cancel an existing scheduled action for the\n * entry (the API cancels it). Reads from ScheduledActionsPresenter, already populated by the list\n * (or the entry form). Renders nothing when there is no scheduled action.\n */\nexport const ScheduleNoticeAlert = observer(({ targetId, verb }: ScheduleNoticeAlertProps) => {\n const presenter = useScheduledActionsPresenter();\n const dateFormatter = useDateFormatter();\n\n const scheduled = targetId ? presenter.getScheduledAction(targetId) : undefined;\n\n if (!scheduled) {\n return null;\n }\n\n const goLiveOn = scheduled.publishOn || scheduled.unpublishOn;\n const actionLabel =\n scheduled.actionType === ScheduleActionType.unpublish ? \"unpublish\" : \"publish\";\n\n return (\n <Alert type={\"warning\"} variant={\"subtle\"} className={\"mb-md\"}>\n This entry has a {actionLabel} scheduled\n {goLiveOn ? ` for ${dateFormatter.format(goLiveOn)}` : \"\"}. {verb} now will cancel it.\n </Alert>\n );\n});\n"],"names":["ScheduleNoticeAlert","observer","targetId","verb","presenter","useScheduledActionsPresenter","dateFormatter","useDateFormatter","scheduled","undefined","goLiveOn","actionLabel","ScheduleActionType","Alert"],"mappings":";;;;;;AAkBO,MAAMA,sBAAsBC,SAAS,CAAC,EAAEC,QAAQ,EAAEC,IAAI,EAA4B;IACrF,MAAMC,YAAYC;IAClB,MAAMC,gBAAgBC;IAEtB,MAAMC,YAAYN,WAAWE,UAAU,kBAAkB,CAACF,YAAYO;IAEtE,IAAI,CAACD,WACD,OAAO;IAGX,MAAME,WAAWF,UAAU,SAAS,IAAIA,UAAU,WAAW;IAC7D,MAAMG,cACFH,UAAU,UAAU,KAAKI,mBAAmB,SAAS,GAAG,cAAc;IAE1E,OAAO,WAAP,GACI,oBAACC,OAAKA;QAAC,MAAM;QAAW,SAAS;QAAU,WAAW;OAAS,qBACzCF,aAAY,cAC7BD,WAAW,CAAC,KAAK,EAAEJ,cAAc,MAAM,CAACI,WAAW,GAAG,IAAG,MAAGP,MAAK;AAG9E"}
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ /**
3
+ * Decorates the "Unpublish entry" dialog to warn (via its `intro` prop) that unpublishing now will
4
+ * cancel an existing scheduled action for the entry.
5
+ */
6
+ export declare const UnpublishScheduleNoticeDecorator: (props: unknown) => React.JSX.Element;
@@ -0,0 +1,17 @@
1
+ import react from "react";
2
+ import { useNamedConfirmationDialog } from "@webiny/app-admin";
3
+ import { UnpublishEntryConfirmDialog } from "@webiny/app-headless-cms/exports/admin/cms.js";
4
+ import { ScheduleNoticeAlert } from "./ScheduleNoticeAlert.js";
5
+ const UnpublishScheduleNoticeDecorator = UnpublishEntryConfirmDialog.createDecorator((Original)=>function(props) {
6
+ const { params } = useNamedConfirmationDialog();
7
+ return /*#__PURE__*/ react.createElement(Original, {
8
+ ...props,
9
+ intro: /*#__PURE__*/ react.createElement(react.Fragment, null, props.intro, /*#__PURE__*/ react.createElement(ScheduleNoticeAlert, {
10
+ targetId: params.entryId,
11
+ verb: "Unpublishing"
12
+ }))
13
+ });
14
+ });
15
+ export { UnpublishScheduleNoticeDecorator };
16
+
17
+ //# sourceMappingURL=UnpublishScheduleNotice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Dialogs/UnpublishScheduleNotice.js","sources":["../../../src/components/Dialogs/UnpublishScheduleNotice.tsx"],"sourcesContent":["import React from \"react\";\nimport { useNamedConfirmationDialog } from \"@webiny/app-admin\";\nimport { UnpublishEntryConfirmDialog } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { ScheduleNoticeAlert } from \"./ScheduleNoticeAlert.js\";\n\n/**\n * Decorates the \"Unpublish entry\" dialog to warn (via its `intro` prop) that unpublishing now will\n * cancel an existing scheduled action for the entry.\n */\nexport const UnpublishScheduleNoticeDecorator = UnpublishEntryConfirmDialog.createDecorator(\n Original => {\n return function UnpublishEntryConfirmDialogWithNotice(props) {\n const { params } = useNamedConfirmationDialog<{ entryId: string }>();\n return (\n <Original\n {...props}\n intro={\n <>\n {props.intro}\n <ScheduleNoticeAlert targetId={params.entryId} verb={\"Unpublishing\"} />\n </>\n }\n />\n );\n };\n }\n);\n"],"names":["UnpublishScheduleNoticeDecorator","UnpublishEntryConfirmDialog","Original","props","params","useNamedConfirmationDialog","ScheduleNoticeAlert"],"mappings":";;;;AASO,MAAMA,mCAAmCC,4BAA4B,eAAe,CACvFC,CAAAA,WACW,SAA+CC,KAAK;QACvD,MAAM,EAAEC,MAAM,EAAE,GAAGC;QACnB,OAAO,WAAP,GACI,oBAACH,UAAAA;YACI,GAAGC,KAAK;YACT,qBACI,0CACKA,MAAM,KAAK,gBACZ,oBAACG,qBAAmBA;gBAAC,UAAUF,OAAO,OAAO;gBAAE,MAAM;;;IAKzE"}
@@ -1,9 +1,9 @@
1
- import { IsModelPublishable } from "@webiny/app-headless-cms/exports/admin/cms.js";
2
- import { ContentEntryEditorConfig } from "@webiny/app-headless-cms/exports/admin/cms/entry/editor.js";
3
1
  import react from "react";
2
+ import { InternalContentEntryEditorConfig } from "@webiny/app-headless-cms";
3
+ import { IsModelPublishable } from "@webiny/app-headless-cms/exports/admin/cms.js";
4
4
  import { MenuItem } from "./MenuItem.js";
5
- const { Actions: Actions } = ContentEntryEditorConfig;
6
- const EditorConfig = ()=>/*#__PURE__*/ react.createElement(ContentEntryEditorConfig, null, /*#__PURE__*/ react.createElement(IsModelPublishable, null, /*#__PURE__*/ react.createElement(Actions.MenuItemAction, {
5
+ const { Actions: Actions } = InternalContentEntryEditorConfig;
6
+ const EditorConfig = ()=>/*#__PURE__*/ react.createElement(InternalContentEntryEditorConfig, null, /*#__PURE__*/ react.createElement(IsModelPublishable, null, /*#__PURE__*/ react.createElement(Actions.MenuItemAction, {
7
7
  name: "schedule",
8
8
  element: /*#__PURE__*/ react.createElement(MenuItem, null)
9
9
  })));
@@ -1 +1 @@
1
- {"version":3,"file":"components/Editor/EditorConfig.js","sources":["../../../src/components/Editor/EditorConfig.tsx"],"sourcesContent":["import { IsModelPublishable } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { ContentEntryEditorConfig } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport React from \"react\";\nimport { MenuItem } from \"./MenuItem.js\";\n\nconst { Actions } = ContentEntryEditorConfig;\n\nexport const EditorConfig = () => {\n return (\n <ContentEntryEditorConfig>\n <IsModelPublishable>\n <Actions.MenuItemAction name={\"schedule\"} element={<MenuItem />} />\n </IsModelPublishable>\n </ContentEntryEditorConfig>\n );\n};\n"],"names":["Actions","ContentEntryEditorConfig","EditorConfig","IsModelPublishable","MenuItem"],"mappings":";;;;AAKA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAEb,MAAMC,eAAe,IACjB,WAAP,GACI,oBAACD,0BAAwBA,MAAAA,WAAAA,GACrB,oBAACE,oBAAkBA,MAAAA,WAAAA,GACf,oBAACH,QAAQ,cAAc;QAAC,MAAM;QAAY,uBAAS,oBAACI,UAAQA"}
1
+ {"version":3,"file":"components/Editor/EditorConfig.js","sources":["../../../src/components/Editor/EditorConfig.tsx"],"sourcesContent":["import React from \"react\";\nimport { InternalContentEntryEditorConfig } from \"@webiny/app-headless-cms\";\nimport { IsModelPublishable } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { MenuItem } from \"./MenuItem.js\";\n\nconst { Actions } = InternalContentEntryEditorConfig;\n\nexport const EditorConfig = () => {\n return (\n <InternalContentEntryEditorConfig>\n <IsModelPublishable>\n <Actions.MenuItemAction name={\"schedule\"} element={<MenuItem />} />\n </IsModelPublishable>\n </InternalContentEntryEditorConfig>\n );\n};\n"],"names":["Actions","InternalContentEntryEditorConfig","EditorConfig","IsModelPublishable","MenuItem"],"mappings":";;;;AAKA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAEb,MAAMC,eAAe,IACjB,WAAP,GACI,oBAACD,kCAAgCA,MAAAA,WAAAA,GAC7B,oBAACE,oBAAkBA,MAAAA,WAAAA,GACf,oBAACH,QAAQ,cAAc;QAAC,MAAM;QAAY,uBAAS,oBAACI,UAAQA"}
@@ -1,2 +1,4 @@
1
1
  import React from "react";
2
- export declare const MenuItem: () => React.JSX.Element | null;
2
+ export declare const MenuItem: (() => React.JSX.Element | null) & {
3
+ displayName: string;
4
+ };
@@ -1,42 +1,46 @@
1
1
  import react, { useCallback } from "react";
2
- import { ContentEntryEditorConfig, useContentEntryEditor } from "@webiny/app-headless-cms/exports/admin/cms/entry/editor.js";
2
+ import { observer } from "mobx-react-lite";
3
+ import { OptionsMenuItem } from "@webiny/app-admin";
4
+ import { useContentEntryFormPresenter } from "@webiny/app-headless-cms/exports/admin/cms/entry/editor.js";
3
5
  import { ReactComponent } from "@webiny/icons/cell_tower.svg";
4
- import { useApolloClient } from "@apollo/react-hooks";
5
6
  import { useScheduleDialog } from "@webiny/app-scheduler";
6
7
  import { usePermissions } from "../../hooks/usePermissions.js";
7
8
  import { createNamespace } from "../../utils/index.js";
8
- const MenuItemWithId = ({ entry, contentModel, loading })=>{
9
- const client = useApolloClient();
9
+ import { useScheduledActionsPresenter } from "../../hooks/useScheduledActionsPresenter.js";
10
+ const MenuItemWithId = ({ entryId, entryTitle, entryStatus, modelId, loading })=>{
11
+ const scheduledActions = useScheduledActionsPresenter();
10
12
  const { showDialog: showSchedulerDialog } = useScheduleDialog({
11
- client,
12
- namespace: createNamespace(contentModel),
13
+ namespace: createNamespace({
14
+ modelId
15
+ }),
13
16
  target: {
14
- id: entry.id,
15
- title: entry.meta.title,
16
- status: entry.meta.status
17
- }
17
+ id: entryId,
18
+ title: entryTitle,
19
+ status: entryStatus
20
+ },
21
+ onCompleted: ()=>scheduledActions.reload()
18
22
  });
19
- const { OptionsMenuItem } = ContentEntryEditorConfig.Actions.MenuItemAction.useOptionsMenuItem();
20
23
  const showDialog = useCallback(()=>{
21
24
  showSchedulerDialog();
22
25
  }, [
23
26
  showSchedulerDialog
24
27
  ]);
25
- const action = entry.meta?.status === "published" ? "unpublish" : "publish";
28
+ const action = "published" === entryStatus ? "unpublish" : "publish";
26
29
  return /*#__PURE__*/ react.createElement(OptionsMenuItem, {
27
30
  icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
28
31
  label: `Schedule ${action}`,
29
32
  onAction: showDialog,
30
- disabled: !entry?.meta?.status || loading,
33
+ disabled: !entryStatus || loading,
31
34
  "data-testid": "cms.content-form.header.schedule"
32
35
  });
33
36
  };
34
- const MenuItem = ()=>{
35
- const { entry, loading, contentModel } = useContentEntryEditor();
37
+ const MenuItem = observer(()=>{
38
+ const presenter = useContentEntryFormPresenter();
36
39
  const { canPublish, canUnpublish } = usePermissions();
37
- const { OptionsMenuItem } = ContentEntryEditorConfig.Actions.MenuItemAction.useOptionsMenuItem();
40
+ const vm = presenter.vm;
41
+ if (!vm.canPublish && !vm.canUnpublish) return null;
38
42
  if (!canPublish && !canUnpublish) return null;
39
- if (!entry.id) return /*#__PURE__*/ react.createElement(OptionsMenuItem, {
43
+ if (!vm.entry) return /*#__PURE__*/ react.createElement(OptionsMenuItem, {
40
44
  icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
41
45
  label: "Schedule",
42
46
  onAction: ()=>void 0,
@@ -44,11 +48,13 @@ const MenuItem = ()=>{
44
48
  "data-testid": "cms.content-form.header.schedule"
45
49
  });
46
50
  return /*#__PURE__*/ react.createElement(MenuItemWithId, {
47
- entry: entry,
48
- contentModel: contentModel,
49
- loading: loading
51
+ entryId: vm.entry.id,
52
+ entryTitle: vm.entry.meta?.title || "",
53
+ entryStatus: vm.entry.meta?.status || "",
54
+ modelId: vm.model.modelId,
55
+ loading: null !== vm.loading
50
56
  });
51
- };
57
+ });
52
58
  export { MenuItem };
53
59
 
54
60
  //# sourceMappingURL=MenuItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"components/Editor/MenuItem.js","sources":["../../../src/components/Editor/MenuItem.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport {\n ContentEntryEditorConfig,\n useContentEntryEditor\n} from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { ReactComponent as ScheduleIcon } from \"@webiny/icons/cell_tower.svg\";\nimport { useApolloClient } from \"@apollo/react-hooks\";\nimport { useScheduleDialog } from \"@webiny/app-scheduler\";\nimport { usePermissions } from \"~/hooks/usePermissions.js\";\nimport { createNamespace } from \"~/utils/index.js\";\n\ninterface MenuItemWithIdProps {\n entry: ReturnType<typeof useContentEntryEditor>[\"entry\"];\n contentModel: ReturnType<typeof useContentEntryEditor>[\"contentModel\"];\n loading: boolean;\n}\n\n/* Rendered only when entry.id exists; hooks that depend on entry.id live here. */\nconst MenuItemWithId = ({ entry, contentModel, loading }: MenuItemWithIdProps) => {\n const client = useApolloClient();\n\n const { showDialog: showSchedulerDialog } = useScheduleDialog({\n client,\n namespace: createNamespace(contentModel),\n target: {\n id: entry.id,\n title: entry.meta.title,\n status: entry.meta.status\n }\n });\n\n const { OptionsMenuItem } =\n ContentEntryEditorConfig.Actions.MenuItemAction.useOptionsMenuItem();\n\n const showDialog = useCallback(() => {\n showSchedulerDialog();\n }, [showSchedulerDialog]);\n\n const action = entry.meta?.status === \"published\" ? \"unpublish\" : \"publish\";\n\n return (\n <OptionsMenuItem\n icon={<ScheduleIcon />}\n label={`Schedule ${action}`}\n onAction={showDialog}\n disabled={!entry?.meta?.status || loading}\n data-testid={\"cms.content-form.header.schedule\"}\n />\n );\n};\n\nexport const MenuItem = () => {\n const { entry, loading, contentModel } = useContentEntryEditor();\n const { canPublish, canUnpublish } = usePermissions();\n\n const { OptionsMenuItem } =\n ContentEntryEditorConfig.Actions.MenuItemAction.useOptionsMenuItem();\n\n if (!canPublish && !canUnpublish) {\n return null;\n }\n\n /* When entry.id is missing (e.g. new unsaved entry), render a disabled item\n * without invoking hooks that require a persisted entry. */\n if (!entry.id) {\n return (\n <OptionsMenuItem\n icon={<ScheduleIcon />}\n label={\"Schedule\"}\n onAction={() => void 0}\n disabled={true}\n data-testid={\"cms.content-form.header.schedule\"}\n />\n );\n }\n\n return <MenuItemWithId entry={entry} contentModel={contentModel} loading={loading} />;\n};\n"],"names":["MenuItemWithId","entry","contentModel","loading","client","useApolloClient","showSchedulerDialog","useScheduleDialog","createNamespace","OptionsMenuItem","ContentEntryEditorConfig","showDialog","useCallback","action","ScheduleIcon","MenuItem","useContentEntryEditor","canPublish","canUnpublish","usePermissions"],"mappings":";;;;;;;AAkBA,MAAMA,iBAAiB,CAAC,EAAEC,KAAK,EAAEC,YAAY,EAAEC,OAAO,EAAuB;IACzE,MAAMC,SAASC;IAEf,MAAM,EAAE,YAAYC,mBAAmB,EAAE,GAAGC,kBAAkB;QAC1DH;QACA,WAAWI,gBAAgBN;QAC3B,QAAQ;YACJ,IAAID,MAAM,EAAE;YACZ,OAAOA,MAAM,IAAI,CAAC,KAAK;YACvB,QAAQA,MAAM,IAAI,CAAC,MAAM;QAC7B;IACJ;IAEA,MAAM,EAAEQ,eAAe,EAAE,GACrBC,yBAAyB,OAAO,CAAC,cAAc,CAAC,kBAAkB;IAEtE,MAAMC,aAAaC,YAAY;QAC3BN;IACJ,GAAG;QAACA;KAAoB;IAExB,MAAMO,SAASZ,MAAM,IAAI,EAAE,WAAW,cAAc,cAAc;IAElE,OAAO,WAAP,GACI,oBAACQ,iBAAAA;QACG,oBAAM,oBAACK,gBAAYA;QACnB,OAAO,CAAC,SAAS,EAAED,QAAQ;QAC3B,UAAUF;QACV,UAAU,CAACV,OAAO,MAAM,UAAUE;QAClC,eAAa;;AAGzB;AAEO,MAAMY,WAAW;IACpB,MAAM,EAAEd,KAAK,EAAEE,OAAO,EAAED,YAAY,EAAE,GAAGc;IACzC,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC;IAErC,MAAM,EAAEV,eAAe,EAAE,GACrBC,yBAAyB,OAAO,CAAC,cAAc,CAAC,kBAAkB;IAEtE,IAAI,CAACO,cAAc,CAACC,cAChB,OAAO;IAKX,IAAI,CAACjB,MAAM,EAAE,EACT,OAAO,WAAP,GACI,oBAACQ,iBAAAA;QACG,oBAAM,oBAACK,gBAAYA;QACnB,OAAO;QACP,UAAU,IAAM,KAAK;QACrB,UAAU;QACV,eAAa;;IAKzB,OAAO,WAAP,GAAO,oBAACd,gBAAcA;QAAC,OAAOC;QAAO,cAAcC;QAAc,SAASC;;AAC9E"}
1
+ {"version":3,"file":"components/Editor/MenuItem.js","sources":["../../../src/components/Editor/MenuItem.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { OptionsMenuItem } from \"@webiny/app-admin\";\nimport { useContentEntryFormPresenter } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { ReactComponent as ScheduleIcon } from \"@webiny/icons/cell_tower.svg\";\nimport { useScheduleDialog } from \"@webiny/app-scheduler\";\nimport { usePermissions } from \"~/hooks/usePermissions.js\";\nimport { createNamespace } from \"~/utils/index.js\";\nimport { useScheduledActionsPresenter } from \"~/hooks/useScheduledActionsPresenter.js\";\n\ninterface MenuItemWithIdProps {\n entryId: string;\n entryTitle: string;\n entryStatus: string;\n modelId: string;\n loading: boolean;\n}\n\nconst MenuItemWithId = ({\n entryId,\n entryTitle,\n entryStatus,\n modelId,\n loading\n}: MenuItemWithIdProps) => {\n const scheduledActions = useScheduledActionsPresenter();\n const { showDialog: showSchedulerDialog } = useScheduleDialog({\n namespace: createNamespace({ modelId }),\n target: {\n id: entryId,\n title: entryTitle,\n status: entryStatus\n },\n onCompleted: () => scheduledActions.reload()\n });\n\n const showDialog = useCallback(() => {\n showSchedulerDialog();\n }, [showSchedulerDialog]);\n\n const action = entryStatus === \"published\" ? \"unpublish\" : \"publish\";\n\n return (\n <OptionsMenuItem\n icon={<ScheduleIcon />}\n label={`Schedule ${action}`}\n onAction={showDialog}\n disabled={!entryStatus || loading}\n data-testid={\"cms.content-form.header.schedule\"}\n />\n );\n};\n\nexport const MenuItem = observer(() => {\n const presenter = useContentEntryFormPresenter();\n const { canPublish, canUnpublish } = usePermissions();\n\n const vm = presenter.vm;\n\n if (!vm.canPublish && !vm.canUnpublish) {\n return null;\n }\n\n if (!canPublish && !canUnpublish) {\n return null;\n }\n\n if (!vm.entry) {\n return (\n <OptionsMenuItem\n icon={<ScheduleIcon />}\n label={\"Schedule\"}\n onAction={() => void 0}\n disabled={true}\n data-testid={\"cms.content-form.header.schedule\"}\n />\n );\n }\n\n return (\n <MenuItemWithId\n entryId={vm.entry.id}\n entryTitle={vm.entry.meta?.title || \"\"}\n entryStatus={vm.entry.meta?.status || \"\"}\n modelId={vm.model.modelId}\n loading={vm.loading !== null}\n />\n );\n});\n"],"names":["MenuItemWithId","entryId","entryTitle","entryStatus","modelId","loading","scheduledActions","useScheduledActionsPresenter","showSchedulerDialog","useScheduleDialog","createNamespace","showDialog","useCallback","action","OptionsMenuItem","ScheduleIcon","MenuItem","observer","presenter","useContentEntryFormPresenter","canPublish","canUnpublish","usePermissions","vm"],"mappings":";;;;;;;;;AAkBA,MAAMA,iBAAiB,CAAC,EACpBC,OAAO,EACPC,UAAU,EACVC,WAAW,EACXC,OAAO,EACPC,OAAO,EACW;IAClB,MAAMC,mBAAmBC;IACzB,MAAM,EAAE,YAAYC,mBAAmB,EAAE,GAAGC,kBAAkB;QAC1D,WAAWC,gBAAgB;YAAEN;QAAQ;QACrC,QAAQ;YACJ,IAAIH;YACJ,OAAOC;YACP,QAAQC;QACZ;QACA,aAAa,IAAMG,iBAAiB,MAAM;IAC9C;IAEA,MAAMK,aAAaC,YAAY;QAC3BJ;IACJ,GAAG;QAACA;KAAoB;IAExB,MAAMK,SAASV,AAAgB,gBAAhBA,cAA8B,cAAc;IAE3D,OAAO,WAAP,GACI,oBAACW,iBAAeA;QACZ,oBAAM,oBAACC,gBAAYA;QACnB,OAAO,CAAC,SAAS,EAAEF,QAAQ;QAC3B,UAAUF;QACV,UAAU,CAACR,eAAeE;QAC1B,eAAa;;AAGzB;AAEO,MAAMW,WAAWC,SAAS;IAC7B,MAAMC,YAAYC;IAClB,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC;IAErC,MAAMC,KAAKL,UAAU,EAAE;IAEvB,IAAI,CAACK,GAAG,UAAU,IAAI,CAACA,GAAG,YAAY,EAClC,OAAO;IAGX,IAAI,CAACH,cAAc,CAACC,cAChB,OAAO;IAGX,IAAI,CAACE,GAAG,KAAK,EACT,OAAO,WAAP,GACI,oBAACT,iBAAeA;QACZ,oBAAM,oBAACC,gBAAYA;QACnB,OAAO;QACP,UAAU,IAAM,KAAK;QACrB,UAAU;QACV,eAAa;;IAKzB,OAAO,WAAP,GACI,oBAACf,gBAAcA;QACX,SAASuB,GAAG,KAAK,CAAC,EAAE;QACpB,YAAYA,GAAG,KAAK,CAAC,IAAI,EAAE,SAAS;QACpC,aAAaA,GAAG,KAAK,CAAC,IAAI,EAAE,UAAU;QACtC,SAASA,GAAG,KAAK,CAAC,OAAO;QACzB,SAASA,AAAe,SAAfA,GAAG,OAAO;;AAG/B"}
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ /**
3
+ * Decorates the content entry form layout to render the scheduled-action bar below the header,
4
+ * above the form content (mirroring how the workflow bar is positioned).
5
+ */
6
+ export declare const ScheduledActionAlertDecorator: (props: unknown) => React.JSX.Element;
@@ -0,0 +1,43 @@
1
+ import react, { useEffect } from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { ReactComponent } from "@webiny/icons/access_time.svg";
4
+ import { Alert } from "@webiny/admin-ui";
5
+ import { ContentEntryFormContent } from "@webiny/app-headless-cms/presentation/contentEntries/views/layout/index.js";
6
+ import { useContentEntryFormPresenter } from "@webiny/app-headless-cms/exports/admin/cms/entry/editor.js";
7
+ import { ScheduleActionType } from "@webiny/app-scheduler/types.js";
8
+ import { formatUtcOffset, useDateFormatter } from "@webiny/app-admin";
9
+ import { useScheduledActionsPresenter } from "../../hooks/useScheduledActionsPresenter.js";
10
+ const ScheduledActionBar = observer(()=>{
11
+ const formPresenter = useContentEntryFormPresenter();
12
+ const presenter = useScheduledActionsPresenter();
13
+ const dateFormatter = useDateFormatter();
14
+ const vm = formPresenter.vm;
15
+ const entryId = vm.entry?.id;
16
+ const modelId = vm.model?.modelId;
17
+ useEffect(()=>{
18
+ if (entryId && modelId) presenter.loadForEntry(modelId, entryId);
19
+ }, [
20
+ presenter,
21
+ entryId,
22
+ modelId
23
+ ]);
24
+ const scheduled = entryId ? presenter.getScheduledAction(entryId) : void 0;
25
+ const status = vm.entry?.meta?.status;
26
+ const redundant = !!scheduled && (scheduled.actionType === ScheduleActionType.unpublish ? "unpublished" === status : "published" === status);
27
+ if (!scheduled || redundant) return null;
28
+ const goLiveOn = scheduled.publishOn || scheduled.unpublishOn;
29
+ const actionLabel = scheduled.actionType === ScheduleActionType.unpublish ? "unpublish" : "publish";
30
+ return /*#__PURE__*/ react.createElement("div", {
31
+ className: "max-w-screen bg-white p-sm border-solid border-b-sm border-neutral-dimmed"
32
+ }, /*#__PURE__*/ react.createElement(Alert, {
33
+ type: "warning",
34
+ variant: "subtle",
35
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null)
36
+ }, goLiveOn ? /*#__PURE__*/ react.createElement(react.Fragment, null, "This entry is scheduled to ", actionLabel, " on", " ", /*#__PURE__*/ react.createElement("strong", null, dateFormatter.format(goLiveOn), " (", formatUtcOffset(), ")"), ".") : /*#__PURE__*/ react.createElement(react.Fragment, null, "This entry is scheduled to ", actionLabel, ".")));
37
+ });
38
+ const ScheduledActionAlertDecorator = ContentEntryFormContent.createDecorator((Original)=>function(props) {
39
+ return /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(ScheduledActionBar, null), /*#__PURE__*/ react.createElement(Original, props));
40
+ });
41
+ export { ScheduledActionAlertDecorator };
42
+
43
+ //# sourceMappingURL=ScheduledActionAlert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components/Editor/ScheduledActionAlert.js","sources":["../../../src/components/Editor/ScheduledActionAlert.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { ReactComponent as ScheduledIcon } from \"@webiny/icons/access_time.svg\";\nimport { Alert } from \"@webiny/admin-ui\";\nimport { ContentEntryFormContent } from \"@webiny/app-headless-cms/presentation/contentEntries/views/layout/index.js\";\nimport { useContentEntryFormPresenter } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { ScheduleActionType } from \"@webiny/app-scheduler/types.js\";\nimport { useDateFormatter } from \"@webiny/app-admin\";\nimport { useScheduledActionsPresenter } from \"~/hooks/useScheduledActionsPresenter.js\";\nimport { formatUtcOffset } from \"@webiny/app-admin\";\n\n/**\n * Full-width bar shown below the entry-form header (above the form content) when the entry has a\n * scheduled publish/unpublish. Positioned like the workflow bar for visual consistency.\n */\nconst ScheduledActionBar = observer(() => {\n const formPresenter = useContentEntryFormPresenter();\n const presenter = useScheduledActionsPresenter();\n const dateFormatter = useDateFormatter();\n\n const vm = formPresenter.vm;\n const entryId = vm.entry?.id;\n const modelId = vm.model?.modelId;\n\n useEffect(() => {\n if (entryId && modelId) {\n presenter.loadForEntry(modelId, entryId);\n }\n }, [presenter, entryId, modelId]);\n\n const scheduled = entryId ? presenter.getScheduledAction(entryId) : undefined;\n\n // Reconcile against the entry's current status: a direct publish/unpublish supersedes the\n // scheduled action (the API cancels it asynchronously), so hide the bar immediately.\n const status = vm.entry?.meta?.status;\n const redundant =\n !!scheduled &&\n (scheduled.actionType === ScheduleActionType.unpublish\n ? status === \"unpublished\"\n : status === \"published\");\n\n if (!scheduled || redundant) {\n return null;\n }\n\n const goLiveOn = scheduled.publishOn || scheduled.unpublishOn;\n const actionLabel =\n scheduled.actionType === ScheduleActionType.unpublish ? \"unpublish\" : \"publish\";\n\n // Match the workflow bar: a full-width white strip (below the header) containing the alert.\n return (\n <div\n className={\"max-w-screen bg-white p-sm border-solid border-b-sm border-neutral-dimmed\"}\n >\n <Alert type={\"warning\"} variant={\"subtle\"} icon={<ScheduledIcon />}>\n {goLiveOn ? (\n <>\n This entry is scheduled to {actionLabel} on{\" \"}\n <strong>\n {dateFormatter.format(goLiveOn)} ({formatUtcOffset()})\n </strong>\n .\n </>\n ) : (\n <>This entry is scheduled to {actionLabel}.</>\n )}\n </Alert>\n </div>\n );\n});\n\n/**\n * Decorates the content entry form layout to render the scheduled-action bar below the header,\n * above the form content (mirroring how the workflow bar is positioned).\n */\nexport const ScheduledActionAlertDecorator = ContentEntryFormContent.createDecorator(Original => {\n return function ContentEntryFormContentWithScheduledBar(props) {\n return (\n <>\n <ScheduledActionBar />\n <Original {...props} />\n </>\n );\n };\n});\n"],"names":["ScheduledActionBar","observer","formPresenter","useContentEntryFormPresenter","presenter","useScheduledActionsPresenter","dateFormatter","useDateFormatter","vm","entryId","modelId","useEffect","scheduled","undefined","status","redundant","ScheduleActionType","goLiveOn","actionLabel","Alert","ScheduledIcon","formatUtcOffset","ScheduledActionAlertDecorator","ContentEntryFormContent","Original","props"],"mappings":";;;;;;;;;AAeA,MAAMA,qBAAqBC,SAAS;IAChC,MAAMC,gBAAgBC;IACtB,MAAMC,YAAYC;IAClB,MAAMC,gBAAgBC;IAEtB,MAAMC,KAAKN,cAAc,EAAE;IAC3B,MAAMO,UAAUD,GAAG,KAAK,EAAE;IAC1B,MAAME,UAAUF,GAAG,KAAK,EAAE;IAE1BG,UAAU;QACN,IAAIF,WAAWC,SACXN,UAAU,YAAY,CAACM,SAASD;IAExC,GAAG;QAACL;QAAWK;QAASC;KAAQ;IAEhC,MAAME,YAAYH,UAAUL,UAAU,kBAAkB,CAACK,WAAWI;IAIpE,MAAMC,SAASN,GAAG,KAAK,EAAE,MAAM;IAC/B,MAAMO,YACF,CAAC,CAACH,aACDA,CAAAA,UAAU,UAAU,KAAKI,mBAAmB,SAAS,GAChDF,AAAW,kBAAXA,SACAA,AAAW,gBAAXA,MAAqB;IAE/B,IAAI,CAACF,aAAaG,WACd,OAAO;IAGX,MAAME,WAAWL,UAAU,SAAS,IAAIA,UAAU,WAAW;IAC7D,MAAMM,cACFN,UAAU,UAAU,KAAKI,mBAAmB,SAAS,GAAG,cAAc;IAG1E,OAAO,WAAP,GACI,oBAAC;QACG,WAAW;qBAEX,oBAACG,OAAKA;QAAC,MAAM;QAAW,SAAS;QAAU,oBAAM,oBAACC,gBAAaA;OAC1DH,WAAW,WAAXA,GACG,0CAAE,+BAC8BC,aAAY,OAAI,mBAC5C,oBAAC,gBACIZ,cAAc,MAAM,CAACW,WAAU,MAAGI,mBAAkB,MAChD,qBAIb,0CAAE,+BAA4BH,aAAY;AAK9D;AAMO,MAAMI,gCAAgCC,wBAAwB,eAAe,CAACC,CAAAA,WAC1E,SAAiDC,KAAK;QACzD,OAAO,WAAP,GACI,wDACI,oBAACzB,oBAAkBA,OAAAA,WAAAA,GACnB,oBAACwB,UAAaC;IAG1B"}
@@ -1,3 +1,5 @@
1
1
  export * from "./Editor/EditorConfig.js";
2
- export * from "./Sidebar/Sidebar.js";
2
+ export * from "./Editor/ScheduledActionAlert.js";
3
+ export * from "./Dialogs/PublishScheduleNotice.js";
4
+ export * from "./Dialogs/UnpublishScheduleNotice.js";
3
5
  export * from "./Browser/BrowserConfig.js";
@@ -1,3 +1,5 @@
1
1
  export * from "./Editor/EditorConfig.js";
2
- export * from "./Sidebar/Sidebar.js";
2
+ export * from "./Editor/ScheduledActionAlert.js";
3
+ export * from "./Dialogs/PublishScheduleNotice.js";
4
+ export * from "./Dialogs/UnpublishScheduleNotice.js";
3
5
  export * from "./Browser/BrowserConfig.js";
@@ -0,0 +1,6 @@
1
+ import { ScheduledActionsPresenter } from "../presentation/scheduledActions/abstractions.js";
2
+ /**
3
+ * Resolves the shared ScheduledActionsPresenter — the source of scheduled-action state for the
4
+ * Live column, the entry-form bar and the publish/unpublish dialog notices.
5
+ */
6
+ export declare const useScheduledActionsPresenter: () => ScheduledActionsPresenter.Interface;
@@ -0,0 +1,12 @@
1
+ import { useMemo } from "react";
2
+ import { useContainer } from "@webiny/app";
3
+ import { ScheduledActionsPresenter } from "../presentation/scheduledActions/abstractions.js";
4
+ const useScheduledActionsPresenter = ()=>{
5
+ const container = useContainer();
6
+ return useMemo(()=>container.resolve(ScheduledActionsPresenter), [
7
+ container
8
+ ]);
9
+ };
10
+ export { useScheduledActionsPresenter };
11
+
12
+ //# sourceMappingURL=useScheduledActionsPresenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks/useScheduledActionsPresenter.js","sources":["../../src/hooks/useScheduledActionsPresenter.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useContainer } from \"@webiny/app\";\nimport { ScheduledActionsPresenter } from \"~/presentation/scheduledActions/abstractions.js\";\n\n/**\n * Resolves the shared ScheduledActionsPresenter — the source of scheduled-action state for the\n * Live column, the entry-form bar and the publish/unpublish dialog notices.\n */\nexport const useScheduledActionsPresenter = (): ScheduledActionsPresenter.Interface => {\n const container = useContainer();\n return useMemo(() => container.resolve(ScheduledActionsPresenter), [container]);\n};\n"],"names":["useScheduledActionsPresenter","container","useContainer","useMemo","ScheduledActionsPresenter"],"mappings":";;;AAQO,MAAMA,+BAA+B;IACxC,MAAMC,YAAYC;IAClB,OAAOC,QAAQ,IAAMF,UAAU,OAAO,CAACG,4BAA4B;QAACH;KAAU;AAClF"}
package/index.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import react from "react";
2
- import { BrowserConfig, EditorConfig, Sidebar } from "./components/index.js";
3
- const CmsScheduler = ()=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(Sidebar, null), /*#__PURE__*/ react.createElement(BrowserConfig, null), /*#__PURE__*/ react.createElement(EditorConfig, null));
2
+ import { RegisterFeature } from "@webiny/app-admin";
3
+ import { ScheduledActionsPresenterFeature } from "./presentation/scheduledActions/feature.js";
4
+ import { BrowserConfig, EditorConfig, PublishScheduleNoticeDecorator, ScheduledActionAlertDecorator, UnpublishScheduleNoticeDecorator } from "./components/index.js";
5
+ const CmsScheduler = ()=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(RegisterFeature, {
6
+ feature: ScheduledActionsPresenterFeature
7
+ }), /*#__PURE__*/ react.createElement(BrowserConfig, null), /*#__PURE__*/ react.createElement(EditorConfig, null), /*#__PURE__*/ react.createElement(ScheduledActionAlertDecorator, null), /*#__PURE__*/ react.createElement(PublishScheduleNoticeDecorator, null), /*#__PURE__*/ react.createElement(UnpublishScheduleNoticeDecorator, null));
4
8
  export { CmsScheduler };
5
9
 
6
10
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["import React from \"react\";\nimport { EditorConfig, BrowserConfig, Sidebar } from \"./components/index.js\";\n\nexport const CmsScheduler = () => {\n return (\n <>\n <Sidebar />\n <BrowserConfig />\n <EditorConfig />\n </>\n );\n};\n"],"names":["CmsScheduler","Sidebar","BrowserConfig","EditorConfig"],"mappings":";;AAGO,MAAMA,eAAe,IACjB,WAAP,GACI,wDACI,oBAACC,SAAOA,OAAAA,WAAAA,GACR,oBAACC,eAAaA,OAAAA,WAAAA,GACd,oBAACC,cAAYA"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["import React from \"react\";\nimport { RegisterFeature } from \"@webiny/app-admin\";\nimport { ScheduledActionsPresenterFeature } from \"./presentation/scheduledActions/feature.js\";\nimport {\n EditorConfig,\n BrowserConfig,\n ScheduledActionAlertDecorator,\n PublishScheduleNoticeDecorator,\n UnpublishScheduleNoticeDecorator\n} from \"./components/index.js\";\n\nexport const CmsScheduler = () => {\n return (\n <>\n <RegisterFeature feature={ScheduledActionsPresenterFeature} />\n <BrowserConfig />\n <EditorConfig />\n <ScheduledActionAlertDecorator />\n <PublishScheduleNoticeDecorator />\n <UnpublishScheduleNoticeDecorator />\n </>\n );\n};\n"],"names":["CmsScheduler","RegisterFeature","ScheduledActionsPresenterFeature","BrowserConfig","EditorConfig","ScheduledActionAlertDecorator","PublishScheduleNoticeDecorator","UnpublishScheduleNoticeDecorator"],"mappings":";;;;AAWO,MAAMA,eAAe,IACjB,WAAP,GACI,wDACI,oBAACC,iBAAeA;QAAC,SAASC;sBAC1B,oBAACC,eAAaA,OAAAA,WAAAA,GACd,oBAACC,cAAYA,OAAAA,WAAAA,GACb,oBAACC,+BAA6BA,OAAAA,WAAAA,GAC9B,oBAACC,gCAA8BA,OAAAA,WAAAA,GAC/B,oBAACC,kCAAgCA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/app-headless-cms-scheduler",
3
- "version": "6.4.12-beta.5",
3
+ "version": "6.5.0-beta.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -13,20 +13,24 @@
13
13
  "author": "Webiny Ltd",
14
14
  "license": "MIT",
15
15
  "dependencies": {
16
- "@apollo/react-hooks": "3.1.5",
17
- "@webiny/admin-ui": "6.4.12-beta.5",
18
- "@webiny/app-headless-cms": "6.4.12-beta.5",
19
- "@webiny/app-headless-cms-common": "6.4.12-beta.5",
20
- "@webiny/app-scheduler": "6.4.12-beta.5",
21
- "@webiny/icons": "6.4.12-beta.5",
16
+ "@webiny/admin-ui": "6.5.0-beta.0",
17
+ "@webiny/app": "6.5.0-beta.0",
18
+ "@webiny/app-admin": "6.5.0-beta.0",
19
+ "@webiny/app-headless-cms": "6.5.0-beta.0",
20
+ "@webiny/app-headless-cms-common": "6.5.0-beta.0",
21
+ "@webiny/app-scheduler": "6.5.0-beta.0",
22
+ "@webiny/feature": "6.5.0-beta.0",
23
+ "@webiny/icons": "6.5.0-beta.0",
24
+ "mobx": "6.16.1",
25
+ "mobx-react-lite": "4.1.1",
22
26
  "react": "18.3.1",
23
27
  "react-dom": "18.3.1"
24
28
  },
25
29
  "devDependencies": {
26
30
  "@types/react": "18.3.31",
27
- "@webiny/build-tools": "6.4.12-beta.5",
31
+ "@webiny/build-tools": "6.5.0-beta.0",
28
32
  "rimraf": "6.1.3",
29
- "typescript": "6.0.3"
33
+ "typescript": "7.0.2"
30
34
  },
31
35
  "publishConfig": {
32
36
  "access": "public"
@@ -0,0 +1,30 @@
1
+ import { type IContentEntriesPresenter, type IContentEntriesInitConfig } from "@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js";
2
+ import { ScheduledActionsPresenter } from "./abstractions.js";
3
+ /**
4
+ * Decorates the content-entries list presenter so the scheduled actions for the current model are
5
+ * (re)loaded whenever the visible rows change. The reaction key includes each row's status/live,
6
+ * so a direct publish/unpublish (which changes those, and lets the API cancel a schedule) triggers
7
+ * a refresh without any extra signalling.
8
+ */
9
+ declare class ContentEntriesPresenterWithScheduling implements IContentEntriesPresenter {
10
+ private scheduledActions;
11
+ private original;
12
+ private _disposeReaction;
13
+ constructor(scheduledActions: ScheduledActionsPresenter.Interface, original: IContentEntriesPresenter);
14
+ get vm(): import("@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js").IContentEntriesViewModel;
15
+ get list(): import("@webiny/app-admin/presentation/listPresenter/abstractions.js").IListPresenter<import("@webiny/app-headless-cms/types.js").CmsContentEntry<import("@webiny/app/types.js").GenericRecord>>;
16
+ get folders(): import("@webiny/app-aco/index.js").IFolderTreePresenter;
17
+ init(config?: IContentEntriesInitConfig): void;
18
+ dispose(): void;
19
+ selectEntry(id: string): void;
20
+ deselectEntry(): void;
21
+ createEntry(): void;
22
+ deleteEntry(id: string): Promise<boolean>;
23
+ publishEntry(id: string): Promise<boolean>;
24
+ unpublishEntry(id: string): Promise<boolean>;
25
+ moveEntry(id: string, folderId: string): Promise<boolean>;
26
+ }
27
+ export declare const ContentEntriesPresenterSchedulingDecorator: typeof ContentEntriesPresenterWithScheduling & {
28
+ __abstraction: import("@webiny/di").Abstraction<IContentEntriesPresenter>;
29
+ };
30
+ export {};
@@ -0,0 +1,67 @@
1
+ import { comparer, reaction } from "mobx";
2
+ import { ContentEntriesPresenter } from "@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js";
3
+ import { ScheduledActionsPresenter } from "./abstractions.js";
4
+ class ContentEntriesPresenterWithScheduling {
5
+ constructor(scheduledActions, original){
6
+ this.scheduledActions = scheduledActions;
7
+ this.original = original;
8
+ this._disposeReaction = null;
9
+ }
10
+ get vm() {
11
+ return this.original.vm;
12
+ }
13
+ get list() {
14
+ return this.original.list;
15
+ }
16
+ get folders() {
17
+ return this.original.folders;
18
+ }
19
+ init(config) {
20
+ this.original.init(config);
21
+ this._disposeReaction = reaction(()=>this.original.list.vm.rows.map((row)=>`${row.id}:${row.meta?.status ?? ""}:${row.live?.version ?? ""}`), (keys)=>{
22
+ if (0 === keys.length) return;
23
+ this.scheduledActions.loadForModel(this.original.vm.model.modelId);
24
+ }, {
25
+ fireImmediately: true,
26
+ equals: comparer.structural
27
+ });
28
+ }
29
+ dispose() {
30
+ if (this._disposeReaction) {
31
+ this._disposeReaction();
32
+ this._disposeReaction = null;
33
+ }
34
+ this.scheduledActions.dispose();
35
+ this.original.dispose();
36
+ }
37
+ selectEntry(id) {
38
+ this.original.selectEntry(id);
39
+ }
40
+ deselectEntry() {
41
+ this.original.deselectEntry();
42
+ }
43
+ createEntry() {
44
+ this.original.createEntry();
45
+ }
46
+ deleteEntry(id) {
47
+ return this.original.deleteEntry(id);
48
+ }
49
+ publishEntry(id) {
50
+ return this.original.publishEntry(id);
51
+ }
52
+ unpublishEntry(id) {
53
+ return this.original.unpublishEntry(id);
54
+ }
55
+ moveEntry(id, folderId) {
56
+ return this.original.moveEntry(id, folderId);
57
+ }
58
+ }
59
+ const ContentEntriesPresenterSchedulingDecorator = ContentEntriesPresenter.createDecorator({
60
+ decorator: ContentEntriesPresenterWithScheduling,
61
+ dependencies: [
62
+ ScheduledActionsPresenter
63
+ ]
64
+ });
65
+ export { ContentEntriesPresenterSchedulingDecorator };
66
+
67
+ //# sourceMappingURL=ContentEntriesPresenterSchedulingDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/scheduledActions/ContentEntriesPresenterSchedulingDecorator.js","sources":["../../../src/presentation/scheduledActions/ContentEntriesPresenterSchedulingDecorator.ts"],"sourcesContent":["import { comparer, reaction } from \"mobx\";\nimport type { IReactionDisposer } from \"mobx\";\nimport {\n ContentEntriesPresenter,\n type IContentEntriesPresenter,\n type IContentEntriesInitConfig\n} from \"@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js\";\nimport { ScheduledActionsPresenter } from \"./abstractions.js\";\n\n/**\n * Decorates the content-entries list presenter so the scheduled actions for the current model are\n * (re)loaded whenever the visible rows change. The reaction key includes each row's status/live,\n * so a direct publish/unpublish (which changes those, and lets the API cancel a schedule) triggers\n * a refresh without any extra signalling.\n */\nclass ContentEntriesPresenterWithScheduling implements IContentEntriesPresenter {\n private _disposeReaction: IReactionDisposer | null = null;\n\n constructor(\n private scheduledActions: ScheduledActionsPresenter.Interface,\n private original: IContentEntriesPresenter\n ) {}\n\n get vm() {\n return this.original.vm;\n }\n\n get list() {\n return this.original.list;\n }\n\n get folders() {\n return this.original.folders;\n }\n\n init(config?: IContentEntriesInitConfig): void {\n this.original.init(config);\n\n this._disposeReaction = reaction(\n () =>\n this.original.list.vm.rows.map(\n row => `${row.id}:${row.meta?.status ?? \"\"}:${row.live?.version ?? \"\"}`\n ),\n keys => {\n if (keys.length === 0) {\n return;\n }\n this.scheduledActions.loadForModel(this.original.vm.model.modelId);\n },\n { fireImmediately: true, equals: comparer.structural }\n );\n }\n\n dispose(): void {\n if (this._disposeReaction) {\n this._disposeReaction();\n this._disposeReaction = null;\n }\n this.scheduledActions.dispose();\n this.original.dispose();\n }\n\n selectEntry(id: string) {\n this.original.selectEntry(id);\n }\n\n deselectEntry() {\n this.original.deselectEntry();\n }\n\n createEntry() {\n this.original.createEntry();\n }\n\n deleteEntry(id: string) {\n return this.original.deleteEntry(id);\n }\n\n publishEntry(id: string) {\n return this.original.publishEntry(id);\n }\n\n unpublishEntry(id: string) {\n return this.original.unpublishEntry(id);\n }\n\n moveEntry(id: string, folderId: string) {\n return this.original.moveEntry(id, folderId);\n }\n}\n\nexport const ContentEntriesPresenterSchedulingDecorator = ContentEntriesPresenter.createDecorator({\n decorator: ContentEntriesPresenterWithScheduling,\n dependencies: [ScheduledActionsPresenter]\n});\n"],"names":["ContentEntriesPresenterWithScheduling","scheduledActions","original","config","reaction","row","keys","comparer","id","folderId","ContentEntriesPresenterSchedulingDecorator","ContentEntriesPresenter","ScheduledActionsPresenter"],"mappings":";;;AAeA,MAAMA;IAGF,YACYC,gBAAqD,EACrDC,QAAkC,CAC5C;aAFUD,gBAAgB,GAAhBA;aACAC,QAAQ,GAARA;aAJJ,gBAAgB,GAA6B;IAKlD;IAEH,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE;IAC3B;IAEA,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI;IAC7B;IAEA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO;IAChC;IAEA,KAAKC,MAAkC,EAAQ;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAACA;QAEnB,IAAI,CAAC,gBAAgB,GAAGC,SACpB,IACI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAC1BC,CAAAA,MAAO,GAAGA,IAAI,EAAE,CAAC,CAAC,EAAEA,IAAI,IAAI,EAAE,UAAU,GAAG,CAAC,EAAEA,IAAI,IAAI,EAAE,WAAW,IAAI,GAE/EC,CAAAA;YACI,IAAIA,AAAgB,MAAhBA,KAAK,MAAM,EACX;YAEJ,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;QACrE,GACA;YAAE,iBAAiB;YAAM,QAAQC,SAAS,UAAU;QAAC;IAE7D;IAEA,UAAgB;QACZ,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACvB,IAAI,CAAC,gBAAgB;YACrB,IAAI,CAAC,gBAAgB,GAAG;QAC5B;QACA,IAAI,CAAC,gBAAgB,CAAC,OAAO;QAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO;IACzB;IAEA,YAAYC,EAAU,EAAE;QACpB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAACA;IAC9B;IAEA,gBAAgB;QACZ,IAAI,CAAC,QAAQ,CAAC,aAAa;IAC/B;IAEA,cAAc;QACV,IAAI,CAAC,QAAQ,CAAC,WAAW;IAC7B;IAEA,YAAYA,EAAU,EAAE;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAACA;IACrC;IAEA,aAAaA,EAAU,EAAE;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,CAACA;IACtC;IAEA,eAAeA,EAAU,EAAE;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAACA;IACxC;IAEA,UAAUA,EAAU,EAAEC,QAAgB,EAAE;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAACD,IAAIC;IACvC;AACJ;AAEO,MAAMC,6CAA6CC,wBAAwB,eAAe,CAAC;IAC9F,WAAWX;IACX,cAAc;QAACY;KAA0B;AAC7C"}
@@ -0,0 +1,28 @@
1
+ import { ListScheduledActionsGateway } from "@webiny/app-scheduler/features/listScheduledActions/abstractions.js";
2
+ import { GetScheduledActionGateway } from "@webiny/app-scheduler/features/getScheduledAction/abstractions.js";
3
+ import type { SchedulerEntry } from "@webiny/app-scheduler/types.js";
4
+ import { type IScheduledActionsPresenter } from "./abstractions.js";
5
+ /**
6
+ * Holds the scheduled actions relevant to the current view (entries list or a single entry),
7
+ * keyed by target (entry) id. Fetching is driven by the presenters that own the view — the list
8
+ * presenter decorator reloads on row changes, the form alert loads the open entry — so this holds
9
+ * no invalidation logic of its own beyond `reload()`.
10
+ */
11
+ declare class ScheduledActionsPresenterImpl implements IScheduledActionsPresenter {
12
+ private listGateway;
13
+ private getGateway;
14
+ private _scheduledActions;
15
+ private _lastLoad;
16
+ constructor(listGateway: ListScheduledActionsGateway.Interface, getGateway: GetScheduledActionGateway.Interface);
17
+ getScheduledAction(targetId: string): SchedulerEntry | undefined;
18
+ loadForModel(modelId: string): Promise<void>;
19
+ loadForEntry(modelId: string, entryId: string): Promise<void>;
20
+ reload(): Promise<void>;
21
+ dispose(): void;
22
+ private fetchModel;
23
+ private fetchEntry;
24
+ }
25
+ export declare const ScheduledActionsPresenter: typeof ScheduledActionsPresenterImpl & {
26
+ __abstraction: import("@webiny/di").Abstraction<IScheduledActionsPresenter>;
27
+ };
28
+ export {};
@@ -0,0 +1,90 @@
1
+ import { makeAutoObservable, observable, runInAction } from "mobx";
2
+ import { ListScheduledActionsGateway } from "@webiny/app-scheduler/features/listScheduledActions/abstractions.js";
3
+ import { GetScheduledActionGateway } from "@webiny/app-scheduler/features/getScheduledAction/abstractions.js";
4
+ import { createNamespace } from "../../utils/index.js";
5
+ import { ScheduledActionsPresenter } from "./abstractions.js";
6
+ const PAGE_SIZE = 100;
7
+ class ScheduledActionsPresenterImpl {
8
+ constructor(listGateway, getGateway){
9
+ this.listGateway = listGateway;
10
+ this.getGateway = getGateway;
11
+ this._scheduledActions = observable.map();
12
+ this._lastLoad = null;
13
+ makeAutoObservable(this, {
14
+ listGateway: false,
15
+ getGateway: false,
16
+ _lastLoad: false
17
+ });
18
+ }
19
+ getScheduledAction(targetId) {
20
+ return this._scheduledActions.get(targetId);
21
+ }
22
+ loadForModel(modelId) {
23
+ const namespace = createNamespace({
24
+ modelId
25
+ });
26
+ this._lastLoad = ()=>this.fetchModel(namespace);
27
+ return this._lastLoad();
28
+ }
29
+ loadForEntry(modelId, entryId) {
30
+ const namespace = createNamespace({
31
+ modelId
32
+ });
33
+ this._lastLoad = ()=>this.fetchEntry(namespace, entryId);
34
+ return this._lastLoad();
35
+ }
36
+ reload() {
37
+ return this._lastLoad ? this._lastLoad() : Promise.resolve();
38
+ }
39
+ dispose() {
40
+ runInAction(()=>this._scheduledActions.clear());
41
+ this._lastLoad = null;
42
+ }
43
+ async fetchModel(namespace) {
44
+ try {
45
+ const actions = new Map();
46
+ let after;
47
+ do {
48
+ const response = await this.listGateway.execute({
49
+ namespace,
50
+ limit: PAGE_SIZE,
51
+ after,
52
+ sort: [
53
+ "scheduledFor_ASC"
54
+ ]
55
+ });
56
+ for (const item of response.items)actions.set(item.targetId, item);
57
+ after = response.meta.hasMoreItems ? response.meta.cursor ?? void 0 : void 0;
58
+ }while (after)
59
+ runInAction(()=>{
60
+ this._scheduledActions.replace(actions);
61
+ });
62
+ } catch (error) {
63
+ console.error(error);
64
+ }
65
+ }
66
+ async fetchEntry(namespace, entryId) {
67
+ try {
68
+ const action = await this.getGateway.execute({
69
+ namespace,
70
+ id: entryId
71
+ });
72
+ runInAction(()=>{
73
+ if (action) this._scheduledActions.set(entryId, action);
74
+ else this._scheduledActions.delete(entryId);
75
+ });
76
+ } catch (error) {
77
+ console.error(error);
78
+ }
79
+ }
80
+ }
81
+ const ScheduledActionsPresenter_ScheduledActionsPresenter = ScheduledActionsPresenter.createImplementation({
82
+ implementation: ScheduledActionsPresenterImpl,
83
+ dependencies: [
84
+ ListScheduledActionsGateway,
85
+ GetScheduledActionGateway
86
+ ]
87
+ });
88
+ export { ScheduledActionsPresenter_ScheduledActionsPresenter as ScheduledActionsPresenter };
89
+
90
+ //# sourceMappingURL=ScheduledActionsPresenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/scheduledActions/ScheduledActionsPresenter.js","sources":["../../../src/presentation/scheduledActions/ScheduledActionsPresenter.ts"],"sourcesContent":["import { makeAutoObservable, observable, runInAction } from \"mobx\";\nimport { ListScheduledActionsGateway } from \"@webiny/app-scheduler/features/listScheduledActions/abstractions.js\";\nimport { GetScheduledActionGateway } from \"@webiny/app-scheduler/features/getScheduledAction/abstractions.js\";\nimport type { SchedulerEntry } from \"@webiny/app-scheduler/types.js\";\nimport { createNamespace } from \"~/utils/index.js\";\nimport {\n ScheduledActionsPresenter as Abstraction,\n type IScheduledActionsPresenter\n} from \"./abstractions.js\";\n\nconst PAGE_SIZE = 100;\n\n/**\n * Holds the scheduled actions relevant to the current view (entries list or a single entry),\n * keyed by target (entry) id. Fetching is driven by the presenters that own the view — the list\n * presenter decorator reloads on row changes, the form alert loads the open entry — so this holds\n * no invalidation logic of its own beyond `reload()`.\n */\nclass ScheduledActionsPresenterImpl implements IScheduledActionsPresenter {\n private _scheduledActions = observable.map<string, SchedulerEntry>();\n private _lastLoad: (() => Promise<void>) | null = null;\n\n constructor(\n private listGateway: ListScheduledActionsGateway.Interface,\n private getGateway: GetScheduledActionGateway.Interface\n ) {\n makeAutoObservable<\n ScheduledActionsPresenterImpl,\n \"listGateway\" | \"getGateway\" | \"_lastLoad\"\n >(this, {\n listGateway: false,\n getGateway: false,\n _lastLoad: false\n });\n }\n\n getScheduledAction(targetId: string): SchedulerEntry | undefined {\n return this._scheduledActions.get(targetId);\n }\n\n loadForModel(modelId: string): Promise<void> {\n const namespace = createNamespace({ modelId });\n this._lastLoad = () => this.fetchModel(namespace);\n return this._lastLoad();\n }\n\n loadForEntry(modelId: string, entryId: string): Promise<void> {\n const namespace = createNamespace({ modelId });\n this._lastLoad = () => this.fetchEntry(namespace, entryId);\n return this._lastLoad();\n }\n\n reload(): Promise<void> {\n return this._lastLoad ? this._lastLoad() : Promise.resolve();\n }\n\n dispose(): void {\n runInAction(() => this._scheduledActions.clear());\n this._lastLoad = null;\n }\n\n private async fetchModel(namespace: string): Promise<void> {\n try {\n const actions = new Map<string, SchedulerEntry>();\n let after: string | undefined = undefined;\n\n do {\n const response = await this.listGateway.execute({\n namespace,\n limit: PAGE_SIZE,\n after,\n sort: [\"scheduledFor_ASC\"]\n });\n for (const item of response.items) {\n actions.set(item.targetId, item);\n }\n after = response.meta.hasMoreItems\n ? (response.meta.cursor ?? undefined)\n : undefined;\n } while (after);\n\n runInAction(() => {\n this._scheduledActions.replace(actions);\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n private async fetchEntry(namespace: string, entryId: string): Promise<void> {\n try {\n const action = await this.getGateway.execute({ namespace, id: entryId });\n runInAction(() => {\n if (action) {\n this._scheduledActions.set(entryId, action);\n } else {\n this._scheduledActions.delete(entryId);\n }\n });\n } catch (error) {\n console.error(error);\n }\n }\n}\n\nexport const ScheduledActionsPresenter = Abstraction.createImplementation({\n implementation: ScheduledActionsPresenterImpl,\n dependencies: [ListScheduledActionsGateway, GetScheduledActionGateway]\n});\n"],"names":["PAGE_SIZE","ScheduledActionsPresenterImpl","listGateway","getGateway","observable","makeAutoObservable","targetId","modelId","namespace","createNamespace","entryId","Promise","runInAction","actions","Map","after","response","item","undefined","error","console","action","ScheduledActionsPresenter","Abstraction","ListScheduledActionsGateway","GetScheduledActionGateway"],"mappings":";;;;;AAUA,MAAMA,YAAY;AAQlB,MAAMC;IAIF,YACYC,WAAkD,EAClDC,UAA+C,CACzD;aAFUD,WAAW,GAAXA;aACAC,UAAU,GAAVA;aALJ,iBAAiB,GAAGC,WAAW,GAAG;aAClC,SAAS,GAAiC;QAM9CC,mBAGE,IAAI,EAAE;YACJ,aAAa;YACb,YAAY;YACZ,WAAW;QACf;IACJ;IAEA,mBAAmBC,QAAgB,EAA8B;QAC7D,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAACA;IACtC;IAEA,aAAaC,OAAe,EAAiB;QACzC,MAAMC,YAAYC,gBAAgB;YAAEF;QAAQ;QAC5C,IAAI,CAAC,SAAS,GAAG,IAAM,IAAI,CAAC,UAAU,CAACC;QACvC,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,aAAaD,OAAe,EAAEG,OAAe,EAAiB;QAC1D,MAAMF,YAAYC,gBAAgB;YAAEF;QAAQ;QAC5C,IAAI,CAAC,SAAS,GAAG,IAAM,IAAI,CAAC,UAAU,CAACC,WAAWE;QAClD,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,SAAwB;QACpB,OAAO,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,KAAKC,QAAQ,OAAO;IAC9D;IAEA,UAAgB;QACZC,YAAY,IAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK;QAC9C,IAAI,CAAC,SAAS,GAAG;IACrB;IAEA,MAAc,WAAWJ,SAAiB,EAAiB;QACvD,IAAI;YACA,MAAMK,UAAU,IAAIC;YACpB,IAAIC;YAEJ,GAAG;gBACC,MAAMC,WAAW,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;oBAC5CR;oBACA,OAAOR;oBACPe;oBACA,MAAM;wBAAC;qBAAmB;gBAC9B;gBACA,KAAK,MAAME,QAAQD,SAAS,KAAK,CAC7BH,QAAQ,GAAG,CAACI,KAAK,QAAQ,EAAEA;gBAE/BF,QAAQC,SAAS,IAAI,CAAC,YAAY,GAC3BA,SAAS,IAAI,CAAC,MAAM,IAAIE,SACzBA;YACV,QAASH,MAAO;YAEhBH,YAAY;gBACR,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAACC;YACnC;QACJ,EAAE,OAAOM,OAAO;YACZC,QAAQ,KAAK,CAACD;QAClB;IACJ;IAEA,MAAc,WAAWX,SAAiB,EAAEE,OAAe,EAAiB;QACxE,IAAI;YACA,MAAMW,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAEb;gBAAW,IAAIE;YAAQ;YACtEE,YAAY;gBACR,IAAIS,QACA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAACX,SAASW;qBAEpC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAACX;YAEtC;QACJ,EAAE,OAAOS,OAAO;YACZC,QAAQ,KAAK,CAACD;QAClB;IACJ;AACJ;AAEO,MAAMG,sDAA4BC,0BAAAA,oBAAgC,CAAC;IACtE,gBAAgBtB;IAChB,cAAc;QAACuB;QAA6BC;KAA0B;AAC1E"}
@@ -0,0 +1,16 @@
1
+ import type { SchedulerEntry } from "@webiny/app-scheduler/types.js";
2
+ export interface IScheduledActionsPresenter {
3
+ /** Loads all scheduled actions for a model (used by the entries list). */
4
+ loadForModel(modelId: string): Promise<void>;
5
+ /** Loads the scheduled action for a single entry (used by the entry form). */
6
+ loadForEntry(modelId: string, entryId: string): Promise<void>;
7
+ /** Re-runs the last load. Call after a schedule/cancel to reflect the change. */
8
+ reload(): Promise<void>;
9
+ /** Returns the scheduled action for a target (entry) id, if any. */
10
+ getScheduledAction(targetId: string): SchedulerEntry | undefined;
11
+ dispose(): void;
12
+ }
13
+ export declare const ScheduledActionsPresenter: import("@webiny/di").Abstraction<IScheduledActionsPresenter>;
14
+ export declare namespace ScheduledActionsPresenter {
15
+ type Interface = IScheduledActionsPresenter;
16
+ }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/admin";
2
+ const ScheduledActionsPresenter = createAbstraction("ScheduledActionsPresenter");
3
+ export { ScheduledActionsPresenter };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/scheduledActions/abstractions.js","sources":["../../../src/presentation/scheduledActions/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { SchedulerEntry } from \"@webiny/app-scheduler/types.js\";\n\nexport interface IScheduledActionsPresenter {\n /** Loads all scheduled actions for a model (used by the entries list). */\n loadForModel(modelId: string): Promise<void>;\n /** Loads the scheduled action for a single entry (used by the entry form). */\n loadForEntry(modelId: string, entryId: string): Promise<void>;\n /** Re-runs the last load. Call after a schedule/cancel to reflect the change. */\n reload(): Promise<void>;\n /** Returns the scheduled action for a target (entry) id, if any. */\n getScheduledAction(targetId: string): SchedulerEntry | undefined;\n dispose(): void;\n}\n\nexport const ScheduledActionsPresenter = createAbstraction<IScheduledActionsPresenter>(\n \"ScheduledActionsPresenter\"\n);\n\nexport namespace ScheduledActionsPresenter {\n export type Interface = IScheduledActionsPresenter;\n}\n"],"names":["ScheduledActionsPresenter","createAbstraction"],"mappings":";AAeO,MAAMA,4BAA4BC,kBACrC"}
@@ -0,0 +1,3 @@
1
+ export declare const ScheduledActionsPresenterFeature: import("@webiny/feature/admin").FeatureDefinition<{
2
+ presenter: import("./abstractions.js").IScheduledActionsPresenter;
3
+ }, []>;
@@ -0,0 +1,19 @@
1
+ import { createFeature } from "@webiny/feature/admin";
2
+ import { ScheduledActionsPresenter } from "./abstractions.js";
3
+ import { ScheduledActionsPresenter as external_ScheduledActionsPresenter_js_ScheduledActionsPresenter } from "./ScheduledActionsPresenter.js";
4
+ import { ContentEntriesPresenterSchedulingDecorator } from "./ContentEntriesPresenterSchedulingDecorator.js";
5
+ const ScheduledActionsPresenterFeature = createFeature({
6
+ name: "Scheduler/ScheduledActionsPresenter",
7
+ register (container) {
8
+ container.register(external_ScheduledActionsPresenter_js_ScheduledActionsPresenter).inSingletonScope();
9
+ container.registerDecorator(ContentEntriesPresenterSchedulingDecorator);
10
+ },
11
+ resolve (container) {
12
+ return {
13
+ presenter: container.resolve(ScheduledActionsPresenter)
14
+ };
15
+ }
16
+ });
17
+ export { ScheduledActionsPresenterFeature };
18
+
19
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/scheduledActions/feature.js","sources":["../../../src/presentation/scheduledActions/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { ScheduledActionsPresenter as Abstraction } from \"./abstractions.js\";\nimport { ScheduledActionsPresenter } from \"./ScheduledActionsPresenter.js\";\nimport { ContentEntriesPresenterSchedulingDecorator } from \"./ContentEntriesPresenterSchedulingDecorator.js\";\n\nexport const ScheduledActionsPresenterFeature = createFeature({\n name: \"Scheduler/ScheduledActionsPresenter\",\n register(container) {\n container.register(ScheduledActionsPresenter).inSingletonScope();\n container.registerDecorator(ContentEntriesPresenterSchedulingDecorator);\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n"],"names":["ScheduledActionsPresenterFeature","createFeature","container","ScheduledActionsPresenter","ContentEntriesPresenterSchedulingDecorator","Abstraction"],"mappings":";;;;AAKO,MAAMA,mCAAmCC,cAAc;IAC1D,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,iEAA2B,gBAAgB;QAC9DD,UAAU,iBAAiB,CAACE;IAChC;IACA,SAAQF,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACG;QACjC;IACJ;AACJ"}
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const Sidebar: () => React.JSX.Element;
@@ -1,27 +0,0 @@
1
- import react from "react";
2
- import { Components } from "@webiny/app-headless-cms";
3
- import { useApolloClient } from "@apollo/react-hooks";
4
- import { IsModelPublishable, useModel } from "@webiny/app-headless-cms/exports/admin/cms.js";
5
- import { usePermissions } from "../../hooks/usePermissions.js";
6
- import { Scheduler } from "@webiny/app-scheduler";
7
- import { SchedulerButton } from "./SchedulerButton.js";
8
- import { createNamespace } from "../../utils/index.js";
9
- const Sidebar = Components.Sidebar.Footer.createDecorator((Original)=>function({ children }) {
10
- const client = useApolloClient();
11
- const { model } = useModel();
12
- const { canPublish, canUnpublish } = usePermissions();
13
- const namespace = createNamespace(model);
14
- if (!canPublish && !canUnpublish) return /*#__PURE__*/ react.createElement(Original, null, children);
15
- return /*#__PURE__*/ react.createElement(Original, null, /*#__PURE__*/ react.createElement(IsModelPublishable, null, children, /*#__PURE__*/ react.createElement(Scheduler, {
16
- namespace: namespace,
17
- client: client,
18
- canPublish: canPublish,
19
- canUnpublish: canUnpublish,
20
- render: ({ showScheduler })=>/*#__PURE__*/ react.createElement(SchedulerButton, {
21
- onClick: showScheduler
22
- })
23
- })));
24
- });
25
- export { Sidebar };
26
-
27
- //# sourceMappingURL=Sidebar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"components/Sidebar/Sidebar.js","sources":["../../../src/components/Sidebar/Sidebar.tsx"],"sourcesContent":["import React from \"react\";\nimport { Components } from \"@webiny/app-headless-cms\";\nimport { useApolloClient } from \"@apollo/react-hooks\";\nimport { IsModelPublishable, useModel } from \"@webiny/app-headless-cms/exports/admin/cms.js\";\nimport { usePermissions } from \"~/hooks/usePermissions.js\";\nimport { Scheduler as BaseScheduler } from \"@webiny/app-scheduler\";\nimport { SchedulerButton } from \"./SchedulerButton.js\";\nimport { createNamespace } from \"~/utils/index.js\";\n\nexport const Sidebar = Components.Sidebar.Footer.createDecorator(Original => {\n return function ScheduleSidebarFooter({ children }) {\n const client = useApolloClient();\n const { model } = useModel();\n const { canPublish, canUnpublish } = usePermissions();\n\n const namespace = createNamespace(model);\n\n if (!canPublish && !canUnpublish) {\n return <Original>{children}</Original>;\n }\n\n return (\n <Original>\n <IsModelPublishable>\n {children}\n <BaseScheduler\n namespace={namespace}\n client={client}\n canPublish={canPublish}\n canUnpublish={canUnpublish}\n render={({ showScheduler }) => {\n return <SchedulerButton onClick={showScheduler} />;\n }}\n />\n </IsModelPublishable>\n </Original>\n );\n };\n});\n"],"names":["Sidebar","Components","Original","children","client","useApolloClient","model","useModel","canPublish","canUnpublish","usePermissions","namespace","createNamespace","IsModelPublishable","BaseScheduler","showScheduler","SchedulerButton"],"mappings":";;;;;;;;AASO,MAAMA,UAAUC,WAAW,OAAO,CAAC,MAAM,CAAC,eAAe,CAACC,CAAAA,WACtD,SAA+B,EAAEC,QAAQ,EAAE;QAC9C,MAAMC,SAASC;QACf,MAAM,EAAEC,KAAK,EAAE,GAAGC;QAClB,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC;QAErC,MAAMC,YAAYC,gBAAgBN;QAElC,IAAI,CAACE,cAAc,CAACC,cAChB,OAAO,WAAP,GAAO,oBAACP,UAAAA,MAAUC;QAGtB,OAAO,WAAP,GACI,oBAACD,UAAAA,MAAAA,WAAAA,GACG,oBAACW,oBAAkBA,MACdV,UAAAA,WAAAA,GACD,oBAACW,WAAaA;YACV,WAAWH;YACX,QAAQP;YACR,YAAYI;YACZ,cAAcC;YACd,QAAQ,CAAC,EAAEM,aAAa,EAAE,GACf,WAAP,GAAO,oBAACC,iBAAeA;oBAAC,SAASD;;;IAMzD"}