feat(campaign): complete durable operator queue
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
export type OperatorQueueAction =
|
||||
| "details"
|
||||
| "report"
|
||||
| "pause"
|
||||
| "resume"
|
||||
| "retry"
|
||||
@@ -9,6 +10,7 @@ export type OperatorQueueAction =
|
||||
|
||||
export type OperatorQueuePermissions = {
|
||||
canRead: boolean;
|
||||
canOpenReport: boolean;
|
||||
canControl: boolean;
|
||||
canRetry: boolean;
|
||||
canQueue: boolean;
|
||||
@@ -19,7 +21,7 @@ export type OperatorQueueFacts = {
|
||||
retryable: number;
|
||||
outcomeUnknown: number;
|
||||
queueableUnattempted: number;
|
||||
queued: number;
|
||||
pausable: number;
|
||||
paused: number;
|
||||
cancellable: number;
|
||||
};
|
||||
@@ -34,6 +36,40 @@ export const OPERATOR_QUEUE_REASON = {
|
||||
noCancellable: "i18n:govoplan-campaign.no_cancellable_queued_work_remains.80e31d49"
|
||||
} as const;
|
||||
|
||||
export type CampaignVersionWorkItem<T> = {
|
||||
campaignId: string;
|
||||
versionId: string;
|
||||
versionNumber: number;
|
||||
isCurrent: boolean;
|
||||
summary: T | null;
|
||||
};
|
||||
|
||||
/** Preserve every audit version so work does not disappear when a new draft becomes current. */
|
||||
export function campaignVersionWorkItems<T>(
|
||||
campaignId: string,
|
||||
currentVersionId: string | null | undefined,
|
||||
versions: Array<{id: string;version_number: number;}>,
|
||||
summaries: Record<string, T | null>
|
||||
): CampaignVersionWorkItem<T>[] {
|
||||
return versions.map((version) => ({
|
||||
campaignId,
|
||||
versionId: version.id,
|
||||
versionNumber: version.version_number,
|
||||
isCurrent: version.id === currentVersionId,
|
||||
summary: summaries[version.id] ?? null
|
||||
}));
|
||||
}
|
||||
|
||||
export type CampaignLifecycleTotals = {pausable: number;paused: number;cancellable: number;};
|
||||
|
||||
export function campaignLifecycleTotals(items: CampaignLifecycleTotals[]): CampaignLifecycleTotals {
|
||||
return items.reduce((totals, item) => ({
|
||||
pausable: totals.pausable + item.pausable,
|
||||
paused: totals.paused + item.paused,
|
||||
cancellable: totals.cancellable + item.cancellable
|
||||
}), { pausable: 0, paused: 0, cancellable: 0 });
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reason each fixed queue action is unavailable. A null result means
|
||||
* the action is permitted and meaningful for the current queue projection.
|
||||
@@ -44,9 +80,10 @@ export function operatorQueueActionBlocks(
|
||||
): Record<OperatorQueueAction, string | null> {
|
||||
return {
|
||||
details: permissions.canRead ? null : OPERATOR_QUEUE_REASON.permissionDenied,
|
||||
report: permissions.canOpenReport ? null : OPERATOR_QUEUE_REASON.permissionDenied,
|
||||
pause: !permissions.canControl
|
||||
? OPERATOR_QUEUE_REASON.permissionDenied
|
||||
: facts.queued > 0
|
||||
: facts.pausable > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noQueued,
|
||||
resume: !permissions.canControl
|
||||
|
||||
Reference in New Issue
Block a user