diff options
Diffstat (limited to 'app/assets/javascripts/feature_flags')
-rw-r--r-- | app/assets/javascripts/feature_flags/components/empty_state.vue (renamed from app/assets/javascripts/feature_flags/components/feature_flags_tab.vue) | 23 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/components/feature_flags.vue | 246 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/components/user_lists_table.vue | 125 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/constants.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/index.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/store/index/actions.js | 34 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/store/index/mutation_types.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/store/index/mutations.js | 54 | ||||
-rw-r--r-- | app/assets/javascripts/feature_flags/store/index/state.js | 9 |
9 files changed, 102 insertions, 403 deletions
diff --git a/app/assets/javascripts/feature_flags/components/feature_flags_tab.vue b/app/assets/javascripts/feature_flags/components/empty_state.vue index d0df00e446b..a6de4972bb1 100644 --- a/app/assets/javascripts/feature_flags/components/feature_flags_tab.vue +++ b/app/assets/javascripts/feature_flags/components/empty_state.vue @@ -1,14 +1,10 @@ <script> -import { GlAlert, GlBadge, GlEmptyState, GlLink, GlLoadingIcon, GlTab } from '@gitlab/ui'; +import { GlAlert, GlEmptyState, GlLink, GlLoadingIcon } from '@gitlab/ui'; export default { - components: { GlAlert, GlBadge, GlEmptyState, GlLink, GlLoadingIcon, GlTab }, + components: { GlAlert, GlEmptyState, GlLink, GlLoadingIcon }, inject: ['errorStateSvgPath', 'featureFlagsHelpPagePath'], props: { - title: { - required: true, - type: String, - }, count: { required: false, type: Number, @@ -56,18 +52,11 @@ export default { clearAlert(index) { this.$emit('dismissAlert', index); }, - onClick(event) { - return this.$emit('changeTab', event); - }, }, }; </script> <template> - <gl-tab @click="onClick"> - <template #title> - <span data-testid="feature-flags-tab-title">{{ title }}</span> - <gl-badge size="sm" class="gl-tab-counter-badge">{{ itemCount }}</gl-badge> - </template> + <div> <gl-alert v-for="(message, index) in alerts" :key="index" @@ -83,7 +72,7 @@ export default { <gl-empty-state v-else-if="errorState" :title="errorTitle" - :description="s__(`FeatureFlags|Try again in a few moments or contact your support team.`)" + :description="s__('FeatureFlags|Try again in a few moments or contact your support team.')" :svg-path="errorStateSvgPath" data-testid="error-state" /> @@ -101,6 +90,6 @@ export default { </gl-link> </template> </gl-empty-state> - <slot> </slot> - </gl-tab> + <slot v-else> </slot> + </div> </template> diff --git a/app/assets/javascripts/feature_flags/components/feature_flags.vue b/app/assets/javascripts/feature_flags/components/feature_flags.vue index 9aa1accb0f2..d08e8d2b3a1 100644 --- a/app/assets/javascripts/feature_flags/components/feature_flags.vue +++ b/app/assets/javascripts/feature_flags/components/feature_flags.vue @@ -1,5 +1,5 @@ <script> -import { GlAlert, GlButton, GlModalDirective, GlSprintf, GlTabs } from '@gitlab/ui'; +import { GlAlert, GlBadge, GlButton, GlModalDirective, GlSprintf } from '@gitlab/ui'; import { isEmpty } from 'lodash'; import { mapState, mapActions } from 'vuex'; @@ -9,50 +9,40 @@ import { historyPushState, } from '~/lib/utils/common_utils'; import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue'; -import { FEATURE_FLAG_SCOPE, USER_LIST_SCOPE } from '../constants'; import ConfigureFeatureFlagsModal from './configure_feature_flags_modal.vue'; -import FeatureFlagsTab from './feature_flags_tab.vue'; +import EmptyState from './empty_state.vue'; import FeatureFlagsTable from './feature_flags_table.vue'; -import UserListsTable from './user_lists_table.vue'; - -const SCOPES = { FEATURE_FLAG_SCOPE, USER_LIST_SCOPE }; export default { components: { ConfigureFeatureFlagsModal, - FeatureFlagsTab, + EmptyState, FeatureFlagsTable, GlAlert, + GlBadge, GlButton, GlSprintf, - GlTabs, TablePagination, - UserListsTable, }, directives: { GlModal: GlModalDirective, }, inject: { - newUserListPath: { default: '' }, + userListPath: { default: '' }, newFeatureFlagPath: { default: '' }, canUserConfigure: {}, featureFlagsLimitExceeded: {}, featureFlagsLimit: {}, }, data() { - const scope = getParameterByName('scope') || SCOPES.FEATURE_FLAG_SCOPE; return { - scope, page: getParameterByName('page') || '1', - isUserListAlertDismissed: false, shouldShowFeatureFlagsLimitWarning: this.featureFlagsLimitExceeded, - selectedTab: Object.values(SCOPES).indexOf(scope), }; }, computed: { ...mapState([ - FEATURE_FLAG_SCOPE, - USER_LIST_SCOPE, + 'featureFlags', 'alerts', 'count', 'pageInfo', @@ -69,64 +59,41 @@ export default { canUserRotateToken() { return this.rotateInstanceIdPath !== ''; }, - currentlyDisplayedData() { - return this.dataForScope(this.scope); - }, shouldRenderPagination() { return ( !this.isLoading && !this.hasError && - this.currentlyDisplayedData.length > 0 && - this.pageInfo[this.scope].total > this.pageInfo[this.scope].perPage + this.featureFlags.length > 0 && + this.pageInfo.total > this.pageInfo.perPage ); }, shouldShowEmptyState() { - return !this.isLoading && !this.hasError && this.currentlyDisplayedData.length === 0; + return !this.isLoading && !this.hasError && this.featureFlags.length === 0; }, shouldRenderErrorState() { return this.hasError && !this.isLoading; }, shouldRenderFeatureFlags() { - return this.shouldRenderTable(SCOPES.FEATURE_FLAG_SCOPE); - }, - shouldRenderUserLists() { - return this.shouldRenderTable(SCOPES.USER_LIST_SCOPE); + return !this.isLoading && this.featureFlags.length > 0 && !this.hasError; }, hasNewPath() { return !isEmpty(this.newFeatureFlagPath); }, }, created() { - this.setFeatureFlagsOptions({ scope: this.scope, page: this.page }); + this.setFeatureFlagsOptions({ page: this.page }); this.fetchFeatureFlags(); - this.fetchUserLists(); }, methods: { ...mapActions([ 'setFeatureFlagsOptions', 'fetchFeatureFlags', - 'fetchUserLists', 'rotateInstanceId', 'toggleFeatureFlag', - 'deleteUserList', 'clearAlert', ]), - onChangeTab(scope) { - this.scope = scope; - this.updateFeatureFlagOptions({ - scope, - page: '1', - }); - }, - onFeatureFlagsTab() { - this.onChangeTab(SCOPES.FEATURE_FLAG_SCOPE); - }, - onUserListsTab() { - this.onChangeTab(SCOPES.USER_LIST_SCOPE); - }, onChangePage(page) { this.updateFeatureFlagOptions({ - scope: this.scope, /* URLS parameters are strings, we need to parse to match types */ page: Number(page).toString(), }); @@ -141,22 +108,7 @@ export default { historyPushState(buildUrlWithCurrentLocation(`?${queryString}`)); this.setFeatureFlagsOptions(parameters); - if (this.scope === SCOPES.FEATURE_FLAG_SCOPE) { - this.fetchFeatureFlags(); - } else { - this.fetchUserLists(); - } - }, - shouldRenderTable(scope) { - return ( - !this.isLoading && - this.dataForScope(scope).length > 0 && - !this.hasError && - this.scope === scope - ); - }, - dataForScope(scope) { - return this[scope]; + this.fetchFeatureFlags(); }, onDismissFeatureFlagsLimitWarning() { this.shouldShowFeatureFlagsLimitWarning = false; @@ -200,6 +152,16 @@ export default { <div :class="topAreaBaseClasses"> <div class="gl-display-flex gl-flex-direction-column gl-md-display-none!"> <gl-button + v-if="userListPath" + :href="userListPath" + variant="confirm" + category="tertiary" + class="gl-mb-3" + data-testid="ff-new-list-button" + > + {{ s__('FeatureFlags|View user lists') }} + </gl-button> + <gl-button v-if="canUserConfigure" v-gl-modal="'configure-feature-flags'" variant="info" @@ -212,17 +174,6 @@ export default { </gl-button> <gl-button - v-if="newUserListPath" - :href="newUserListPath" - variant="confirm" - category="secondary" - class="gl-mb-3" - data-testid="ff-new-list-button" - > - {{ s__('FeatureFlags|New user list') }} - </gl-button> - - <gl-button v-if="hasNewPath" :href="featureFlagsLimitExceeded ? '' : newFeatureFlagPath" variant="confirm" @@ -232,101 +183,70 @@ export default { {{ s__('FeatureFlags|New feature flag') }} </gl-button> </div> - <gl-tabs v-model="selectedTab" class="gl-align-items-center gl-w-full"> - <feature-flags-tab - :title="s__('FeatureFlags|Feature Flags')" - :count="count.featureFlags" - :alerts="alerts" - :is-loading="isLoading" - :loading-label="s__('FeatureFlags|Loading feature flags')" - :error-state="shouldRenderErrorState" - :error-title="s__(`FeatureFlags|There was an error fetching the feature flags.`)" - :empty-state="shouldShowEmptyState" - :empty-title="s__('FeatureFlags|Get started with feature flags')" - :empty-description=" - s__( - 'FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality.', - ) - " - data-testid="feature-flags-tab" - @dismissAlert="clearAlert" - @changeTab="onFeatureFlagsTab" - > - <feature-flags-table - v-if="shouldRenderFeatureFlags" - :feature-flags="featureFlags" - @toggle-flag="toggleFeatureFlag" - /> - </feature-flags-tab> - <feature-flags-tab - :title="s__('FeatureFlags|User Lists')" - :count="count.userLists" - :alerts="alerts" - :is-loading="isLoading" - :loading-label="s__('FeatureFlags|Loading user lists')" - :error-state="shouldRenderErrorState" - :error-title="s__(`FeatureFlags|There was an error fetching the user lists.`)" - :empty-state="shouldShowEmptyState" - :empty-title="s__('FeatureFlags|Get started with user lists')" - :empty-description=" - s__( - 'FeatureFlags|User lists allow you to define a set of users to use with Feature Flags.', - ) - " - data-testid="user-lists-tab" - @dismissAlert="clearAlert" - @changeTab="onUserListsTab" + <div + class="gl-display-flex gl-align-items-baseline gl-flex-direction-row gl-justify-content-space-between gl-mt-6" + > + <div class="gl-display-flex gl-align-items-center"> + <h2 data-testid="feature-flags-tab-title" class="gl-font-size-h2 gl-my-0"> + {{ s__('FeatureFlags|Feature Flags') }} + </h2> + <gl-badge v-if="count" class="gl-ml-4">{{ count }}</gl-badge> + </div> + <div + class="gl-display-none gl-md-display-flex gl-align-items-center gl-justify-content-end" > - <user-lists-table - v-if="shouldRenderUserLists" - :user-lists="userLists" - @delete="deleteUserList" - /> - </feature-flags-tab> - <template #tabs-end> - <li - class="gl-display-none gl-md-display-flex gl-align-items-center gl-flex-fill-1 gl-justify-content-end" + <gl-button + v-if="userListPath" + :href="userListPath" + variant="confirm" + category="tertiary" + class="gl-mb-0 gl-mr-4" + data-testid="ff-user-list-button" > - <gl-button - v-if="canUserConfigure" - v-gl-modal="'configure-feature-flags'" - variant="info" - category="secondary" - data-qa-selector="configure_feature_flags_button" - data-testid="ff-configure-button" - class="gl-mb-0 gl-mr-4" - > - {{ s__('FeatureFlags|Configure') }} - </gl-button> - - <gl-button - v-if="newUserListPath" - :href="newUserListPath" - variant="confirm" - category="secondary" - class="gl-mb-0 gl-mr-4" - data-testid="ff-new-list-button" - > - {{ s__('FeatureFlags|New user list') }} - </gl-button> + {{ s__('FeatureFlags|View user lists') }} + </gl-button> + <gl-button + v-if="canUserConfigure" + v-gl-modal="'configure-feature-flags'" + variant="info" + category="secondary" + data-qa-selector="configure_feature_flags_button" + data-testid="ff-configure-button" + class="gl-mb-0 gl-mr-4" + > + {{ s__('FeatureFlags|Configure') }} + </gl-button> - <gl-button - v-if="hasNewPath" - :href="featureFlagsLimitExceeded ? '' : newFeatureFlagPath" - variant="confirm" - data-testid="ff-new-button" - @click="onNewFeatureFlagCLick" - > - {{ s__('FeatureFlags|New feature flag') }} - </gl-button> - </li> - </template> - </gl-tabs> + <gl-button + v-if="hasNewPath" + :href="featureFlagsLimitExceeded ? '' : newFeatureFlagPath" + variant="confirm" + data-testid="ff-new-button" + @click="onNewFeatureFlagCLick" + > + {{ s__('FeatureFlags|New feature flag') }} + </gl-button> + </div> + </div> + <empty-state + :alerts="alerts" + :is-loading="isLoading" + :loading-label="s__('FeatureFlags|Loading feature flags')" + :error-state="shouldRenderErrorState" + :error-title="s__(`FeatureFlags|There was an error fetching the feature flags.`)" + :empty-state="shouldShowEmptyState" + :empty-title="s__('FeatureFlags|Get started with feature flags')" + :empty-description=" + s__( + 'FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality.', + ) + " + data-testid="feature-flags-tab" + @dismissAlert="clearAlert" + > + <feature-flags-table :feature-flags="featureFlags" @toggle-flag="toggleFeatureFlag" /> + </empty-state> </div> - <table-pagination - v-if="shouldRenderPagination" - :change="onChangePage" - :page-info="pageInfo[scope]" - /> + <table-pagination v-if="shouldRenderPagination" :change="onChangePage" :page-info="pageInfo" /> </div> </template> diff --git a/app/assets/javascripts/feature_flags/components/user_lists_table.vue b/app/assets/javascripts/feature_flags/components/user_lists_table.vue deleted file mode 100644 index 765f59228a6..00000000000 --- a/app/assets/javascripts/feature_flags/components/user_lists_table.vue +++ /dev/null @@ -1,125 +0,0 @@ -<script> -import { - GlButton, - GlButtonGroup, - GlModal, - GlSprintf, - GlTooltipDirective, - GlModalDirective, -} from '@gitlab/ui'; -import { __, s__, sprintf } from '~/locale'; -import timeagoMixin from '~/vue_shared/mixins/timeago'; - -export default { - components: { GlButton, GlButtonGroup, GlModal, GlSprintf }, - directives: { GlTooltip: GlTooltipDirective, GlModal: GlModalDirective }, - mixins: [timeagoMixin], - props: { - userLists: { - type: Array, - required: true, - }, - }, - translations: { - createdTimeagoLabel: s__('UserList|created %{timeago}'), - deleteListTitle: s__('UserList|Delete %{name}?'), - deleteListMessage: s__('User list %{name} will be removed. Are you sure?'), - editUserListLabel: s__('FeatureFlags|Edit User List'), - }, - modal: { - id: 'deleteListModal', - actionPrimary: { - text: __('Delete user list'), - attributes: { variant: 'danger', 'data-testid': 'modal-confirm' }, - }, - }, - data() { - return { - deleteUserList: null, - }; - }, - computed: { - deleteListName() { - return this.deleteUserList?.name; - }, - modalTitle() { - return sprintf(this.$options.translations.deleteListTitle, { - name: this.deleteListName, - }); - }, - }, - methods: { - createdTimeago(list) { - return sprintf(this.$options.translations.createdTimeagoLabel, { - timeago: this.timeFormatted(list.created_at), - }); - }, - displayList(list) { - return list.user_xids.replace(/,/g, ', '); - }, - onDelete() { - this.$emit('delete', this.deleteUserList); - }, - confirmDeleteList(list) { - this.deleteUserList = list; - }, - }, -}; -</script> -<template> - <div> - <div - v-for="list in userLists" - :key="list.id" - data-testid="ffUserList" - class="gl-border-b-solid gl-border-gray-100 gl-border-b-1 gl-w-full gl-py-4 gl-display-flex gl-justify-content-space-between" - > - <div class="gl-display-flex gl-flex-direction-column gl-overflow-hidden gl-flex-grow-1"> - <span data-testid="ffUserListName" class="gl-font-weight-bold gl-mb-2"> - {{ list.name }} - </span> - <span - v-gl-tooltip - :title="tooltipTitle(list.created_at)" - data-testid="ffUserListTimestamp" - class="gl-text-gray-300 gl-mb-2" - > - {{ createdTimeago(list) }} - </span> - <span data-testid="ffUserListIds" class="gl-str-truncated">{{ displayList(list) }}</span> - </div> - - <gl-button-group class="gl-align-self-start gl-mt-2"> - <gl-button - :href="list.path" - category="secondary" - icon="pencil" - :aria-label="$options.translations.editUserListLabel" - data-testid="edit-user-list" - /> - <gl-button - v-gl-modal="$options.modal.id" - category="secondary" - variant="danger" - icon="remove" - :aria-label="$options.modal.actionPrimary.text" - data-testid="delete-user-list" - @click="confirmDeleteList(list)" - /> - </gl-button-group> - </div> - <gl-modal - :title="modalTitle" - :modal-id="$options.modal.id" - :action-primary="$options.modal.actionPrimary" - static - @primary="onDelete" - > - <gl-sprintf :message="$options.translations.deleteListMessage"> - <template #name> - <b>{{ deleteListName }}</b> - </template> - </gl-sprintf> - </gl-modal> - </div> -</template> diff --git a/app/assets/javascripts/feature_flags/constants.js b/app/assets/javascripts/feature_flags/constants.js index 658984456a5..f697f203cf5 100644 --- a/app/assets/javascripts/feature_flags/constants.js +++ b/app/assets/javascripts/feature_flags/constants.js @@ -21,9 +21,6 @@ export const fetchUserIdParams = property(['parameters', 'userIds']); export const NEW_VERSION_FLAG = 'new_version_flag'; export const LEGACY_FLAG = 'legacy_flag'; -export const FEATURE_FLAG_SCOPE = 'featureFlags'; -export const USER_LIST_SCOPE = 'userLists'; - export const EMPTY_PARAMETERS = { parameters: {}, userListId: undefined }; export const STRATEGY_SELECTIONS = [ diff --git a/app/assets/javascripts/feature_flags/index.js b/app/assets/javascripts/feature_flags/index.js index d2371a2aa8b..5c0d9cb8624 100644 --- a/app/assets/javascripts/feature_flags/index.js +++ b/app/assets/javascripts/feature_flags/index.js @@ -22,7 +22,7 @@ export default () => { unleashApiUrl, canUserAdminFeatureFlag, newFeatureFlagPath, - newUserListPath, + userListPath, featureFlagsLimitExceeded, featureFlagsLimit, } = el.dataset; @@ -40,9 +40,9 @@ export default () => { csrfToken: csrf.token, canUserConfigure: canUserAdminFeatureFlag !== undefined, newFeatureFlagPath, - newUserListPath, featureFlagsLimitExceeded: featureFlagsLimitExceeded !== undefined, featureFlagsLimit, + userListPath, }, render(createElement) { return createElement(FeatureFlagsComponent); diff --git a/app/assets/javascripts/feature_flags/store/index/actions.js b/app/assets/javascripts/feature_flags/store/index/actions.js index 4372c280f39..751f627ca48 100644 --- a/app/assets/javascripts/feature_flags/store/index/actions.js +++ b/app/assets/javascripts/feature_flags/store/index/actions.js @@ -1,4 +1,3 @@ -import Api from '~/api'; import axios from '~/lib/utils/axios_utils'; import * as types from './mutation_types'; @@ -26,19 +25,6 @@ export const receiveFeatureFlagsSuccess = ({ commit }, response) => commit(types.RECEIVE_FEATURE_FLAGS_SUCCESS, response); export const receiveFeatureFlagsError = ({ commit }) => commit(types.RECEIVE_FEATURE_FLAGS_ERROR); -export const fetchUserLists = ({ state, dispatch }) => { - dispatch('requestUserLists'); - - return Api.fetchFeatureFlagUserLists(state.projectId, state.options.page) - .then(({ data, headers }) => dispatch('receiveUserListsSuccess', { data, headers })) - .catch(() => dispatch('receiveUserListsError')); -}; - -export const requestUserLists = ({ commit }) => commit(types.REQUEST_USER_LISTS); -export const receiveUserListsSuccess = ({ commit }, response) => - commit(types.RECEIVE_USER_LISTS_SUCCESS, response); -export const receiveUserListsError = ({ commit }) => commit(types.RECEIVE_USER_LISTS_ERROR); - export const toggleFeatureFlag = ({ dispatch }, flag) => { dispatch('updateFeatureFlag', flag); @@ -57,26 +43,6 @@ export const receiveUpdateFeatureFlagSuccess = ({ commit }, data) => export const receiveUpdateFeatureFlagError = ({ commit }, id) => commit(types.RECEIVE_UPDATE_FEATURE_FLAG_ERROR, id); -export const deleteUserList = ({ state, dispatch }, list) => { - dispatch('requestDeleteUserList', list); - - return Api.deleteFeatureFlagUserList(state.projectId, list.iid) - .then(() => dispatch('fetchUserLists')) - .catch((error) => - dispatch('receiveDeleteUserListError', { - list, - error: error?.response?.data ?? error, - }), - ); -}; - -export const requestDeleteUserList = ({ commit }, list) => - commit(types.REQUEST_DELETE_USER_LIST, list); - -export const receiveDeleteUserListError = ({ commit }, { error, list }) => { - commit(types.RECEIVE_DELETE_USER_LIST_ERROR, { error, list }); -}; - export const rotateInstanceId = ({ state, dispatch }) => { dispatch('requestRotateInstanceId'); diff --git a/app/assets/javascripts/feature_flags/store/index/mutation_types.js b/app/assets/javascripts/feature_flags/store/index/mutation_types.js index 189c763782e..ed05294a6f3 100644 --- a/app/assets/javascripts/feature_flags/store/index/mutation_types.js +++ b/app/assets/javascripts/feature_flags/store/index/mutation_types.js @@ -4,13 +4,6 @@ export const REQUEST_FEATURE_FLAGS = 'REQUEST_FEATURE_FLAGS'; export const RECEIVE_FEATURE_FLAGS_SUCCESS = 'RECEIVE_FEATURE_FLAGS_SUCCESS'; export const RECEIVE_FEATURE_FLAGS_ERROR = 'RECEIVE_FEATURE_FLAGS_ERROR'; -export const REQUEST_USER_LISTS = 'REQUEST_USER_LISTS'; -export const RECEIVE_USER_LISTS_SUCCESS = 'RECEIVE_USER_LISTS_SUCCESS'; -export const RECEIVE_USER_LISTS_ERROR = 'RECEIVE_USER_LISTS_ERROR'; - -export const REQUEST_DELETE_USER_LIST = 'REQUEST_DELETE_USER_LIST'; -export const RECEIVE_DELETE_USER_LIST_ERROR = 'RECEIVE_DELETE_USER_LIST_ERROR'; - export const UPDATE_FEATURE_FLAG = 'UPDATE_FEATURE_FLAG'; export const RECEIVE_UPDATE_FEATURE_FLAG_SUCCESS = 'RECEIVE_UPDATE_FEATURE_FLAG_SUCCESS'; export const RECEIVE_UPDATE_FEATURE_FLAG_ERROR = 'RECEIVE_UPDATE_FEATURE_FLAG_ERROR'; diff --git a/app/assets/javascripts/feature_flags/store/index/mutations.js b/app/assets/javascripts/feature_flags/store/index/mutations.js index 25eb7da1c72..54e48a4b80c 100644 --- a/app/assets/javascripts/feature_flags/store/index/mutations.js +++ b/app/assets/javascripts/feature_flags/store/index/mutations.js @@ -1,17 +1,16 @@ import Vue from 'vue'; import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; -import { FEATURE_FLAG_SCOPE, USER_LIST_SCOPE } from '../../constants'; import { mapToScopesViewModel } from '../helpers'; import * as types from './mutation_types'; const mapFlag = (flag) => ({ ...flag, scopes: mapToScopesViewModel(flag.scopes || []) }); const updateFlag = (state, flag) => { - const index = state[FEATURE_FLAG_SCOPE].findIndex(({ id }) => id === flag.id); - Vue.set(state[FEATURE_FLAG_SCOPE], index, flag); + const index = state.featureFlags.findIndex(({ id }) => id === flag.id); + Vue.set(state.featureFlags, index, flag); }; -const createPaginationInfo = (state, headers) => { +const createPaginationInfo = (headers) => { let paginationInfo; if (Object.keys(headers).length) { const normalizedHeaders = normalizeHeaders(headers); @@ -32,44 +31,16 @@ export default { [types.RECEIVE_FEATURE_FLAGS_SUCCESS](state, response) { state.isLoading = false; state.hasError = false; - state[FEATURE_FLAG_SCOPE] = (response.data.feature_flags || []).map(mapFlag); + state.featureFlags = (response.data.feature_flags || []).map(mapFlag); - const paginationInfo = createPaginationInfo(state, response.headers); - state.count = { - ...state.count, - [FEATURE_FLAG_SCOPE]: paginationInfo?.total ?? state[FEATURE_FLAG_SCOPE].length, - }; - state.pageInfo = { - ...state.pageInfo, - [FEATURE_FLAG_SCOPE]: paginationInfo, - }; + const paginationInfo = createPaginationInfo(response.headers); + state.count = paginationInfo?.total ?? state.featureFlags.length; + state.pageInfo = paginationInfo; }, [types.RECEIVE_FEATURE_FLAGS_ERROR](state) { state.isLoading = false; state.hasError = true; }, - [types.REQUEST_USER_LISTS](state) { - state.isLoading = true; - }, - [types.RECEIVE_USER_LISTS_SUCCESS](state, response) { - state.isLoading = false; - state.hasError = false; - state[USER_LIST_SCOPE] = response.data || []; - - const paginationInfo = createPaginationInfo(state, response.headers); - state.count = { - ...state.count, - [USER_LIST_SCOPE]: paginationInfo?.total ?? state[USER_LIST_SCOPE].length, - }; - state.pageInfo = { - ...state.pageInfo, - [USER_LIST_SCOPE]: paginationInfo, - }; - }, - [types.RECEIVE_USER_LISTS_ERROR](state) { - state.isLoading = false; - state.hasError = true; - }, [types.REQUEST_ROTATE_INSTANCE_ID](state) { state.isRotating = true; state.hasRotateError = false; @@ -90,18 +61,9 @@ export default { updateFlag(state, mapFlag(data)); }, [types.RECEIVE_UPDATE_FEATURE_FLAG_ERROR](state, i) { - const flag = state[FEATURE_FLAG_SCOPE].find(({ id }) => i === id); + const flag = state.featureFlags.find(({ id }) => i === id); updateFlag(state, { ...flag, active: !flag.active }); }, - [types.REQUEST_DELETE_USER_LIST](state, list) { - state.userLists = state.userLists.filter((l) => l !== list); - }, - [types.RECEIVE_DELETE_USER_LIST_ERROR](state, { error, list }) { - state.isLoading = false; - state.hasError = false; - state.alerts = [].concat(error.message); - state.userLists = state.userLists.concat(list).sort((l1, l2) => l1.iid - l2.iid); - }, [types.RECEIVE_CLEAR_ALERT](state, index) { state.alerts.splice(index, 1); }, diff --git a/app/assets/javascripts/feature_flags/store/index/state.js b/app/assets/javascripts/feature_flags/store/index/state.js index f8439b02639..488da265b28 100644 --- a/app/assets/javascripts/feature_flags/store/index/state.js +++ b/app/assets/javascripts/feature_flags/store/index/state.js @@ -1,11 +1,8 @@ -import { FEATURE_FLAG_SCOPE, USER_LIST_SCOPE } from '../../constants'; - export default ({ endpoint, projectId, unleashApiInstanceId, rotateInstanceIdPath }) => ({ - [FEATURE_FLAG_SCOPE]: [], - [USER_LIST_SCOPE]: [], + featureFlags: [], alerts: [], - count: {}, - pageInfo: { [FEATURE_FLAG_SCOPE]: {}, [USER_LIST_SCOPE]: {} }, + count: 0, + pageInfo: {}, isLoading: true, hasError: false, endpoint, |