Passed
Push — master ( 6e6c55...72b2aa )
by Christian
11:52 queued 10s
created

src/Administration/Resources/app/administration/src/module/sw-cms/elements/image-gallery/config/index.js   B

Complexity

Total Complexity 46
Complexity/F 1.31

Size

Lines of Code 247
Function Count 35

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 144
dl 0
loc 247
rs 8.72
c 0
b 0
f 0
wmc 46
mnd 11
bc 11
fnc 35
bpm 0.3142
cpm 1.3142
noi 4

How to fix   Complexity   

Complexity

Complex classes like src/Administration/Resources/app/administration/src/module/sw-cms/elements/image-gallery/config/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-cms-el-config-image-gallery.html.twig';
2
import './sw-cms-el-config-image-gallery.scss';
3
4
const { Component, Mixin, Utils } = 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 { cloneDeep } = Shopware.Utils.object;
6
const Criteria = Shopware.Data.Criteria;
7
8
Component.register('sw-cms-el-config-image-gallery', {
9
    template,
10
11
    mixins: [
12
        Mixin.getByName('cms-element')
13
    ],
14
15
    inject: ['repositoryFactory', 'feature'],
16
17
    data() {
18
        return {
19
            mediaModalIsOpen: false,
20
            initialFolderId: null,
21
            enitiy: this.element,
22
            mediaItems: [],
23
            columnWidth: '100px'
24
        };
25
    },
26
27
    computed: {
28
        mediaRepository() {
29
            return this.repositoryFactory.create('media');
30
        },
31
32
        uploadTag() {
33
            return `cms-element-media-config-${this.element.id}`;
34
        },
35
36
        defaultFolderName() {
37
            return this.cmsPageState._entityName;
38
        },
39
40
        sliderItems() {
41
            if (this.element.data && this.element.data.sliderItems && this.element.data.sliderItems.length > 0) {
42
                return this.element.data.sliderItems;
43
            }
44
45
            return [];
46
        },
47
48
        sliderItemsConfigValue() {
49
            return Utils.get(this.element, 'config.sliderItems.value');
50
        },
51
52
        gridAutoRows() {
53
            return `grid-auto-rows: ${this.columnWidth}`;
54
        },
55
56
        isProductPage() {
57
            return Utils.get(this.cmsPageState, 'currentPage.type', '') === 'product_detail';
58
        }
59
    },
60
61
    watch: {
62
        sliderItems() {
63
            this.updateColumnWidth();
64
        },
65
66
        sliderItemsConfigValue(value) {
67
            if (!value) {
68
                this.element.config.sliderItems.value = [];
69
                return;
70
            }
71
72
            const isSourceMapped = Utils.get(this.element, 'config.sliderItems.source') === 'mapped';
73
            const isSliderLengthValid = value && value.length === this.sliderItems.length;
74
75
            if (isSourceMapped || isSliderLengthValid || !this.sliderItems.length) {
76
                return;
77
            }
78
79
            this.mediaItems = this.sliderItems.map((item) => {
80
                return item.media;
81
            });
82
83
            this.element.config.sliderItems.value = this.sliderItems.map(item => {
84
                return {
85
                    mediaId: item.media.id,
86
                    mediaUrl: item.media.url,
87
                    newTab: item.newTab,
88
                    url: item.url
89
                };
90
            });
91
        }
92
    },
93
94
    created() {
95
        this.createdComponent();
96
    },
97
98
    mounted() {
99
        this.mountedComponent();
100
    },
101
102
    methods: {
103
        async createdComponent() {
104
            this.initElementConfig('image-gallery');
105
106
            const { source: sliderItemsSource, value: sliderItemsValue } = this.element.config.sliderItems;
107
108
            if (sliderItemsSource === 'static' && sliderItemsValue && sliderItemsValue.length > 0) {
0 ignored issues
show
Best Practice introduced by
If you intend to check if the variable sliderItemsValue is declared in the current environment, consider using typeof sliderItemsValue === "undefined" instead. This is safe if the variable is not actually declared.
Loading history...
Bug introduced by
The variable sliderItemsSource seems to be never declared. If this is a global, consider adding a /** global: sliderItemsSource */ 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...
109
                const mediaIds = sliderItemsValue.map((configElement) => {
110
                    return configElement.mediaId;
111
                });
112
113
                const criteria = new Criteria();
114
                criteria.setIds(mediaIds);
115
116
                const searchResult = await this.mediaRepository.search(criteria, 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...
117
                this.mediaItems = mediaIds.map((mediaId) => {
118
                    return searchResult.get(mediaId);
119
                });
120
            }
121
122
            this.initConfig();
123
        },
124
125
        mountedComponent() {
126
            this.updateColumnWidth();
127
        },
128
129
        initConfig() {
130
            if (!this.isProductPage || Utils.get(this.element, 'translated.config')) {
131
                return;
132
            }
133
134
            this.element.config.sliderItems.source = 'mapped';
135
            this.element.config.sliderItems.value = 'product.media';
136
            this.element.config.navigationDots.value = 'inside';
137
            this.element.config.zoom.value = true;
138
            this.element.config.fullScreen.value = true;
139
            this.element.config.displayMode.value = 'contain';
140
            this.element.config.minHeight.value = '430px';
141
        },
142
143
        updateColumnWidth() {
144
            if (!this.$refs.demoMediaGrid) {
145
                return;
146
            }
147
148
            this.$nextTick(() => {
149
                const cssColumns = window.getComputedStyle(this.$refs.demoMediaGrid, null)
150
                    .getPropertyValue('grid-template-columns')
151
                    .split(' ');
152
                this.columnWidth = cssColumns[0];
153
            });
154
        },
155
156
        onOpenMediaModal() {
157
            this.mediaModalIsOpen = true;
158
        },
159
160
        onCloseMediaModal() {
161
            this.mediaModalIsOpen = false;
162
        },
163
164
        onImageUpload(mediaItem) {
165
            this.element.config.sliderItems.value.push({
166
                mediaUrl: mediaItem.url,
167
                mediaId: mediaItem.id,
168
                url: null,
169
                newTab: false
170
            });
171
172
            this.mediaItems.push(mediaItem);
173
            this.updateMediaDataValue();
174
            this.emitUpdateEl();
175
        },
176
177
        onItemRemove(mediaItem, index) {
178
            const key = mediaItem.id;
179
            this.element.config.sliderItems.value =
180
                this.element.config.sliderItems.value.filter(
181
                    (item, i) => (item.mediaId !== key || i !== index)
182
                );
183
184
            this.mediaItems = this.mediaItems.filter(
185
                (item, i) => (item.id !== key || i !== index)
186
            );
187
188
            this.updateMediaDataValue();
189
            this.emitUpdateEl();
190
        },
191
192
        onMediaSelectionChange(mediaItems) {
193
            mediaItems.forEach((item) => {
194
                this.element.config.sliderItems.value.push({
195
                    mediaUrl: item.url,
196
                    mediaId: item.id,
197
                    url: null,
198
                    newTab: false
199
                });
200
            });
201
202
            this.mediaItems.push(...mediaItems);
203
            this.updateMediaDataValue();
204
            this.emitUpdateEl();
205
        },
206
207
        updateMediaDataValue() {
208
            if (this.element.config.sliderItems.value) {
209
                const sliderItems = cloneDeep(this.element.config.sliderItems.value);
210
211
                sliderItems.forEach((galleryItem) => {
212
                    this.mediaItems.forEach((mediaItem) => {
213
                        if (galleryItem.mediaId === mediaItem.id) {
214
                            galleryItem.media = mediaItem;
215
                        }
216
                    });
217
                });
218
219
                if (!this.element.data) {
220
                    this.$set(this.element, 'data', { sliderItems });
221
                } else {
222
                    this.$set(this.element.data, 'sliderItems', sliderItems);
223
                }
224
            }
225
        },
226
227
        onChangeMinHeight(value) {
228
            this.element.config.minHeight.value = value === null ? '' : value;
229
230
            this.$emit('element-update', this.element);
231
        },
232
233
        onChangeDisplayMode(value) {
234
            if (['cover', 'contain'].includes(value)) {
235
                this.element.config.verticalAlign.value = null;
236
            } else {
237
                this.element.config.minHeight.value = '';
238
            }
239
240
            this.$emit('element-update', this.element);
241
        },
242
243
        emitUpdateEl() {
244
            this.$emit('element-update', this.element);
245
        }
246
    }
247
});
248