diff --git a/client/src/views/webhook/fields/event.js b/client/src/views/webhook/fields/event.js index 98aef91009..9161696403 100644 --- a/client/src/views/webhook/fields/event.js +++ b/client/src/views/webhook/fields/event.js @@ -26,26 +26,22 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/webhook/fields/event', ['views/fields/varchar'], function (Dep) { +import VarcharFieldView from 'views/fields/varchar'; - return Dep.extend({ +export default class extends VarcharFieldView { - setupOptions: function () { - var itemList = []; + setupOptions() { + const itemList = []; - var scopeList = this.getMetadata().getScopeObjectList(); + const scopeList = this.getMetadata().getScopeObjectList() + .sort((v1, v2) => v1.localeCompare(v2)); - scopeList = scopeList.sort(function (v1, v2) { - return v1.localeCompare(v2); - }.bind(this)); + scopeList.forEach(scope => { + itemList.push(`${scope}.create`); + itemList.push(`${scope}.update`); + itemList.push(`${scope}.delete`); + }); - scopeList.forEach(function (scope) { - itemList.push(scope + '.' + 'create'); - itemList.push(scope + '.' + 'update'); - itemList.push(scope + '.' + 'delete'); - }, this); - - this.params.options = itemList; - }, - }); -}); + this.params.options = itemList; + } +} diff --git a/client/src/views/webhook/fields/user.js b/client/src/views/webhook/fields/user.js index f6a6655cdf..aa6acade40 100644 --- a/client/src/views/webhook/fields/user.js +++ b/client/src/views/webhook/fields/user.js @@ -26,11 +26,9 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/webhook/fields/user', ['views/fields/link'], function (Dep) { +import LinkFieldView from 'views/fields/link'; - return Dep.extend({ +export default class extends LinkFieldView { - selectPrimaryFilterName: 'activeApi', - - }); -}); + selectPrimaryFilterName = 'activeApi'; +} diff --git a/client/src/views/webhook/record/list.js b/client/src/views/webhook/record/list.js index 21af0d2e17..00fc4bf83a 100644 --- a/client/src/views/webhook/record/list.js +++ b/client/src/views/webhook/record/list.js @@ -26,11 +26,9 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/webhook/record/list', ['views/record/list'], function (Dep) { +import ListRecordView from 'views/record/list'; - return Dep.extend({ +export default class extends ListRecordView { - massActionList: ['remove', 'massUpdate', 'export'], - - }); -}); + massActionList = ['remove', 'massUpdate', 'export'] +} diff --git a/client/src/views/working-time-calendar/fields/time-ranges.js b/client/src/views/working-time-calendar/fields/time-ranges.js index a3b943db18..5e2ba44712 100644 --- a/client/src/views/working-time-calendar/fields/time-ranges.js +++ b/client/src/views/working-time-calendar/fields/time-ranges.js @@ -26,319 +26,322 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/working-time-calendar/fields/time-ranges', ['views/fields/base'], function (Dep) { +import BaseFieldView from 'views/fields/base'; + +export default class extends BaseFieldView { + + // language=Handlebars + listTemplateContent = ` +
+ {{#each itemDataList}} + {{{var viewKey ../this}}}{{#unless isLast}}  ·  {{/unless}} + {{/each}} +
+ {{#unless itemDataList.length}} + {{translate 'None'}} + {{/unless}} + ` + + // language=Handlebars + detailTemplateContent = ` +
+ {{#each itemDataList}} +
+ {{{var viewKey ../this}}} +
+ {{/each}} +
+ {{#unless itemDataList.length}} + {{translate 'None'}} + {{/unless}} + ` + + // language=Handlebars + editTemplateContent = ` +
+ {{#each itemDataList}} +
+ {{{var viewKey ../this}}} +
+ {{/each}} +
+
+ +
+ ` + + // noinspection JSCheckFunctionSignatures + data() { + const data = super.data(); + + data.itemDataList = this.itemKeyList.map((key, i) => { + return { + key: key.toString(), + viewKey: this.composeViewKey(key), + isLast: i === this.itemKeyList.length - 1, + }; + }); + + // noinspection JSValidateTypes + return data; + } + + setup() { + super.setup(); + + this.validations = [ + () => this.validateRequired(), + () => this.validateValid(), + ]; + + this.addHandler('click', '.add-item', () => this.addItem()); + + this.addHandler('click', '.remove-item', (e, target) => { + this.removeItem(parseInt(target.dataset.key)); + }); + } + + prepare() { + this.initItems(); + + return this.createItemViews(); + } + + initItems() { + this.itemKeyList = []; + + this.getItemListFromModel().forEach((item, i) => { + this.itemKeyList.push(i); + }); + } /** - * @class - * @name Class - * @memberOf module:views/working-time-calendar/fields/time-ranges - * @extends module:views/fields/base + * @returns {Promise} */ - return Dep.extend(/** @lends module:views/working-time-calendar/fields/time-ranges.Class# */{ + createItemView(item, key) { + const viewName = this.isEditMode() ? + 'views/working-time-calendar/fields/time-ranges/item-edit' : + 'views/working-time-calendar/fields/time-ranges/item-detail'; - listTemplateContent: ` -
- {{#each itemDataList}} - {{{var viewKey ../this}}}{{#unless isLast}}  ·  {{/unless}} - {{/each}} -
- {{#unless itemDataList.length}} - {{translate 'None'}} - {{/unless}} - `, - - detailTemplateContent: ` -
- {{#each itemDataList}} -
- {{{var viewKey ../this}}} -
- {{/each}} -
- {{#unless itemDataList.length}} - {{translate 'None'}} - {{/unless}} - `, - - editTemplateContent: ` -
- {{#each itemDataList}} -
- {{{var viewKey ../this}}} -
- {{/each}} -
-
- -
- `, - - fetchEmptyAsNull: false, - - validations: ['required', 'valid'], - - events: { - 'click .add-item': function () { - this.addItem(); - }, - 'click .remove-item': function (e) { - let key = parseInt($(e.currentTarget).attr('data-key')); - - this.removeItem(key); - }, - }, - - data: function () { - let data = Dep.prototype.data.call(this); - - data.itemDataList = this.itemKeyList.map((key, i) => { - return { - key: key.toString(), - viewKey: this.composeViewKey(key), - isLast: i === this.itemKeyList.length - 1, - }; - }); - - return data; - }, - - prepare: function () { - this.initItems(); - - return this.createItemViews(); - }, - - initItems: function () { - this.itemKeyList = []; - - this.getItemListFromModel().forEach((item, i) => { - this.itemKeyList.push(i); - }); - }, - - /** - * @returns {Promise} - */ - createItemView: function (item, key) { - let viewName = this.isEditMode() ? - 'views/working-time-calendar/fields/time-ranges/item-edit' : - 'views/working-time-calendar/fields/time-ranges/item-detail'; - - return this.createView( - this.composeViewKey(key), - viewName, - { - value: item, - selector: '.item[data-key="' + key + '"]', - key: key, - } - ) - .then(view => { - this.listenTo(view, 'change', () => { - this.trigger('change'); - }); - - return view; - }); - }, - - /** - * @returns {Promise} - */ - createItemViews: function () { - this.itemKeyList.forEach(key => { - this.clearView(this.composeViewKey(key)); - }); - - if (!this.model.has(this.name)) { - return Promise.resolve(); + return this.createView( + this.composeViewKey(key), + viewName, + { + value: item, + selector: `.item[data-key="${key}"]`, + key: key, } - - let itemList = this.getItemListFromModel(); - - let promiseList = []; - - this.itemKeyList.forEach((key, i) => { - let item = itemList[i]; - - let promise = this.createItemView(item, key); - - promiseList.push(promise); + ) + .then(view => { + this.listenTo(view, 'change', () => { + this.trigger('change'); }); - return Promise.all(promiseList); - }, - - getItemView: function (key) { - return this.getView(this.composeViewKey(key)); - }, - - composeViewKey: function (key) { - return 'item-' + key; - }, - - /** - * @return {[string|null, string|null][]} - */ - getItemListFromModel: function () { - return Espo.Utils.cloneDeep(this.model.get(this.name) || []); - }, - - addItem: function () { - let itemList = this.getItemListFromModel(); - - let value = null; - - if (itemList.length) { - value = itemList[itemList.length - 1][1]; - } - - let item = [value, null]; - - itemList.push(item); - - let key = this.itemKeyList[this.itemKeyList.length - 1]; - - if (typeof key === 'undefined') { - key = 0; - } - - key++; - - this.itemKeyList.push(key); - - this.$el.find('.item-list').append( - $('
') - .addClass('item') - .attr('data-key', key) - ); - - this.createItemView(item, key) - .then(view => view.render()) - .then(() => { - this.trigger('change'); - }); - }, - - removeItem: function (key) { - let index = this.itemKeyList.indexOf(key); - - if (key === -1) { - return; - } - - let itemList = this.getItemListFromModel(); - - this.itemKeyList.splice(index, 1); - itemList.splice(index, 1); - - this.model.set(this.name, itemList, {ui: true}); + return view; + }); + } + /** + * @returns {Promise} + */ + createItemViews() { + this.itemKeyList.forEach(key => { this.clearView(this.composeViewKey(key)); + }); - this.$el.find(`.item[data-key="${key}"`).remove(); + if (!this.model.has(this.name)) { + return Promise.resolve(); + } - this.trigger('change'); - }, + const itemList = this.getItemListFromModel(); - fetch: function () { - let itemList = []; + const promiseList = []; - this.itemKeyList.forEach(key => { - itemList.push( - this.getItemView(key).fetch() - ); + this.itemKeyList.forEach((key, i) => { + const item = itemList[i]; + + const promise = this.createItemView(item, key); + + promiseList.push(promise); + }); + + return Promise.all(promiseList); + } + + /** + * @param {string} key + * @return {import('./time-ranges/item-edit').default} + */ + getItemView(key) { + // noinspection JSValidateTypes + return this.getView(this.composeViewKey(key)); + } + + composeViewKey(key) { + return `item-${key}`; + } + + /** + * @return {[string|null, string|null][]} + */ + getItemListFromModel() { + return Espo.Utils.cloneDeep(this.model.get(this.name) || []); + } + + addItem() { + const itemList = this.getItemListFromModel(); + + let value = null; + + if (itemList.length) { + value = itemList[itemList.length - 1][1]; + } + + const item = [value, null]; + + itemList.push(item); + + let key = this.itemKeyList[this.itemKeyList.length - 1]; + + if (typeof key === 'undefined') { + key = 0; + } + + key++; + + this.itemKeyList.push(key); + + this.$el.find('.item-list').append( + $('
') + .addClass('item') + .attr('data-key', key) + ); + + this.createItemView(item, key) + .then(view => view.render()) + .then(() => { + this.trigger('change'); }); + } - let data = {}; + removeItem(key) { + const index = this.itemKeyList.indexOf(key); - data[this.name] = Espo.Utils.cloneDeep(itemList); + if (key === -1) { + return; + } - if (data[this.name].length === 0) { - data[this.name] = null; - } + const itemList = this.getItemListFromModel(); - return data; - }, + this.itemKeyList.splice(index, 1); + itemList.splice(index, 1); - validateRequired: function () { - if (!this.isRequired()) { - return false; - } + this.model.set(this.name, itemList, {ui: true}); - if (this.getItemListFromModel().length) { - return false; - } + this.clearView(this.composeViewKey(key)); - let msg = this.translate('fieldIsRequired', 'messages') - .replace('{field}', this.getLabelText()); + this.$el.find(`.item[data-key="${key}"`).remove(); - this.showValidationMessage(msg, '.add-item-container'); + this.trigger('change'); + } - return true; - }, + fetch() { + const itemList = []; - validateValid: function () { - if (!this.isRangesInvalid()) { - return false; - } + this.itemKeyList.forEach(key => { + itemList.push( + this.getItemView(key).fetch() + ); + }); - let msg = this.translate('fieldInvalid', 'messages') - .replace('{field}', this.getLabelText()); + const data = {}; - this.showValidationMessage(msg, '.add-item-container'); + data[this.name] = Espo.Utils.cloneDeep(itemList); - return true; - }, + if (data[this.name].length === 0) { + data[this.name] = null; + } - isRangesInvalid: function () { - let itemList = this.getItemListFromModel(); - - for (let i = 0; i < itemList.length; i++) { - let item = itemList[i]; - - if (this.isRangeInvalid(item[0], item[1], true)) { - return true; - } - - if (i === 0) { - continue; - } - - let prevItem = item[i - 1]; - - if (this.isRangeInvalid(prevItem[1], item[0])) { - return true; - } - } + return data; + } + validateRequired() { + if (!this.isRequired()) { return false; - }, + } - /** - * @param {string|null} from - * @param {string|null} to - * @param {boolean} [noEmpty] - */ - isRangeInvalid: function (from, to, noEmpty) { - if (from === null || to === null) { + if (this.getItemListFromModel().length) { + return false; + } + + const msg = this.translate('fieldIsRequired', 'messages') + .replace('{field}', this.getLabelText()); + + this.showValidationMessage(msg, '.add-item-container'); + + return true; + } + + validateValid() { + if (!this.isRangesInvalid()) { + return false; + } + + const msg = this.translate('fieldInvalid', 'messages') + .replace('{field}', this.getLabelText()); + + this.showValidationMessage(msg, '.add-item-container'); + + return true; + } + + isRangesInvalid() { + const itemList = this.getItemListFromModel(); + + for (let i = 0; i < itemList.length; i++) { + const item = itemList[i]; + + if (this.isRangeInvalid(item[0], item[1], true)) { return true; } - let fromNumber = parseFloat(from.replace(':', '.')); - let toNumber = parseFloat(to.replace(':', '.')); - - if (noEmpty && fromNumber === toNumber) { - return true; + if (i === 0) { + continue; } - return fromNumber > toNumber; - }, - }); -}); + const prevItem = item[i - 1]; + + if (this.isRangeInvalid(prevItem[1], item[0])) { + return true; + } + } + + return false; + } + + /** + * @param {string|null} from + * @param {string|null} to + * @param {boolean} [noEmpty] + */ + isRangeInvalid(from, to, noEmpty) { + if (from === null || to === null) { + return true; + } + + const fromNumber = parseFloat(from.replace(':', '.')); + const toNumber = parseFloat(to.replace(':', '.')); + + if (noEmpty && fromNumber === toNumber) { + return true; + } + + return fromNumber > toNumber; + } +} diff --git a/client/src/views/working-time-calendar/fields/time-ranges/item-detail.js b/client/src/views/working-time-calendar/fields/time-ranges/item-detail.js index bf27c0f94d..a722b57187 100644 --- a/client/src/views/working-time-calendar/fields/time-ranges/item-detail.js +++ b/client/src/views/working-time-calendar/fields/time-ranges/item-detail.js @@ -26,45 +26,39 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/working-time-calendar/fields/time-ranges/item-detail', ['view', 'lib!moment'], -(Dep, /** @param {moment} */moment) => { +import View from 'view'; +import moment from 'moment'; - /** - * @extends module:view - */ - class Class extends Dep - { - templateContent = ` - {{start}} -  –  - {{end}} - ` +export default class extends View { - data() { - return { - start: this.convertTimeToDisplay(this.value[0]), - end: this.convertTimeToDisplay(this.value[1]), - }; - } + templateContent = ` + {{start}} +  –  + {{end}} + ` - setup() { - this.value = this.options.value; - } - - convertTimeToDisplay(value) { - if (!value) { - return ''; - } - - let m = moment(value, 'HH:mm'); - - if (!m.isValid()) { - return ''; - } - - return m.format(this.getDateTime().timeFormat); - } + data() { + return { + start: this.convertTimeToDisplay(this.value[0]), + end: this.convertTimeToDisplay(this.value[1]), + }; } - return Class; -}); + setup() { + this.value = this.options.value; + } + + convertTimeToDisplay(value) { + if (!value) { + return ''; + } + + const m = moment(value, 'HH:mm'); + + if (!m.isValid()) { + return ''; + } + + return m.format(this.getDateTime().timeFormat); + } +} diff --git a/client/src/views/working-time-calendar/fields/time-ranges/item-edit.js b/client/src/views/working-time-calendar/fields/time-ranges/item-edit.js index 0e3fdbe7e2..780ff7fac8 100644 --- a/client/src/views/working-time-calendar/fields/time-ranges/item-edit.js +++ b/client/src/views/working-time-calendar/fields/time-ranges/item-edit.js @@ -26,144 +26,144 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/working-time-calendar/fields/time-ranges/item-edit', ['view', 'lib!moment'], function (Dep, moment) { +import View from 'view'; +import moment from 'moment'; - return Dep.extend({ +export default class extends View { - // language=Handlebars - templateContent: ` -
-
- -
-
-  –  -
-
- -
-
- -
+ + // language=Handlebars + templateContent = ` +
+
+
- `, +
+  –  +
+
+ +
+
+ +
+
+ ` - timeFormatMap: { - 'HH:mm': 'H:i', - 'hh:mm A': 'h:i A', - 'hh:mm a': 'h:i a', - 'hh:mmA': 'h:iA', - 'hh:mma': 'h:ia', - }, + timeFormatMap = { + 'HH:mm': 'H:i', + 'hh:mm A': 'h:i A', + 'hh:mm a': 'h:i a', + 'hh:mmA': 'h:iA', + 'hh:mma': 'h:ia', + } - minuteStep: 30, + minuteStep = 30 - data: function () { - let data = {}; + data () { + const data = {}; - data.start = this.convertTimeToDisplay(this.value[0]); - data.end = this.convertTimeToDisplay(this.value[1]); + data.start = this.convertTimeToDisplay(this.value[0]); + data.end = this.convertTimeToDisplay(this.value[1]); - data.key = this.key; + data.key = this.key; - return data; - }, + return data; + } - setup: function () { - this.value = this.options.value || [null, null]; - this.key = this.options.key; - }, + setup () { + this.value = this.options.value || [null, null]; + this.key = this.options.key; + } - convertTimeToDisplay: function (value) { - if (!value) { - return ''; - } + convertTimeToDisplay(value) { + if (!value) { + return ''; + } - let m = moment(value, 'HH:mm'); + const m = moment(value, 'HH:mm'); - if (!m.isValid()) { - return ''; - } + if (!m.isValid()) { + return ''; + } - return m.format(this.getDateTime().timeFormat); - }, + return m.format(this.getDateTime().timeFormat); + } - convertTimeFromDisplay: function (value) { - if (!value) { - return null; - } + convertTimeFromDisplay(value) { + if (!value) { + return null; + } - let m = moment(value, this.getDateTime().timeFormat); + const m = moment(value, this.getDateTime().timeFormat); - if (!m.isValid()) { - return null; - } + if (!m.isValid()) { + return null; + } - return m.format('HH:mm'); - }, + return m.format('HH:mm'); + } - afterRender: function () { - this.$start = this.$el.find('[data-name="start"]'); - this.$end = this.$el.find('[data-name="end"]'); + afterRender() { + this.$start = this.$el.find('[data-name="start"]'); + this.$end = this.$el.find('[data-name="end"]'); - this.initTimepicker(this.$start); - this.initTimepicker(this.$end); + this.initTimepicker(this.$start); + this.initTimepicker(this.$end); - this.setMinTime(); + this.setMinTime(); - this.$start.on('change', () => this.setMinTime()); - }, + this.$start.on('change', () => this.setMinTime()); + } - setMinTime: function () { - let value = this.$start.val(); + setMinTime() { + const value = this.$start.val(); - this.$end.timepicker('option', 'maxTime', this.convertTimeToDisplay('23:59')); + this.$end.timepicker('option', 'maxTime', this.convertTimeToDisplay('23:59')); - if (!value) { - this.$end.timepicker('option', 'minTime', null); + if (!value) { + this.$end.timepicker('option', 'minTime', null); - return; - } + return; + } - this.$end.timepicker('option', 'minTime', value); - }, + this.$end.timepicker('option', 'minTime', value); + } - initTimepicker: function ($el) { - $el.timepicker({ - step: this.minuteStep, - timeFormat: this.timeFormatMap[this.getDateTime().timeFormat], - }); + initTimepicker($el) { + $el.timepicker({ + step: this.minuteStep, + timeFormat: this.timeFormatMap[this.getDateTime().timeFormat], + }); - $el.on('change', () => this.trigger('change')); + $el.on('change', () => this.trigger('change')); + $el.attr('autocomplete', 'espo-time-range-item'); + } - $el.attr('autocomplete', 'espo-time-range-item'); - }, - - fetch: function () { - return [ - this.convertTimeFromDisplay(this.$start.val()), - this.convertTimeFromDisplay(this.$end.val()), - ]; - }, - }); -}); + fetch() { + return [ + this.convertTimeFromDisplay(this.$start.val()), + this.convertTimeFromDisplay(this.$end.val()), + ]; + } +}