refs https://github.com/TryGhost/Team/issues/1295
- moved `?firstStart` query param handling into `'home'` route as it seemed like a preferable location
- switched to using `resetController` hook to manage removal of query param which seemed more reliable than the transition approach
- added `firstStart` query param to the transitions when completing step 3 of the setup flow
Updates Admin UX for Contributors
When logged in as a Contributor:
- removes sidebar, added floating account menu and dark-mode switch to right side. Updated mobile menu accordingly
- all post by the given user is listed in the Post list
- changed post filtering
- hides email columns in post list
- removes publishmenu for Contributors in Post preview modal
- visual tweaks
Updated email newsletter settings
- Added toggle to disable email newsletters
- Hides email related UI when email is completely turned off
- Rearranged email newsletter settings
- Added publish-menu preview in
- Changed default-recipients setting
- Updated publish-menu to show Publish as default action
- Removed the confirmation modal during publishing when no emails are intended to be sent
No issue
- Authors don't need access to staff page and don't need to see breadcrumbs on their profile page
- There's enough space in the side navigation for the post views to be visible by default
refs https://github.com/TryGhost/Team/issues/1277
- removed inclusion of `email_recipients` in member query when fetching member for display on the member details screen as it was only used for the activity feed
- added `<Member::ActivityFeed>` template-only component as a replacement for `<GhMemberActivityFeed>`
- uses `members-event-fetcher` resource for consistency with main activity feed and dashboard widget. Allows for a template-only component because data fetching behaviour can be managed directly from the template rather than requiring a backing component
no issue
- many "The automatic session initialization is deprecated" were shown in test output due to an old method of initializing the session service
- switched to explicit session setup in the application route's `beforeModel` hook
- https://github.com/simplabs/ember-simple-auth/issues/2314
refs https://github.com/TryGhost/Team/issues/1277
- added `/members-activity` route with associated controller, template, and components behind labs flag
- table component currently renders some dummy rows
- added navigation item to main menu
- will use the currently set `?filter` query param unless clicked whilst already on the `/members-activity` screen in which case it will reset the query
- added link to dashboard members activity panel
- added link to member details activity panel
- sets the filter param to `?filter=member:{member.id}` in preparation for the feed to be filtered to the member's activity
- updated the labs-flag test helper file to export both `enableLabsFlag()` and the new `disableLabsFlag()` so it's easier to test for flag-disabled functionality
no issue
- ran the `ember-native-class-codemod` codemod to convert just the route classes to native class syntax and performed some minor manual cleanup
- modern Ember uses native classes rather than EmberObject-based objects, this brings us closer to normalizing our code style across the codebase
- skipped the Application route as that requires deeper testing with a replacement for the `ShortcutsRoute` mixin
no issue
- mixins are deprecated in Ember so we want to remove their usage
- pre-requisite for easier automation for switching to native class syntax
- removed ShortcutsRoute mixin in favor of using the `{{on-key}}` modifier and standard controller action
no issue
- mixins are deprecated in Ember so we want to remove their usage
- pre-requisite for easier automation for switching to native class syntax
- removed ShortcutsRoute mixin in favor of using the `{{on-key}}` modifier and standard controller action
no issue
Mixins are deprecated in Ember so we want to remove their usage. The `CurrentUserSettings` mixin was used in Route files to provide `transitionAuthor()` (that also transitions contributors) and `transitionEditor()` methods so the the consuming route could use them to prevent access to authors/editors. In practice the only reason this was used was to prevent access to admin-only routes.
- added an `AdminRoute` class that inherits from our `AuthenticatedRoute` class
- when any route inherits from this class it will only allow access to admins and owners, any other user will be redirected to the home screen (dashboard or site depending on permissions)
- updated all of our admin-only routes to use the new `AdminRoute`
- allowed for removal of `CurrentUserSettings` mixin usage
- allowed for `beforeModel()` hooks to be removed from consuming routes in many cases
- some admin-only routes were extending/inheriting directly from Ember's `Route` based on the assumption that the router hierarchy would have a parent route perform the redirect. Those have also been switched to `AdminRoute` for consistency and to prevent accidentally making them available if the router hierarchy changes
- `/#/settings` does not use the `AdminRoute` so that it can redirect to the current user's setting page for non-admin users
- removed `CurrentUserSettings` mixin file
- cleaned up unnecessary computed property and function used for redirect-when-disabled in the Zapier route
no issue
- the controllers and templates for the old theme setting screens have been removed already but the route files had been missed in the cleanup
refs https://github.com/TryGhost/Team/issues/559
- switched to new ember-promise-modals pattern
- removed controller and template in favor of opening modals directly from the route
- removed unused `mousedown` event handlers - they are only necessary when an input blur would trigger validation errors
- fixed Enter key not triggering create action by adding an `{{on-key "Enter"}}` event handler to the name input
- fixed scroll not resetting to top of integrations screens when navigating between them by adding `{{scroll-top}}` element modifier to the main content sections
refs https://github.com/TryGhost/Team/issues/1164
- removed flag and labs screen toggle
- removed all conditionals
- removed all old/unused route/controller/component files
- renamed labs components and classes to non-labs naming
refs https://github.com/TryGhost/Team/issues/1169
We want all publish actions to trigger a confirmation modal. Currently that confirmation modal is controlled by `<GhPublishmenu>` which made it difficult to use from the route-induced publish shortcut.
- removed old shortcut mixin approach from the editor route
- added modern keyboard handler to a hidden element that is rendered any time the publish menu is present
no issue
When we were given a source+ref we were using that to find a theme object from the built-in list of marketplace themes and if it wasn't found redirecting to the change-theme screen. That redirect didn't need to happen because we only need the `ref` and can determine the theme name from that.
- passed `ref` through to the install modal as a data argument
- updated install modal to get theme name from passed in theme or extracted from passed in `ref` when theme is not known
- adjusted "isDefaultTheme" so it always checks against Casper rather than using the `ref: 'default'` value from the list of marketplace themes
no refs
- access to membership settings is restricted to owners and admins as contributors/authors cannot perform any actions on the page
- redirects non owners/admins back to site when trying to access membership settings via URL
no issue
The marketplace still uses the `/settings/theme/install` route but that was removed as part of the redesign for design settings.
- added `settings.design.change-theme.install` route that uses the newer theme install modal
- requires backing controller for query param support despite no template being rendered
- uses the `change-theme` controller's official theme list to fetch theme details based on query param `ref`
- added `settings.change-theme` route that lives on the old `/settings/theme/install` path and redirects to the new install route
- commented out the old theme settings routes ready for full cleanup/removal
refs https://github.com/TryGhost/Team/issues/1121
- adds error reporting for `notifications.showAlert()` in addition to `notifications.showAPIError()` because the former is used for some handled errors but will still show the undesired red error bar
- adds `shown_to_user` tag to all reported errors. Only errors that result in the red error bar will be reported with the tag as `true`, there may still be cases where we display errors outside of the red error bar but those wouldn't make it to Sentry either, we'll need a full audit of Admin source to find those situations and handle the reporting manually
- adds `ghost` context to errors that are shown in the red bar
- `ghost_error_code` - code returned from the API or passed manually through the `notifications.showAPIError()` options argument. Will be filled in once the error message has been audited+approved
- `displayed_message` - the full error message displayed to the user. Admin combines multiple attributes from the error details so it's useful to see what we actually show
- `full_error` - the actual API error response or a client-side generated error object
- `source` - whether the red bar came from `.showAlert()` or `.showAPIError()`, useful for tracking down where errors originated
no issue
- moved navigation settings tests from old settings/design tests to a separate file and unskipped them
- added happy-path acceptance tests for
- rendering design screen
- installing an official theme from the themes list
- uploading a custom theme
closes https://github.com/TryGhost/Team/issues/1161
- when a site is in private mode, design previews, the portal previews on membership, customize portal and offer pages were unable to load.
- For design and theme previews, the request to fetch preview data was failing due to cors and cookie not attached when admin and frontend have split urls.
- For portal and offer previews, there was no authentication done on private site before load, so if user opened the pages directly on them it failed to load the site.
- this change adds a new service that authenticates private site from admin as soon as user session is loaded, so previews on settings will always find the authenticated session for private sites and load correctly.
- it also updates fetch method for previews to include credentials so they are always able to fetch the site data after login
- removes authentication from site route since that was done as its now centrally taken care of by the frontend service
no issue
- Lapsed trials and subscriptions will set the site's hosting config to `forceUpgrade` in which case a Ghost(Pro) site does not have a valid subscription or trial
- In this state we need to redirect all routes for all staff users to `/#/pro` to ensure the subscription can be put back into an active state
- This commit tackles
- Route update on startup on the application route level
- Catching and redirecting all transition (utils routes)
- Fetching the owner user to pass this information to the Ghost(Pro) app for better communication to non-owner staff users
- Allowing non-owner users in the force upgrade state to transition to the `/#/pro` route
no issue
We want to automatically show brand settings expanded in the design menu when the active theme has no custom theme settings, in order to do that without causing visual noise/jank we need to ensure that we have all the data we need up-front before the design menu is rendered.
- optimized `customThemeSettings` loading behaviour
- `.load()` will now only perform a fetch if settings have not previously been loaded so it can be called without causing unnecessary waits
- `.reload()` will force a clear+refetch of the settings - called by `themeManagement.activate()` after successfully changing a theme
- moved fetching of theme settings from the design menu constructor to the `settings.design` route's `model()` hook
- means the app will wait for loading to finish before showing any of the design settings screen so we can guarantee the data we need is available
- moved update of preview html from the design menu constructor to the design settings route as it's a more appropriate place to find screen setup/loading behaviour
refs https://github.com/TryGhost/Team/issues/1149
- uses `willTransition` action rather than `deactivate` hook because we also want to close the table when navigating to the theme demo child routes
refs https://github.com/TryGhost/Team/issues/1149
- `customThemeSettings.rollback()` was not performing the correct job, changed to rollback attributes on each model rather than resetting everything to empty
- moved leave confirmation handling to the `settings.design.index` route so that it's always called when moving to the change-theme route, previously with the behaviour on the main `settings.design` route the willtransition/deactivate was not called when expected because that route is still active when on `settings.design.change-theme`
refs https://github.com/TryGhost/Team/issues/1136
- adds dropdown for active/archived offers selection
- wires active/archived offers on list screen to API
- filters offers list on archived/active based on selection
refs https://github.com/TryGhost/Team/issues/1130
- added new route for viewing themes so back/forward buttons can be used
- takes theme name as a parameter
- opens a fullscreen modal with an iframe containing the theme demo
- changed installable themes list to link to new route
- swapped `previewUrl` in theme data to point at the real demo rather than the ghost.org demo page
refs https://github.com/TryGhost/Team/issues/1130
- match latest design where the theme table is under an "advanced" toggle on the change-theme screen rather than a completely separate screen
refs https://github.com/TryGhost/Team/issues/1130
- added link to design sidebar
- dropped change-theme modal and associated route behaviour
- copied basic themes marketplace list into the change-theme controller/template
refs https://github.com/TryGhost/Team/issues/1130
- added `ui.contextualNavMenu` property that when set will switch the main nav menu between components, if it's not set then it will show the default "main" menu component
- added `design` menu sub-component of `gh-nav-menu` ready for use via `contextualNavMenu`
- moved sidebar contents from the design modal into this component
- updated design route to set/reset `ui.contextualNavMenu` to `design` on entering/leaving the route
- all other design routes are sub-routes so this works across all other design screens
- moved base design modal preview into the `settings/design/index` controller/template
- using index means that it's the default screen for `/settings/design` but will be automatically replaced by any other `design.x` routes
- moved `design/advanced` modal content into the `settings.design.advanced` controller/template and removed the modal handling from the route
refs https://github.com/TryGhost/Team/issues/1084
- updates shareable offer link UI to to open directly instead of route
- calculates offer url from code and updates in link modal
- wires copy button on link modal
- removes route based link code for modal
refs https://github.com/TryGhost/Team/issues/1111
Extracted functionality for listing, downloading, activating, and deleting from the theme controller/template into separate components and services so that they are more composable/reusable in different situations.
- moved theme activation to a new `theme-management` service that uses the `modals` service to open the theme warnings modal or limits upgrade modal as required
- the activate process is a task so that consumers can store a reference to the task instance and cancel it to close any related warning/limit modals (eg, when navigating away from the route or closing the modal that kicked off the process)
- created new-pattern modals for custom theme limit upgrade, theme errors, and delete confirmation so that we can treat them as promises and close where needed from parent
- duplicated theme table component as `<GhThemeTableLabs>` with an actions redesign and a refactor to handle download, activation, and deletion itself making use of the new theme-management service and modals
- fixed some oddities with design modal's transition/modal close handling by simplifying the async behaviour and being more explicit
- added advanced design modal that contains the new theme table component and linked to it from footer of design modal's sidebar
no issue
- appears to be left-over from copy/paste of an earlier screen re-structure
- cleaning up for easier extraction of functionality to new screens / modals
refs https://github.com/TryGhost/Team/issues/559
When modals are re-used across the app it's annoying to have to remember the class names that it uses in every location it's used.
- added a `DEFAULT_MODAL_OPTIONS` object to the modals service that's keyed on the modal to be opened and contains any options that are repeated across every instance
- overrode the `modals.open()` method to merge in the default options before calling `super()`
- updated invocation points of shared modals to remove duplicated class name options
no issue
- opened modal was assigned to `this.customizeModal` but the rest of the code expected `this.offerModal` so correct closing behaviour wasn't gauranteed
refs https://github.com/TryGhost/Team/issues/1111
- added override of the `ember-promise-modals` container component so that it doesn't render the background element when `omitBackground` is passed as an option when opening the modal
- fixes the flicker by not having a dark background transition in whilst the white overlay modal is also transitioning in from transparent->opaque
refs https://github.com/TryGhost/Team/issues/1111
refs https://github.com/TryGhost/Team/issues/1103
- moved customize modal from a link on the design screen to the main design screen
- changed modal design to be a full-screen overlay with side bar that emulates standard Admin design
- added toggled groups of settings in sidebar
- added `{{set-has}}` helper for use in conditionals matching when a Set contains an object
- added grouping of theme settings
- dropped unfinished advanced/change theme modals
no-issue
This adds the ability to apply complex filters to members, as well as to
perform bulk actions on the filtered set, including unsubscribing,
adding & removing labels.
refs https://github.com/TryGhost/Team/issues/1070
- split select form component into it's own component so it's cleaner when we get to additional setting types
- added change handler that updates the setting record's value when a new option is selected
- added `.isDirty` to the custom-theme-settings service so we can warn of unsaved changes and revert any changed values when needed
- added save of custom theme settings to the customize design modal's save routine
- added missing `notifications` service import to customize design controller
refs https://github.com/TryGhost/Team/issues/1045
If the customize modal is open and you manually changed the URL, on navigating the modal would close and a transition to the manually entered URL would start but then you'd be transitioned back to `settings.design`.
The problem occurs because `beforeModalClose` is always called when the modal closes causing the redirect.
- added a `hasConfirmed` boolean that is set to `true` when leaving the customize route if there are no unsaved changes or the changes have been confirmed
- skipped the unsaved changes check and redirect in `beforeModalClose` when `hasConfirmed` is true
refs https://github.com/TryGhost/Team/issues/1045
- added tabs to the the customise design modal's sidebar for general settings and theme settings
- copied settings from the existing branding modal plus site description from general settings screen into the general settings tab
- theme settings tab left blank ready for static design
- `saveTask` put on the controller so that we can access it from the route, allowing us to pause modal closing when navigating away (implementation left for later)
refs https://github.com/TryGhost/Team/issues/559
refs https://github.com/TryGhost/Team/issues/1045
- removed need for `{{will-destroy}}` in the modal template by using `willTransition()` in the route that opened the modal instead
- used the property of new modals acting as promises to implement an unsaved changes confirmation modal
- added `confirmUnsavedChanges()` method that opens a "are you sure you want to leave?" modal that is treated as a promise. If the modal is closed by the "Leave" button the promise returns true in which case we rollback the unsaved changes. The modal is returned so that other behaviour can use this method and wait for the confirmation result
- added `willTransition()` route hook that calls `confirmUnsavedChanges()` when there are unsaved changes and will only continue to transition if the "Leave" button is pressed
- added `beforeClose()` hook to the customize modal when opening so that we can prevent the customize modal from closing when "Stay" is clicked in the confirmation modal
- updated `activate()` hook to store the modal instance so it can be closed later
- updated `deactivate()` hook to call `.close()` on the modal instance rather than using private data/methods on the modals service
refs https://github.com/TryGhost/Team/issues/1045
- added new `settings.design.customize` route
- used the route's `activate` and `deactivate` hooks to trigger and close the customize modal
- added `modals/design/customize` component that uses the existing branding modal design without it's contents as a base
- has `{{will-destroy}}` hook that transitions back to the settings screen so the route will update when the modal gets closed
refs https://github.com/TryGhost/Team/issues/1045
- added blank `/settings/design` route and associated screen
- redirects to settings index if associated labs flag is not enabled
- when custom theme settings labs flag is enabled, replaced Branding and Theme links with single Design link
refs https://github.com/TryGhost/Team/issues/559
- moved the modal component class, template, and sub-components into a `components/modals/` directory to keep the top-level dir cleaner
- migrated component class to full glimmer syntax
refs https://github.com/TryGhost/Team/issues/559
- moved the modal component class and template into a `components/modals/` directory to keep the top-level dir cleaner
- migrated component class to glimmer syntax
- moved route transition behaviour directly into the class to avoid weird route-action indirection
no issue
- Clicking on the Ghost(Pro) item in the navigation would always reload the billing management app and enforcing to fetch all data again, even tho it has been fetched and cached before
- This commit removed loc that replaces the iframe content every time we click on the button
- Renamed `setBillingWindowOpen` to `toggleProWindow` as it's more accurate in its description
- Removed `closeBillingWindow` as it's unused throughout the app
no refs
- resets filter columns on list when query params are removed from the url via sidebar click transition
- reloads the updated list on new bulk actions on the filtered list
no issue
- Grammarly is a suspect in some reported editor errors but it's usage hasn't been available inside of Sentry to know for sure
- when the grammarly extension is present it adds a `data-gr-ext-installed` data attribute to the `body` element, we now use that to add a `grammarly: true/false` tag to error reports so we can more easily track down the cause of editor bugs
refs https://github.com/TryGhost/Team/issues/884
Drop-to-upload functionality was lost in the first version of the new feature image uploader inside the main editor area, this adds it back in.
- fixed dropzone flickering issue by switching the event listeners to the capture rather than bubble phase so we can indicate a drag is occurring on the body without each individual drag/drop handler needing to know about it
- moved the event handler init/cleanup to the `ui` service
- moved the event handler init call to the application service as it no longer requires auth to have occurred for access to the labs flag setting
- removed the `featureImgDragDrop` labs flag
no issue
- there was no need for the decorator as the class is up to date with Octane idioms after swapping `init()` for `constructor()`
- added a comment about the need for `member.get('id')`
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/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 `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/884
- add `[data-user-is-dragging]` to `body` element when any drag is occurring so that we can make drop zones active
- added dropzone and drop handling to feature image component
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
refs https://github.com/TryGhost/Team/issues/723
- if the `/site/` API returns a `sentry_dsn` then we configure Sentry for error reporting as soon as we've loaded the initial unauthenticated data
- once we're authenticated and we have the full Ghost version available, override the Sentry event processor to use the full release
- updated `notifications.showAlert()` which is our fallback for API errors that shows the red banner at the top - these are the errors we're most interested in getting visibility for and reducing
no issue
- stripe connect/disconnect functionality has moved to a modal as part of the new membership screen
- removed `settings/members-payments` route and related route/controller/template files
- updated link to stripe connect in product screen to show an alert as a reminder to update to use the new modal (products screens are not usable for now, they'll be worked on again later)
no issue
- added actions for handling close/confirm/cancel of portal settings rather than re-using the route-level leave modal because the portal settings modal does not need any knowledge of the route
- added controller reset that is called when the route is exited to ensure no modals are shown when navigating back to the membership screen
- fixed "cannot set on destroyed" error when portal settings are opened and closed quickly
- removed usage of old `{{action}}` helper - this has been replaced with `{{on}}` and `{{fn}}`
This reverts commit 0cf2fc9c24.
Hiding the launch wizard when there are existing prices causes an annoying flicker on the dashboard everytime we reload the page or navigate away. Instead of handling this client side, we'll push up the logic to hide the wizard on server.
refs https://github.com/TryGhost/Team/issues/644
In case the prices are already set for the default product, its confusing to have the launch wizard show the price setup again. We remove the wizard completely if the prices are already created for the default product.
no issue
- simplified query params as they are only used to display a notification
- removed all controller knowledge and associated reset behaviour for query params
- moved notification display from `setupController` to `beforeModel` so the raw query params can be pulled off of the transition object
- removed unused service injections from `<GhMembersEmailSetting>`
- removed unused service injections and properties from members-email controller that were left over from a copy/paste
- converted members-email controller to a native class
- fixed "leave settings" confirmation modal behaviour that wasn't moved across in the the settings screen re-org
refs https://github.com/TryGhost/Team/issues/599
- Previously user received genetic limit error after putting in integration name and clicking "create" button. This created a little frustrating experience.
- The updated flow does the check before loading the integration modal, so the user receives communication about needed upgrade before doing any work