Passed
Push — trunk ( 07b8ab...c11caa )
by Christian
10:45 queued 12s
created

index.ts ➔ onClose   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
import type { PropType } from 'vue';
2
import type RepositoryType from 'src/core/data/repository.data';
3
import type CriteriaType from 'src/core/data/criteria.data';
4
import type EntityCollectionType from 'src/core/data/entity-collection.data';
5
import template from './sw-order-state-history-modal.html.twig';
6
import type { StateMachineState, StateMachineHistory, Order } from '../../order.types';
7
8
const { Component, Mixin } = Shopware;
9
const { Criteria } = Shopware.Data;
10
11
interface StateMachineHistoryData {
12
    order: StateMachineState,
13
    transaction: StateMachineState,
14
    delivery: StateMachineState,
15
    createdAt: Date,
16
    user: {
17
        username: string
18
    },
19
    entity: string,
20
}
21
22
interface CombinedStates {
23
    order: StateMachineState,
24
    ['order_transaction']: StateMachineState,
25
    ['order_delivery']: StateMachineState,
26
}
27
28
// eslint-disable-next-line sw-deprecation-rules/private-feature-declarations
29
Component.register('sw-order-state-history-modal', {
30
    template,
31
32
    inject: [
33
        'repositoryFactory',
34
        'stateStyleDataProviderService',
35
    ],
36
37
    mixins: [
38
        Mixin.getByName('notification'),
39
    ],
40
41
    props: {
42
        order: {
43
            type: Object as PropType<Order>,
44
            required: true,
45
        },
46
        isLoading: {
47
            type: Boolean,
48
            required: true,
49
        },
50
    },
51
52
    data(): {
53
        dataSource: StateMachineHistoryData[],
54
        statesLoading: boolean,
55
        limit: number,
56
        page: number,
57
        total: number,
58
        steps: number[],
59
        } {
60
        return {
61
            dataSource: [],
62
            statesLoading: true,
63
            limit: 10,
64
            page: 1,
65
            total: 0,
66
            steps: [5, 10, 25],
67
        };
68
    },
69
70
    computed: {
71
        stateMachineHistoryRepository(): RepositoryType {
72
            return this.repositoryFactory.create('state_machine_history');
73
        },
74
75
        stateMachineHistoryCriteria(): CriteriaType {
76
            const criteria = new Criteria(this.page, this.limit);
77
78
            const entityIds = [
79
                this.order.id,
80
                ...this.order.transactions.map((transaction) => {
81
                    return transaction.id;
82
                }),
83
                ...this.order.deliveries.map((delivery) => {
84
                    return delivery.id;
85
                }),
86
            ];
87
88
            criteria.addFilter(
89
                Criteria.equalsAny(
90
                    'state_machine_history.entityId.id',
91
                    entityIds,
92
                ),
93
            );
94
            criteria.addFilter(
95
                Criteria.equalsAny(
96
                    'state_machine_history.entityName',
97
                    ['order', 'order_transaction', 'order_delivery'],
98
                ),
99
            );
100
            criteria.addAssociation('fromStateMachineState');
101
            criteria.addAssociation('toStateMachineState');
102
            criteria.addAssociation('user');
103
            criteria.addSorting({
104
                field: 'state_machine_history.createdAt',
105
                order: 'ASC',
106
                naturalSorting: false,
107
            });
108
109
            return criteria;
110
        },
111
112
        columns(): Array<{property: string, label: string}> {
113
            return [
114
                { property: 'createdAt', label: this.$tc('sw-order.stateHistoryModal.column.createdAt') },
115
                { property: 'entity', label: this.$tc('sw-order.stateHistoryModal.column.entity') },
116
                { property: 'user', label: this.$tc('sw-order.stateHistoryModal.column.user') },
117
                { property: 'transaction', label: this.$tc('sw-order.stateHistoryModal.column.transaction') },
118
                { property: 'delivery', label: this.$tc('sw-order.stateHistoryModal.column.delivery') },
119
                { property: 'order', label: this.$tc('sw-order.stateHistoryModal.column.order') },
120
            ];
121
        },
122
    },
123
124
    created() {
125
        this.createdComponent();
126
    },
127
128
    methods: {
129
        createdComponent(): void {
130
            void this.loadHistory();
131
        },
132
133
        async loadHistory(): Promise<void> {
134
            this.statesLoading = true;
135
136
            try {
137
                await this.getStateHistoryEntries();
138
            } catch (error: unknown) {
139
                // @ts-expect-error
140
                // eslint-disable-next-line max-len
141
                // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
142
                const errorMessage = error?.response?.data?.errors?.[0]?.detail || '';
143
144
                // @ts-expect-error
145
                // eslint-disable-next-line @typescript-eslint/no-unsafe-call
146
                this.createNotificationError({
147
                    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
148
                    message: errorMessage,
149
                });
150
            } finally {
151
                this.statesLoading = false;
152
            }
153
        },
154
155
        getStateHistoryEntries(): Promise<EntityCollectionType> {
156
            return this.stateMachineHistoryRepository.search(this.stateMachineHistoryCriteria)
157
                .then((fetchedEntries: EntityCollectionType) => {
158
                    this.dataSource = this.buildStateHistory(fetchedEntries as unknown as StateMachineHistory[]);
159
                    this.total = fetchedEntries.total ?? 1;
160
                    return Promise.resolve(fetchedEntries);
161
                });
162
        },
163
164
        buildStateHistory(allEntries: StateMachineHistory[]): StateMachineHistoryData[] {
165
            const states = {
166
                order: allEntries.filter((entry) => {
167
                    return entry.entityName === 'order';
168
                })[0]?.fromStateMachineState ?? this.order.stateMachineState,
169
                order_transaction: allEntries.filter((entry) => {
170
                    return entry.entityName === 'order_transaction';
171
                })[0]?.fromStateMachineState ?? this.order.transactions.last()?.stateMachineState,
172
                order_delivery: allEntries.filter((entry) => {
173
                    return entry.entityName === 'order_delivery';
174
                })[0]?.fromStateMachineState ?? this.order.deliveries.first()?.stateMachineState,
175
            };
176
177
            const entries = [] as Array<StateMachineHistoryData>;
178
179
            if (this.page === 1) {
180
                // Prepend start state
181
                entries.push(this.createEntry(states, this.order));
182
            }
183
184
            allEntries.forEach((entry: StateMachineHistory) => {
185
                states[entry.entityName] = entry.toStateMachineState;
186
                entries.push(this.createEntry(states, entry));
187
            });
188
189
            return entries;
190
        },
191
192
        createEntry(states: CombinedStates, entry: StateMachineHistory | Order): StateMachineHistoryData {
193
            return {
194
                order: states.order,
195
                transaction: states.order_transaction,
196
                delivery: states.order_delivery,
197
                createdAt: 'orderDateTime' in entry ? entry.orderDateTime : entry.createdAt,
198
                user: entry.user,
199
                entity: 'entityName' in entry ? entry.entityName : 'order',
200
            };
201
        },
202
203
        getVariantState(entity: string, state: StateMachineState): string {
204
            // eslint-disable-next-line max-len
205
            // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-return
206
            return this.stateStyleDataProviderService
207
                .getStyle(`${entity}.state`, state.technicalName).variant;
208
        },
209
210
        onClose(): void {
211
            this.$emit('modal-close');
212
        },
213
214
        onPageChange({ page, limit }: { page: number, limit: number }): void {
215
            this.page = page;
216
            this.limit = limit;
217
218
            void this.loadHistory();
219
        },
220
    },
221
});
222