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/972
If a filter is applied in the new members list then the URL gets updated and the filter dropdown contains the filters that have been created. When refreshing the page while a filter is applied, the URL remains the same, the filter is still applied but the UI in the filter dropdown resets and doesn't show the appropriate filter fields and values.
This change parses the nql filter from URL using `nql-lang` library and rebuilds the filter UI blocks based on current filter in URL. It also ignores any invalid or unexpected filters in the UI.
closes https://github.com/TryGhost/Team/issues/971
reverts abe5c6d681
We use vertical-collection to allow infinite loading + scrolling for members list instead of loading and rendering all members at once. The behavior was not working correctly with updated list for filtering feature, as we dynamically update columns. This change fixes the scroll behavior and members loading together by updating the containerSelector for vertical collection.
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/966
With introduction of members filtering, the current way of editing member labels needed an upgrade. This change updates the member label input component to include editing option which allows triggering label edit modal directly from the filtering menu when working with labels. The long term idea is to make this a consistent global pattern with labels dropdown, extending to member details screen as well.
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
refs https://github.com/TryGhost/Team/issues/943
- separates the new alpha members filtering to its own `-labs` component
- fixes behaviour for existing filtering feature on members list which was overwritten with last change
- updates up action handling to modern glimmer syntax
no issue
- converted publish menu and `gh-tags-list-item` components to glimmer syntax so data attributes can be passed in via `...attributes`
- added explicit `data-test-button` bound attribute to `gh-task-button` component
- moved `modal-theme-warnings` auto-bound data attribute from JS file to explicit html attribute in template
refs https://github.com/TryGhost/Team/issues/585
requires https://github.com/TryGhost/Ghost/pull/12082
When a label or status filter is selected on the members screen show a "Delete selected" option in the actions dropdown. Bulk deleted members will _not_ have any subscription data modified in Stripe, if a member should be deleted and have their subscription cancelled it's necessary to do that on a per-member basis.
- updated bulk delete handling to match API
- added link to bulk delete confirmation modal in members actions dropdown (only shown when label, status, or search is used)
- updated testing framework for members
- added label factory for easier test setup
- updated `GET /members` and `DEL /members` endpoints to work with label filters
- updated test selectors for easier reference in tests
* Admin UI update basics
Added the basics for the Admin UI/style update. Very far from being done...
* Admin style updates
- exploring menu
- enabling full width content (integrations selection bg)
- updated main screens
closes https://github.com/TryGhost/Ghost/issues/12421
- added `emailOpenRate` property to member model
- added open-rate column to the members list
- hidden when email analytics is disabled
- added `{{feature "flag"}}` helper so feature flags can be checked in templates without injecting the feature service into the backing class
- added `order` query param to the members controller/route and wired it into the data fetching routine
- added order dropdown to the filter bar with "Newest" (default) and "Open rate" as the two options
- whole dropdown is hidden if email analytics is disabled
Co-authored-by: Kevin Ansfield <kevin@lookingsideways.co.uk>
no issue
- display a confirmation modal when bulk deleting members
- hit the `DELETE /members/?all=true` endpoint when confirming
- show counts of members deleted/skipped
- fix selection reset when leaving edit mode
no issue
- initial UI for bulk-selection, focusing for now on first stage which is limited to select-all and delete actions
- adds "Edit" button to the members table that shows the "selection" toolbar in place of the table header and shows a checkbox next to each member
requires https://github.com/TryGhost/Ghost/pull/11892
- adds `?paid` query parameter to members route that is tied to the `?paid` query param in the API request
- added all/free/paid members dropdown to members filter component
no issue
- passed in the `refreshData` action to the `<GhMembersNoMembers>` component and called it after creating the member
- converted `<GhMembersNoMembers>` to a glimmer component
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
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
- 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
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
- 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
- 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}}`
refs https://github.com/TryGhost/Ghost/issues/11755
- adjusted estimated height to match actual rendered size and enabled `staticHeight` to switch to a simpler algorithm inside vertical-collection
- prevents some jank seen when scrolling where rows jump
no issue
- added `geolocation` attribute to member model with json-string transform
- prevent geolocation from being sent back to the API in member serializer
- add "Location" column to members list
- if country is "US" then display "{State}, US" otherwise show full country name such as "United Kingdom"
- displays "-" if no geolocation data has been collected for the member
no issue
refs TryGhost/Ghost#11538
* Added members label handling v1
* Added members label dropdown in list screen
* Updated selected labels and member list UI refactor
* Added v1 label add/delete modal
* Added add label modal v1
* Fixed disabled check for new label save
* First stab at member filters layout
* Updated member detail screen design
* Member detail refinements
* Added basic editing for member labels
* Fixed label deletion from members list
* Updated filtered list header
* Refinements for dropdown and empty filter state
* Refined label modal
* Updated member labels fetch logic
* Added custom dropdown component for labels
* Refined style for dropdown
* Refined dropdown button
* Restructure and refine members dropdown styles
* Added selected indication to dropdown
* Fixed dropdown footer style
* Removed member label placeholder
* Removed add label from member list actions
* New label refinements
* Added confirmation modal for label delete
* Added duplicate validation check for labels
* Updated validation check with slug
* Updated copy
* Updated actions dropdown copy
* Fixed visual glitch of dropdown on FF
* Hide scrollbar for labels dropdown
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
- the member count is automatically calculated via the length of the live members array so there's no need to manually decrement it - if we do manually decrement then the count is off by one because the auto calculation runs to get the new value before the manual decrement
no issue
The tag and member screens share the same underlying UI/UX patterns but were using different code patterns. This brings both in line so that we have consistent code patterns that can be re-used for other screens.
- fixed cleanup of new tags by adding the `deactivate` hook to the `tag` route
- updated `member` and `member.new` route/controller setup to match tag route/controller setup
- added `save` action to member controller so that Ctrl/Cmd+S works on member screen
- updated tag route/controller to utilise the same instant display w/background refresh when accessing the tag details screen
- completed transition of non-component tag/members templates over to angle bracket component syntax