Passed
Push — master ( 830895...5e8384 )
by Christian
13:38
created

src/Administration/Resources/app/administration/src/module/sw-settings-listing/component/sw-settings-listing-option-criteria-grid/index.js   C

Complexity

Total Complexity 56
Complexity/F 1.27

Size

Lines of Code 364
Function Count 44

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 56
eloc 191
mnd 12
bc 12
fnc 44
dl 0
loc 364
rs 5.5199
bpm 0.2727
cpm 1.2727
noi 3
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like src/Administration/Resources/app/administration/src/module/sw-settings-listing/component/sw-settings-listing-option-criteria-grid/index.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import template from './sw-settings-listing-option-criteria-grid.html.twig';
2
import './sw-settings-listing-option-criteria-grid.scss';
3
4
const { Mixin } = Shopware;
0 ignored issues
show
Bug introduced by
The variable Shopware seems to be never declared. If this is a global, consider adding a /** global: Shopware */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
5
const { Criteria } = Shopware.Data;
6
7
Shopware.Component.register('sw-settings-listing-option-criteria-grid', {
8
    template,
9
10
    inject: ['repositoryFactory'],
11
12
    mixins: [
13
        Mixin.getByName('notification'),
14
        Mixin.getByName('sw-inline-snippet')
15
    ],
16
17
    props: {
18
        productSortingEntity: {
19
            type: Object,
20
            required: true
21
        }
22
    },
23
24
    data() {
25
        return {
26
            customFields: [],
27
            selectedCriteria: null,
28
            customFieldSetIDs: null
29
        };
30
    },
31
32
    computed: {
33
        customFieldRepository() {
34
            return this.repositoryFactory.create('custom_field');
35
        },
36
37
        customFieldSetRepository() {
38
            return this.repositoryFactory.create('custom_field_set');
39
        },
40
41
        customFieldSetRelationsRepository() {
42
            return this.repositoryFactory.create('custom_field_set_relation');
43
        },
44
45
        customFieldCriteria() {
46
            const criteria = new Criteria();
47
48
            criteria.addFilter(
49
                Criteria.equalsAny('customFieldSetId', this.customFieldSetIDs)
50
            );
51
52
            return criteria;
53
        },
54
55
        customFieldsRelationsCriteria() {
56
            const criteria = new Criteria();
57
58
            criteria.addFilter(Criteria.equals('entityName', 'product'));
59
60
            return criteria;
61
        },
62
63
        /**
64
         * Sorts custom fields by their priority in an ascending order.
65
         * @returns {[]}
66
         */
67
        sortedProductSortingFields() {
68
            return this.productSortingEntity.fields.sort((a, b) => {
69
                if (a.priority === b.priority) {
70
                    return 0;
71
                }
72
73
                return a.priority < b.priority ? 1 : -1;
74
            });
75
        },
76
77
        unusedCustomFields() {
78
            return this.customFields.filter(customField => {
79
                return !this.productSortingEntity.fields.some(field => {
80
                    return field.field === customField.name ||
81
                        field.field === `customFields.${customField.name}`;
82
                });
83
            });
84
        },
85
86
        productSortingEntityColumns() {
87
            return [
88
                {
89
                    property: 'field',
90
                    label: this.$tc('sw-settings-listing.general.productSortingCriteriaGrid.header.name'),
91
                    inlineEdit: 'string'
92
                },
93
                {
94
                    property: 'order',
95
                    label: this.$tc('sw-settings-listing.general.productSortingCriteriaGrid.header.order'),
96
                    inlineEdit: 'string'
97
                },
98
                {
99
                    property: 'priority',
100
                    label: this.$tc('sw-settings-listing.general.productSortingCriteriaGrid.header.priority'),
101
                    inlineEdit: 'number'
102
                }
103
            ];
104
        },
105
106
        criteriaOptions() {
107
            const criteriaOptions = [
108
                {
109
                    value: 'product.name',
110
                    label: this.$tc(
111
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.name'
112
                    )
113
                },
114
                {
115
                    value: 'product.ratingAverage',
116
                    label: this.$tc(
117
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.ratingAverage'
118
                    )
119
                },
120
                {
121
                    value: 'product.productNumber',
122
                    label: this.$tc(
123
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.productNumber'
124
                    )
125
                },
126
                {
127
                    value: 'product.releaseDate',
128
                    label: this.$tc(
129
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.releaseDate'
130
                    )
131
                },
132
                {
133
                    value: 'product.stock',
134
                    label: this.$tc(
135
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.stock'
136
                    )
137
                },
138
                {
139
                    value: 'product.listingPrices',
140
                    label: this.$tc(
141
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.listingPrices'
142
                    )
143
                },
144
                {
145
                    value: 'product.sales',
146
                    label: this.$tc(
147
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.label.product.sales'
148
                    )
149
                },
150
                {
151
                    value: 'customField',
152
                    label: this.$tc('sw-settings-listing.general.productSortingCriteriaGrid.options.label.customField')
153
                }
154
            ];
155
156
            return criteriaOptions.sort((a, b) => {
157
                return a.label.localeCompare(b.label);
158
            });
159
        },
160
161
        orderOptions() {
162
            return [
163
                {
164
                    label: this.$tc('global.default.ascending'),
165
                    value: 'asc'
166
                },
167
                {
168
                    label: this.$tc('global.default.descending'),
169
                    value: 'desc'
170
                }
171
            ];
172
        }
173
    },
174
175
    watch: {
176
        productSortingEntity: {
177
            handler() {
178
                if (!this.productSortingEntity || !this.productSortingEntity.fields) {
179
                    return;
180
                }
181
182
                this.productSortingEntity.fields.forEach(field => {
183
                    if (field.field === null) {
184
                        field.field = 'customField';
185
                    }
186
                });
187
            },
188
            deep: true
189
        }
190
    },
191
192
    created() {
193
        this.createdComponent();
194
    },
195
196
    methods: {
197
        createdComponent() {
198
            this.fetchCustomFieldSetIds().then(() => {
199
                this.fetchCustomFields();
200
            });
201
        },
202
203
        fetchCustomFieldSetIds() {
204
            return this.customFieldSetRelationsRepository.search(
205
                this.customFieldsRelationsCriteria,
206
                Shopware.Context.api
0 ignored issues
show
Bug introduced by
The variable Shopware seems to be never declared. If this is a global, consider adding a /** global: Shopware */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
207
            ).then(response => {
208
                this.customFieldSetIDs = response.map(currentField => {
209
                    return currentField.customFieldSetId;
210
                });
211
            });
212
        },
213
214
        fetchCustomFields() {
215
            this.customFieldRepository.search(this.customFieldCriteria, Shopware.Context.api).then(response => {
0 ignored issues
show
Bug introduced by
The variable Shopware seems to be never declared. If this is a global, consider adding a /** global: Shopware */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
216
                this.customFields = response;
217
            });
218
        },
219
220
        /**
221
         * Checks if the given field is a custom field.
222
         * @param {string} fieldName
223
         * @returns {boolean}
224
         */
225
        isItemACustomField(fieldName) {
226
            const strippedFieldName = this.stripCustomFieldPath(fieldName);
227
228
            return this.customFields.some(currentCustomField => {
229
                return currentCustomField.name === strippedFieldName;
230
            });
231
        },
232
233
        getCustomFieldByName(technicalName) {
234
            return this.customFields.find(currentCustomField => {
235
                return currentCustomField.name === technicalName;
236
            });
237
        },
238
239
        /**
240
         * First checks if the newly added criteria is already used. If not it emits an 'criteria-add' event.
241
         * Otherwise it creates an error notification.
242
         * @param {string} fieldName
243
         */
244
        onAddCriteria(fieldName) {
245
            if (!this.criteriaIsAlreadyUsed(fieldName)) {
246
                this.$emit('criteria-add', fieldName);
247
248
                const record = this.productSortingEntity.fields.find(field => field.field === fieldName);
249
                if (record) {
250
                    this.$refs.dataGrid.onDbClickCell(record);
251
                }
252
253
                return;
254
            }
255
256
            const criteriaName = this.getCriteriaSnippetByFieldName(fieldName);
257
258
            this.createNotificationError({
259
                message: this.$t(
260
                    'sw-settings-listing.general.productSortingCriteriaGrid.options.criteriaAlreadyUsed',
261
                    { criteriaName }
262
                )
263
            });
264
        },
265
266
        getOrderSnippet(order) {
267
            if (order === 'asc') {
268
                return this.$tc('global.default.ascending');
269
            }
270
271
            return this.$tc('global.default.descending');
272
        },
273
274
        onRemoveCriteria(item) {
275
            this.$emit('criteria-delete', item);
276
        },
277
278
        getCriteriaTemplate(fieldName) {
279
            return { field: fieldName, order: 'asc', priority: 1, naturalSorting: 0 };
280
        },
281
282
        onSaveInlineEdit(item) {
283
            if (item.field === null) {
284
                this.createNotificationError({
285
                    message: this.$t(
286
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.customFieldCriteriaNotNull'
287
                    )
288
                });
289
290
                return;
291
            }
292
293
            if (item.field === 'customFields') {
294
                item.field = `customFields.${item.field}`;
295
            }
296
297
            if (item.field === 'customField') {
298
                this.createNotificationError({
299
                    message: this.$t(
300
                        'sw-settings-listing.general.productSortingCriteriaGrid.options.customFieldCriteriaNotNull'
301
                    )
302
                });
303
304
                this.filterEmptyCustomFields(item);
305
                return;
306
            }
307
308
            this.$emit('inline-edit-save');
309
        },
310
311
        onCancelInlineEdit(item) {
312
            if (item && item.field === 'customField') {
313
                this.filterEmptyCustomFields(item);
314
            }
315
        },
316
317
        filterEmptyCustomFields(item) {
318
            this.productSortingEntity.fields = this.productSortingEntity.fields.filter(field => {
319
                return field.field !== item.field;
320
            });
321
        },
322
323
        /**
324
         * removes the stripCustomFieldPath `customFields.` part of the string.
325
         * @param {string} fieldName
326
         * @returns {string}
327
         */
328
        stripCustomFieldPath(fieldName) {
329
            return fieldName.replace(/customFields\./, '');
330
        },
331
332
        /**
333
         * Returns the snippet of the corresponding field.
334
         * @param {string} fieldName
335
         * @returns {string}
336
         */
337
        getCriteriaSnippetByFieldName(fieldName) {
338
            return this.$tc(`sw-settings-listing.general.productSortingCriteriaGrid.options.label.${fieldName}`);
339
        },
340
341
        criteriaIsAlreadyUsed(criteriaName) {
342
            return this.productSortingEntity.fields.some(currentCriteria => {
343
                return currentCriteria.field === criteriaName;
344
            });
345
        },
346
347
        getCustomFieldLabelByCriteriaName(criteriaName) {
348
            const technicalName = this.stripCustomFieldPath(criteriaName);
349
            const customField = this.getCustomFieldByName(technicalName);
350
351
            return this.getInlineSnippet(customField.config.label) || technicalName;
352
        },
353
354
        getCustomFieldName(customField) {
355
            const inlineSnippet = this.getInlineSnippet(customField.config.label);
356
357
            if (!inlineSnippet) {
358
                return customField.name;
359
            }
360
361
            return inlineSnippet;
362
        }
363
    }
364
});
365