no issue
- removes the "old" members screens
- swaps route names and links to point at the new members screens that were behind the experiments flag
Why are the new screens faster?
- only loads 50 members at once rather than every member in the database
- loads pages of members in as-needed whilst scrolling
- fetches member stats from the API rather than calculating locally
- caches members list and stats data for 60 seconds to avoid re-fetching when navigating to/from the members list
- moves search and filtering duties to the API rather than calculating locally
no issue
- the members list uses occluded rendering to keep scrolling performance high but this will cause constant reflows of the table contents whilst scrolling because contents are swapped in and out causing the browser to adjust the column widths to match longest/shortest content in the currently rendered set of rows
- applying `table-layout: fixed` to the table means that columns will always match the sizes defined by the first row of the table (in this case the header) ensuring that there is no dynamic resizing whilst scrolling
no issue
- `display: table` doesn't provide an equivalent of `colspan` so the loading state needs to include the same number of `display: table-cell` elements as the live state
no issue
- template-only components (eg, `<GhMembersListItem>`) will now use a glimmer class rather than regular component class for their automatically-created backing classes
refs https://github.com/TryGhost/Ghost/issues/11841
- Allows editors to see email customization option for sending test newsletters
- Editors had the necessary permission fixtures but the UI was previously only available to owners or administrators
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
requires https://github.com/TryGhost/Ghost/pull/11854
- ties the search input on the members screen to a `?search` query param, debounced at 250ms to avoid unnecessary API requests and UI churn
- updated the members route's `model` hook to pass through the search param in the API request query parameters
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
- added `format-number` helper that uses browser's built-in `toLocaleString()` method to format numbers such as adding commas or periods to improve number readability (`123,000` instead of `123000`)
- updated members chart totals to use the helper
- replaced direct `.toLocaleString()` usage with the new helper so we can change global number formatting if needed
no issue
- added mocked API for `/admin/members/stats/` that generates random data for the chart
- re-architected `<GhMembersChart>` to fetch data from the API rather than calculating stats from all members loaded in memory
- enabled mirage in development so that the chart can be tested before the live API is ready
no issue
- moved model loading back into the route
- updated model loading to refresh correctly when `label` query param changes
- fixed infinite loading/"no members" display in members list by using the `members.loading` property that `ella-sparse` gives us (previously we'd never leave the loading display because `this.members.length` would be 0)
- changed the members nav link to reset query params only if it's clicked whilst on the members screen - matches posts/pages behaviour and lets you navigate without having to re-enter your filter/search
refs 654d373655
- `<PowerSelect>` no longer has it's own wrapper element so `@classNames=` has no effect and needs to be added to an explicit wrapper element
no issue
- changed the `replaceRoute` after saving to transition to the `member-old` route instead of `member` route
- updated tests to work with the old routes (for now)
no issue
- with the sparsely loaded list you can scroll to an area which is being loaded in the background
- if a list row is being loaded, display a "loading" version of the row so it doesn't look like you're stuck on a blank screen
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
- disabled members search/filter/chart as they won't work without all members loaded into memory (they will be added back later)
- added `ember-ella-sparse` to handle a sparse array of members
- updated `fetchMembersTask` to return a sparse array instance
- updated components that work on a `member` instance to use `.get` because all items in a sparse array are proxy objects
- changed list loading behaviour to not refresh the list from the API unless the client-side list is more than a minute old - allows for much snappier nav between list and details screens
no issue
- moved labels fetching into the controller to unify members+labels loading approaches
- removed unnecessary `deactivate` hook on members route because the label form component already rolls back the model attributes when it's destroyed
- unified non owner/admin redirect approach across members and member routes
no issue
- ran [`ember-native-class-codemod`](https://github.com/ember-codemods/ember-native-class-codemod) on members-related files
- updated files to remove need for `@classic` decorator where possible
- switched to tracked properties
- removed usage of `this.get/set/toggleProperty` etc
- swapped usage of `{{action 'foo'}}` for `{{this.foo}}`
no issue
- some styles such as `border: none` inside `.gh-btn-white` were being stripped when ran through `clean-css` leading to visual differences between development and production
- disabled `ember-cli`'s default CSS minification as we already use `cssnano` for minification in our postcss pipeline for both dev and prod builds
no issue
- members screens will be undergoing heavy development to change how underlying data loading works
- duplicated all related screens and components so that development can occur behind the `enableDeveloperExperiments` flag without breaking the existing screens
- added "Members (dev)" link to the duplicate screens in nav bar when `enableDeveloperExperiments` is on
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
refs 654d373655
- ember-power-select switch to Glimmer components meant that our mousedown handler that was going through Ember's event bus was firing after the EPS events which trigger dropdown open/close and therefore not triggering the delete action
no issue
Keeps component JS backing files and template files in the same directory which avoids hunting across directories when working with components. Also lets you see all components when looking at one directory, whereas previously template-only or js-only components may not have been obvious without looking at both directories.
- ran [codemod](https://github.com/ember-codemods/ember-component-template-colocation-migrator/) for app-level components
- manually moved in-repo-addon component templates in `lib/koenig-editor`
- removed all explicit `layout` imports as JS/template associations are now made at build-time removing the need for them
- updated `.embercli` to default to new flat component structure