From 75a138cb391d620c9be33ad12f8da803e4f57b9c Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Wed, 2 Feb 2022 14:11:11 -0800 Subject: [PATCH] [chore] Ran native classes codemod for app/services (#2240) refs https://github.com/TryGhost/Admin/pull/2227 - a continuation of #2227 that runs the native classes codemod against app/services --- ghost/admin/app/services/ajax.js | 49 +++++----- ghost/admin/app/services/billing.js | 49 +++++----- ghost/admin/app/services/clock.js | 17 ++-- ghost/admin/app/services/config.js | 44 +++++---- ghost/admin/app/services/dropdown.js | 10 ++- ghost/admin/app/services/event-bus.js | 12 ++- ghost/admin/app/services/feature.js | 90 +++++++++++++------ ghost/admin/app/services/ghost-paths.js | 4 +- ghost/admin/app/services/lazy-loader.js | 23 +++-- ghost/admin/app/services/media-queries.js | 17 ++-- ghost/admin/app/services/media.js | 4 +- .../app/services/member-import-validator.js | 21 +++-- ghost/admin/app/services/notifications.js | 53 ++++++----- ghost/admin/app/services/resize-detector.js | 12 +-- ghost/admin/app/services/settings.js | 27 +++--- ghost/admin/app/services/slug-generator.js | 13 ++- ghost/admin/app/services/upgrade-status.js | 17 ++-- 17 files changed, 283 insertions(+), 179 deletions(-) diff --git a/ghost/admin/app/services/ajax.js b/ghost/admin/app/services/ajax.js index f8cdcff7c2..4639b52b34 100644 --- a/ghost/admin/app/services/ajax.js +++ b/ghost/admin/app/services/ajax.js @@ -1,4 +1,5 @@ import AjaxService from 'ember-ajax/services/ajax'; +import classic from 'ember-classic-decorator'; import config from 'ghost-admin/config/environment'; import moment from 'moment'; import {AjaxError, isAjaxError, isForbiddenError} from 'ember-ajax/errors'; @@ -160,29 +161,33 @@ export function isAcceptedResponse(errorOrStatus) { return false; } -let ajaxService = AjaxService.extend({ - config: service(), - session: service(), +@classic +class ajaxService extends AjaxService { + @service + config; + + @service + session; // flag to tell our ESA authenticator not to try an invalidate DELETE request // because it's been triggered by this service's 401 handling which means the // DELETE would fail and get stuck in an infinite loop // TODO: find a more elegant way to handle this - skipSessionDeletion: false, + skipSessionDeletion = false; get headers() { return { 'X-Ghost-Version': config.APP.version, 'App-Pragma': 'no-cache' }; - }, + } init() { - this._super(...arguments); + super.init(...arguments); if (this.isTesting === undefined) { this.isTesting = config.environment === 'test'; } - }, + } async _makeRequest(hash) { // ember-ajax recognises `application/vnd.api+json` as a JSON-API request @@ -220,7 +225,7 @@ let ajaxService = AjaxService.extend({ return data; }; - const makeRequest = this._super.bind(this); + const makeRequest = super._makeRequest.bind(this); while (retryingMs <= maxRetryingMs && !success) { try { @@ -253,7 +258,7 @@ let ajaxService = AjaxService.extend({ } } } - }, + } handleResponse(status, headers, payload, request) { if (this.isVersionMismatchError(status, headers, payload)) { @@ -291,8 +296,8 @@ let ajaxService = AjaxService.extend({ this.session.invalidate(); } - return this._super(...arguments); - }, + return super.handleResponse(...arguments); + } normalizeErrorResponse(status, headers, payload) { if (payload && typeof payload === 'object') { @@ -313,45 +318,45 @@ let ajaxService = AjaxService.extend({ } } - return this._super(status, headers, payload); - }, + return super.normalizeErrorResponse(status, headers, payload); + } isVersionMismatchError(status, headers, payload) { return isVersionMismatchError(status, payload); - }, + } isServerUnreachableError(status) { return isServerUnreachableError(status); - }, + } isRequestEntityTooLargeError(status) { return isRequestEntityTooLargeError(status); - }, + } isUnsupportedMediaTypeError(status) { return isUnsupportedMediaTypeError(status); - }, + } isMaintenanceError(status, headers, payload) { return isMaintenanceError(status, payload); - }, + } isThemeValidationError(status, headers, payload) { return isThemeValidationError(status, payload); - }, + } isHostLimitError(status, headers, payload) { return isHostLimitError(status, payload); - }, + } isEmailError(status, headers, payload) { return isEmailError(status, payload); - }, + } isAcceptedResponse(status) { return isAcceptedResponse(status); } -}); +} // we need to reopen so that internal methods use the correct contentType ajaxService.reopen({ diff --git a/ghost/admin/app/services/billing.js b/ghost/admin/app/services/billing.js index 22857f3890..1136d75c47 100644 --- a/ghost/admin/app/services/billing.js +++ b/ghost/admin/app/services/billing.js @@ -1,20 +1,29 @@ import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; -export default Service.extend({ - router: service(), - config: service(), - ghostPaths: service(), - store: service(), +@classic +export default class BillingService extends Service { + @service + router; - billingRouteRoot: '#/pro', - billingWindowOpen: false, - subscription: null, - previousRoute: null, - action: null, - ownerUser: null, + @service + config; + + @service + ghostPaths; + + @service + store; + + billingRouteRoot = '#/pro'; + billingWindowOpen = false; + subscription = null; + previousRoute = null; + action = null; + ownerUser = null; init() { - this._super(...arguments); + super.init(...arguments); if (this.config.get('hostSettings.billing.url')) { window.addEventListener('message', (event) => { @@ -23,7 +32,7 @@ export default Service.extend({ } }); } - }, + } handleRouteChangeInIframe(destinationRoute) { if (this.billingWindowOpen) { @@ -37,7 +46,7 @@ export default Service.extend({ window.history.replaceState(window.history.state, '', billingRoute); } } - }, + } getIframeURL() { // initiate getting owner user in the background @@ -54,7 +63,7 @@ export default Service.extend({ } return url; - }, + } async getOwnerUser() { if (!this.ownerUser) { @@ -69,7 +78,7 @@ export default Service.extend({ this.set('ownerUser', user); } return this.ownerUser; - }, + } // Sends a route update to a child route in the BMA, because we can't control // navigating to it otherwise @@ -86,7 +95,7 @@ export default Service.extend({ this.set('action', null); } - }, + } // Controls billing window modal visibility and sync of the URL visible in browser // and the URL opened on the iframe. It is responsible to non user triggered iframe opening, @@ -100,7 +109,7 @@ export default Service.extend({ this.sendRouteUpdate(); this.set('billingWindowOpen', value); - }, + } // Controls navigation to billing window modal which is triggered from the application UI. // For example: pressing "View Billing" link in navigation menu. It's main side effect is @@ -124,9 +133,9 @@ export default Service.extend({ this.sendRouteUpdate(); this.router.transitionTo(childRoute || '/pro'); - }, + } getBillingIframe() { return document.getElementById('billing-frame'); } -}); +} diff --git a/ghost/admin/app/services/clock.js b/ghost/admin/app/services/clock.js index 9f550812ab..1c78fb8e24 100644 --- a/ghost/admin/app/services/clock.js +++ b/ghost/admin/app/services/clock.js @@ -1,4 +1,5 @@ import Service from '@ember/service'; +import classic from 'ember-classic-decorator'; import config from 'ghost-admin/config/environment'; import moment from 'moment'; import {run} from '@ember/runloop'; @@ -7,15 +8,16 @@ const ONE_SECOND = 1000; // Creates a clock service to run intervals. -export default Service.extend({ - second: null, - minute: null, - hour: null, +@classic +export default class ClockService extends Service { + second = null; + minute = null; + hour = null; init() { - this._super(...arguments); + super.init(...arguments); this.tick(); - }, + } tick() { let now = moment().utc(); @@ -32,5 +34,4 @@ export default Service.extend({ }, ONE_SECOND); } } - -}); +} diff --git a/ghost/admin/app/services/config.js b/ghost/admin/app/services/config.js index 7fa7ac3ccb..d3e1ec60c5 100644 --- a/ghost/admin/app/services/config.js +++ b/ghost/admin/app/services/config.js @@ -1,23 +1,30 @@ import Ember from 'ember'; import RSVP from 'rsvp'; import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; import timezoneData from '@tryghost/timezone-data'; import {computed} from '@ember/object'; // ember-cli-shims doesn't export _ProxyMixin const {_ProxyMixin} = Ember; -export default Service.extend(_ProxyMixin, { - ajax: service(), - ghostPaths: service(), - session: service(), +@classic +export default class ConfigService extends Service.extend(_ProxyMixin) { + @service + ajax; - content: null, + @service + ghostPaths; + + @service + session; + + content = null; init() { - this._super(...arguments); + super.init(...arguments); this.content = {}; - }, + } fetch() { let promises = []; @@ -29,7 +36,7 @@ export default Service.extend(_ProxyMixin, { } return RSVP.all(promises); - }, + } fetchUnauthenticated() { let siteUrl = this.ghostPaths.url.api('site'); @@ -44,7 +51,7 @@ export default Service.extend(_ProxyMixin, { }).then(() => { this.notifyPropertyChange('content'); }); - }, + } fetchAuthenticated() { let configUrl = this.ghostPaths.url.api('config'); @@ -53,22 +60,25 @@ export default Service.extend(_ProxyMixin, { }).then(() => { this.notifyPropertyChange('content'); }); - }, + } - availableTimezones: computed(function () { + @computed + get availableTimezones() { return RSVP.resolve(timezoneData); - }), + } - blogDomain: computed('blogUrl', function () { + @computed('blogUrl') + get blogDomain() { let blogUrl = this.get('blogUrl'); let blogDomain = blogUrl .replace(/^https?:\/\//, '') .replace(/\/?$/, ''); return blogDomain; - }), + } - emailDomain: computed('blogDomain', function () { + @computed('blogDomain') + get emailDomain() { let blogDomain = this.blogDomain || ''; const domainExp = blogDomain.match(new RegExp('^([^/:?#]+)(?:[/:?#]|$)', 'i')); const domain = (domainExp && domainExp[1]) || ''; @@ -76,7 +86,7 @@ export default Service.extend(_ProxyMixin, { return domain.replace(/^(www)\.(?=[^/]*\..{2,5})/, ''); } return domain; - }), + } getSiteUrl(path) { const siteUrl = new URL(this.get('blogUrl')); @@ -85,4 +95,4 @@ export default Service.extend(_ProxyMixin, { return `${siteUrl.origin}${fullPath}`; } -}); +} diff --git a/ghost/admin/app/services/dropdown.js b/ghost/admin/app/services/dropdown.js index 647b78abdf..63a3aba350 100644 --- a/ghost/admin/app/services/dropdown.js +++ b/ghost/admin/app/services/dropdown.js @@ -1,23 +1,25 @@ import $ from 'jquery'; +import classic from 'ember-classic-decorator'; // This is used by the dropdown initializer to manage closing & toggling import BodyEventListener from 'ghost-admin/mixins/body-event-listener'; import Evented from '@ember/object/evented'; import Service from '@ember/service'; -export default Service.extend(Evented, BodyEventListener, { +@classic +export default class DropdownService extends Service.extend(Evented, BodyEventListener) { bodyClick(event) { let dropdownSelector = '.ember-basic-dropdown-trigger, .ember-basic-dropdown-content'; if ($(event.target).closest(dropdownSelector).length <= 0) { this.closeDropdowns(); } - }, + } closeDropdowns() { this.trigger('close'); - }, + } toggleDropdown(dropdownName, dropdownButton) { this.trigger('toggle', {target: dropdownName, button: dropdownButton}); } -}); +} diff --git a/ghost/admin/app/services/event-bus.js b/ghost/admin/app/services/event-bus.js index bae2e9ba61..fe89b4c587 100644 --- a/ghost/admin/app/services/event-bus.js +++ b/ghost/admin/app/services/event-bus.js @@ -1,14 +1,18 @@ import Evented from '@ember/object/evented'; import Service from '@ember/service'; +import classic from 'ember-classic-decorator'; -export default Service.extend(Evented, { +@classic +export default class EventBusService extends Service.extend(Evented) { publish() { return this.trigger(...arguments); - }, + } + subscribe() { return this.on(...arguments); - }, + } + unsubscribe() { return this.off(...arguments); } -}); +} diff --git a/ghost/admin/app/services/feature.js b/ghost/admin/app/services/feature.js index a330aa1521..28a7936466 100644 --- a/ghost/admin/app/services/feature.js +++ b/ghost/admin/app/services/feature.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import Ember from 'ember'; import EmberError from '@ember/error'; import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; import {computed, set} from '@ember/object'; export function feature(name, options = {}) { @@ -36,35 +37,69 @@ export function feature(name, options = {}) { })); } -export default Service.extend({ - store: service(), - config: service(), - session: service(), - settings: service(), - notifications: service(), - lazyLoader: service(), +@classic +export default class FeatureService extends Service { + @service + store; + + @service + config; + + @service + session; + + @service + settings; + + @service + notifications; + + @service + lazyLoader; // features - emailAnalytics: feature('emailAnalytics'), + @feature('emailAnalytics') + emailAnalytics; // user-specific flags - nightShift: feature('nightShift', {user: true, onChange: '_setAdminTheme'}), - dashboardHideGettingStarted: feature('dashboardHideGettingStarted', {user: true}), + @feature('nightShift', {user: true, onChange: '_setAdminTheme'}) + nightShift; + + @feature('dashboardHideGettingStarted', {user: true}) + dashboardHideGettingStarted; // labs flags - multipleProducts: feature('multipleProducts'), - oauthLogin: feature('oauthLogin'), - membersActivity: feature('membersActivity'), - urlCache: feature('urlCache'), - beforeAfterCard: feature('beforeAfterCard'), - tweetGridCard: feature('tweetGridCard'), - membersActivityFeed: feature('membersActivityFeed'), - improvedOnboarding: feature('improvedOnboarding'), - tierWelcomePages: feature('tierWelcomePages'), + @feature('multipleProducts') + multipleProducts; - _user: null, + @feature('oauthLogin') + oauthLogin; - labs: computed('settings.labs', function () { + @feature('membersActivity') + membersActivity; + + @feature('urlCache') + urlCache; + + @feature('beforeAfterCard') + beforeAfterCard; + + @feature('tweetGridCard') + tweetGridCard; + + @feature('membersActivityFeed') + membersActivityFeed; + + @feature('improvedOnboarding') + improvedOnboarding; + + @feature('tierWelcomePages') + tierWelcomePages; + + _user = null; + + @computed('settings.labs') + get labs() { let labs = this.get('settings.labs'); try { @@ -72,9 +107,10 @@ export default Service.extend({ } catch (e) { return {}; } - }), + } - accessibility: computed('_user.accessibility', function () { + @computed('_user.accessibility') + get accessibility() { let accessibility = this.get('_user.accessibility'); try { @@ -82,14 +118,14 @@ export default Service.extend({ } catch (e) { return {}; } - }), + } fetch() { return this.settings.fetch().then(() => { this.set('_user', this.session.user); return this._setAdminTheme().then(() => true); }); - }, + } update(key, value, options = {}) { let serviceProperty = options.user ? 'accessibility' : 'labs'; @@ -126,7 +162,7 @@ export default Service.extend({ return this.get(`${serviceProperty}.${key}`); }); - }, + } _setAdminTheme(enabled) { let nightShift = enabled; @@ -142,4 +178,4 @@ export default Service.extend({ $('link[title=dark]').prop('disabled', true); }); } -}); +} diff --git a/ghost/admin/app/services/ghost-paths.js b/ghost/admin/app/services/ghost-paths.js index 9200291878..505d0747e3 100644 --- a/ghost/admin/app/services/ghost-paths.js +++ b/ghost/admin/app/services/ghost-paths.js @@ -1,4 +1,6 @@ import Service from '@ember/service'; +import classic from 'ember-classic-decorator'; import ghostPaths from 'ghost-admin/utils/ghost-paths'; -export default Service.extend(ghostPaths()); +@classic +export default class GhostPathsService extends Service.extend(ghostPaths()) {} diff --git a/ghost/admin/app/services/lazy-loader.js b/ghost/admin/app/services/lazy-loader.js index 85e19995a3..3c5ba81bf9 100644 --- a/ghost/admin/app/services/lazy-loader.js +++ b/ghost/admin/app/services/lazy-loader.js @@ -1,24 +1,29 @@ import RSVP from 'rsvp'; import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; import config from 'ghost-admin/config/environment'; -export default Service.extend({ - ajax: service(), - ghostPaths: service(), +@classic +export default class LazyLoaderService extends Service { + @service + ajax; + + @service + ghostPaths; // This is needed so we can disable it in unit tests - testing: undefined, + testing = undefined; - scriptPromises: null, + scriptPromises = null; init() { - this._super(...arguments); + super.init(...arguments); this.scriptPromises = {}; if (this.testing === undefined) { this.testing = config.environment === 'test'; } - }, + } loadScript(key, url) { if (this.testing) { @@ -52,7 +57,7 @@ export default Service.extend({ this.scriptPromises[key] = scriptPromise; return scriptPromise; - }, + } loadStyle(key, url, alternate = false) { if (this.testing || document.querySelector(`#${key}-styles`)) { @@ -82,4 +87,4 @@ export default Service.extend({ document.querySelector('head').appendChild(link); }); } -}); +} diff --git a/ghost/admin/app/services/media-queries.js b/ghost/admin/app/services/media-queries.js index b43367eea6..b8eb560fde 100644 --- a/ghost/admin/app/services/media-queries.js +++ b/ghost/admin/app/services/media-queries.js @@ -1,5 +1,6 @@ import Evented from '@ember/object/evented'; import Service from '@ember/service'; +import classic from 'ember-classic-decorator'; import {run} from '@ember/runloop'; const MEDIA_QUERIES = { @@ -9,18 +10,19 @@ const MEDIA_QUERIES = { maxWidth1000: '(max-width: 1000px)' }; -export default Service.extend(Evented, { +@classic +export default class MediaQueriesService extends Service.extend(Evented) { init() { - this._super(...arguments); + super.init(...arguments); this._handlers = []; this.loadQueries(MEDIA_QUERIES); - }, + } loadQueries(queries) { Object.keys(queries).forEach((key) => { this.loadQuery(key, queries[key]); }); - }, + } loadQuery(key, queryString) { let query = window.matchMedia(queryString); @@ -37,13 +39,12 @@ export default Service.extend(Evented, { }); query.addListener(handler); this._handlers.push([query, handler]); - }, + } willDestroy() { this._handlers.forEach(([query, handler]) => { query.removeListener(handler); }); - this._super(...arguments); + super.willDestroy(...arguments); } - -}); +} diff --git a/ghost/admin/app/services/media.js b/ghost/admin/app/services/media.js index 78a58d0b16..a5978782c3 100644 --- a/ghost/admin/app/services/media.js +++ b/ghost/admin/app/services/media.js @@ -1,6 +1,8 @@ import Service from '@ember/service'; +import classic from 'ember-classic-decorator'; // dummy service to account for not having the ember-responsive dependency // available for ember-light-table (we don't use it so no need for the dep) // see https://github.com/offirgolan/ember-light-table/issues/576 -export default Service.extend({}); +@classic +export default class MediaService extends Service {} diff --git a/ghost/admin/app/services/member-import-validator.js b/ghost/admin/app/services/member-import-validator.js index 0e1ac3a3f8..1c3de56818 100644 --- a/ghost/admin/app/services/member-import-validator.js +++ b/ghost/admin/app/services/member-import-validator.js @@ -1,17 +1,24 @@ import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; import validator from 'validator'; import {isEmpty} from '@ember/utils'; -export default Service.extend({ - ajax: service(), - membersUtils: service(), - ghostPaths: service(), +@classic +export default class MemberImportValidatorService extends Service { + @service + ajax; + + @service + membersUtils; + + @service + ghostPaths; check(data) { let sampledData = this._sampleData(data); let mapping = this._detectDataTypes(sampledData); return mapping; - }, + } /** * Method implements foollowing sampling logic: @@ -62,7 +69,7 @@ export default Service.extend({ } return validatedSet; - }, + } /** * Detects supported data types and auto-detects following two needed for validation: @@ -117,4 +124,4 @@ export default Service.extend({ return mapping; } -}); +} diff --git a/ghost/admin/app/services/notifications.js b/ghost/admin/app/services/notifications.js index 97dff9cc13..a5af6ce637 100644 --- a/ghost/admin/app/services/notifications.js +++ b/ghost/admin/app/services/notifications.js @@ -1,5 +1,6 @@ import * as Sentry from '@sentry/browser'; import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; import {dasherize} from '@ember/string'; import {A as emberA, isArray as isEmberArray} from '@ember/array'; import {filter} from '@ember/object/computed'; @@ -20,28 +21,34 @@ import { // to avoid stacking of multiple error messages whilst leaving enough // specificity to re-use keys for i18n lookups -export default Service.extend({ - delayedNotifications: null, - content: null, +@classic +export default class NotificationsService extends Service { + delayedNotifications = null; + content = null; init() { - this._super(...arguments); + super.init(...arguments); this.delayedNotifications = emberA(); this.content = emberA(); - }, + } - config: service(), - upgradeStatus: service(), + @service + config; - alerts: filter('content', function (notification) { + @service + upgradeStatus; + + @filter('content', function (notification) { let status = get(notification, 'status'); return status === 'alert'; - }), + }) + alerts; - notifications: filter('content', function (notification) { + @filter('content', function (notification) { let status = get(notification, 'status'); return status === 'notification'; - }), + }) + notifications; handleNotification(message, delayed) { // If this is an alert message from the server, treat it as html safe @@ -70,7 +77,7 @@ export default Service.extend({ } else { this.delayedNotifications.pushObject(message); } - }, + } showAlert(message, options) { options = options || {}; @@ -107,7 +114,7 @@ export default Service.extend({ key: options.key, actions: options.actions }, options.delayed); - }, + } showNotification(message, options) { options = options || {}; @@ -121,7 +128,7 @@ export default Service.extend({ key: options.key, actions: options.actions }, options.delayed); - }, + } showAPIError(resp, options) { // handle "global" errors @@ -139,7 +146,7 @@ export default Service.extend({ } this._showAPIError(resp, options); - }, + } _showAPIError(resp, options) { options = options || {}; @@ -188,14 +195,14 @@ export default Service.extend({ options.isApiError = true; this.showAlert(msg, options); - }, + } displayDelayed() { this.delayedNotifications.forEach((message) => { this.content.pushObject(message); }); this.set('delayedNotifications', []); - }, + } closeNotification(notification) { let content = this.content; @@ -208,19 +215,19 @@ export default Service.extend({ } else { content.removeObject(notification); } - }, + } closeNotifications(key) { this._removeItems('notification', key); - }, + } closeAlerts(key) { this._removeItems('alert', key); - }, + } clearAll() { this.content.clear(); - }, + } _removeItems(status, key) { if (key) { @@ -239,11 +246,11 @@ export default Service.extend({ } else { this.set('content', this.content.rejectBy('status', status)); } - }, + } // take a key and return the first two elements, eg: // "invite.revoke.failed" => "invite.revoke" _getKeyBase(key) { return key.split('.').slice(0, 2).join('.'); } -}); +} diff --git a/ghost/admin/app/services/resize-detector.js b/ghost/admin/app/services/resize-detector.js index 158baed0c4..a83b9197e8 100644 --- a/ghost/admin/app/services/resize-detector.js +++ b/ghost/admin/app/services/resize-detector.js @@ -1,13 +1,15 @@ import Service from '@ember/service'; +import classic from 'ember-classic-decorator'; import erd from 'element-resize-detector'; -export default Service.extend({ +@classic +export default class ResizeDetectorService extends Service { init() { - this._super(...arguments); + super.init(...arguments); this.detector = erd({ strategy: 'scroll' }); - }, + } setup(selector, callback) { let element = document.querySelector(selector); @@ -16,7 +18,7 @@ export default Service.extend({ console.error(`service:resize-detector - could not find element matching ${selector}`); } this.detector.listenTo(element, callback); - }, + } teardown(selector, callback) { let element = document.querySelector(selector); @@ -24,4 +26,4 @@ export default Service.extend({ this.detector.removeListener(element, callback); } } -}); +} diff --git a/ghost/admin/app/services/settings.js b/ghost/admin/app/services/settings.js index f4007bf14d..5e1b84990e 100644 --- a/ghost/admin/app/services/settings.js +++ b/ghost/admin/app/services/settings.js @@ -2,24 +2,27 @@ import Ember from 'ember'; import RSVP from 'rsvp'; import Service, {inject as service} from '@ember/service'; import ValidationEngine from 'ghost-admin/mixins/validation-engine'; +import classic from 'ember-classic-decorator'; import {get} from '@ember/object'; // ember-cli-shims doesn't export _ProxyMixin const {_ProxyMixin} = Ember; -export default Service.extend(_ProxyMixin, ValidationEngine, { - store: service(), +@classic +export default class SettingsService extends Service.extend(_ProxyMixin, ValidationEngine) { + @service + store; // will be set to the single Settings model, it's a reference so any later // changes to the settings object in the store will be reflected - content: null, + content = null; - validationType: 'setting', - _loadingPromise: null, + validationType = 'setting'; + _loadingPromise = null; // this is an odd case where we only want to react to changes that we get // back from the API rather than local updates - settledIcon: '', + settledIcon = ''; // the settings API endpoint is a little weird as it's singular and we have // to pass in all types - if we ever fetch settings without all types then @@ -35,7 +38,7 @@ export default Service.extend(_ProxyMixin, ValidationEngine, { } return this._loadingPromise; - }, + } fetch() { if (!this.content) { @@ -43,7 +46,7 @@ export default Service.extend(_ProxyMixin, ValidationEngine, { } else { return RSVP.resolve(this); } - }, + } reload() { return this._loadSettings().then((settings) => { @@ -51,7 +54,7 @@ export default Service.extend(_ProxyMixin, ValidationEngine, { this.set('settledIcon', get(settings, 'icon')); return this; }); - }, + } async save() { let settings = this.content; @@ -63,13 +66,13 @@ export default Service.extend(_ProxyMixin, ValidationEngine, { await settings.save(); this.set('settledIcon', settings.icon); return settings; - }, + } rollbackAttributes() { return this.content?.rollbackAttributes(); - }, + } changedAttributes() { return this.content?.changedAttributes(); } -}); +} diff --git a/ghost/admin/app/services/slug-generator.js b/ghost/admin/app/services/slug-generator.js index 1ba86525d2..f3722d94d9 100644 --- a/ghost/admin/app/services/slug-generator.js +++ b/ghost/admin/app/services/slug-generator.js @@ -1,11 +1,16 @@ import RSVP from 'rsvp'; import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; const {resolve} = RSVP; -export default Service.extend({ - ghostPaths: service(), - ajax: service(), +@classic +export default class SlugGeneratorService extends Service { + @service + ghostPaths; + + @service + ajax; generateSlug(slugType, textToSlugify) { let url; @@ -23,4 +28,4 @@ export default Service.extend({ return slug; }); } -}); +} diff --git a/ghost/admin/app/services/upgrade-status.js b/ghost/admin/app/services/upgrade-status.js index 0bb4036e4f..52d24b0fee 100644 --- a/ghost/admin/app/services/upgrade-status.js +++ b/ghost/admin/app/services/upgrade-status.js @@ -1,19 +1,22 @@ import Service, {inject as service} from '@ember/service'; +import classic from 'ember-classic-decorator'; import {get, set} from '@ember/object'; import {htmlSafe} from '@ember/template'; -export default Service.extend({ - notifications: service(), +@classic +export default class UpgradeStatusService extends Service { + @service + notifications; - isRequired: false, - message: '', + isRequired = false; + message = ''; // called when notifications are fetched during app boot for notifications // where the `location` is not 'top' and `custom` is false handleUpgradeNotification(notification) { let message = get(notification, 'message'); set(this, 'message', htmlSafe(message)); - }, + } // called when a MaintenanceError is encountered maintenanceAlert() { @@ -21,7 +24,7 @@ export default Service.extend({ 'Sorry, Ghost is currently undergoing maintenance, please wait a moment then try again.', {type: 'error', key: 'api-error.under-maintenance'} ); - }, + } // called when a VersionMismatchError is encountered requireUpgrade() { @@ -31,4 +34,4 @@ export default Service.extend({ {type: 'error', key: 'api-error.upgrade-required'} ); } -}); +}