diff --git a/.eslintrc.js b/.eslintrc.js index 08f43856e96..d3720ccf04b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,8 @@ module.exports = { sourceType: 'module' }, plugins: [ - 'ember' + 'ember', + 'ember-suave' ], extends: [ 'eslint:recommended', @@ -66,9 +67,16 @@ module.exports = { 'new-cap': 'off', 'eqeqeq': ['error', 'smart'], 'one-var': 'off', + 'padding-line-between-statements': 'off', + 'lines-between-class-members': ['error', "always", { exceptAfterSingleLine: true }], 'ember-suave/no-const-outside-module-scope': 'off', 'ember-suave/require-access-in-comments': 'off', + 'ember-suave/lines-between-object-properties': 'off', 'ember/no-get': 'error', + // TODO: Re-enable later + 'no-duplicate-imports': 'warn', + 'no-await-in-loop': 'warn', + 'import/no-relative-parent-imports': 'warn', }, globals: { module : true, diff --git a/.template-lintrc.js b/.template-lintrc.js index 5eb453abff4..cf1e5de0144 100644 --- a/.template-lintrc.js +++ b/.template-lintrc.js @@ -6,6 +6,14 @@ module.exports = { rules: { 'no-nested-interactive': { ignoredTags: ['label'] // Allow label tag inside a or any other interactive element - } + }, + 'link-rel-noopener': true, + // TODO: Remove and fix + 'require-button-type': false, + 'no-partial': false, + 'require-valid-alt-text': false, + 'no-inline-styles': false, + 'no-negated-condition': false, + 'no-invalid-meta': false // Crashing the linter https://github.com/ember-template-lint/ember-template-lint/pull/1087 } }; diff --git a/.travis.yml b/.travis.yml index 621e91eedd9..ce8acac8276 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,7 @@ script: - yarn lint:scss - COVERAGE=true yarn test - ROOT_URL=open-event-frontend ember build -prod + - bash scripts/test_fastboot.sh after_success: - 'bash <(curl -s https://codecov.io/bash)' diff --git a/app/adapters/application.js b/app/adapters/application.js index a692e994292..8b72f458507 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.js @@ -3,7 +3,6 @@ import { computed } from '@ember/object'; import ENV from 'open-event-frontend/config/environment'; import JSONAPIAdapter from 'ember-data/adapters/json-api'; import HasManyQueryAdapterMixin from 'ember-data-has-many-query/mixins/rest-adapter'; -import AdapterFetch from 'ember-fetch/mixins/adapter-fetch'; import FastbootAdapter from 'ember-data-storefront/mixins/fastboot-adapter'; /** @@ -20,7 +19,7 @@ export const fixFilterQuery = query => { return query; }; -export default JSONAPIAdapter.extend(HasManyQueryAdapterMixin, AdapterFetch, FastbootAdapter, { +export default JSONAPIAdapter.extend(HasManyQueryAdapterMixin, FastbootAdapter, { host : ENV.APP.apiHost, namespace : ENV.APP.apiNamespace, diff --git a/app/components/account/application-section.js b/app/components/account/application-section.js index c6ad772b80a..14c40ba5d9f 100644 --- a/app/components/account/application-section.js +++ b/app/components/account/application-section.js @@ -15,8 +15,8 @@ export default Component.extend({ this.loader.load(`/auth/oauth/login/${ provider }/${ authData.authorizationCode }/?redirect_uri=${ authData.redirectUri}`) .then(async response => { let credentials = { - 'identification' : response.email, - 'password' : response.facebook_login_hash + 'username' : response.email, + 'password' : response.facebook_login_hash }; let authenticator = 'authenticator:jwt'; diff --git a/app/components/event-invoice/billing-info.js b/app/components/event-invoice/billing-info.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/event-invoice/billing-info.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/event-invoice/event-info.js b/app/components/event-invoice/event-info.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/event-invoice/event-info.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/event-invoice/invoice-summary.js b/app/components/event-invoice/invoice-summary.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/event-invoice/invoice-summary.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/event-invoice/payee-info.js b/app/components/event-invoice/payee-info.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/event-invoice/payee-info.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/forms/admin/settings/system/captcha-form.js b/app/components/forms/admin/settings/system/captcha-form.js index c9dedd35d0c..7822b3c17a3 100644 --- a/app/components/forms/admin/settings/system/captcha-form.js +++ b/app/components/forms/admin/settings/system/captcha-form.js @@ -2,4 +2,4 @@ import Component from '@ember/component'; export default class extends Component { -} \ No newline at end of file +} diff --git a/app/components/forms/admin/settings/system/order-expiry-form.js b/app/components/forms/admin/settings/system/order-expiry-form.js index c9dedd35d0c..7822b3c17a3 100644 --- a/app/components/forms/admin/settings/system/order-expiry-form.js +++ b/app/components/forms/admin/settings/system/order-expiry-form.js @@ -2,4 +2,4 @@ import Component from '@ember/component'; export default class extends Component { -} \ No newline at end of file +} diff --git a/app/components/forms/login-form.js b/app/components/forms/login-form.js index 414d2c09900..6c62f4f56e5 100644 --- a/app/components/forms/login-form.js +++ b/app/components/forms/login-form.js @@ -44,7 +44,7 @@ export default class extends Component.extend(FormMixin) { @action async submit() { this.onValid(async() => { - let credentials = { identification: this.identification, password: this.password }, + let credentials = { username: this.identification, password: this.password }, authenticator = 'authenticator:jwt'; this.setProperties({ errorMessage : null, @@ -60,8 +60,8 @@ export default class extends Component.extend(FormMixin) { } } catch (e) { - if (e.error) { - this.set('errorMessage', this.l10n.tVar(e.error)); + if (e.json && e.json.error) { + this.set('errorMessage', this.l10n.tVar(e.json.error)); } else { this.set('errorMessage', this.l10n.t('An unexpected error occurred.')); } diff --git a/app/components/forms/wizard/basic-details-step.js b/app/components/forms/wizard/basic-details-step.js index dd0a5e0d7a3..dda2574aa03 100644 --- a/app/components/forms/wizard/basic-details-step.js +++ b/app/components/forms/wizard/basic-details-step.js @@ -12,6 +12,7 @@ import { inject as service } from '@ember/service'; import EventWizardMixin from 'open-event-frontend/mixins/event-wizard'; import { protocolLessValidUrlPattern } from 'open-event-frontend/utils/validators'; import ENV from 'open-event-frontend/config/environment'; +import $ from 'jquery'; export default Component.extend(FormMixin, EventWizardMixin, { @@ -128,6 +129,12 @@ export default Component.extend(FormMixin, EventWizardMixin, { // TODO: Removing the Event Time Validations due to the weird and buggy behaviour. Will be restored once a perfect solution is found. Please check issue: https://github.com/fossasia/open-event-frontend/issues/3667 getValidationRules() { + $.fn.form.settings.rules.checkMaxMinPrice = () => { + return $('.ui.form').form('get value', 'min_price') <= $('.ui.form').form('get value', 'max_price'); + }; + $.fn.form.settings.rules.checkMaxMinOrder = () => { + return $('.ui.form').form('get value', 'ticket_min_order') <= $('.ui.form').form('get value', 'ticket_max_order'); + }; let validationRules = { inline : true, @@ -257,6 +264,10 @@ export default Component.extend(FormMixin, EventWizardMixin, { { type : 'number', prompt : this.l10n.t('Invalid number') + }, + { + type : 'checkMaxMinOrder', + prompt : this.l10n.t('Minimum order should not be greater than maximum') } ] }, @@ -274,6 +285,10 @@ export default Component.extend(FormMixin, EventWizardMixin, { { type : 'integer[1..]', prompt : this.l10n.t('Maximum tickets per order should be greater than 0') + }, + { + type : 'checkMaxMinOrder', + prompt : this.l10n.t('Maximum order should not be less than minimum') } ] }, @@ -287,6 +302,10 @@ export default Component.extend(FormMixin, EventWizardMixin, { { type : 'integer[1..]', prompt : this.l10n.t('Minimum price needs to be greater than zero') + }, + { + type : 'checkMaxMinPrice', + prompt : this.l10n.t('Minimum price should not be greater than maximum') } ] }, @@ -300,6 +319,10 @@ export default Component.extend(FormMixin, EventWizardMixin, { { type : 'integer[1..]', prompt : this.l10n.t('Maximum price needs to be greater than zero') + }, + { + type : 'checkMaxMinPrice', + prompt : this.l10n.t('Maximum price should not be less than minimum') } ] }, diff --git a/app/components/modals/cropper-modal.js b/app/components/modals/cropper-modal.js index 41a1a702aeb..02921fcbb44 100644 --- a/app/components/modals/cropper-modal.js +++ b/app/components/modals/cropper-modal.js @@ -27,11 +27,13 @@ export default class extends ModalBase { } } + @action resetImage() { this.onHide(); this.onVisible(); } + @action cropImage() { $('img', this.element).croppie('result', { type: 'base64', size: 'original', quality: 1, format: 'jpeg' }).then(result => { diff --git a/app/components/orders/organizer-info.js b/app/components/orders/organizer-info.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/orders/organizer-info.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/paypal-button.js b/app/components/paypal-button.js index 3963acba426..1c5ca2738f4 100644 --- a/app/components/paypal-button.js +++ b/app/components/paypal-button.js @@ -136,4 +136,4 @@ export default Component.extend({ } } -}); \ No newline at end of file +}); diff --git a/app/components/public/ticket-list.js b/app/components/public/ticket-list.js index 84e76e654b1..d185121c252 100644 --- a/app/components/public/ticket-list.js +++ b/app/components/public/ticket-list.js @@ -2,9 +2,8 @@ import Component from '@ember/component'; import { computed } from '@ember/object'; import FormMixin from 'open-event-frontend/mixins/form'; import { inject as service } from '@ember/service'; -import { sumBy } from 'lodash-es'; +import { sumBy, merge } from 'lodash-es'; import { A } from '@ember/array'; -import { merge } from 'lodash-es'; export default Component.extend(FormMixin, { store: service(), diff --git a/app/components/tables/utilities/pagination.js b/app/components/tables/utilities/pagination.js index 3b393ad4a83..9f236a54981 100644 --- a/app/components/tables/utilities/pagination.js +++ b/app/components/tables/utilities/pagination.js @@ -35,6 +35,7 @@ export default class extends Component { return this.currentPage <= 1; } + @computed('currentPage', 'pageCount') get moveToNextPageDisabled() { return this.currentPage >= this.pageCount; diff --git a/app/components/ui-table-server.js b/app/components/ui-table-server.js index d67411d2214..625be6c0f91 100644 --- a/app/components/ui-table-server.js +++ b/app/components/ui-table-server.js @@ -83,8 +83,7 @@ export default ModelsTable.extend({ if (!get(this.data, 'query')) { console.warn('You must use https://emberjs.com/api/data/classes/DS.Store.html#method_query for loading data'); query = merge({}, this.query); - store = this.store; - modelName = this.modelName; + ({ store, modelName } = this); } else { query = merge({}, get(this.data, 'query')); store = get(this.data, 'store'); diff --git a/app/components/ui-table/cell/admin/events/event-is-featured.js b/app/components/ui-table/cell/admin/events/event-is-featured.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/admin/events/event-is-featured.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/admin/events/event-is-promoted.js b/app/components/ui-table/cell/admin/events/event-is-promoted.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/admin/events/event-is-promoted.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/admin/messages/cell-options.js b/app/components/ui-table/cell/admin/messages/cell-options.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/admin/messages/cell-options.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/cell-event-date.js b/app/components/ui-table/cell/cell-event-date.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/cell-event-date.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/cell-event-state.js b/app/components/ui-table/cell/cell-event-state.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/cell-event-state.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/cell-sessions-dashboard.js b/app/components/ui-table/cell/cell-sessions-dashboard.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/cell-sessions-dashboard.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/cell-speakers-dashboard.js b/app/components/ui-table/cell/cell-speakers-dashboard.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/cell-speakers-dashboard.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/cell-sponsor-image.js b/app/components/ui-table/cell/cell-sponsor-image.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/cell-sponsor-image.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/cell-sponsor-sanitize.js b/app/components/ui-table/cell/cell-sponsor-sanitize.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/cell-sponsor-sanitize.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/cell-action.js b/app/components/ui-table/cell/events/cell-action.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/cell-action.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/cell-amount.js b/app/components/ui-table/cell/events/cell-amount.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/cell-amount.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/cell-event-invoice.js b/app/components/ui-table/cell/events/cell-event-invoice.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/cell-event-invoice.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/speakers/cell-buttons.js b/app/components/ui-table/cell/events/view/speakers/cell-buttons.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/speakers/cell-buttons.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/speakers/cell-is-featured.js b/app/components/ui-table/cell/events/view/speakers/cell-is-featured.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/speakers/cell-is-featured.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/speakers/cell-simple-sessions.js b/app/components/ui-table/cell/events/view/speakers/cell-simple-sessions.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/speakers/cell-simple-sessions.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/speakers/speaker-logo.js b/app/components/ui-table/cell/events/view/speakers/speaker-logo.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/speakers/speaker-logo.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/speakers/speaker-mobile.js b/app/components/ui-table/cell/events/view/speakers/speaker-mobile.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/speakers/speaker-mobile.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/tickets/access-codes/cell-actions.js b/app/components/ui-table/cell/events/view/tickets/access-codes/cell-actions.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/tickets/access-codes/cell-actions.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/cell/events/view/tickets/access-codes/cell-url.js b/app/components/ui-table/cell/events/view/tickets/access-codes/cell-url.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/cell/events/view/tickets/access-codes/cell-url.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/expand-row-cell.js b/app/components/ui-table/expand-row-cell.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/expand-row-cell.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/header-row-filtering.js b/app/components/ui-table/header-row-filtering.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/header-row-filtering.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/header-row-sorting.js b/app/components/ui-table/header-row-sorting.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/header-row-sorting.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/header-rows-grouped.js b/app/components/ui-table/header-rows-grouped.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/header-rows-grouped.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/ui-table/header-sorting-icons.js b/app/components/ui-table/header-sorting-icons.js new file mode 100644 index 00000000000..bb93d73f350 --- /dev/null +++ b/app/components/ui-table/header-sorting-icons.js @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default Component.extend({ +}); diff --git a/app/components/widgets/forms/billing-info.js b/app/components/widgets/forms/billing-info.js index a360fe8bd08..72f82142fa6 100644 --- a/app/components/widgets/forms/billing-info.js +++ b/app/components/widgets/forms/billing-info.js @@ -7,4 +7,4 @@ export default Component.extend({ countries: computed(function() { return orderBy(countries, 'name'); }) -}); \ No newline at end of file +}); diff --git a/app/controllers/account/billing/invoices/list.js b/app/controllers/account/billing/invoices/list.js index f5112d09204..1de3d50cd3d 100644 --- a/app/controllers/account/billing/invoices/list.js +++ b/app/controllers/account/billing/invoices/list.js @@ -139,4 +139,4 @@ export default class extends Controller.extend(EmberTableControllerMixin) { } return columns; } -} \ No newline at end of file +} diff --git a/app/controllers/admin/content/events.js b/app/controllers/admin/content/events.js index 0c5f39856c4..ff2f3b08b03 100644 --- a/app/controllers/admin/content/events.js +++ b/app/controllers/admin/content/events.js @@ -23,6 +23,7 @@ export default class extends Controller { this.set('isLoading', false); } } + @action openModalFor(modelInstanceOrName) { const modelName = typeof modelInstanceOrName === 'string' ? modelInstanceOrName : modelInstanceOrName.constructor.modelName; @@ -31,6 +32,7 @@ export default class extends Controller { this.set(camelCasedValue, modelInstance); modelInstance.openModal = true; } + @action deleteEventProperty(eventProp) { this.set('isLoading', true); @@ -53,6 +55,7 @@ export default class extends Controller { this.set('isLoading', false); }); } + @action addEventProperty(modelInstance) { const camelCasedValue = camelCase(modelInstance.constructor.modelName); diff --git a/app/controllers/admin/content/pages.js b/app/controllers/admin/content/pages.js index e1a7b032520..0f5e2631def 100644 --- a/app/controllers/admin/content/pages.js +++ b/app/controllers/admin/content/pages.js @@ -19,6 +19,7 @@ export default class extends Controller { } this.set('isFormOpen', true); } + @action savePage(page) { page.save() diff --git a/app/controllers/admin/content/system-images/list.js b/app/controllers/admin/content/system-images/list.js index f5fcce4f57b..4bc7274c11f 100644 --- a/app/controllers/admin/content/system-images/list.js +++ b/app/controllers/admin/content/system-images/list.js @@ -1,6 +1,5 @@ import Controller from '@ember/controller'; -import { computed } from '@ember/object'; -import { action } from '@ember/object'; +import { computed, action } from '@ember/object'; export default class extends Controller { diff --git a/app/controllers/admin/events/list.js b/app/controllers/admin/events/list.js index 4c883d3e539..2a918b762da 100644 --- a/app/controllers/admin/events/list.js +++ b/app/controllers/admin/events/list.js @@ -64,14 +64,14 @@ export default class extends Controller.extend(EmberTableControllerMixin) { }, { name : 'Sessions', - valuePath : 'eventStatisticsGeneral', + valuePath : 'generalStatistics', cellComponent : 'ui-table/cell/cell-sessions', width : 90 }, { name : 'Speakers', - valuePath : 'eventStatisticsGeneral', + valuePath : 'generalStatistics', cellComponent : 'ui-table/cell/cell-speakers-dashboard', width : 90 }, @@ -147,6 +147,7 @@ export default class extends Controller.extend(EmberTableControllerMixin) { isEventDeleteModalOpen : false }); } + @action async restoreEvent(event_id) { this.set('isLoading', true); diff --git a/app/controllers/admin/permissions/event-roles.js b/app/controllers/admin/permissions/event-roles.js index 560e90c4944..88a62ebaa71 100644 --- a/app/controllers/admin/permissions/event-roles.js +++ b/app/controllers/admin/permissions/event-roles.js @@ -6,6 +6,7 @@ export default class extends Controller { get services() { return this.model.services.sortBy('name'); } + @computed('model.permissions') get permissions() { return this.model.permissions.sortBy('serviceName'); diff --git a/app/controllers/admin/permissions/system-roles.js b/app/controllers/admin/permissions/system-roles.js index ae105dbdce1..a0eb7f5c612 100644 --- a/app/controllers/admin/permissions/system-roles.js +++ b/app/controllers/admin/permissions/system-roles.js @@ -26,6 +26,7 @@ export default class extends Controller { } this.set('isAddSystemRoleModalOpen', true); } + @action deleteSystemRole(role) { this.set('isLoading', true); @@ -46,6 +47,7 @@ export default class extends Controller { this.set('isLoading', false); }); } + @action addSystemRole() { this.set('isLoading', true); @@ -83,6 +85,7 @@ export default class extends Controller { }); } } + @action updatePermissions() { this.set('isLoading', true); diff --git a/app/controllers/admin/sessions/list.js b/app/controllers/admin/sessions/list.js index 252cb04f8fd..e5d6ec41493 100644 --- a/app/controllers/admin/sessions/list.js +++ b/app/controllers/admin/sessions/list.js @@ -71,6 +71,7 @@ export default class extends Controller.extend(EmberTableControllerMixin) { } ]; } + @action async deleteSession(session_id) { this.set('isLoading', true); diff --git a/app/controllers/admin/settings/billing.js b/app/controllers/admin/settings/billing.js index 8dc9423bd34..d40c3ea1cc7 100644 --- a/app/controllers/admin/settings/billing.js +++ b/app/controllers/admin/settings/billing.js @@ -12,6 +12,7 @@ export default class extends Controller { get countries() { return orderBy(filter(countries, country => paymentCountries.includes(country.code)), 'name'); } + payment @action async updateInvoiceModel() { diff --git a/app/controllers/admin/users/view/events/list.js b/app/controllers/admin/users/view/events/list.js index 2ee97d9e2ad..4cc6e52be77 100644 --- a/app/controllers/admin/users/view/events/list.js +++ b/app/controllers/admin/users/view/events/list.js @@ -41,14 +41,14 @@ export default class extends Controller.extend(EmberTableControllerMixin) { }, { name : 'Sessions', - valuePath : 'eventStatisticsGeneral', + valuePath : 'generalStatistics', width : 90, isSortable : false, cellComponent : 'ui-table/cell/cell-sessions-dashboard' }, { name : 'Speakers', - valuePath : 'eventStatisticsGeneral', + valuePath : 'generalStatistics', cellComponent : 'ui-table/cell/cell-speakers-dashboard', isSortable : false }, diff --git a/app/controllers/create.js b/app/controllers/create.js index 21fa47c4a83..d1d7bbacaaf 100644 --- a/app/controllers/create.js +++ b/app/controllers/create.js @@ -10,6 +10,7 @@ export default class extends Controller.extend(EventWizardMixin) { ['tickets', 'socialLinks', 'copyright', 'tax', 'stripeAuthorization'] ); } + @action move() { this.saveEventDataAndRedirectTo( diff --git a/app/controllers/event-invoice/paid.js b/app/controllers/event-invoice/paid.js index 6a9eae18492..32577ad61ab 100644 --- a/app/controllers/event-invoice/paid.js +++ b/app/controllers/event-invoice/paid.js @@ -27,4 +27,4 @@ export default class extends Controller { } this.set('isLoading', false); } -} \ No newline at end of file +} diff --git a/app/controllers/events/import.js b/app/controllers/events/import.js index c8a11d8b713..7bd20404be6 100644 --- a/app/controllers/events/import.js +++ b/app/controllers/events/import.js @@ -31,6 +31,7 @@ export default class extends Controller { }); }, 3000); } + @action uploadFile(files) { let [file] = files; diff --git a/app/controllers/events/list.js b/app/controllers/events/list.js index 7d2ca1be6c9..a5edf0ee526 100644 --- a/app/controllers/events/list.js +++ b/app/controllers/events/list.js @@ -43,12 +43,12 @@ export default class extends Controller.extend(EmberTableControllerMixin) { }, { name : 'Sessions', - valuePath : 'eventStatisticsGeneral', + valuePath : 'generalStatistics', cellComponent : 'ui-table/cell/cell-sessions-dashboard' }, { name : 'Speakers', - valuePath : 'eventStatisticsGeneral', + valuePath : 'generalStatistics', cellComponent : 'ui-table/cell/cell-speakers-dashboard' }, { diff --git a/app/controllers/events/view.js b/app/controllers/events/view.js index ea3c37b5bfa..c3b0a04cd9a 100644 --- a/app/controllers/events/view.js +++ b/app/controllers/events/view.js @@ -7,6 +7,7 @@ export default class extends Controller { openDeleteEventModal() { this.set('isEventDeleteModalOpen', true); } + @action togglePublishState() { if (isEmpty(this.model.locationName)) { @@ -44,6 +45,7 @@ export default class extends Controller { this.set('isLoading', false); }); } + @action deleteEvent() { this.set('isLoading', true); @@ -66,6 +68,7 @@ export default class extends Controller { }); this.set('isEventDeleteModalOpen', false); } + @action copyEvent() { this.set('isCopying', true); diff --git a/app/controllers/events/view/edit/attendee.js b/app/controllers/events/view/edit/attendee.js index 73de9836122..55dfae876f9 100644 --- a/app/controllers/events/view/edit/attendee.js +++ b/app/controllers/events/view/edit/attendee.js @@ -38,4 +38,4 @@ export default Controller.extend(EventWizardMixin, { } } } -}); \ No newline at end of file +}); diff --git a/app/controllers/events/view/edit/basic-details.js b/app/controllers/events/view/edit/basic-details.js index 8e00401ac84..56ccc6f85d0 100644 --- a/app/controllers/events/view/edit/basic-details.js +++ b/app/controllers/events/view/edit/basic-details.js @@ -16,4 +16,4 @@ export default Controller.extend(EventWizardMixin, { ); } } -}); \ No newline at end of file +}); diff --git a/app/controllers/events/view/edit/sessions-speakers.js b/app/controllers/events/view/edit/sessions-speakers.js index 5ad85c42235..fb3b0255fdc 100644 --- a/app/controllers/events/view/edit/sessions-speakers.js +++ b/app/controllers/events/view/edit/sessions-speakers.js @@ -28,4 +28,4 @@ export default Controller.extend(EventWizardMixin, { ); } } -}); \ No newline at end of file +}); diff --git a/app/controllers/events/view/edit/sponsors.js b/app/controllers/events/view/edit/sponsors.js index bc4b1ad91a4..11f21a25200 100644 --- a/app/controllers/events/view/edit/sponsors.js +++ b/app/controllers/events/view/edit/sponsors.js @@ -18,4 +18,4 @@ export default Controller.extend(EventWizardMixin, { } } -}); \ No newline at end of file +}); diff --git a/app/controllers/events/view/export.js b/app/controllers/events/view/export.js index b55adfb958a..c74a059fa8f 100644 --- a/app/controllers/events/view/export.js +++ b/app/controllers/events/view/export.js @@ -53,6 +53,7 @@ export default class extends Controller { }); }, 3000); } + @action startGeneration() { this.set('isLoading', true); diff --git a/app/controllers/events/view/scheduler.js b/app/controllers/events/view/scheduler.js index 5c59e290918..12f4460b160 100644 --- a/app/controllers/events/view/scheduler.js +++ b/app/controllers/events/view/scheduler.js @@ -11,18 +11,21 @@ export default class extends Controller { } return false; } + isLoading = false; header = { left : 'today prev,next', center : 'title', right : 'timelineDay,timelineThreeDays,agendaWeek,month' } + view = { timelineThreeDays: { type : 'timeline', duration : { days: 3 } } } + updateSession(start, end, microlocationId, sessionId) { let payload = { data: { @@ -58,11 +61,13 @@ export default class extends Controller { this.notify.error(`Error: ${reason}`); }); } + unscheduleSession(session) { window.$('.full-calendar').fullCalendar('removeEvents', session._id); this.updateSession(null, null, session.resourceId, session.serverId); this.target.send('refresh'); } + @action drop(date, jsEvent, ui, resourceId) { let start = date; @@ -71,14 +76,17 @@ export default class extends Controller { this.updateSession(start, end, resourceId, window.$(ui.helper).data('serverId')); window.$(ui.helper).remove(); } + @action eventDrop(session) { this.updateSession(session.start, session.end, session.resourceId, session.serverId); } + @action eventResize(session) { this.updateSession(session.start, session.end, session.resourceId, session.serverId); } + @action eventRender(session, element) { element.append(''); @@ -87,6 +95,7 @@ export default class extends Controller { controller.unscheduleSession(session); }); } + @action togglePublishState() { this.set('isLoading', true); diff --git a/app/controllers/events/view/tickets/access-codes/list.js b/app/controllers/events/view/tickets/access-codes/list.js index 8e3b643a8db..0fdda95b45c 100644 --- a/app/controllers/events/view/tickets/access-codes/list.js +++ b/app/controllers/events/view/tickets/access-codes/list.js @@ -59,6 +59,7 @@ export default class extends Controller.extend(EmberTableControllerMixin) { this.set('isLoading', false); }); } + @action toggleStatus(access_id) { this.set('isLoading', true); @@ -76,6 +77,7 @@ export default class extends Controller.extend(EmberTableControllerMixin) { this.set('isLoading', false); }); } + @action editAccessCode(id) { this.transitionToRoute('events.view.tickets.access-codes.edit', id); diff --git a/app/controllers/events/view/tickets/orders/list.js b/app/controllers/events/view/tickets/orders/list.js index bd5b2b5a12f..f38d0aaaa16 100644 --- a/app/controllers/events/view/tickets/orders/list.js +++ b/app/controllers/events/view/tickets/orders/list.js @@ -75,6 +75,7 @@ export default class extends Controller.extend(EmberTableControllerMixin) { this.set('isLoading', false); }); } + @action deleteOrder(order_id) { this.set('isLoading', true); diff --git a/app/controllers/my-sessions/view.js b/app/controllers/my-sessions/view.js index 91f80b095f0..2175b6c723d 100644 --- a/app/controllers/my-sessions/view.js +++ b/app/controllers/my-sessions/view.js @@ -41,4 +41,4 @@ export default class extends Controller { this.set('isProposalDeleteModalOpen', false); }); } -} \ No newline at end of file +} diff --git a/app/controllers/oauth/callback.js b/app/controllers/oauth/callback.js index b5f5b873fc4..ec6d6bdf294 100644 --- a/app/controllers/oauth/callback.js +++ b/app/controllers/oauth/callback.js @@ -5,8 +5,8 @@ export default Controller.extend({ this.loader.post(`/auth/oauth/login/${ queryParams.provider }?code=${ queryParams.code }`) .then(response => { let credentials = { - identification : response.email, - password : response.oauth_hash + username : response.email, + password : response.oauth_hash }, authenticator = 'authenticator:jwt'; diff --git a/app/controllers/public/index.js b/app/controllers/public/index.js index 41a34e8dee7..4f7708a04b6 100644 --- a/app/controllers/public/index.js +++ b/app/controllers/public/index.js @@ -29,7 +29,7 @@ export default Controller.extend({ .then(() => { let credentials = newUser.getProperties('email', 'password'), authenticator = 'authenticator:jwt'; - credentials.identification = newUser.email; + credentials.username = newUser.email; this.session .authenticate(authenticator, credentials) .then(async() => { @@ -63,10 +63,10 @@ export default Controller.extend({ }, - async loginExistingUser(identification, password) { + async loginExistingUser(username, password) { this.set('isLoading', true); let credentials = { - identification, + username, password }; let authenticator = 'authenticator:jwt'; @@ -83,7 +83,7 @@ export default Controller.extend({ }) .catch(reason => { if (!(this.isDestroyed || this.isDestroying)) { - if (reason && Object.prototype.hasOwnProperty.call(reason, 'status_code') && reason.status_code === 401) { + if (reason && reason.status === 401) { this.set('errorMessage', this.l10n.t('Your credentials were incorrect.')); } else { this.set('errorMessage', this.l10n.t('An unexpected error occurred.')); @@ -149,4 +149,4 @@ export default Controller.extend({ } } -}); \ No newline at end of file +}); diff --git a/app/controllers/register.js b/app/controllers/register.js index 2ec65b53d63..7d8eaa485cd 100644 --- a/app/controllers/register.js +++ b/app/controllers/register.js @@ -36,10 +36,10 @@ export default Controller.extend({ }); }, - async loginExistingUser(identification, password, token, eventId) { + async loginExistingUser(username, password, token, eventId) { this.set('isLoading', true); let credentials = { - identification, + username, password }; let authenticator = 'authenticator:jwt'; diff --git a/app/helpers/header-date.js b/app/helpers/header-date.js index 961a1d64b4c..8df0fae1b8d 100644 --- a/app/helpers/header-date.js +++ b/app/helpers/header-date.js @@ -6,4 +6,4 @@ export function headerDate(params) { return `${moment(params[0]).tz(timezone).format('dddd, MMMM Do YYYY, h:mm A')} (${moment.tz(params[0], timezone).zoneAbbr()})`; } -export default Helper.helper(headerDate); \ No newline at end of file +export default Helper.helper(headerDate); diff --git a/app/models/event.js b/app/models/event.js index 9d96115ee69..e301eb396c8 100644 --- a/app/models/event.js +++ b/app/models/event.js @@ -95,27 +95,27 @@ export default ModelBase.extend(CustomPrimaryKeyMixin, { /** * Relationships */ - type : belongsTo('event-type'), - topic : belongsTo('event-topic'), - subTopic : belongsTo('event-sub-topic'), - location : belongsTo('event-location'), - sessions : hasMany('session'), - sponsors : hasMany('sponsor'), - microlocations : hasMany('microlocation'), - tracks : hasMany('track'), - tickets : hasMany('ticket'), - orders : hasMany('order'), - socialLinks : hasMany('social-link'), - emailNotifications : hasMany('email-notification'), - speakers : hasMany('speaker'), - invoice : hasMany('event-invoice'), - speakersCall : belongsTo('speakers-call'), - stripeAuthorization : belongsTo('stripe-authorization'), - eventStatisticsGeneral : belongsTo('event-statistics-general'), - tax : belongsTo('tax'), - copyright : belongsTo('event-copyright'), - sessionTypes : hasMany('session-type'), - user : belongsTo('user', { inverse: 'events' }), + type : belongsTo('event-type'), + topic : belongsTo('event-topic'), + subTopic : belongsTo('event-sub-topic'), + location : belongsTo('event-location'), + sessions : hasMany('session'), + sponsors : hasMany('sponsor'), + microlocations : hasMany('microlocation'), + tracks : hasMany('track'), + tickets : hasMany('ticket'), + orders : hasMany('order'), + socialLinks : hasMany('social-link'), + emailNotifications : hasMany('email-notification'), + speakers : hasMany('speaker'), + invoice : hasMany('event-invoice'), + speakersCall : belongsTo('speakers-call'), + stripeAuthorization : belongsTo('stripe-authorization'), + generalStatistics : belongsTo('event-statistics-general'), + tax : belongsTo('tax'), + copyright : belongsTo('event-copyright'), + sessionTypes : hasMany('session-type'), + user : belongsTo('user', { inverse: 'events' }), customForms : hasMany('custom-form'), attendees : hasMany('attendee'), diff --git a/app/models/notification.js b/app/models/notification.js index b72fe058353..8e53d38a863 100644 --- a/app/models/notification.js +++ b/app/models/notification.js @@ -1,7 +1,6 @@ import attr from 'ember-data/attr'; -import { hasMany } from 'ember-data/relationships'; +import { belongsTo, hasMany } from 'ember-data/relationships'; import ModelBase from 'open-event-frontend/models/base'; -import { belongsTo } from 'ember-data/relationships'; export default ModelBase.extend({ title : attr('string'), diff --git a/app/router.js b/app/router.js index 600ca73e374..228d9d3f797 100644 --- a/app/router.js +++ b/app/router.js @@ -1,26 +1,25 @@ -import Router from '@ember/routing/router'; import { scheduleOnce } from '@ember/runloop'; import { inject as service } from '@ember/service'; import config from 'open-event-frontend/config/environment'; import RouterScroll from 'ember-router-scroll'; -const router = Router.extend(RouterScroll, { - location : config.locationType, - rootURL : config.rootURL, - metrics : service(), - session : service(), - headData : service(), +class Router extends RouterScroll { + location = config.locationType; + rootURL = config.rootURL; + @service metrics; + @service session; + @service headData; setTitle(title) { this.headData.set('title', title); - }, + } init() { - this._super(...arguments); + super.init(...arguments); this.on('routeDidChange', () => { this._trackPage(); }); - }, + } _trackPage() { scheduleOnce('afterRender', this, () => { @@ -30,9 +29,9 @@ const router = Router.extend(RouterScroll, { this.set('session.currentRouteName', title); }); } -}); +} -router.map(function() { +Router.map(function() { this.route('login'); this.route('register'); this.route('reset-password'); @@ -219,4 +218,4 @@ router.map(function() { }); }); -export default router; +export default Router; diff --git a/app/routes/account/billing/invoices/list.js b/app/routes/account/billing/invoices/list.js index e03db51d653..383a4ea417d 100644 --- a/app/routes/account/billing/invoices/list.js +++ b/app/routes/account/billing/invoices/list.js @@ -16,6 +16,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { return this.l10n.t('All'); } } + async model(params) { this.set('params', params); const searchField = 'status'; @@ -65,6 +66,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { }; } + @action refreshRoute() { this.refresh(); diff --git a/app/routes/account/billing/payment-info.js b/app/routes/account/billing/payment-info.js index 3248990a07c..3c37cd76198 100644 --- a/app/routes/account/billing/payment-info.js +++ b/app/routes/account/billing/payment-info.js @@ -5,4 +5,4 @@ export default class extends Route.extend(AuthenticatedRouteMixin) { titleToken() { return this.l10n.t('Payment Info'); } -} \ No newline at end of file +} diff --git a/app/routes/admin/sessions/list.js b/app/routes/admin/sessions/list.js index c8b48d5fb50..659b0a31d8c 100644 --- a/app/routes/admin/sessions/list.js +++ b/app/routes/admin/sessions/list.js @@ -18,6 +18,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { return this.l10n.t('Session'); } } + async model(params) { this.set('params', params); const searchField = 'title'; diff --git a/app/routes/admin/settings/billing.js b/app/routes/admin/settings/billing.js index cb4c9b0c8ef..20a7384bdfa 100644 --- a/app/routes/admin/settings/billing.js +++ b/app/routes/admin/settings/billing.js @@ -4,6 +4,7 @@ export default class extends Route { titleToken() { return this.l10n.t('Admin Billing'); } + model() { return this.modelFor('admin.settings'); } diff --git a/app/routes/admin/users/list.js b/app/routes/admin/users/list.js index 0d310a5f145..68d7cd748c6 100644 --- a/app/routes/admin/users/list.js +++ b/app/routes/admin/users/list.js @@ -93,6 +93,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { queryString = this.applySortFilters(queryString, params); return this.asArray(this.store.query('user', queryString)); } + @action refreshRoute() { this.refresh(); diff --git a/app/routes/events/view/index.js b/app/routes/events/view/index.js index 6bb1d3bd25f..c3dfa7a4713 100644 --- a/app/routes/events/view/index.js +++ b/app/routes/events/view/index.js @@ -22,7 +22,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { roleInvites : await eventDetails.query('roleInvites', {}), sessionTypes : await eventDetails.query('sessionTypes', {}), socialLinks : await eventDetails.query('socialLinks', {}), - statistics : await eventDetails.query('eventStatisticsGeneral', {}), + statistics : await eventDetails.query('generalStatistics', {}), orderStat : await eventDetails.query('orderStatistics', {}), tickets : await eventDetails.query('tickets', {}), roles : await this.store.findAll('role') diff --git a/app/routes/events/view/speakers/list.js b/app/routes/events/view/speakers/list.js index ba45d350091..f07f852d231 100644 --- a/app/routes/events/view/speakers/list.js +++ b/app/routes/events/view/speakers/list.js @@ -23,6 +23,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { this.transitionTo('public', event.id); } } + async model(params) { this.set('params', params); const searchField = 'name'; diff --git a/app/routes/events/view/tickets/attendees/list.js b/app/routes/events/view/tickets/attendees/list.js index d19cd57d77f..e25a242b2b6 100644 --- a/app/routes/events/view/tickets/attendees/list.js +++ b/app/routes/events/view/tickets/attendees/list.js @@ -20,6 +20,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { return this.l10n.t('All'); } } + async model(params) { this.set('params', params); const searchField = 'firstname'; diff --git a/app/routes/events/view/tickets/discount-codes/list.js b/app/routes/events/view/tickets/discount-codes/list.js index c5f2fc4a886..a853a375582 100644 --- a/app/routes/events/view/tickets/discount-codes/list.js +++ b/app/routes/events/view/tickets/discount-codes/list.js @@ -13,6 +13,7 @@ export default class extends Route.extend(EmberTableRouteMixin) { return this.l10n.t('Expired'); } } + async model(params) { this.set('params', params); let filterOptions = []; diff --git a/app/routes/public/speakers.js b/app/routes/public/speakers.js index 0e5dc2d6128..85a24b59dea 100644 --- a/app/routes/public/speakers.js +++ b/app/routes/public/speakers.js @@ -29,7 +29,7 @@ export default Route.extend({ ]; return this.infinity.model('speakers', { filter : filterOptions, - perPage : 6, + perPage : 12, startingPage : 1, perPageParam : 'page[size]', pageParam : 'page[number]', diff --git a/app/serializers/event.js b/app/serializers/event.js index 2012aa1359b..4797a235063 100644 --- a/app/serializers/event.js +++ b/app/serializers/event.js @@ -10,26 +10,13 @@ export default ApplicationSerializer.extend(CustomPrimaryKeyMixin, { subTopic : 'event-sub-topic', copyright : 'event-copyright' }, - normalize() { - const payload = this._super(...arguments); - payload.data = this.addLinks(payload.data); - return payload; - }, - addLinks(event) { - event.relationships.eventStatisticsGeneral = { - links: { - related : `/v1/events/${event.id}/general-statistics`, - self : `/v1/events/${event.id}/general-statistics` - } - }; - event.relationships.orderStatistics = { - links: { - related : `/v1/events/${event.id}/order-statistics`, - self : `/v1/events/${event.id}/order-statistics` - } - }; - return event; + serialize() { + const json = this._super(...arguments); + delete json.data.relationships['general-statistics']; + delete json.data.relationships['order-statistics']; + + return json; } }); diff --git a/app/services/loader.js b/app/services/loader.js index 55a834d9ae5..25a458e5b62 100644 --- a/app/services/loader.js +++ b/app/services/loader.js @@ -4,7 +4,7 @@ import $ from 'jquery'; import { getErrorMessage } from 'open-event-frontend/utils/errors'; import { buildUrl } from 'open-event-frontend/utils/url'; import httpStatus from 'http-status'; -import objectToFormData from 'object-to-formdata'; +import { objectToFormData } from 'object-to-formdata'; import fetch from 'fetch'; import { clone, assign, merge, pick, isString } from 'lodash-es'; const bodyAllowedIn = ['PATCH', 'POST', 'PUT']; diff --git a/app/templates/application.hbs b/app/templates/application.hbs index aea36ffd28f..9e83c406fe3 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -5,7 +5,7 @@ {{model.cookiePolicy}} {{#if model.cookiePolicyLink}} -
For more information click here.
+Click here For more information
{{/if}} {{/if}} diff --git a/app/templates/attendee-app.hbs b/app/templates/attendee-app.hbs index dee3ca552f0..f97bf3ab45c 100644 --- a/app/templates/attendee-app.hbs +++ b/app/templates/attendee-app.hbs @@ -1,5 +1,5 @@ diff --git a/app/templates/components/account/email-preferences-section.hbs b/app/templates/components/account/email-preferences-section.hbs index 52c5cd3c418..bb4b9d38dff 100644 --- a/app/templates/components/account/email-preferences-section.hbs +++ b/app/templates/components/account/email-preferences-section.hbs @@ -25,7 +25,7 @@