mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merged PR 1984: fix(reward-confirmation): improve action card visibility and status messages
fix(reward-confirmation): improve action card visibility and status messages Refactor confirmation action card to only display for items with 'Rücklage' feature. Replace boolean completion check with state-based system using ProcessingStatusState enum (Cancelled, NotFound, Collected). Add specific completion messages for each state to provide clearer user feedback. Changes: - Add displayActionCard computed signal to check for 'Rücklage' feature - Replace getProcessingStatusCompleted with getProcessingStatusState helper - Add ProcessingStatusState enum with three states (Cancelled, NotFound, Collected) - Update completion messages in template to use @switch based on processingStatus - Wrap entire action card in @if block checking displayActionCard - Add proper test coverage for new helper function - Update component spec to provide required dependencies Ref: #5391, #5404, #5406
This commit is contained in:
committed by
Lorenz Hilpert
parent
27541ab94a
commit
6e614683c5
@@ -1,64 +1,78 @@
|
|||||||
<div
|
@if (displayActionCard()) {
|
||||||
class="w-[24.5rem] h-full p-4 flex flex-col gap-4 rounded-lg bg-isa-secondary-100"
|
<div
|
||||||
[class.confirmation-list-item-done]="item().status !== 1"
|
class="w-[24.5rem] h-full p-4 flex flex-col gap-4 rounded-lg bg-isa-secondary-100"
|
||||||
>
|
[class.confirmation-list-item-done]="item().status !== 1"
|
||||||
@if (!isComplete()) {
|
>
|
||||||
<div
|
@if (!isComplete()) {
|
||||||
data-what="confirmation-message"
|
<div
|
||||||
data-which="confirmation-comment"
|
data-what="confirmation-message"
|
||||||
class="isa-text-body-2-bold"
|
data-which="confirmation-comment"
|
||||||
>
|
class="isa-text-body-2-bold"
|
||||||
Bitte buchen Sie die Prämie aus dem Abholfach aus oder wählen Sie eine
|
|
||||||
andere Aktion.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-row justify-between items-center">
|
|
||||||
<ui-dropdown
|
|
||||||
class="h-8 border-none pl-0 hover:bg-transparent"
|
|
||||||
[value]="selectedAction()"
|
|
||||||
(valueChange)="setDropdownAction($event)"
|
|
||||||
>
|
>
|
||||||
<ui-dropdown-option [value]="LoyaltyCollectType.Collect"
|
Bitte buchen Sie die Prämie aus dem Abholfach aus oder wählen Sie eine
|
||||||
>Prämie ausbuchen</ui-dropdown-option
|
andere Aktion.
|
||||||
>
|
</div>
|
||||||
<ui-dropdown-option [value]="LoyaltyCollectType.OutOfStock"
|
|
||||||
>Nicht gefunden</ui-dropdown-option
|
|
||||||
>
|
|
||||||
<ui-dropdown-option [value]="LoyaltyCollectType.Cancel"
|
|
||||||
>Stornieren</ui-dropdown-option
|
|
||||||
>
|
|
||||||
</ui-dropdown>
|
|
||||||
|
|
||||||
<button
|
<div class="flex flex-row justify-between items-center">
|
||||||
class="flex items-center gap-2 self-end"
|
<ui-dropdown
|
||||||
type="button"
|
class="h-8 border-none pl-0 hover:bg-transparent"
|
||||||
uiButton
|
[value]="selectedAction()"
|
||||||
color="primary"
|
(valueChange)="setDropdownAction($event)"
|
||||||
size="small"
|
>
|
||||||
(click)="onCollect()"
|
<ui-dropdown-option [value]="LoyaltyCollectType.Collect"
|
||||||
[pending]="isLoading()"
|
>Prämie ausbuchen</ui-dropdown-option
|
||||||
[disabled]="isLoading()"
|
>
|
||||||
data-what="button"
|
<ui-dropdown-option [value]="LoyaltyCollectType.OutOfStock"
|
||||||
data-which="complete"
|
>Nicht gefunden</ui-dropdown-option
|
||||||
|
>
|
||||||
|
<ui-dropdown-option [value]="LoyaltyCollectType.Cancel"
|
||||||
|
>Stornieren</ui-dropdown-option
|
||||||
|
>
|
||||||
|
</ui-dropdown>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="flex items-center gap-2 self-end"
|
||||||
|
type="button"
|
||||||
|
uiButton
|
||||||
|
color="primary"
|
||||||
|
size="small"
|
||||||
|
(click)="onCollect()"
|
||||||
|
[pending]="isLoading()"
|
||||||
|
[disabled]="isLoading()"
|
||||||
|
data-what="button"
|
||||||
|
data-which="complete"
|
||||||
|
>
|
||||||
|
<ng-icon name="isaActionCheck" uiButtonIcon></ng-icon>
|
||||||
|
Abschließen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<div
|
||||||
|
data-what="done-message"
|
||||||
|
data-which="done-comment"
|
||||||
|
class="isa-text-body-2-bold"
|
||||||
>
|
>
|
||||||
<ng-icon name="isaActionCheck" uiButtonIcon></ng-icon>
|
@switch (processingStatus()) {
|
||||||
Abschließen
|
@case (ProcessingStatusState.Cancelled) {
|
||||||
</button>
|
Artikel wurde storniert und die Lesepunkte wieder gutgeschrieben.
|
||||||
</div>
|
}
|
||||||
} @else {
|
@case (ProcessingStatusState.NotFound) {
|
||||||
<div
|
Die Prämienbestellung wurde storniert und die Lesepunkte wieder
|
||||||
data-what="done-message"
|
gutgeschrieben. Bitte korrigieren Sie bei Bedarf den Filialbestand.
|
||||||
data-which="done-comment"
|
}
|
||||||
class="isa-text-body-2-bold"
|
@case (ProcessingStatusState.Collected) {
|
||||||
>
|
Der Artikel wurde aus dem Bestand ausgebucht und kann dem Kunden
|
||||||
Artikel wurde Storniert und Lesepunkte gut geschrieben.
|
mitgegeben werden.
|
||||||
</div>
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="flex items-center gap-2 self-end text-isa-accent-green isa-text-body-2-bold"
|
class="flex items-center gap-2 self-end text-isa-accent-green isa-text-body-2-bold"
|
||||||
>
|
>
|
||||||
<ng-icon name="isaActionCheck"></ng-icon>
|
<ng-icon name="isaActionCheck"></ng-icon>
|
||||||
Abgeschlossen
|
Abgeschlossen
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import {
|
|||||||
OrderRewardCollectFacade,
|
OrderRewardCollectFacade,
|
||||||
LoyaltyCollectType,
|
LoyaltyCollectType,
|
||||||
OrderItemSubsetResource,
|
OrderItemSubsetResource,
|
||||||
getProcessingStatusCompleted,
|
getProcessingStatusState,
|
||||||
|
ProcessingStatusState,
|
||||||
} from '@isa/oms/data-access';
|
} from '@isa/oms/data-access';
|
||||||
import { ButtonComponent } from '@isa/ui/buttons';
|
import { ButtonComponent } from '@isa/ui/buttons';
|
||||||
import { NgIcon } from '@ng-icons/core';
|
import { NgIcon } from '@ng-icons/core';
|
||||||
@@ -23,6 +24,7 @@ import {
|
|||||||
DropdownButtonComponent,
|
DropdownButtonComponent,
|
||||||
DropdownOptionComponent,
|
DropdownOptionComponent,
|
||||||
} from '@isa/ui/input-controls';
|
} from '@isa/ui/input-controls';
|
||||||
|
import { hasOrderTypeFeature } from '@isa/checkout/data-access';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'checkout-confirmation-list-item-action-card',
|
selector: 'checkout-confirmation-list-item-action-card',
|
||||||
@@ -39,6 +41,7 @@ import {
|
|||||||
})
|
})
|
||||||
export class ConfirmationListItemActionCardComponent {
|
export class ConfirmationListItemActionCardComponent {
|
||||||
LoyaltyCollectType = LoyaltyCollectType;
|
LoyaltyCollectType = LoyaltyCollectType;
|
||||||
|
ProcessingStatusState = ProcessingStatusState;
|
||||||
#orderRewardCollectFacade = inject(OrderRewardCollectFacade);
|
#orderRewardCollectFacade = inject(OrderRewardCollectFacade);
|
||||||
#store = inject(OrderConfiramtionStore);
|
#store = inject(OrderConfiramtionStore);
|
||||||
#orderItemSubsetResource = inject(OrderItemSubsetResource);
|
#orderItemSubsetResource = inject(OrderItemSubsetResource);
|
||||||
@@ -61,13 +64,22 @@ export class ConfirmationListItemActionCardComponent {
|
|||||||
|
|
||||||
orderItemSubsets = this.#orderItemSubsetResource.orderItemSubsets;
|
orderItemSubsets = this.#orderItemSubsetResource.orderItemSubsets;
|
||||||
selectedAction = signal<LoyaltyCollectType>(LoyaltyCollectType.Collect);
|
selectedAction = signal<LoyaltyCollectType>(LoyaltyCollectType.Collect);
|
||||||
isComplete = computed(() => {
|
|
||||||
|
processingStatus = computed(() => {
|
||||||
const subsets = this.orderItemSubsets();
|
const subsets = this.orderItemSubsets();
|
||||||
const statuses = subsets?.map((subset) => subset.processingStatus);
|
const statuses = subsets?.map((subset) => subset.processingStatus);
|
||||||
return getProcessingStatusCompleted(statuses);
|
return getProcessingStatusState(statuses);
|
||||||
});
|
});
|
||||||
isLoading = signal(false);
|
isLoading = signal(false);
|
||||||
|
|
||||||
|
isComplete = computed(() => {
|
||||||
|
return this.processingStatus() !== undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
displayActionCard = computed(() =>
|
||||||
|
hasOrderTypeFeature(this.item().features, ['Rücklage']),
|
||||||
|
);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
effect(() => {
|
effect(() => {
|
||||||
const item = this.item();
|
const item = this.item();
|
||||||
|
|||||||
@@ -77,10 +77,12 @@ export class OrderConfirmationItemListItemComponent {
|
|||||||
)?.data;
|
)?.data;
|
||||||
|
|
||||||
// Fallback: use DisplayOrderItem features if not found in cart
|
// Fallback: use DisplayOrderItem features if not found in cart
|
||||||
return foundItem ?? {
|
return (
|
||||||
features: item.features,
|
foundItem ?? {
|
||||||
availability: undefined,
|
features: item.features,
|
||||||
destination: undefined,
|
availability: undefined,
|
||||||
};
|
destination: undefined,
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
import { OrderItemProcessingStatusValue } from '../../schemas';
|
|
||||||
import { getProcessingStatusCompleted } from './get-processing-status-completed.helper';
|
|
||||||
|
|
||||||
describe('getProcessingStatusCompleted', () => {
|
|
||||||
it('should return true when all statuses are different from Bestellt (16)', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses = [
|
|
||||||
OrderItemProcessingStatusValue.Versendet, // 64
|
|
||||||
OrderItemProcessingStatusValue.Eingetroffen, // 128
|
|
||||||
OrderItemProcessingStatusValue.Abgeholt, // 256
|
|
||||||
];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true when statuses include various completed states', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses = [
|
|
||||||
OrderItemProcessingStatusValue.Zugestellt, // 4194304
|
|
||||||
OrderItemProcessingStatusValue.Abgeholt, // 256
|
|
||||||
OrderItemProcessingStatusValue.Versendet, // 64
|
|
||||||
];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when at least one status is Bestellt (16)', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses = [
|
|
||||||
OrderItemProcessingStatusValue.Versendet, // 64
|
|
||||||
OrderItemProcessingStatusValue.Bestellt, // 16
|
|
||||||
OrderItemProcessingStatusValue.Abgeholt, // 256
|
|
||||||
];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when all statuses are Bestellt (16)', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses = [
|
|
||||||
OrderItemProcessingStatusValue.Bestellt, // 16
|
|
||||||
OrderItemProcessingStatusValue.Bestellt, // 16
|
|
||||||
OrderItemProcessingStatusValue.Bestellt, // 16
|
|
||||||
];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when array is empty', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses: number[] = [];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when statuses is undefined', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses = undefined;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true with single status different from Bestellt', () => {
|
|
||||||
// Arrange
|
|
||||||
const statuses = [OrderItemProcessingStatusValue.Abgeholt]; // 256
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = getProcessingStatusCompleted(statuses);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { OrderItemProcessingStatusValue } from '../../schemas';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if all processing statuses are completed (not in "Bestellt" state).
|
|
||||||
* Returns true if all statuses are different from "Bestellt" (16).
|
|
||||||
* Returns false if any status is still "Bestellt" (16) or if the array is empty/undefined.
|
|
||||||
*/
|
|
||||||
export const getProcessingStatusCompleted = (
|
|
||||||
statuses: number[] | undefined,
|
|
||||||
): boolean => {
|
|
||||||
if (!statuses || statuses.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return statuses.every(
|
|
||||||
(status) => status !== OrderItemProcessingStatusValue.Bestellt,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { OrderItemProcessingStatusValue } from '../../schemas';
|
||||||
|
import { ProcessingStatusState } from '../../models';
|
||||||
|
import { getProcessingStatusState } from './get-processing-status-state.helper';
|
||||||
|
|
||||||
|
describe('getProcessingStatusState', () => {
|
||||||
|
describe('Cancelled status', () => {
|
||||||
|
it('should return Cancelled when all items are cancelled', () => {
|
||||||
|
// Arrange
|
||||||
|
const statuses = [
|
||||||
|
OrderItemProcessingStatusValue.StorniertKunde, // 512
|
||||||
|
OrderItemProcessingStatusValue.Storniert, // 1024
|
||||||
|
OrderItemProcessingStatusValue.StorniertLieferant, // 2048
|
||||||
|
];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = getProcessingStatusState(statuses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBe(ProcessingStatusState.Cancelled);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('NotFound status', () => {
|
||||||
|
it('should return NotFound when all items are NichtLieferbar', () => {
|
||||||
|
// Arrange
|
||||||
|
const statuses = [
|
||||||
|
OrderItemProcessingStatusValue.NichtLieferbar, // 4096
|
||||||
|
OrderItemProcessingStatusValue.NichtLieferbar, // 4096
|
||||||
|
];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = getProcessingStatusState(statuses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBe(ProcessingStatusState.NotFound);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Collected status', () => {
|
||||||
|
it('should return Collected when all items are Abgeholt', () => {
|
||||||
|
// Arrange
|
||||||
|
const statuses = [
|
||||||
|
OrderItemProcessingStatusValue.Abgeholt, // 256
|
||||||
|
OrderItemProcessingStatusValue.Abgeholt, // 256
|
||||||
|
];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = getProcessingStatusState(statuses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBe(ProcessingStatusState.Collected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Undefined cases', () => {
|
||||||
|
it('should return undefined when array is empty', () => {
|
||||||
|
// Arrange
|
||||||
|
const statuses: number[] = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = getProcessingStatusState(statuses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined when statuses is undefined', () => {
|
||||||
|
// Arrange
|
||||||
|
const statuses = undefined;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = getProcessingStatusState(statuses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined when items have mixed statuses', () => {
|
||||||
|
// Arrange
|
||||||
|
const statuses = [
|
||||||
|
OrderItemProcessingStatusValue.StorniertKunde, // 512
|
||||||
|
OrderItemProcessingStatusValue.Abgeholt, // 256
|
||||||
|
];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = getProcessingStatusState(statuses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { OrderItemProcessingStatusValue } from '../../schemas';
|
||||||
|
import { ProcessingStatusState } from '../../models';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the completion status of order items based on their processing statuses.
|
||||||
|
*
|
||||||
|
* @param statuses - Array of processing status values to evaluate
|
||||||
|
* @returns The processing status state:
|
||||||
|
* - `ProcessingStatusState.Cancelled` if all items are cancelled
|
||||||
|
* - `ProcessingStatusState.NotFound` if all items are marked as not available
|
||||||
|
* - `ProcessingStatusState.Collected` if all items are collected
|
||||||
|
* - `undefined` if statuses don't match any completion state
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* const statuses = [512, 1024]; // StorniertKunde, Storniert
|
||||||
|
* getProcessingStatusState(statuses); // ProcessingStatusState.Cancelled
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const getProcessingStatusState = (
|
||||||
|
statuses: number[] | undefined,
|
||||||
|
): ProcessingStatusState | undefined => {
|
||||||
|
if (!statuses || statuses.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all statuses are cancelled
|
||||||
|
const allCancelled = statuses.every(
|
||||||
|
(status) =>
|
||||||
|
status === OrderItemProcessingStatusValue.StorniertKunde ||
|
||||||
|
status === OrderItemProcessingStatusValue.Storniert ||
|
||||||
|
status === OrderItemProcessingStatusValue.StorniertLieferant,
|
||||||
|
);
|
||||||
|
if (allCancelled) {
|
||||||
|
return ProcessingStatusState.Cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all statuses are not available
|
||||||
|
const allNotFound = statuses.every(
|
||||||
|
(status) => status === OrderItemProcessingStatusValue.NichtLieferbar,
|
||||||
|
);
|
||||||
|
if (allNotFound) {
|
||||||
|
return ProcessingStatusState.NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all statuses are collected
|
||||||
|
const allCollected = statuses.every(
|
||||||
|
(status) => status === OrderItemProcessingStatusValue.Abgeholt,
|
||||||
|
);
|
||||||
|
if (allCollected) {
|
||||||
|
return ProcessingStatusState.Collected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
@@ -1 +1 @@
|
|||||||
export * from './get-processing-status-completed.helper';
|
export * from './get-processing-status-state.helper';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export * from './eligible-for-return';
|
|||||||
export * from './gender';
|
export * from './gender';
|
||||||
export * from './logistician';
|
export * from './logistician';
|
||||||
export * from './order';
|
export * from './order';
|
||||||
|
export * from './processing-status-state';
|
||||||
export * from './quantity';
|
export * from './quantity';
|
||||||
export * from './receipt-item-list-item';
|
export * from './receipt-item-list-item';
|
||||||
export * from './receipt-item-task-list-item';
|
export * from './receipt-item-task-list-item';
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Processing status state types for order items
|
||||||
|
*/
|
||||||
|
export const ProcessingStatusState = {
|
||||||
|
/** Item was cancelled by customer, merchant, or supplier */
|
||||||
|
Cancelled: 'cancelled',
|
||||||
|
/** Item was not found / not available */
|
||||||
|
NotFound: 'not-found',
|
||||||
|
/** Item was successfully collected */
|
||||||
|
Collected: 'collected',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type ProcessingStatusState =
|
||||||
|
(typeof ProcessingStatusState)[keyof typeof ProcessingStatusState];
|
||||||
Reference in New Issue
Block a user