Skip to content

Commit 4af56eb

Browse files
committed
feat(app-headless-cms-scheduler): schedule dialog
1 parent fdd9228 commit 4af56eb

File tree

23 files changed

+424
-164
lines changed

23 files changed

+424
-164
lines changed

packages/api-headless-cms-scheduler/src/scheduler/ScheduleRecord.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import {
2-
type DateOnType,
32
type IScheduleEntryValues,
43
type IScheduleRecord,
54
type ScheduledOnType,
65
ScheduleType
76
} from "~/scheduler/types.js";
87
import type { CmsEntry, CmsIdentity, CmsModel } from "@webiny/api-headless-cms/types/index.js";
98
import { WebinyError } from "@webiny/error";
10-
import { isoStringToDate } from "~/scheduler/dates.js";
119

1210
export interface IScheduleRecordParams {
1311
id: string;
@@ -22,7 +20,7 @@ export interface IScheduleRecordParams {
2220
* The date when the action is to be set as done.
2321
* User can set publishedOn (and other relevant dates) with this parameter.
2422
*/
25-
dateOn: DateOnType | undefined;
23+
// dateOn: DateOnType | undefined;
2624
type: ScheduleType;
2725
title: string;
2826
}
@@ -34,7 +32,7 @@ export class ScheduleRecord implements IScheduleRecord {
3432
public readonly scheduledBy: CmsIdentity;
3533
public readonly publishOn: ScheduledOnType | undefined;
3634
public readonly unpublishOn: ScheduledOnType | undefined;
37-
public readonly dateOn: DateOnType | undefined;
35+
// public readonly dateOn: DateOnType | undefined;
3836
public readonly type: ScheduleType;
3937
public readonly title: string;
4038

@@ -43,7 +41,7 @@ export class ScheduleRecord implements IScheduleRecord {
4341
this.targetId = record.targetId;
4442
this.model = record.model;
4543
this.scheduledBy = record.scheduledBy;
46-
this.dateOn = record.dateOn;
44+
// this.dateOn = record.dateOn;
4745
this.publishOn = record.type === ScheduleType.publish ? record.scheduledOn : undefined;
4846
this.unpublishOn = record.type === ScheduleType.unpublish ? record.scheduledOn : undefined;
4947
this.type = record.type;
@@ -83,7 +81,7 @@ export const transformScheduleEntry = (
8381
title: entry.values.title,
8482
targetId: entry.values.targetId,
8583
scheduledOn: new Date(entry.values.scheduledOn),
86-
dateOn: isoStringToDate(entry.values.dateOn),
84+
// dateOn: isoStringToDate(entry.values.dateOn),
8785
scheduledBy: entry.savedBy,
8886
model: targetModel
8987
});

packages/api-headless-cms-scheduler/src/scheduler/actions/PublishScheduleAction.ts

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import type { ISchedulerService } from "~/service/types.js";
2020
import { dateToISOString } from "~/scheduler/dates.js";
2121
import { NotFoundError } from "@webiny/handler-graphql";
2222
import { dateInTheFuture } from "~/utils/dateInTheFuture.js";
23-
import { WebinyError } from "@webiny/error/index";
2423
import { parseIdentifier } from "@webiny/utils/parseIdentifier.js";
2524

2625
export type PublishScheduleActionCms = Pick<
@@ -61,7 +60,7 @@ export class PublishScheduleAction implements IScheduleAction {
6160
public async schedule(params: IScheduleActionScheduleParams): Promise<IScheduleRecord> {
6261
const { targetId, input, scheduleRecordId } = params;
6362

64-
const targetEntry = await this.getUpdateableTargetEntry(targetId);
63+
const targetEntry = await this.getTargetEntry(targetId);
6564

6665
const title = targetEntry.values[this.targetModel.titleFieldId] || "Unknown entry title";
6766
const identity = this.getIdentity();
@@ -79,7 +78,7 @@ export class PublishScheduleAction implements IScheduleAction {
7978
model: this.targetModel,
8079
scheduledBy: publishedEntry.savedBy,
8180
scheduledOn: new Date(publishedEntry.savedOn),
82-
dateOn: currentDate,
81+
// dateOn: currentDate,
8382
type: ScheduleType.publish,
8483
title
8584
});
@@ -106,7 +105,6 @@ export class PublishScheduleAction implements IScheduleAction {
106105
model: this.targetModel,
107106
scheduledBy: publishedEntry.savedBy,
108107
scheduledOn: currentDate,
109-
dateOn: input.dateOn,
110108
type: ScheduleType.publish,
111109
title
112110
});
@@ -120,7 +118,6 @@ export class PublishScheduleAction implements IScheduleAction {
120118
title,
121119
type: ScheduleType.publish,
122120
scheduledOn: dateToISOString(input.scheduleOn),
123-
dateOn: input.dateOn ? dateToISOString(input.dateOn) : undefined,
124121
scheduledBy: identity
125122
});
126123

@@ -153,27 +150,15 @@ export class PublishScheduleAction implements IScheduleAction {
153150
const currentDate = new Date();
154151
const targetId = original.targetId;
155152

156-
const targetEntry = await this.getUpdateableTargetEntry(targetId);
153+
const targetEntry = await this.getTargetEntry(targetId);
157154

158155
/**
159156
* There are two cases when we can immediately publish the entry:
160157
* 1. If the user requested it.
161158
* 2. If the entry is scheduled for a date in the past.
162159
*/
163160
if (input.immediately || input.scheduleOn < currentDate) {
164-
const updatedTargetEntry = await this.cms.updateEntry(
165-
this.targetModel,
166-
targetEntry.id,
167-
{
168-
lastPublishedOn: input.dateOn ? input.dateOn.toISOString() : undefined,
169-
lastPublishedBy: this.getIdentity()
170-
}
171-
);
172-
173-
const publishedEntry = await this.cms.publishEntry(
174-
this.targetModel,
175-
updatedTargetEntry.id
176-
);
161+
await this.cms.publishEntry(this.targetModel, targetEntry.id);
177162
/**
178163
* We can safely cancel the original schedule entry and the event.
179164
*
@@ -188,20 +173,21 @@ export class PublishScheduleAction implements IScheduleAction {
188173
return {
189174
...original,
190175
publishOn: currentDate,
191-
unpublishOn: undefined,
192-
dateOn: publishedEntry.lastPublishedOn
193-
? new Date(publishedEntry.lastPublishedOn)
194-
: undefined
176+
unpublishOn: undefined
177+
// dateOn: publishedEntry.lastPublishedOn
178+
// ? new Date(publishedEntry.lastPublishedOn)
179+
// : undefined
195180
};
196181
}
197182

198-
await this.cms.updateEntry<
199-
Pick<IScheduleEntryValues, "scheduledOn" | "dateOn" | "scheduledBy">
200-
>(this.scheduleModel, original.id, {
201-
scheduledBy: this.getIdentity(),
202-
scheduledOn: dateToISOString(input.scheduleOn),
203-
dateOn: input.dateOn ? dateToISOString(input.dateOn) : undefined
204-
});
183+
await this.cms.updateEntry<Pick<IScheduleEntryValues, "scheduledOn" | "scheduledBy">>(
184+
this.scheduleModel,
185+
original.id,
186+
{
187+
scheduledBy: this.getIdentity(),
188+
scheduledOn: dateToISOString(input.scheduleOn)
189+
}
190+
);
205191

206192
try {
207193
await this.service.update({
@@ -214,8 +200,7 @@ export class PublishScheduleAction implements IScheduleAction {
214200
return {
215201
...original,
216202
publishOn: new Date(),
217-
unpublishOn: undefined,
218-
dateOn: input.dateOn
203+
unpublishOn: undefined
219204
};
220205
}
221206

@@ -255,17 +240,7 @@ export class PublishScheduleAction implements IScheduleAction {
255240
}
256241
}
257242

258-
private async getUpdateableTargetEntry<T = CmsEntryValues>(id: string): Promise<CmsEntry<T>> {
259-
const entry = await this.cms.getEntryById<T>(this.targetModel, id);
260-
if (entry.locked) {
261-
throw new WebinyError(
262-
`Cannot schedule a publish action for entry "${entry.id}" because it is locked.`,
263-
"ENTRY_LOCKED",
264-
{
265-
entryId: entry.id
266-
}
267-
);
268-
}
269-
return entry;
243+
private async getTargetEntry<T = CmsEntryValues>(id: string): Promise<CmsEntry<T>> {
244+
return await this.cms.getEntryById<T>(this.targetModel, id);
270245
}
271246
}

packages/api-headless-cms-scheduler/src/scheduler/actions/UnpublishScheduleAction.ts

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import type { ISchedulerService } from "~/service/types.js";
2020
import { dateToISOString } from "~/scheduler/dates.js";
2121
import { NotFoundError } from "@webiny/handler-graphql";
2222
import { dateInTheFuture } from "~/utils/dateInTheFuture.js";
23-
import { WebinyError } from "@webiny/error";
2423
import { parseIdentifier } from "@webiny/utils/parseIdentifier.js";
2524

2625
export type UnpublishScheduleActionCms = Pick<
@@ -61,7 +60,7 @@ export class UnpublishScheduleAction implements IScheduleAction {
6160
public async schedule(params: IScheduleActionScheduleParams): Promise<IScheduleRecord> {
6261
const { targetId, input, scheduleRecordId } = params;
6362

64-
const targetEntry = await this.getUpdateableTargetEntry(targetId);
63+
const targetEntry = await this.getTargetEntry(targetId);
6564
const title = targetEntry.values[this.targetModel.titleFieldId] || "Unknown entry title";
6665
const identity = this.getIdentity();
6766

@@ -77,7 +76,7 @@ export class UnpublishScheduleAction implements IScheduleAction {
7776
model: this.targetModel,
7877
scheduledBy: unpublishedEntry.savedBy,
7978
scheduledOn: currentDate,
80-
dateOn: currentDate,
79+
// dateOn: currentDate,
8180
type: ScheduleType.unpublish,
8281
title
8382
});
@@ -95,7 +94,7 @@ export class UnpublishScheduleAction implements IScheduleAction {
9594
model: this.targetModel,
9695
scheduledBy: identity,
9796
scheduledOn: input.scheduleOn,
98-
dateOn: input.dateOn,
97+
// dateOn: input.dateOn,
9998
type: ScheduleType.unpublish,
10099
title
101100
});
@@ -111,7 +110,7 @@ export class UnpublishScheduleAction implements IScheduleAction {
111110
targetModelId: this.targetModel.modelId,
112111
title,
113112
type: ScheduleType.unpublish,
114-
dateOn: input.dateOn ? dateToISOString(input.dateOn) : undefined,
113+
// dateOn: input.dateOn ? dateToISOString(input.dateOn) : undefined,
115114
scheduledBy: identity,
116115
scheduledOn: dateToISOString(input.scheduleOn)
117116
});
@@ -146,14 +145,14 @@ export class UnpublishScheduleAction implements IScheduleAction {
146145
const currentDate = new Date();
147146
const targetId = original.targetId;
148147

149-
const targetEntry = await this.getUpdateableTargetEntry(targetId);
148+
const targetEntry = await this.getTargetEntry(targetId);
150149
/**
151150
* There are two cases when we can immediately publish the entry:
152151
* 1. If the user requested it.
153152
* 2. If the entry is scheduled for a date in the past.
154153
*/
155154
if (input.immediately || dateInTheFuture(input.scheduleOn)) {
156-
const publishedEntry = await this.cms.unpublishEntry(this.targetModel, targetEntry.id);
155+
await this.cms.unpublishEntry(this.targetModel, targetEntry.id);
157156
/**
158157
* We can safely cancel the original schedule entry and the event.
159158
*
@@ -168,19 +167,19 @@ export class UnpublishScheduleAction implements IScheduleAction {
168167
return {
169168
...original,
170169
publishOn: undefined,
171-
unpublishOn: currentDate,
172-
dateOn: publishedEntry.lastPublishedOn
173-
? new Date(publishedEntry.lastPublishedOn)
174-
: undefined
170+
unpublishOn: currentDate
171+
// dateOn: publishedEntry.lastPublishedOn
172+
// ? new Date(publishedEntry.lastPublishedOn)
173+
// : undefined
175174
};
176175
}
177176

178-
await this.cms.updateEntry<Pick<IScheduleEntryValues, "scheduledOn" | "dateOn">>(
177+
await this.cms.updateEntry<Pick<IScheduleEntryValues, "scheduledOn">>(
179178
this.scheduleModel,
180179
original.id,
181180
{
182-
scheduledOn: dateToISOString(input.scheduleOn),
183-
dateOn: input.dateOn ? dateToISOString(input.dateOn) : undefined
181+
scheduledOn: dateToISOString(input.scheduleOn)
182+
// dateOn: input.dateOn ? dateToISOString(input.dateOn) : undefined
184183
}
185184
);
186185

@@ -198,8 +197,8 @@ export class UnpublishScheduleAction implements IScheduleAction {
198197
return {
199198
...original,
200199
publishOn: undefined,
201-
unpublishOn: currentDate,
202-
dateOn: input.dateOn
200+
unpublishOn: currentDate
201+
// dateOn: input.dateOn
203202
};
204203
}
205204

@@ -240,17 +239,7 @@ export class UnpublishScheduleAction implements IScheduleAction {
240239
}
241240
}
242241

243-
private async getUpdateableTargetEntry<T = CmsEntryValues>(id: string): Promise<CmsEntry<T>> {
244-
const entry = await this.cms.getEntryById<T>(this.targetModel, id);
245-
if (entry.locked) {
246-
throw new WebinyError(
247-
`Cannot schedule a unpublish action for entry "${entry.id}" because it is locked.`,
248-
"ENTRY_LOCKED",
249-
{
250-
entryId: entry.id
251-
}
252-
);
253-
}
254-
return entry;
242+
private async getTargetEntry<T = CmsEntryValues>(id: string): Promise<CmsEntry<T>> {
243+
return await this.cms.getEntryById<T>(this.targetModel, id);
255244
}
256245
}

packages/api-headless-cms-scheduler/src/scheduler/types.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,12 @@ export type DateOnType = Date;
2424
export interface ISchedulerInputImmediately {
2525
immediately: true;
2626
scheduleOn?: never;
27-
dateOn?: DateOnType;
2827
type: ScheduleType;
2928
}
3029

3130
export interface ISchedulerInputScheduled {
3231
immediately?: false;
3332
scheduleOn: ScheduledOnType;
34-
dateOn?: DateOnType;
3533
type: ScheduleType;
3634
}
3735

@@ -42,7 +40,7 @@ export interface IScheduleRecord {
4240
targetId: string;
4341
model: CmsModel;
4442
scheduledBy: CmsIdentity;
45-
dateOn: DateOnType | undefined;
43+
// dateOn: DateOnType | undefined;
4644
publishOn: ScheduledOnType | undefined;
4745
unpublishOn: ScheduledOnType | undefined;
4846
type: ScheduleType;
@@ -82,7 +80,7 @@ export interface IScheduleEntryValues {
8280
targetId: string;
8381
targetModelId: string;
8482
scheduledBy: CmsIdentity;
85-
dateOn: DateISOString | undefined;
83+
// dateOn: DateISOString | undefined;
8684
scheduledOn: DateISOString;
8785
type: string;
8886
title: string;

packages/app-headless-cms-scheduler/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
"@webiny/app-admin": "0.0.0",
1818
"@webiny/app-headless-cms-common": "0.0.0",
1919
"@webiny/app-utils": "0.0.0",
20+
"@webiny/form": "0.0.0",
2021
"@webiny/icons": "0.0.0",
2122
"@webiny/react-composition": "0.0.0",
2223
"@webiny/react-properties": "0.0.0",
2324
"@webiny/ui": "0.0.0",
25+
"@webiny/validation": "0.0.0",
2426
"apollo-client": "^2.6.10",
2527
"lodash": "^4.17.21",
2628
"mobx": "^6.9.0",

packages/app-headless-cms-scheduler/src/Domain/Repositories/SchedulerItems/SchedulerItemsRepository.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class SchedulerItemsRepository implements ISchedulerItemsRepository {
6565
}
6666

6767
public async getItem(params: Omit<ISchedulerGetExecuteParams, "modelId">) {
68-
const response = await this.getGateway.execute({
68+
const item = await this.getGateway.execute({
6969
...params,
7070
modelId: this.model.modelId
7171
});
@@ -76,12 +76,12 @@ export class SchedulerItemsRepository implements ISchedulerItemsRepository {
7676
this.items = [];
7777
});
7878

79-
if (!response?.item) {
79+
if (!item) {
8080
return;
8181
}
8282

8383
runInAction(() => {
84-
this.items = [response.item];
84+
this.items = [item];
8585
});
8686
}
8787

packages/app-headless-cms-scheduler/src/Gateways/SchedulerGetGateway.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ export interface ISchedulerGetExecuteParams {
55
id: string;
66
}
77

8-
export interface ISchedulerGetGatewayResponse {
9-
item: SchedulerEntry;
10-
}
8+
export type ISchedulerGetGatewayResponse = SchedulerEntry | null;
119

1210
export interface ISchedulerGetGateway {
1311
execute(params: ISchedulerGetExecuteParams): Promise<ISchedulerGetGatewayResponse>;

0 commit comments

Comments
 (0)