mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 03:44:29 +03:00
[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
This commit is contained in:
parent
48e5eb0261
commit
75a138cb39
@ -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({
|
||||
|
@ -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');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -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}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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()) {}
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -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 {}
|
||||
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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('.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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'}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user