feat(campaign): add durable operator queue controls
This commit is contained in:
78
webui/src/features/operator/operatorQueueModel.ts
Normal file
78
webui/src/features/operator/operatorQueueModel.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
export type OperatorQueueAction =
|
||||
| "details"
|
||||
| "pause"
|
||||
| "resume"
|
||||
| "retry"
|
||||
| "queue-unsent"
|
||||
| "reconcile"
|
||||
| "cancel";
|
||||
|
||||
export type OperatorQueuePermissions = {
|
||||
canRead: boolean;
|
||||
canControl: boolean;
|
||||
canRetry: boolean;
|
||||
canQueue: boolean;
|
||||
canReconcile: boolean;
|
||||
};
|
||||
|
||||
export type OperatorQueueFacts = {
|
||||
retryable: number;
|
||||
outcomeUnknown: number;
|
||||
queueableUnattempted: number;
|
||||
queued: number;
|
||||
paused: number;
|
||||
cancellable: number;
|
||||
};
|
||||
|
||||
export const OPERATOR_QUEUE_REASON = {
|
||||
permission: "i18n:govoplan-campaign.you_do_not_have_permission_for_this_action.dfcfbad6",
|
||||
noQueued: "i18n:govoplan-campaign.no_queued_jobs_can_be_paused.acaa0b4e",
|
||||
noPaused: "i18n:govoplan-campaign.no_paused_jobs_can_be_resumed.869b6275",
|
||||
noFailed: "i18n:govoplan-campaign.no_failed_jobs_are_eligible_for_retry.e65a69f9",
|
||||
noUnsent: "i18n:govoplan-campaign.no_unsent_jobs_are_available_to_queue.585bfe87",
|
||||
noUnknown: "i18n:govoplan-campaign.no_uncertain_outcomes_require_reconciliation.933bc53c",
|
||||
noCancellable: "i18n:govoplan-campaign.no_cancellable_queued_work_remains.80e31d49"
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Return the reason each fixed queue action is unavailable. A null result means
|
||||
* the action is permitted and meaningful for the current queue projection.
|
||||
*/
|
||||
export function operatorQueueActionBlocks(
|
||||
facts: OperatorQueueFacts,
|
||||
permissions: OperatorQueuePermissions
|
||||
): Record<OperatorQueueAction, string | null> {
|
||||
return {
|
||||
details: permissions.canRead ? null : OPERATOR_QUEUE_REASON.permission,
|
||||
pause: !permissions.canControl
|
||||
? OPERATOR_QUEUE_REASON.permission
|
||||
: facts.queued > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noQueued,
|
||||
resume: !permissions.canControl
|
||||
? OPERATOR_QUEUE_REASON.permission
|
||||
: facts.paused > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noPaused,
|
||||
retry: !permissions.canRetry
|
||||
? OPERATOR_QUEUE_REASON.permission
|
||||
: facts.retryable > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noFailed,
|
||||
"queue-unsent": !permissions.canQueue
|
||||
? OPERATOR_QUEUE_REASON.permission
|
||||
: facts.queueableUnattempted > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noUnsent,
|
||||
reconcile: !permissions.canReconcile
|
||||
? OPERATOR_QUEUE_REASON.permission
|
||||
: facts.outcomeUnknown > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noUnknown,
|
||||
cancel: !permissions.canControl
|
||||
? OPERATOR_QUEUE_REASON.permission
|
||||
: facts.cancellable > 0
|
||||
? null
|
||||
: OPERATOR_QUEUE_REASON.noCancellable
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user