refs https://github.com/TryGhost/Team/issues/973
- added `@showCreate` option to `<GhInputWithSelect>` that enables the create option without having to pass a function in `@showCreateWhen`
- fixed autofocus not focusing input element in `<GhInputWithSelect>` when `autofocus="true"` isn't enough by itself
- updated `selectOrCreate` in `<GhInputWithSelect>` to trigger `onChange` if it's passed in rather than `onInput`
- swapped input in labs snippet input to `<GhInputWithSelect>`
- added actions for updating a snippet when an existing snippet is selected
- added action to editor control for saving an updated snippet
refs https://github.com/TryGhost/Team/issues/994
Non-owner admin users have visibility of the "Connect with Stripe" UI in Admin, but lack permissions to setup the Stripe session in order to actually connect Stripe. This leads to a dead-end with a raw JSON api response, which should never be the case. This change patches the UI by removing Stripe Connect paths for non-owner admins.
closes https://github.com/TryGhost/Team/issues/969
Wires the bulk action operation UI to Ghost API to perform operations on filtered member list - unsubscribe filtered members, add label to filtered members or remove label from filtered members
refs https://github.com/TryGhost/Team/issues/954
- The transition values wever missing for new "sent" email status and caused a 500 error to be displayed even though it had nothing to do with server errors
- There will be more tweaks to this in future iterations, this is a stop gap solution to have a working UI
closes https://github.com/TryGhost/Team/issues/965
If there's only one filter row in the members filter builder modal, then clicking on "X" in that row resets the fields instead of removing the complete row and showing empty filter builder
refs https://github.com/TryGhost/Team/issues/969
A lot of power of filtering members comes from ability to perform actions on the filtered member list. This change adds bulk operation actions on the the UI to apply on filtered members, but has not wired them up to the API yet.
- adds unsubscribe bulk operation UI
- adds label addition bulk operation UI
- adds label removal bulk operation UI
- adds new single label selection UI for add/remove label to members UI
refs https://github.com/TryGhost/Team/issues/943
- adds new columns to member list table based on selected filters in UI
- handles dynamic columns in members list with formatted output like for labels
- works behind the filtering feature flag
no issue
- added free members to dashboard controller's count stats data
- moved email open rate chart into it's own dashboard box
- added free members count chart under paid members chart (where email open rate used to be)
refs e25e36352d
Since the concat method does not change the existing array but instead returns a new array, the extra filters on the API query object were not being applied. The extra filter included filtering on `created_at` date for members which was not applied as the filter was not stored in the array correctly.
no issue
- added `dashboardTwo` feature flag and labs screen toggle
- added `dashboard-labs` route with duplicated dashboard controller/template
- added redirect to `dashboard` route so it transitions to `dashboard-labs` when the feature is enabled
refs https://github.com/TryGhost/Team/issues/927
- we'll soon need access to adjusted accent colours outside of the application controller so they're now available on the `ui` service
closes https://github.com/TryGhost/Team/issues/865
Ghost now returns a forbidden error rather than an unauthorized error when saving whilst logged out so the session invalidation was not being triggered.
- added forbidden check to ajax service to trigger session invalidation
- added automatic retry of save in editor when re-authenticating
- fixed re-population of user and proxy services when re-authenticating, it's not needed at that point because nothing has been cleared
issue https://github.com/TryGhost/Team/issues/857
- The goal is to avoid testing for the owner role only is cases where we should be testing for the owner or admin role
- `isOwner` => `isOwnerOnly`
- `isAdmin` => `isAdminOnly`
- `isOwnerOrAdmin` => `isAdmin` (concerns now both Owner and Admins)
no issue
Having `session.user` return a promise made dealing with it in components difficult because you always had to remember it returned a promise rather than a model and had to handle the async behaviour. It also meant that you couldn't use any current user properties directly inside getters which made refactors to Glimmer/Octane idioms harder to reason about.
`session.user` was a cached computed property so it really made no sense for it to be a promise - it was loaded on first access and then always returned instantly but with a fulfilled promise rather than the underlying model.
Refactoring to a synchronous property that is loaded as part of the authentication flows (we load the current user to check that we're logged in - we may as well make use of that!) means one less thing to be aware of/remember and provides a nicer migration process to Glimmer components. As part of the refactor, the auth flows and pre-load of required data across other services was also simplified to make it easier to find and follow.
- refactored app setup and `session.user`
- added `session.populateUser()` that fetches a user model from the current user endpoint and sets it on `session.user`
- removed knowledge of app setup from the `cookie` authenticator and moved it into = `session.postAuthPreparation()`, this means we have the same post-authentication setup no matter which authenticator is used so we have more consistent behaviour in tests which don't use the `cookie` authenticator
- switched `session` service to native class syntax to get the expected `super()` behaviour
- updated `handleAuthentication()` so it populate's `session.user` and performs post-auth setup before transitioning (handles sign-in after app load)
- updated `application` route to remove duplicated knowledge of app preload behaviour that now lives in `session.postAuthPreparation()` (handles already-authed app load)
- removed out-of-date attempt at pre-loading data from setup controller as that's now handled automatically via `session.handleAuthentication`
- updated app code to not treat `session.user` as a promise
- predominant usage was router `beforeModel` hooks that transitioned users without valid permissions, this sets us up for an easier removal of the `current-user-settings` mixin in the future
no issue
- there can be cases where the connection fails but Ctrl/Cmd+S won't work as a direct retry (eg, publish fails so the status reverts, in that case Cmd+S would save a draft rather than re-attempt a publish)
- switched to a neutral "try again" message
refs https://github.com/TryGhost/Team/issues/803
With multiple products we'll re-enable segmentation by product for posts, which also means need to add a new option to the default post access setting in Membership settings. This change -
- adds new `A segment` option to default post access dropdown behind the alpha flag for multiple products
- shows member segment select dropdown for `A segment` option
- handles update of `defaultContentVisibility` to allow setting custom filter
closes https://github.com/TryGhost/Team/issues/837
We previously added automatic retries to the editor controller for post saves; reviewing the resulting logs in Sentry we can see this stopped the "Server unreachable" error alerts showing to users because the requests typically succeeded on the first retry that was made 5 seconds later. However the problem is not limited to post saves and we can see other requests hitting the same issue, including when working in the editor such as adding embed cards, uploading images, or fetching member counts before publishing.
All of the API network requests we make in Admin run through an `ajax` service that makes and handles the request/response. By moving the retry logic for specific errors out of the editor controller and into the ajax service we can make temporary connection handling more graceful across the app.
- move retry behaviour from the editor controller to the `ajax` service so we can retry any request rather than just post save requests
- speed up retries so we reconnect as soon as possible
- first retry at 500ms, then every 1000ms (previous was every 5s which meant overly long waits)
- reduce total retry time from >30s to 15s
- improve reporting to Sentry
- report when a retry was required
- report when a retry failed
- include the total time taken for both success and failure reports
- include the `server` header value from requests to distinguish between CDNs
- include type of error so we can distinguish "server unreachable" from "maintenance" retries
refs a6c6def7e1
- we weren't checking if an error was a validation error by examining the number of errors on the post model, this meant we weren't falling through to the generic error handling/display logic that shows an alert for validation errors when a save isn't a background/silent save
no issue
- when Ghost is in maintenance mode after an upgrade we know it will come back shortly so automatically retrying the save in the same way we do for "server unreachable" errors provides a smoother experience compared to halting and showing a red alert bar
no issue
- post status was not being reset after certain types of failure to publish/unpublish/schedule which meant that the editor could be left in an odd in-between state where the displayed status did not reflect reality
- fixed "saving/publish/schedule failed:" wording in error message when a server unreachable error was detected, the "saving/publish/schedule" did not reflect the actual status change because we were passing through only the current status rather than previous+new status'
no issue
- if a ServerUnreachable error is triggered by a non-background-save then we'd show the expected custom alert and then immediately overwrite it because `savePost`'s catch was not expecting an `undefined` error
refs https://github.com/TryGhost/Team/issues/792
- updates product benefit to use `name` instead of `label` attribute for benefit text
- updates model/serializer/validator to correctly handle benefit attributes
- added `+` button for adding new labels as the enter behavior is closing the popup(needs fix)
closes https://github.com/TryGhost/Team/issues/799
- previous logic was still using `stripe_plans` for MRR currency, which is not used anymore
- updates first product's currency as default mrr currency
refs https://github.com/TryGhost/Team/issues/788
- automatically retry any failed save attempts every 5 seconds for up to 30 seconds
- only show error bar after when we completely give up
- clear error bar if a later save is successful
- update error message to specify there's a connection problem and to retry with Cmd+S
- notify Sentry of a successful save after an initial failure including the number of attempts that were made and the total time for save to succeed in seconds