Passed
Push — master ( 235c52...927bab )
by Daniel
30:30 queued 10s
created

js/admin.js   A

Complexity

Total Complexity 42
Complexity/F 1.31

Size

Lines of Code 355
Function Count 32

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 42
eloc 163
c 0
b 0
f 0
dl 0
loc 355
rs 9.0399
mnd 10
bc 10
fnc 32
bpm 0.3125
cpm 1.3125
noi 0

How to fix   Complexity   

Complexity

Complex classes like js/admin.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
/**
2
 * CMS Pico - Create websites using Pico CMS for Nextcloud.
3
 *
4
 * @copyright Copyright (c) 2017, Maxence Lange (<[email protected]>)
5
 * @copyright Copyright (c) 2019, Daniel Rudolf (<[email protected]>)
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
/** global: OC */
24
/** global: OCA */
25
/** global: jQuery */
26
27
(function (document, $, OC, OCA) {
28
	'use strict';
29
30
	/**
31
	 * @class
32
	 * @extends OCA.CMSPico.List
33
	 *
34
	 * @param {jQuery}        $element
35
	 * @param {Object}        [options]
36
	 * @param {string}        [options.route]
37
	 * @param {jQuery|string} [options.template]
38
	 * @param {jQuery|string} [options.systemTemplate]
39
	 * @param {jQuery|string} [options.customTemplate]
40
	 * @param {jQuery|string} [options.newTemplate]
41
	 * @param {jQuery|string} [options.copyTemplate]
42
	 * @param {jQuery|string} [options.loadingTemplate]
43
	 * @param {jQuery|string} [options.errorTemplate]
44
	 */
45
	OCA.CMSPico.AdminList = function ($element, options) {
46
		this.initialize($element, options);
47
	};
48
49
	/**
50
	 * @lends OCA.CMSPico.AdminList.prototype
51
	 */
52
	OCA.CMSPico.AdminList.prototype = $.extend({}, OCA.CMSPico.List.prototype, {
53
		/** @member {Object[]|string[]} */
54
		systemItems: [],
55
56
		/** @member {Object[]|string[]} */
57
		customItems: [],
58
59
		/** @member {Object[]|string[]} */
60
		newItems: [],
61
62
		/** @member {jQuery} */
63
		$systemTemplate: $(),
64
65
		/** @member {jQuery} */
66
		$customTemplate: $(),
67
68
		/** @member {jQuery} */
69
		$newTemplate: $(),
70
71
		/** @member {jQuery} */
72
		$copyTemplate: $(),
73
74
		/**
75
		 * @constructs
76
		 *
77
		 * @param {jQuery}        $element
78
		 * @param {Object}        [options]
79
		 * @param {string}        [options.route]
80
		 * @param {jQuery|string} [options.template]
81
		 * @param {jQuery|string} [options.systemTemplate]
82
		 * @param {jQuery|string} [options.customTemplate]
83
		 * @param {jQuery|string} [options.newTemplate]
84
		 * @param {jQuery|string} [options.copyTemplate]
85
		 * @param {jQuery|string} [options.loadingTemplate]
86
		 * @param {jQuery|string} [options.errorTemplate]
87
		 */
88
		initialize: function ($element, options) {
89
			OCA.CMSPico.List.prototype.initialize.apply(this, arguments);
90
91
			options = $.extend({
92
				systemTemplate: $element.data('systemTemplate'),
93
				customTemplate: $element.data('customTemplate'),
94
				newTemplate: $element.data('newTemplate'),
95
				copyTemplate: $element.data('copyTemplate')
96
			}, options);
97
98
			this.$systemTemplate = $(options.systemTemplate);
99
			this.$customTemplate = $(options.customTemplate);
100
			this.$newTemplate = $(options.newTemplate);
101
			this.$copyTemplate = $(options.copyTemplate);
102
103
			var signature = 'OCA.CMSPico.AdminList.initialize()';
104
			if (!this.$systemTemplate.length) throw signature + ': No valid system item template given';
105
			if (!this.$customTemplate.length) throw signature + ': No valid custom item template given';
106
		},
107
108
		/**
109
		 * @public
110
		 *
111
		 * @param {Object}            data
112
		 * @param {Object[]|string[]} data.systemItems
113
		 * @param {Object[]|string[]} data.customItems
114
		 * @param {Object[]|string[]} data.newItems
115
		 */
116
		update: function (data) {
117
			var that = this;
118
119
			this.systemItems = data.systemItems;
120
			this.customItems = data.customItems;
121
			this.newItems = data.newItems;
122
123
			this._content(this.$template);
124
125
			$.each(data.systemItems, function (_, value) {
126
				var itemData = (typeof value === 'object') ? value : { name: value },
127
					$item = that._content(that.$systemTemplate, itemData);
128
				that._setupItem($item, itemData);
129
			});
130
131
			$.each(data.customItems, function (_, value) {
132
				var itemData = (typeof value === 'object') ? value : { name: value },
133
					$item = that._content(that.$customTemplate, itemData);
134
				that._setupItem($item, itemData);
135
			});
136
137
			$.each(data.newItems, function (_, value) {
138
				var itemData = (typeof value === 'object') ? value : { name: value },
139
					$item = that._content(that.$newTemplate, itemData);
140
				that._setupItem($item, itemData);
141
			});
142
143
			this._setup();
144
		},
145
146
		/**
147
		 * @protected
148
		 */
149
		_setup: function () {
150
			var $newItem = this.$element.find('.action-new-item'),
151
				$newItemButton = this.$element.find('.action-new'),
152
				that = this;
153
154
			if ($newItem.val()) {
155
				$newItemButton.on('click.CMSPicoAdminList', function (event) {
156
					event.preventDefault();
157
					that._api('POST', '', {item: $newItem.val()});
158
				});
159
			} else {
160
				$newItemButton.add($newItem).prop('disabled', true);
161
			}
162
163
			this.$element.find('.action-reload').on('click.CMSPicoAdminList', function (event) {
164
				event.preventDefault();
165
				that.reload();
166
			});
167
		},
168
169
		/**
170
		 * @protected
171
		 *
172
		 * @param {jQuery}  $item
173
		 * @param {Object}  itemData
174
		 * @param {string}  itemData.name
175
		 * @param {boolean} [itemData.compat]
176
		 * @param {string}  [itemData.compatReason]
177
		 * @param {Object}  [itemData.compatReasonData]
178
		 */
179
		_setupItem: function ($item, itemData) {
180
			var that = this;
181
182
			$item.find('.info-compat').each(function () {
183
				var $this = $(this),
184
					$icon = $this.find('[class^="icon-"], [class*=" icon-"]'),
185
					compat = (itemData.compat === undefined) || !!itemData.compat;
186
187
				$this.data('value', compat);
188
189
				$icon
190
					.addClass(compat ? 'icon-checkmark' : 'icon-error-color')
191
					.removeClass(compat ? 'icon-error-color' : 'icon-checkmark');
192
193
				if ($icon.hasClass('has-tooltip')) {
194
					var compatReason = $icon.prop('title') || '';
195
					if (itemData.compatReason) {
196
						var rawCompatReason = OCA.CMSPico.Util.unescape(itemData.compatReason);
197
						compatReason = t('cms_pico', rawCompatReason, itemData.compatReasonData);
198
					}
199
200
					$icon
201
						.prop('title', compatReason)
202
						.tooltip();
203
				}
204
			});
205
206
			$item.find('.action-sync').on('click.CMSPicoAdminList', function (event) {
207
				event.preventDefault();
208
				that._api('POST', itemData.name);
209
			});
210
211
			$item.find('.action-copy').each(function () {
212
				var $this = $(this),
213
					dialogId = 'picocms-dialog-copy',
214
					dialogTitle = $this.data('originalTitle') || $this.prop('title') || $this.text();
215
216
				var $dialog = that.$copyTemplate.octemplate({
217
					id: dialogId,
218
					title: dialogTitle,
219
					source: itemData.name
220
				});
221
222
				var dialogButtons = [
223
					{
224
						text: t('cms_pico', 'Abort'),
225
						click: function (event) {
226
							$dialog.ocdialog('close');
227
						}
228
					},
229
					{
230
						text: t('cms_pico', 'Copy'),
231
						defaultButton: true,
232
						click: function (event) {
233
							var value = $dialog.find('.input-name').val();
234
							that._api('CLONE', itemData.name, { name: value });
235
236
							$dialog.ocdialog('close');
237
						}
238
					}
239
				];
240
241
				$this.on('click.CMSPicoAdminList', function (event) {
242
					event.preventDefault();
243
244
					$('#' + dialogId).ocdialog('close');
245
246
					$('#app-content').append($dialog);
247
					$dialog.ocdialog({ buttons: dialogButtons });
248
					$dialog.find('.input-name').focus();
249
				});
250
			});
251
252
			$item.find('.action-delete').on('click.CMSPicoAdminList', function (event) {
253
				event.preventDefault();
254
				that._api('DELETE', itemData.name);
255
			});
256
		}
257
	});
258
259
	$('.picocms-admin-list').each(function () {
260
		var $this = $(this),
261
			adminList = new OCA.CMSPico.AdminList($this);
262
263
		$this.data('CMSPicoAdminList', adminList);
264
		adminList.reload();
265
	});
266
267
	/**
268
	 * @class
269
	 * @extends OCA.CMSPico.Form
270
	 *
271
	 * @param {jQuery} $element
272
	 * @param {Object} [options]
273
	 * @param {string} [options.route]
274
	 */
275
	OCA.CMSPico.LimitGroupsForm = function ($element, options) {
276
		this.initialize($element, options);
277
	};
278
279
	/**
280
	 * @lends OCA.CMSPico.LimitGroupsForm.prototype
281
	 */
282
	OCA.CMSPico.LimitGroupsForm.prototype = $.extend({}, OCA.CMSPico.Form.prototype, {
283
		/**
284
		 * @public
285
		 */
286
		prepare: function () {
287
			var that = this,
288
				$input = this.$element.find('input');
289
290
			// loading order is crucial - and Nextcloud loads its own JS settings files last... m(
291
			$(function () {
292
				OC.Settings.setupGroupsSelect($input);
293
294
				$input.on('change.CMSPicoLimitGroupsForm', function (event) {
295
					that.submit();
296
				});
297
			});
298
		},
299
300
		/**
301
		 * @public
302
		 */
303
		submit: function () {
304
			var $input = this.$element.find(':input'),
305
				data = this.$element.serialize();
306
307
			$input.prop('disabled', true);
308
309
			$.ajax({
310
				method: 'POST',
311
				url: OC.generateUrl(this.route),
312
				data: data
313
			}).done(function (data, textStatus, jqXHR) {
314
				$input.prop('disabled', false);
315
			});
316
		}
317
	});
318
319
	$('.picocms-limit_groups-form').each(function () {
320
		var $this = $(this),
321
			limitGroupsForm = new OCA.CMSPico.LimitGroupsForm($this);
322
323
		$this.data('CMSPicoLimitGroupsForm', limitGroupsForm);
324
		limitGroupsForm.prepare();
325
	});
326
327
	/**
328
	 * @class
329
	 * @extends OCA.CMSPico.Form
330
	 *
331
	 * @param {jQuery} $element
332
	 * @param {Object} [options]
333
	 * @param {string} [options.route]
334
	 */
335
	OCA.CMSPico.LinkModeForm = function ($element, options) {
336
		this.initialize($element, options);
337
	};
338
339
	/**
340
	 * @lends OCA.CMSPico.LinkModeForm.prototype
341
	 */
342
	OCA.CMSPico.LinkModeForm.prototype = $.extend({}, OCA.CMSPico.Form.prototype, {
343
		/**
344
		 * @public
345
		 */
346
		prepare: function () {
347
			var that = this,
348
				$input = this.$element.find('input[type="radio"]');
349
350
			$input.on('change.CMSPicoLinkModeForm', function (event) {
351
				that.submit();
352
			});
353
		},
354
355
		/**
356
		 * @public
357
		 */
358
		submit: function () {
359
			var $input = this.$element.find(':input'),
360
				data = this.$element.serialize();
361
362
			$input.prop('disabled', true);
363
364
			$.ajax({
365
				method: 'POST',
366
				url: OC.generateUrl(this.route),
367
				data: data
368
			}).done(function (data, textStatus, jqXHR) {
369
				$input.prop('disabled', false);
370
			});
371
		}
372
	});
373
374
	$('.picocms-link_mode-form').each(function () {
375
		var $this = $(this),
376
			linkModeForm = new OCA.CMSPico.LinkModeForm($this);
377
378
		$this.data('CMSPicoLinkModeForm', linkModeForm);
379
		linkModeForm.prepare();
380
	});
381
})(document, jQuery, OC, OCA);
382