no refs
MRR start date value for charts was being calculated with start value as 0, assuming we have the data for first date in our range to use as start value. Since the events data returned only has data on dates where any MRR event happened, in case the first date in our range didn't have any. data we started from 0 instead of value on previous date. This fix
- updates calculation to pick the start value for chart based on value on last date in our range(30 days)
- adds unit tests for stats
no issue
- the stale data checks would always return false because the calculation was reversed
- `old date - new date` will always result in a negative number so it would never be greater than 60000
- switched to `new date - old date` to get a positive number so the `>` comparison works
- moved `1 * 60 * 1000` into a constant so it's easier to the intended behaviour at a glance
refs: https://github.com/TryGhost/Team/issues/510
- The config API has been changed to return the full hostSettings key, not just the billing URL
- This has been done because we are adding more config, and it's easier to reason about if Admin has the same config as server
- Proxying each value also requires multiple updates to the API each time
- This updates all the places where the old values were used
refs 10b48b1d6d
refs 1531712d92
- the tour feature is no longer used so all associated code can be removed
- removes `liquid-tether` dependency as it was only used by the tour throbbers/popovers
refs https://github.com/TryGhost/Team/issues/469
- Fixed calculation for total/paid member count to use last value from outside range
- Fixed stats data override in dashboard
refs 7687571b12
While extracting the portal preview url setup to member-utils, the util incorrectly referenced values for free/monthly/yearly plans and so stopped reacting to selected plans in Portal preview. This change fixes the `isFreeChecked`, `isMonthlyChecked` and `isYearlyChecked` references in util.
refs https://github.com/TryGhost/Team/issues/460
- add `showTour` property to `ui` service
- updated `<GhTourItem>` to not render anything if `ui.showTour` is `false`
- updated launch wizard template to hide tour when open and re-enable when closed
refs https://github.com/TryGhost/Team/issues/460
- use the `user.accessibility` field via the `feature` service to add a `launchComplete` property
- this is the best place we have currently for UI-specific concerns
- toggle the property to `true` when the "Launch!" button is clicked in the final wizard step
- hide the launch site wizard link on the dashboard if launch has been completed
refs
- dropped the portal service in favour of using the existing `membersUtils` service
- renamed `getPreviewUrl()` to `getPortalPreviewUrl()`
- update the iframe src to point to the portal preview url when on the pricing step
- added free/monthly/yearly checkboxes to pricing step
- update iframe src with regenerated portal preview params when making changes
no issue
Updated settings navigation to a completely redesigned flow for Ghost 4.0 🎉
Co-authored-by: Kevin Ansfield <kevin@lookingsideways.co.uk>
Co-authored-by: Fabien O'Carroll <fabien@allou.is>
Co-authored-by: Rish <zrishabhgarg@gmail.com>
refs https://github.com/TryGhost/Team/issues/450
- duplicated and refactored/updated direct and connect settings UI from labs to the "connect stripe" step of the launch site wizard
- updated wizard buttons to be right-aligned
no issue
Adds new FirstPromoter integration on the integrations page. FirstPromoter enables sites to launch their own members referral program, and integration allows Site admins to directly add their FirstPromoter tracking ID in the settings to enable FirstPromoter script on their site.
closes https://github.com/TryGhost/Ghost/issues/12396
We use two stylesheets ghost-light.css and ghost-dark.css for light mode and night mode respectively. The problem occurs when we disable the light stylesheet when we enable dark stylesheet, as there is a moment when there is no style applied. This causes flash of unstyled content (or a big logo when users flip the night mode switch)
Since the ghost-dark style is loaded after the ghost-light stylesheet, we only need to enable or disable the dark stylesheet. When the dark stylesheet is enabled, the light stylesheet will be overridden automatically by the browser. I could not find any performance implications on overriding styles. The only performance implication is around loading a new stylesheet which we already do.
no refs
depends on https://github.com/TryGhost/Ghost/pull/12472
The members CSV importer gets an overhaul and works with new importer module in members service, performing the import in a background job when the import will take too long to complete in a reasonable time and send an email with data on completion. Also includes updated CSV mapping UI and error handling to allow easier import from different type of exports.
Co-authored-by: Fabien O'Carroll <fabien@allou.is>
Co-authored-by: Peter Zimon <zimo@ghost.org>
no issue
- email analytics feature has a potential to be resource-intensive so it may be switched off via config, when this is the case we don't want to show stats in the admin that are out of date or won't be added/updated
- fixed page link titles saying "Edit this post" instead of "Edit this page"
no-issue
This adds three initial customisation options for newsletters:
1. Show/Hide site title and logo
2. Set font to serif/sans serif
3. Display a publish with Ghost badge
This is the first step in allowing customisation of the look and feel of newsletters.
Co-authored-by: Rish <zrishabhgarg@gmail.com>
Co-authored-by: Peter Zimon <zimo@ghost.org>
refs fd91b593a5
- fixed incorrect call `pluralize(undefined, {withoutCount: true})` when number is undefined - `pluralize()` expects only one argument when no number is provided
- fixed destructuring in ghPluralize
- fixed linting error for undefined method after removal of `formatNumber` import
- fixed typo of import path in members controller
closes https://github.com/TryGhost/Ghost/issues/12110
- adds `{{gh-pluralize}}` helper that wraps the `{{pluralize}}` helper from `ember-inflector` but formats the number using our `{{format-number}}` helper
- updates all uses of `{{pluralize}}` to `{{gh-pluralize}}`
refs https://github.com/TryGhost/Ghost/issues/11971
- Newsletter preview email request has been using hardcoded fixed error message
- Reads custom error message from server's API response to show when available
no issue
- A new validation stage has been introduced as a second step after CSV file has been dropped. It is meant to catch any obvious validation errors and output detailed statistics about
- These improvements also improve sampling logic which increases sample size to 30 non-empty cells which are used to validate stripe_customer_ids when there's such need.
- New sampling logic also introduces improved automatic field type detection which allows to better map email and stripe_customer_id fields to CSV columns
refs #10318
* Updated settings model with new settings
* Removed parseSubscriptionSettings from settings service
* Updated members-utils to use new settings
* Updated labs controller to use new settings
* Fixed dependency for member-settings-form
* Updated members-lab-setting component to use new settings
* Updated disconnect modal to use new settings
* Updated members portal modal to use new settings
* Removed Direct from settings
* Renamed members_allow_signup -> members_allow_free_signup
* Allowed for null fromAddress
refs https://github.com/TryGhost/Ghost/issues/10318
- API has been updated to still work with `default_locale` for backwards compatibility but it makes sense for the client to match the underlying settings keys
refs https://github.com/TryGhost/Ghost/issues/10318
- primary change is in the settings service which is the only place we fetch the settings endpoint
- mocked APIs and fixture data updated to expect and to filter on `?group` rather than `?type`
no issue
depends on 77e1ada6c6
- reverts commit 6760527 with modifications for naming
- Adds new portal settings UI in Labs -> Members setting
- Allows customization of new portal-* settings upstream
- Updates settings service to include portal group
- Updates settings modal to include new portal-* settings
no issues.
- removes email and Stripe duplicate customer ID check to focus validation that might affect the whole dataset
- applies visual style and refines copy
no issues.
- changed warning style when import can still happen
- combines all warnings to a single section
- hides details for warnings behind an expandable list so that
- updated copy
no issue
- Added client side detection rule for Stripe's customer ids. Based on the check performed on the server side - cb26fd9305/core/server/api/canary/members.js (L43-L60)
- Also expanded check to a whole set of data as that should not be too slow of a check (did the same for emails). Kept the rest consistent to the data that is sent to the server for the check.
no-issue
This is now the central place for checking if stripe is configured for
members and we want to make sure that the Stripe Connect correctly
affects this value
no issue
- Adds validations for imported CSV data
- These checks include obvious validation checks for data - like if email addresses are valid, checking if Stripe configured when entries with stripe_customer_id are present and additional server-side validation for entries with stripe_customer_id to check if they appear in connected Stripe account
- The validation set is calculated by naive choosing of first 5, middle 5 and 5 tail records from imported set. This logic comes from observations that errors usually apear withing "test" records in the beggining or the end of the file. These selection rules might change in the future if we find a need for it.
- Adds papaparse CSV parser, which was chosen for it's maturity and relatively small minified size. In the future this library should be lazy-loaded to make the first page load UX nicer
no issue
- This logic is planned to be reused in more places, e.g. members import data validation. This change is meant to be a prep work for that.
- With stripe connect functionality coming it is important to have a central place checking for configured Stripe
requires fdeb7daf40
- swapped to using settings model for storing custom views instead of user accessibility field
- added conditional that checks current user is an admin/owner when displaying the manage custom views button in the content filter (only admins/owners can edit settings model)
- passed `session.user` into the `<GhContentFilter>` component as an argument so that the conditional getter doesn't need to handle async user access
- fixed no-shadow linting error in settings service
no issue
- move members loading code into `members` controller so that it's more accessible to other areas of the app
- add `refreshData()` to the `members` controller which forces members list and stats to be re-fetched
- call `members.refreshData()` after successful upload of members import file
- store range/days in `membersStats` service so that it's remembered across refreshes and component renders
no issue
- the "days changed" logic was incorrect so we were always performing new fetches rather than using existing data
- added a minor improvement that returns an in-progress fetch promise if we have one and params haven't changed - avoids triggering unnecessary extra fetches in the rare occasions the chart is re-rendered before a previous stats fetch has finished
no issue
- "stale data" logic was incorrect so we were always returning `undefined` from `membersStats.fetch()`
- improved behaviour of the chart when stats are not available or are loading
no issue
- added a `member-stats` service to keep member stats state outside of the chart component's lifecycle
- returns memoized member stats when fetching if the query hasn't changed and the data is less than a minute old
- reduces potentially heavy network requests when quickly navigating between members list and other screens
no issue
- Opted in to use explicit `hisotry.replaceState` and setting iframe's `src` using assignment instead of tracking it through computed property. This allows for tighter control over when iframe's history is updated which was causing problems when `src` was bound to computed property
- Added billing page metadata. This way browser history records appear with nicer signature
- Removed "update button" iframe and rewrote "global iframe" to not use modals. This allows to have single iframe on a page, which simplifies `postMessage` communication and preserve history inside iframe to be able to navigate it after closure
- Added route change handler responding to BMA app route changes. Allows to sync browser URL visible to the user with active route in BMA iframe. The sync is based on `hisory.replaceState` method that makes sure singular history records are kept in the browser history
- Added nested wildcard billing route. This is meant to catch all the nested routes inside of BMA iframe
no issue
- if `user.accessibility` is `null` as it is for newly created users then toggling the expansion state of custom views menus failed to save because we were assuming there was an object available
no issue
- apply defaults during service initialisation so that `navigation.settings.expanded.posts` doesn't start out as "undefined" then transition to "true" on first render resulting in unnecessary animation in the sidebar
- speeds up acceptance tests which no longer need to wait for animation to complete before continuing
no issue
- This change allows to open BMA popup using external link and pass in information using query parameters. Main use case being redirects from external sites
no issue
- Added billing update button to navigation menu. Ghost-Admin communicates with billing iframe and displays this button based on the plan data that iframe returns
- Ghost-Admin communicates with an iframe using same mechanism as with token exchange - throu `window.postMessage` API
no issue
- There is no way to turn on "Complimentary" subscription when Stripe is not connected
- There is no constructiove information that can be shown about subscriptions
no issue
- removed an old guard that was exiting early when `user.accessibility` was null which meant that the default views were never being inserted into the custom views list
no issue
- the `custom-views` and `navigation` services would trigger their observers immediately when `this.session.user` changed but that would occur before authentication had fully finished which was resulting in the `this.session.user` access triggering a request with no cookie/an old cookie set and causing a 403 error that interrupted the setup and authentication flows
no issue
- list custom post views in collapsable sidebar navigation
- default views: Draft, Scheduled, Published (except for contributors)
- record expanded/collapsed state of the navigation menus in user settings via new `navigation` service
- adds `customViews` service that manages custom views
- provides list of default views
- gives access to "active" custom view based on current route and query params
- manages loading/saving of custom views to user settings
- show "Add view" button in the content filter when the posts list has been filtered
- show "Edit view" button in the content filter when the posts list filter matches a saved view
Co-authored-by: Peter Zimon <peter.zimon@gmail.com>
no issue
Ember is migrating to `<AngleBracketSyntax />` for component invocation, see https://github.com/emberjs/rfcs/blob/master/text/0311-angle-bracket-invocation.md
We were in a half-way situation where some templates used angle bracket syntax in some places, this PR updates templates to use the syntax everywhere.
This simplifies the rules for what template code is referring to...
`<Component>` = a component
`{{helper}}` = a helper (or locally assigned handlebars variable)
`{{this.foo}}` = data on the template backing context (a component/controller)
`{{@foo}}` = a named argument passed into the component that the component backing class has not modified (note: this commit does not introduce any named arguments)
- ran codemod https://github.com/ember-codemods/ember-angle-brackets-codemod on the following directories:
- `app/templates`
- `lib/koenig-editor/addon/templates`
- removed positional params from components as angle bracket syntax does not support them
- `gh-feature-flag`
- `gh-tour-item`
- `gh-cm-editor`
- `gh-fullscreen-modal`
- `gh-task-button`
- updates some code that was missed in 3c851293c1 to use explicit this
no issue
- adds `whats-new` service that fetches the changelog from ghost.org and exposes the latest changelog entries
- trigger a background fetch of the changelog from ghost.org when first loading the admin when logged in, or after signing in
- adds a "What's new" menu item next to the user popup menu
- adds an indicator to the user menu button and what's new menu item if there are unseen changelog entries
- closing the changelog modal will update the "last seen date", clearing both indicators
closes https://github.com/TryGhost/Ghost/issues/10995
- when first loading the site preview, if private mode is enabled submit the login form in the background to get the cookie before loading the iframe
- refactors post-authentication preloading to ensure it occurs before post-authentication route hooks are called
- adds `showSuccess` attribute to `<GhTaskButton>` so that when set to `false` it can stay in the running state after "success" to avoid state change flashes whilst waiting for a transition
refs. https://github.com/TryGhost/Team/issues/205
Major update to Ghost Admin UI including:
- improved general consistency (typography, colors and contrast, UI components, icons)
- new design for post and pages lists, improved discoverability of filters
- search moved to modal
- account menu is decoupled from ghost logo
- further usability fixes
no issue
- moved `document-title` Route extension's functionality into the `ui` service
- updates the title each time the router service emits a route changed event
- `ui.updateDocumentTitle()` can now be called directly from components rather than the confusing `this.send('updateDocumentTitle')` bubbling behaviour
- refactored the `titleToken` implementation to use the now-formalised `RouteInfo`'s `metadata` field (https://github.com/emberjs/rfcs/blob/master/text/0398-RouteInfo-Metadata.md#appendix-a)
no issue
- modified `ui` service's `routeDidChange` handler to update it's `mainClass` property based on the new route's metadata
- used in the future for switching screen background colours
To use the feature, modify or add a `buildRouteInfoMetadata` hook in the route which you'd like to change, eg:
```js
export default AuthenticatedRoute.extend({
...
buildRouteInfoMetadata() {
return {
bodyClasses: ['my-body-class'],
mainClasses: ['grey-bg'] // <--------
};
}
});
```
The route hierarchy is taken into consideration with classes being added for all currently shown routes. For example if you wanted to add an `editor` class to all editor routes you could use the hook in `routes/editor.js` then if you added an `editor-new` class in `routes/editor/new.js` the resulting HTML output on the "New story" screen would be:
```html
<main class="gh-main editor editor-new">
```
no issue
- removed `styleBody` mixin in favour of using Ember's `buildRouteInfoMetadata` hook and router events in the `ui` service
- refactored separate CSS classes for each unauthenticated route into a single `.unauthenticated-route` class because hiding mobile nav whilst unauthenticated was the only use for body classes
Over in:
* https://github.com/whatwg/html/issues/3840
* https://bugzilla.mozilla.org/show_bug.cgi?id=1281135
I'm trying to come up with a model for `<link rel="stylesheet" disabled>` in
which Blink / WebKit and Firefox can agree on.
See that HTML spec issue for all the inconsistencies of WebKit / Blink, and the
following post for more context:
* https://groups.google.com/d/msg/mozilla.dev.platform/BdgNaChHnpY/mhXzCBwSCgAJ
---
Unfortunately, my change to Firefox breaks the Ghost Admin panel night-mode
switch (you can see it in Firefox Nightly).
This is because with my change, removing the `disabled` attribute from an
stylesheet behaves the same regardless of whether the `disabled` attribute is
added dynamically or not.
That means that adding the `disabled` attribute dynamically "unloads" the
stylesheet completely (just like when the attribute is there before inserting
the link in the document, or from the parser). Thus removing the attribute will
load the stylesheet again and fire a load event.
This is problematic for the code as-is, because it means that each time that the
load event fires when the disabled attribute is removed on an alternate, then
it's added again. :)
Prevent that from happening by removing the load event listener ASAP. What this
code wants is to only resolve the promise once after all.
Given this is so far the only regression from my change that has been reported
(over at https://bugzilla.mozilla.org/show_bug.cgi?id=1546707), I think fixing
the Ghost-Admin panel is worth it.
If this pattern is somehow common, then we'll probably revert that patch and go
back to the sad current state of affairs regarding interop :(
closes https://github.com/TryGhost/Ghost/issues/10629
- the error was occurring due to `session.user` CP being populated with a rejected promise when attempting to access the first route. The CP has no dependent key so any further attempts to access `session.user` would be rejected
- marking the CP as "changed" immediately after logging in means that the next request will create a new promise and successfully fetch the user
no issue
- `notifications.displayDelayed()` resets the `delayedNotifications` array but it wasn't using `.set()` which was throwing an Ember error because it wouldn't be tracked
no refs.
- added "View site" as the first and default menu item in navigation bar to be able to browse the site without leaving the Admin
- rearranged left sidebar items according to new structure (moved Labs down to bottom)
- removed "View site" from publication main menu because it's become redundant
- added Night shift toggle in line with Labs menu to be able quickly access it
no issue
- ran [es5-getter-ember-codemod](https://github.com/rondale-sc/es5-getter-ember-codemod)
- [es5 getters RFC](https://github.com/emberjs/rfcs/blob/master/text/0281-es5-getters.md)
- updates the majority of `object.get('property')` with `object.property` with exceptions:
- `.get('nested.property')` - it's not possible to determine if this is relying on "safe" path chaining for when `nested` doesn't exist
- `.get('config.x')` and `.get('settings.x')` - both our `config` and `settings` services are proxy objects which do not support es5 getters
- this PR is not exhaustive, there are still a number of places where `.get('service.foo')` and similar could be replaced but it gets us a long way there in a quick and automated fashion
no issue
- `/config/` can only be requested when authenticated
- updated `/config/` mock to look for an Authentication header and return a 403 if it's missing
- updated `ajax` service to add an `Authentication` header when authenticated in testing env (cookies are not present when testing)
- updated `config` service to add `fetchUnauthenticated()` and `fetchAuthenticated()` methods in addition to `.fetch()`
- updated `application` route to only fetch authenticated config when authenticated
- updated `signin` controller to correctly fetch config after sign-in
no issue
- added `page` model
- removed `page` param from Post model
- added pages screen with associated links
- added `:type` param to editor screens to work with the right models
- removed post<->page toggle and associated tour item
no issue
- lazy loaded scripts such as the CodeMirror asset used on the Code Injection screen could throw errors such as `TypeError: Cannot set property 'modeOption' of undefined`
- this was caused by "loading" promise returned from the `lazyLoader` service returning as soon as the network request finished which can be before the loaded script has been parsed and run meaning any processing occurring after the promise returns could be depending on unloaded code
- switched the lazyLoader service's loading mechanism from an ajax fetch to insertion of a `<script>` tag which can have `load` event attached which _will_ return after parsing/loading has completed
closes https://github.com/TryGhost/Ghost/issues/10455
- call `loadNew()` when initialising the `unsplash` service. Services are lazy-initialised so this is only called when the service is first injected which happens when the `<GhUnsplash>` component is first rendered
no issue
- the autonav behaviour has outlasted it's usefulness - it was mostly useful for editing but the editor screen is now always fullscreen and the number of low-resolution screens has dropped significantly
- dropped the components and all supporting code associated with autonav behaviour
no issue
- upgrade to latest `ember-source` and related dependencies including `ember-cli`
- upgrade to latest `ember-mocha` and modern ember testing setup
- https://github.com/emberjs/rfcs/blob/master/text/0268-acceptance-testing-refactor.md
- switch from using global acceptance test helpers and `native-dom-helpers` to using the new `ember-test-helpers` methods
- use [`chai-dom`](https://github.com/nathanboktae/chai-dom) assertions where in some places (still a lot of places in the tests that could use these)
- pin `ember-in-viewport` to 3.0.x to work around incompatibilities between different versions used in `ember-light-table`, `ember-infinity`, and `ember-sticky-element`
- incompatibilities manifested as "Invalid value used as weak map key" errors thrown when using `ember-light-table` (subscribers screen)
- pin `ember-power-datepicker` to unreleased version that contains a move from global acceptance test helpers to modern test helpers
refs #9865
- removed all `oauth2` and token-based ESA auth
- added new `cookie` authenticator which handles session creation
- updated the session store to extend from the `ephemeral` in-memory store and to restore by fetching the currently logged in user and using the success/failure state to indicate authentication state
- ESA automatically calls this `.restore()` method on app boot
- the `session` service caches the current-user query so there's no unnecessary requests being made for the "logged in" state
- removed the now-unnecessary token refresh and logout routines from the `application` route
- removed the now-unnecessary token refresh routines from the `ajax` service
- removed `access_token` query param from iframe file downloaders
- changed Ember Data adapters and `ghost-paths` to use the `/ghost/api/v2/admin/` namespace
refs https://github.com/TryGhost/Ghost/issues/9724
- standardised `{{gh-unsplash}}` actions and action arguments to better represent a generic "image source"
- added `{{gh-unsplash searchTerm="ghosts"}}` parameter
- added `payload` param to `card` definitions used for plus/slash menus so that default payload params can be passed to cards
- added a concept of "image selectors" to image card
- if a `payload.imageSelector` param is received by the card it will look it up in it's list of known selectors and display the appropriate image selection component
- if the card was created with an image selector param and the image selector is closed without selecting an image then the card will be removed
- delete image cards during cleanup if they were created via selector but have no src
closes https://github.com/TryGhost/Ghost/issues/9563
- fixes incorrect gravatar URLs by removing incorrect HTML encoding of the URL and enforcing URL encoding
- centralise image URL generation in the User model so that default image logic isn't spread across the app
- remove unnecessary proxy mixin from `ghost-paths` service (allows property access without `.get()`)
no issue
- fixes babel deprecation warning coming from `ember-element-resize-detector`
- re-created basic `resize-detector` service to wrap `element-resize-detector`
- import `element-resize-detector` directly from `npm` (includes bump to latest version)
- drop usage of jQuery selectors
no issue
- bump deps with no major breaking changes
- bump yarn.lock sub-dependencies
- resolve deprecation warnings for removal of Authorizers in ember-simple-auth
no issue
- disabled Ember Simple Auth's default token revocation
- we trigger session invalidation on a 401 which means our token isn't valid so the revoke requests will also fail
- renamed application route's `invalidateSession` to `logout` in order to distinguish it from any ESA methods
- added the token revocation requests to this action, we can be fairly sure at this point that the current tokens will be valid so the requests will succeed
- added check to `ajax.handleResponse` so that we don't invalidate the session for requests to external services
- removed pointless assertion from the ajax integration test
closesTryGhost/Ghost#9472
- add `changedAttributes()` passthrough to `settings` service
- use `changedAttributes()` in general settings `toggleIsPrivate` method to reset the password to the last known value when disabling private mode
requires https://github.com/TryGhost/Ghost/pull/9277
- added a `koenigEditor` feature flag
- modified the feature service to accept a `developer` boolean on the options object passed into the internal `feature` method, if `true` the feature flag won't be enabled unless the `enableDeveloperExperiments` config option is also enabled
- added "developer feature testing" section in labs that's only visible if `enableDeveloperExperiments` config flag is enabled
- added koenig editor toggle to the developer section in labs
- enabled a switch between the markdown and koenig editors
- modified the default value of the `mobiledoc` attr in the Post model to be a blank mobiledoc or blank markdown mobiledoc depending on the feature flag
- modified the `autofocus` switch in editor controller's `setPost` method so that it is always switched, even for new->edit where the post model isn't swapped
- added a compatibility check to the editor controller's `setPost` method that shows an alert and force enables the koenig editor if the koenig flag is not enabled and the opened post is not compatible with the markdown editor
- fixed various issues that have appeared due to the old koenig alpha becoming out of sync with master
refs https://github.com/TryGhost/Ghost/issues/5071
Upgrade messages are now shown on the About screen rather than as alerts. Notifications that are marked as `top` or `custom` are still shown as alerts to allow for certain upgrade messages to be given more visibility.
- remove old `upgrade-notification` service
- update the `upgrade-status` service:
- add a `message` property that contains an upgrade notification if any exists
- add a `handleUpgradeNotification` method that accepts a Notification model instance and extracts the `notification.message` property into a html safe string for use in templates
- when loading server notifications during app boot, pass notifications that aren't marked as `top` or `custom` to the new `handleUpgradeNotification` method
- update the `about.hbs` template to pull the upgrade message from the `upgradeStatus` service
no issue
- `Ember.testing` is or will soon be a getter/setter in Ember with the value set during a test, however destructuring will read the value when the module is evaluated
- moves all uses of `Ember.testing` inline
no issue
- upgrade `ember-ajax` to 3.0.0
- `ember-ajax` [now passes the payload through directly](https://github.com/ember-cli/ember-ajax/releases/tag/v3.0.0) rather than trying to normalize it so all our error handling needed to be updated
no issue
Automated tools, code generators, and editor integrations are increasingly standardising on the import style used in `ember-modules-codemod`. Our import style differed a little with regards to service/controller injection imports which meant we were starting to see inconsistent naming.
no issue
- Unsplash integration is enabled by default for all users
- it's no longer necessary to create your own Unsplash application and configure your application ID
refs https://github.com/TryGhost/Ghost/issues/8958
- Ghost OAuth isn't coming back, time for the code to disappear and simply all the things
- fixes the `Usage of router is deprecated` notices that flood the console/test logs when testing
no issue
- add eslint-plugin-ember, configure no-old-shims rule
- run `eslint --fix` on `app`, `lib`, `mirage`, and `tests` to move imports to the new module imports
- further cleanup of Ember globals usage
- remove event-dispatcher initializer now that `canDispatchToEventManager` is deprecated
closes https://github.com/TryGhost/Ghost/issues/8859, requires https://github.com/TryGhost/Ghost/pull/8895
- adds Unsplash app to app settings
- enable/disable toggle
- validation and testing of Unsplash App ID
- Unsplash App ID field hidden if provided via Ghost config
- adds `fetchPrivate` method to `config` service to pull config that requires authentication and updates authentication routines to fetch private config
- adds Unsplash buttons to editor toolbar and `{{gh-image-uploader}}`
- only present when Unsplash app is enabled
- opens Unsplash image selector when clicked
- `{{gh-image-uploader}}` has a new `allowUnsplash` attribute to control display of the unsplash button on a per-uploader basis
- adds Unsplash image selector (`{{gh-unsplash}}`)
- uses new `unsplash` service to handle API requests and maintain state
- search
- infinite scroll
- zoom image
- insert image
- download image
- adds `{{gh-scroll-trigger}}` that will fire an event when the component is rendered into or enters the visible screen area via scrolling
- updates `ui` service
- adds `isFullscreen` property and updates `gh-editor` so that it gets set/unset when toggling editor fullscreen mode
- adds `hasSideNav` and `isSideNavHidden` properties
- updates `media-queries` service so that it fires an event each time a breakpoint is entered/exited
- removes the need for observers in certain circumstances
no issue
- moves general UI state control such as menu display, autonav, settings menu, etc into a `ui` service for easier use within components
- no longer required to jump through hoops passing state and actions down from application controller into components
- removes indirect "route" actions in favour of calling actions/methods directly on the `ui` service