refs https://github.com/TryGhost/Team/issues/1410
- added block invocation support to `<GhDatePicker>` that exposes the calendar components used inside the datepicker dropdown allowing for customisation of the dropdown content
- updated "last seen" datepicker to use the block invocation support to add buttons that select typical "time ago" dates
Co-authored-by: Peter Zimon <peter.zimon@gmail.com>
no issue
- members having multiple subscriptions is not really expected but if it does happen then the most recently updated subscription is most likely to be the one that we're interested in showing the details of in the members table
- added `{{most-recently-updated arr}}` helper+function that will return the item in the array argument with the most recent "updated at" value
- uses `updatedAtUTC` or `updatedAt` or `updated_at` values so it will work against any of our models or un-transformed API response objects
- updated `<GhMembersListItemColumn>` to use a `mostRecentSubscription` getter when showing subscription data rather than assuming the first object in the subscriptions array should be displayed
refs https://github.com/TryGhost/Team/issues/1188
- The api throws a validation error when we try to add benefits with an empty name
- Before saving, we remove benefits with an empty name
- Added test for empty benefit names
refs https://github.com/TryGhost/Team/issues/1410
- we have problems translating an "x days ago" NQL filter back to the UI component so as a temporary measure we're switching to a datepicker input as we have a working solution for that
- a later iteration will add shortcut buttons for selecting typical "x days ago" dates in the datepicker
refs https://github.com/TryGhost/Toolbox/issues/222
- Without Admin API versioning through URL, Content-Versioning header will be the best way to suggest an expected version of the resource (formatting). Having this header in place should minimize the ammount of breaking changes and would allow for the server to respond accordingly for a particular client version
refs https://github.com/TryGhost/Toolbox/issues/222
- Admin API has the latest version alliased without a verion to prepare to the switch in Ghost v5. As we completely control Ghost Admin it makes sense to dogfood our latest changes
- Starting with Ghost v5 there will be no API versioning in the URL, this is groundwork for those new realities
no issue
- shortened invalid date format error message in `<GhDatePicker>` to "Date must be YYYY-MM-DD" so it's less likely to wrap
- added `@maxDateError` and `@minDateError` arguments to `<GhDatePicker>` allowing override of the default "Must be on or before xxxx-xx-xx" message shown when the inputted date is outside of the allowed range
- updated `<GhDatePicker>` usage in the "Created" member filter to use "Must be in the past" error message when a future date is selected
closes https://github.com/TryGhost/Team/issues/1319
Due to how JS implements numbers, it's possible that when we multiple a number with 2 decimal places by 100 that we do not end up with an integer e.g. 9.95 * 100 = 994.999...
This is not a valid price for the API and so we must round it to the nearest integer. We round off prices both at source as well as in ties serializer to make sure we never send non integer prices to API.
no issue
- added datepicker based filter for the next billing date of paid subscriptions
- updated table to add "Next billing date" column when filtered, showing the paid subscription's current period end date
no issue
- if `<option>` elements are re-rendered without the parent `<select>` being re-rendered, Firefox does not pick up the new `selected` option
- we were seeing this behaviour when the options in an operator select get updated after changing the filter type, Firefox was always selecting the first option rather than the "selected" option
- switched the `filters` array from an EmberArray instance over to a tracked built in Array instance and changed the "edit" behaviour when changing a filter type so we fully replace a `Filter` instance in the filters array with a new instance which causes an overall re-render of that filter row avoiding the Firefox issue
no issue
- added datepicker based filter for the start date of paid subscriptions
- updated table to add "Start date" column when filtered, showing the paid subscription's start date
no issue
- prevents automatically filtering out all of today's members as soon as a "Created" filter is added as happened when the default was "before"
no issue
- updated default date filter values so they match the date in the site timezone rather than local timezone
- fixes problems such as defaulting to 2022-03-01 when you're in UTC@4AM but the current date in the site timezone of UTC-5 at that time is 2022-02-28
no issue
- updated NQL generation to adjust dates in filter string so they are the UTC equivalent
- eg, in UTC-5 "created on or after 2022-02-22" becomes `created_at:>='2022-02-22 05:00:00'`
- updated NQL parsing to take a UTC date filter, convert to a date in the site timezone, then convert to a local date in a way that the datepicker input value matches the respective site timezone date
- eg, in UTC-5 `created_at:<='2022-02-22 04:59:59` becomes "created on or before 2022-02-21"
closes https://github.com/TryGhost/Ghost/issues/13611
- added `{{moment-site-tz}}` helper for transforming any date into the selected site's timezone
- allows for use on any date in the system
- keeps transformation a display-level concern
- updated members table to use `{{moment-site-tz}}` to transform the date before display
refs: https://github.com/TryGhost/Team/issues/1376
- adjust line heights for paragraphs
- vertical align content
- added subheader for actions
- added import members link
- updated action for customise site
refs https://github.com/TryGhost/Admin/pull/2274
- every time the filters UI was opened we were fetching the products list from the API which seemed wasteful and was also causing the filter type select to re-render after it had initially rendered with a selected value
- Firefox appears to have a bug where if a select's `<options>` list is re-rendered and that list contains `<optgroup>` elements then it loses the previous select value, reverting to the first `<option>` in the list
- switched to only fetching the products list once when the overall filter component is first rendered and used `peekAll('product')` so we always have a live count of the number of products in Ember Data's store without having to fetch anything
refs https://github.com/TryGhost/Team/issues/1390
- added `membersTimeFilters` feature flag and labs toggle
- added `<GhDatePicker>` component that lifts functionality from the `<GhDateTimePicker>` component
- `<GhDateTimePicker>` has not yet been refactored to use the new component internally as there are some odd/complex interactions with error handling with it's existing use-cases and they are in critical publishing paths so the refactor doesn't belong as part of this change
- added "Created at" filter type to members filters
- uses new date picker component for input value
- has "before", "on or before", "after", "on or after" operators
- "on" and "not on" operators were skipped as they require two NQL statements to represent, breaking the current 1:1 statement:filter approach used in the NQL-based query param parsing
refs: https://github.com/TryGhost/Team/issues/1376
- renamed finishing touches file to done
- no last modal, just the done screen for first start
- added options for next steps
No issue
- Changed the Member details page to be more scalable and flexible, depending on whether creators are using subscriptions, emails, and stats.
* Hidden email stats on member detail page when subscriptions are off
* Hid subscription box on member details page when Stripe is not connected
* Updated copy and layout of member details page
* Updated old activity feed styles on member page
* Fixed padding issue for empty activity feed
* Fixed current and new activity feed
* Added Last seen to member details page behind feature flag
* Updated lint todo file
* Fixed spacing issue in member details
no issue
- a new member has no `id` but we were passing the empty value through to the members event fetcher resulting in a query that fetches all events
- extracted the empty state of the member activity feed to a separate component so we could use it in multiple places
- added a conditional around the main activity feed template to shortcut it when a new member is passed in
closes https://github.com/TryGhost/Team/issues/1029
- allows site owner to filter members on specific tier
- needs tiers beta flag enabled and site should have more than 1 paid tiers.
refs https://github.com/TryGhost/Team/issues/1029
- `?include` query in API needs to be transformed from camel case to snake case
- the transformation was missing for building query in relationship adapter, causing incorrect camel-case `?include` in api like `emailRecipients` instead of `email_recipients`
refs https://github.com/TryGhost/Team/issues/1393
- This prevents the `last_seen_at` from being sent to the API
- In the future the API will accept this property, this is a temporary fix
no issue
- updated the selection of available filter properties to remove any with the "Email" group when the default email recipients setting is set to "disabled"
closes https://github.com/TryGhost/Team/issues/1388
- added `lastSeenAtUTC` property to member model
- added `last_seen_at` filter column handling to `<GhMembersListItemColumn>`
- uses same format as the "Created" column showing the date only and a "days ago" string
refs https://github.com/TryGhost/Team/issues/1388
refs https://github.com/TryGhost/Team/issues/1337
- when filtering the members table, extra columns are shown to make any filtered data visible but we didn't have any tests for the functionality
- updated the `filterColumnLabels` getter to return an object with the original filter type name and the display label so it's easier to use test selectors
closes https://github.com/TryGhost/Team/issues/1384
- when setting the filter type, change the filter's relation/operator to match the filter type's first operator so the filter string and the UI are in sync
closes https://github.com/TryGhost/Team/issues/1307
- adds "Last seen more/less than x days ago" option to members filtering UI
- re-ordered a few related objects/arrays so they are consistent
refs https://github.com/TryGhost/Ghost/issues/14101
Applied scout rule to fix linter errors when touching a file.
- added local `updateProperty` and `validateProperty` methods to remove use of `target=`
- our validation implementation does not properly bind `this` so direct usage of `this.integration.validate` fails
- added `on-input` argument support to our `TextInput` mixin so we we're not overwriting the native event handlers on classic input components
closes https://github.com/TryGhost/Ghost/pull/14183
refs 3ee0c3ff53
- unskipped test for integration saving
- fixed missed rename from `save` to `saveTask`
- fixed `saveTask` throwing from a "handled" validation error
closes https://github.com/TryGhost/Team/issues/1381
refs 21b4b15a1c
- when the email newsletter settings was refactored, the `emailTrackOpens: reads('settings.emailTrackOpens')` was removed as it's a confusing redirection but it's usage in the toggle action was missed
refs https://github.com/TryGhost/Team/issues/1358
- added acceptance tests for members settings screen
- subscription access management
- default post access management
- free tier management
- fixed `enableLabsFlag()` test helper overwriting existing flag settings when enabling another one
- updated API mocks and fixtures
- matched product fixtures to default tiers-enabled products
- updated product API mocks to include benefit handling
closes https://github.com/TryGhost/Team/issues/1309
closes https://github.com/TryGhost/Team/issues/1336
- the error occurred because the `<Members::FilterValue>` component detaches it's value from the passed in value it was initialized with. Due to the detached handling, after changing the filter type away from the default label filter to a text input based filter, the internal value stayed as `[]` even though the filter type's value was changed. When the blur event was triggered in that state the internal `[]` value was used to update the filter resulting in an invalid filter string
- added a quick-fix of assigning the input's value in the blur event handler meaning we get the expected `''` value
- allows for passing tests to be created ready for a deeper fix/refactor later
- added `nql` dependency and used it in the `GET /members` API mock to match members against the filter param so behaviour matches the real API
- tested increase in code size - dev build increased by ~180KB, no difference in prod
- added acceptance tests for all current filters and search
refs: https://github.com/TryGhost/Team/issues/1373
- added some additional styles to dropdown to better handle names and emails together
- widened the search box to better fit names and emails
refs https://github.com/TryGhost/Team/issues/1336
refs bf9bbc3aa6
- adds basic search param handling to `GET /members` API mock
- adds acceptance tests for basic search behaviour
- contains regression check for search input not being visible when no members match
closes https://github.com/TryGhost/Team/issues/1320
- added `@allowEdit` argument to `<GhMemberLabelInput>` and changed the dropdown to only show the edit label when `@allowEdit` is truthy
- updated usage in the filter UI and members detail screens to allow editing
refs https://github.com/TryGhost/Team/issues/1320
- added a tracked `labels` property in `<ModalImportMembers::CsvFileMapping>` and passed it through to `<GhMembersLabelInput>` so that it has a list of labels that can be added to
- fixed error from sorting labels if one doesn't have a name
- added acceptance test for selecting labels in the members import flow
refs https://github.com/TryGhost/Team/issues/1320
- fixed event handling in `gh-file-input` for test-initiated uploads
- added `POST /members/upload/` API mock that emulates uploading a single member
- it's enough for this particular test and can be expanded as needed
- added acceptance test that does a simple 1-member, no Stripe, CSV upload with no mapping changes
refs https://github.com/TryGhost/Team/issues/1320
- start of acceptance tests ready for more detailed testing
- added ignore of `no-duplicate-landmark-elements` lint rule in import modal template
- the rule was a false flag because the conditionals only allow one `<header>` element to be rendered at a time
No ref
- When memberships are set up but no members are present, we would display the email sending UI in a disabled state. We're now notifying the user why they can't send emails and how to start sending
Refs 72d3d6debc
- Fixed PSM error by moving the action on to the button and change the styling so the button is the main styled element that fills the whole area
- Hid the post-list-item error, which will warn in 30 and error in 60 days
refs 8052166cbe
- when migrating the bulk delete logic to a new modal the `isTesting` property was missed meaning test runs were triggering actual downloads, littering your downloads folder with repeated CSV files
no issue
- our API always returns an array whether we're performing a browse or find request but Ember Data expects explicit find requests to return a single object and throws deprecations when it sees an array
- https://deprecations.emberjs.com/ember-data/v2.x/#toc_store-queryrecord-array-response-with-restserializer
- we previously had `normalizeSingleResponse` overrides in specific models that we use with `queryRecord` but we've since introduced `queryRecord` usage on more models but the associated "fix" was not duplicated in the serializers for those models leading to many deprecation warnings logged to the console in development and when testing
- moved the fix to the application serializer so it applies to all models
- explicitly excluded `setting` model because that's a special-case and has it's own array-into-object serialization to represent multiple settings records as a single model instance
refs https://github.com/TryGhost/Ghost/issues/14101
refs https://github.com/TryGhost/Admin/pull/2256
Before migrating to native classes we had a number of controllers/components that had an `.actions.foo` action and a `.foo` task. The automated migration to native classes didn't take that into account and we've ended up with duplicate top-level property names. These duplicates are confusing and can potentially lead to errors or unexpected behaviour, they'll also be flagged as linter errors when we bump our eslint version.
- switched tasks with matching action names to `.actionTask` naming scheme
refs https://github.com/TryGhost/Team/issues/559
Members controller was becoming bloated and difficult to follow due to catering for many different concerns.
- converted old modal to newer promise-modal style
- pulled full bulk unsubscribing logic out of the members controller and into the modal so logic is contained in one place
refs https://github.com/TryGhost/Team/issues/559
Members controller was becoming bloated and difficult to follow due to catering for many different concerns.
- converted old modal to newer promise-modal style
- pulled full label-removing logic out of the members controller and into the modal so logic is contained in one place
refs https://github.com/TryGhost/Team/issues/559
Members controller was becoming bloated and difficult to follow due to catering for many different concerns.
- converted old modal to newer promise-modal style
- pulled full label-removing logic out of the members controller and into the modal so logic is contained in one place
no issue
- left-over from earlier iterations
- adding a new label whilst filtering will be added back in so we don't want to confuse things with similar-but-unused code
refs https://github.com/TryGhost/Team/issues/559
Members controller was becoming bloated and difficult to follow due to catering for many different concerns.
- converted old modal to newer promise-modal style
- pulled full label-adding logic out of the members controller and into the modal so logic is contained in one place
- added `{{members-count-fetcher}}` resource that allows for member counts to be fetched directly from templates avoiding duplicated code
no issue
- routes no longer automatically trigger save for cmd+s, it should be explicitly tied to the action that should be performed
- added `{{on-key "cmd+s"}}` to the `<GhTaskButton>` save buttons
- `{{on-key}}` with no explicit action triggers a click action on the attached element, in this case the screen's save buttons
no issue
- since `ember-concurrency@2.0` it's possible to use the standard imports as decorators removing the need for the extra `ember-concurrency-decorators` dependency and imports
refs https://github.com/TryGhost/Team/issues/1309
General cleanup to switch to more modern idioms.
- removed unnecessary assignment of properties in component's `constructor`
- dropped use of `EmberObject`, use an explicitly defined `Filter` class instead
- marked properties that change as `@tracked`
- switched to direct property setting with `=` instead of `.set()`
refs https://github.com/TryGhost/Team/issues/1319
Due to how JS implements numbers, it's possible that when we multiple a
number with 2 decimal places by 100 that we do not end up with an
integer e.g. 9.95 * 100 = 994.999...
This is not a valid price for the API and so we must round it to the
nearest integer. Rounding is safe here, because the errors involved in
floating point operations are very small.
refs https://github.com/TryGhost/Ghost/issues/14101
- dropped use of unnecessary `<GhTextInput>` component
- switched action calls over to standard `{{on "event"}}` rather than the sometimes error-prone overriding of EmberObject component event handlers
no issue
- currently the components are screen-specific rather than generalised so shouldn't have the `gh-` prefix
- fixed linter error for confusing `{{#unless}}...{{else}}` usage
no issue
- the members filtering is out of labs, we don't need to keep the labs component naming around
- renamed `-labs` components/classes to non-labs naming, replacing old and unused non-labs components where necessary
closes https://github.com/TryGhost/Team/issues/1318
The `{{if this.members.length "" "hidden"}}` class meant that whenever loading occurred the search input was briefly changed to `display: none` which caused focus to be lost making searching rather painful. It also meant the search input disappeared completely when no members matched a search.
- switched to a standard `<input>` element to get better event handling ergonomics
- added `searchIsFocused` tracked property that is set to `true` any time the search input has focus - works around an unexpected re-render when clearing the search input whilst it has focus
- switched the "hide" conditional to a getter that takes members length, search param text, and search input focus into account so there are no unexpected hides of the search bar
no issue
- the reset button was only clearing the `filter` param rather than resetting all query params
- removed unnecessary `searchText` indirection, the search input can work directly with the query param
refs https://github.com/TryGhost/Ghost/issues/14101
- extracted the ratio zoom handling to a `{{ratio-zoom}}` modifier to clean up the component and avoid needing lifecycle hooks that don't exist in Glimmer components
- disabled `no-nested-interactive` linting in the template - not ideal but we'd need a much bigger design refactor to eliminate the nested links
refs https://github.com/TryGhost/Ghost/issues/14101
- swapped use of `<LiquidWormhole>` to `{{#in-element}}` because we weren't animating anything
- we can now use `{{css-transition}}` instead if we want to animate in the future
- swapped use of `ShortcutsMixin` for ember-keyboard's `{{on-key}}` modifier
- added `{{query-selector}}` helper so we can grab an element from inside the template rather than requiring a backing component function (used to pass the wormhole element to `{{#in-element}}`)
- added `{{on-resize}}` modifier so the `resizeDetector` service can be used directly from the template rather than requiring a backing component to wait for render and use query selectors to grab an element
no issue
- shows an unsplash button when no image is present, opening the full unsplash selector when clicked
- behind the `improvedOnboarding` labs flag
closes https://github.com/TryGhost/Team/issues/1294
- ensures latest member activity is shown when improvedOnboarding feature is enabled no matter what the `editorIsLaunchComplete` value is to better show what the dashboard will look like when the launch wizard is removed
no issue
- softens the disappearance by fading out and collapsing the height when removing
- uses `{{css-transition}}` modifier from https://peec.github.io/ember-css-transitions/docs/insert-destroy
- max-height used in order to animate collapse of a `height: auto` panel, 350px starting point chosen as it's slightly bigger than the largest height of the panel at mobile widths
closes https://github.com/TryGhost/Team/issues/1310
- added `/setup/finishing-touches` route
- refreshes theme preview on access
- uses existing setting form components to build a reduced settings menu
- updated `/?firstStart=true` handling to transition to `/setup/finishing-touches` instead of showing the get-started modal
- updated standard setup flow to show the get-started modal upon completion
- `/?firstStart=true` flow for now will only be used when a theme has been chosen before site creation
refs https://github.com/TryGhost/Team/issues/1310
We want to use parts of the "Brand setting" form in a separate streamlined settings screen after site setup but that wasn't possible without a lot of duplication.
- extracted individual form fields into separate components for re-use
- included minor refactors like using `uploader.registerFileInput` and `uploader.triggerFileDialog` instead of continually duplicating the same file input trigger method
- fixed accessibility issues
- changed input titles from `<div>` to `<label>` and associated with the component's input fields
- changed `<img {{on "click" upload}}>` to `<input type="image">` so they act as proper buttons and are linked to the label (required a styling change so `img` and `input[type="image"]` are treated equally)
- finished cleanup of `.description-container-labs` by renaming to `.description-container`
refs https://github.com/TryGhost/Team/issues/1071
Default content visibility for specific tiers is now stored across 2 settings - `tiers` on `default_content_visibility` and list of tier ids on `default_content_visibility_tiers` setting, which is consistent with pattern of storing visibility on posts. This change -
- updates visibility filter UI for default content visibility segment select
- cleans up common visibility segment select component to handle ids directly instead of nql segments
- updates setting model
refs https://github.com/TryGhost/Team/issues/1310
- we had a `<GhBrowserPreview>` component but it wasn't being used everywhere because it's behaviour didn't match the mobile/desktop switch with no iframe re-render that we needed for some screens
- updated component to match all required behaviour
- include a switch between desktop and mobile views
- default fallbacks for `@title` and `@icon` arguments
- switched design settings themes over to using the component instead of repeating the same set of markup
refs https://github.com/TryGhost/Admin/pull/2227
A continuation of #2227 that runs the native classes codemod against app/serializers.
Most of the serializers that are trying to be transformed are failing with the same issue:
```
Validation errors:
[attrs]: Transform not supported - value is of type object. For more details: eslint-plugin-ember/avoid-leaking-state-in-ember-objects
2022-02-02T05:54:58.571Z [warn] [app/serializers/role.js]: FAILURE
```
refs https://github.com/TryGhost/Admin/pull/2238
Follow up to #2238, this should remove the existing no-implicit-this lint errors and any new violations should be flagged right away.
* run the no-implicit-this codemod
* updated todos
no issue
- This will help with the octane migration and you can still run the lint rules even when they are todos. (Checkout the docs at 158b119667/docs/todos.md) The good news is any new code will be checked against the recommended config.
- I fixed all the auto fixable things we could get in this PR as well
refs https://github.com/TryGhost/Team/issues/1303
- added rudimentary styling to the new onboarding modal
- added in three new icons to go with the new modal
- added the styling to the main.css for the moment
refs https://github.com/TryGhost/Team/issues/1252
- on stripe disconnect, the prices on tiers are deleted, which causes the archive/unarchive on them to fail in admin
- this change removes the archive/activate option for such tiers, which will get properly cleaned up once we start removing tiers on stripe disconnect
refs https://github.com/TryGhost/Team/issues/1252
- enables available tiers list for portal in case of a single tier as well, which was previously hidden
- allows site owners to enable a tier again for Portal if it was archived in past
no refs
- in an edge-case scenario, if an offer is using a tier with missing price, it will not throw an error because of lack of price
- this case will be auto-handled once we delete all existing offers in future on stripe disconnect
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
refs: https://github.com/TryGhost/Team/issues/1277
- added a z-index to fix breadcrumbs when filters overlap
- made the scrolling list longer on the member activity page to remove gap
refs https://github.com/TryGhost/Admin/pull/2227
- in the switch to native class syntax the `super()` calls for click handlers in the `<GhDropdown>` and `<GhDropdownButton>` components were lost, meaning the event propagation was not cancelled by the DropdownMixin's `click()` handler resulting in the click-to-open being immediately undone by the body click-to-close
no issue
- if a member has no name when they are selected on the member activity screen we weren't showing anything in the header breadcrumbs or member filter
- switched to showing name or email
no issue
- ran [ember-native-class-codemod](https://github.com/ember-codemods/ember-native-class-codemod) to convert the majority of remaining EmberObject based controllers and components to native class syntax using the `@classic` decorator
- skipped older style modal components (`components/modal-*.js`) due to observed incompatibilities in some cases
refs TryGhost/Team#1071
Specific tier visibility for a post was previously stored in `visibility` column directly, which had a limitation of 50 charts. Going forward, for the specific tiers visibility of post/page, we use `tiers` array in API that contains list of tiers with access for post. This change -
- replaces `filter` type to `tiers` for visibility
- adds new visibility filter segment component in post settings menu which stores array of tiers instead of nql string for visibility
- updates serializer and model for post/page
- updates tests
refs https://github.com/TryGhost/Team/issues/1252
- allows site owners to (un)archive existing tiers via Admin UI
- adds option to switch between archived or active tiers view
Co-authored-by: Djordje Vlaisavljevic <dzvlais@gmail.com>
refs https://github.com/TryGhost/Team/issues/1294
- added `dashboardHideGettingStarted` feature flag that uses the `user.accessibility` JSON blob
- added `{{toggle-feature}}` helper which returns a function that can be used with the `{{on}}` helper to toggle a feature flag on or off from templates
- hooked up the dismiss behaviour for the dashboard widget using the `toggle-feature` helper
- hid the dashboard when `dashboardHideGettingStarted` feature is enabled