Passed
Push — master ( e1ffd9...b77c41 )
by Daniel
25:06
created

js/admin.js   A

Complexity

Total Complexity 42
Complexity/F 1.31

Size

Lines of Code 345
Function Count 32

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 42
eloc 156
mnd 10
bc 10
fnc 32
dl 0
loc 345
rs 9.0399
bpm 0.3125
cpm 1.3125
noi 0
c 0
b 0
f 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
						.tooltip('dispose')
202
						.attr('title', compatReason)
203
						.tooltip();
204
				}
205
			});
206
207
			$item.find('.action-sync').on('click.CMSPicoAdminList', function (event) {
208
				event.preventDefault();
209
				that._api('POST', itemData.name);
210
			});
211
212
			$item.find('.action-copy').each(function () {
213
				var $this = $(this);
214
215
				var dialog = new OCA.CMSPico.Dialog(that.$copyTemplate, {
216
					title: $this.data('originalTitle') || $this.prop('title') || $this.text(),
217
					templateData: { source: itemData.name },
218
					buttons: [
219
						{ type: OCA.CMSPico.Dialog.BUTTON_ABORT },
220
						{
221
							type: OCA.CMSPico.Dialog.BUTTON_SUBMIT,
222
							text: t('cms_pico', 'Copy')
223
						}
224
					]
225
				});
226
227
				dialog.on('open.CMSPicoAdminList', function () {
228
					this.$element.find('.input-name').focus();
229
				});
230
231
				dialog.on('submit.CMSPicoAdminList', function () {
232
					var value = this.$element.find('.input-name').val();
233
					that._api('CLONE', itemData.name, { name: value });
234
				});
235
236
				$this.on('click.CMSPicoAdminList', function (event) {
237
					event.preventDefault();
238
					dialog.open();
239
				});
240
			});
241
242
			$item.find('.action-delete').on('click.CMSPicoAdminList', function (event) {
243
				event.preventDefault();
244
				that._api('DELETE', itemData.name);
245
			});
246
		}
247
	});
248
249
	$('.picocms-admin-list').each(function () {
250
		var $this = $(this),
251
			adminList = new OCA.CMSPico.AdminList($this);
252
253
		$this.data('CMSPicoAdminList', adminList);
254
		adminList.reload();
255
	});
256
257
	/**
258
	 * @class
259
	 * @extends OCA.CMSPico.Form
260
	 *
261
	 * @param {jQuery} $element
262
	 * @param {Object} [options]
263
	 * @param {string} [options.route]
264
	 */
265
	OCA.CMSPico.LimitGroupsForm = function ($element, options) {
266
		this.initialize($element, options);
267
	};
268
269
	/**
270
	 * @lends OCA.CMSPico.LimitGroupsForm.prototype
271
	 */
272
	OCA.CMSPico.LimitGroupsForm.prototype = $.extend({}, OCA.CMSPico.Form.prototype, {
273
		/**
274
		 * @public
275
		 */
276
		prepare: function () {
277
			var that = this,
278
				$input = this.$element.find('input');
279
280
			// loading order is crucial - and Nextcloud loads its own JS settings files last... m(
281
			$(function () {
282
				OC.Settings.setupGroupsSelect($input);
283
284
				$input.on('change.CMSPicoLimitGroupsForm', function (event) {
285
					that.submit();
286
				});
287
			});
288
		},
289
290
		/**
291
		 * @public
292
		 */
293
		submit: function () {
294
			var $input = this.$element.find(':input'),
295
				data = this.$element.serialize();
296
297
			$input.prop('disabled', true);
298
299
			$.ajax({
300
				method: 'POST',
301
				url: OC.generateUrl(this.route),
302
				data: data
303
			}).done(function (data, textStatus, jqXHR) {
304
				$input.prop('disabled', false);
305
			});
306
		}
307
	});
308
309
	$('.picocms-limit_groups-form').each(function () {
310
		var $this = $(this),
311
			limitGroupsForm = new OCA.CMSPico.LimitGroupsForm($this);
312
313
		$this.data('CMSPicoLimitGroupsForm', limitGroupsForm);
314
		limitGroupsForm.prepare();
315
	});
316
317
	/**
318
	 * @class
319
	 * @extends OCA.CMSPico.Form
320
	 *
321
	 * @param {jQuery} $element
322
	 * @param {Object} [options]
323
	 * @param {string} [options.route]
324
	 */
325
	OCA.CMSPico.LinkModeForm = function ($element, options) {
326
		this.initialize($element, options);
327
	};
328
329
	/**
330
	 * @lends OCA.CMSPico.LinkModeForm.prototype
331
	 */
332
	OCA.CMSPico.LinkModeForm.prototype = $.extend({}, OCA.CMSPico.Form.prototype, {
333
		/**
334
		 * @public
335
		 */
336
		prepare: function () {
337
			var that = this,
338
				$input = this.$element.find('input[type="radio"]');
339
340
			$input.on('change.CMSPicoLinkModeForm', function (event) {
341
				that.submit();
342
			});
343
		},
344
345
		/**
346
		 * @public
347
		 */
348
		submit: function () {
349
			var $input = this.$element.find(':input'),
350
				data = this.$element.serialize();
351
352
			$input.prop('disabled', true);
353
354
			$.ajax({
355
				method: 'POST',
356
				url: OC.generateUrl(this.route),
357
				data: data
358
			}).done(function (data, textStatus, jqXHR) {
359
				$input.prop('disabled', false);
360
			});
361
		}
362
	});
363
364
	$('.picocms-link_mode-form').each(function () {
365
		var $this = $(this),
366
			linkModeForm = new OCA.CMSPico.LinkModeForm($this);
367
368
		$this.data('CMSPicoLinkModeForm', linkModeForm);
369
		linkModeForm.prepare();
370
	});
371
})(document, jQuery, OC, OCA);
372