debian-mirror-gitlab/app/assets/javascripts/feature_flags/components/feature_flags.vue

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

252 lines
7.6 KiB
Vue
Raw Normal View History

2021-01-03 14:25:43 +05:30
<script>
2021-09-04 01:27:46 +05:30
import { GlAlert, GlBadge, GlButton, GlModalDirective, GlSprintf } from '@gitlab/ui';
2021-03-11 19:13:27 +05:30
import { isEmpty } from 'lodash';
import { mapState, mapActions } from 'vuex';
2021-01-03 14:25:43 +05:30
2021-09-30 23:02:18 +05:30
import { buildUrlWithCurrentLocation, historyPushState } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
2021-03-11 19:13:27 +05:30
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
2021-01-03 14:25:43 +05:30
import ConfigureFeatureFlagsModal from './configure_feature_flags_modal.vue';
2021-09-04 01:27:46 +05:30
import EmptyState from './empty_state.vue';
2021-03-11 19:13:27 +05:30
import FeatureFlagsTable from './feature_flags_table.vue';
2021-01-03 14:25:43 +05:30
export default {
components: {
ConfigureFeatureFlagsModal,
2021-09-04 01:27:46 +05:30
EmptyState,
2021-01-03 14:25:43 +05:30
FeatureFlagsTable,
GlAlert,
2021-09-04 01:27:46 +05:30
GlBadge,
2021-01-03 14:25:43 +05:30
GlButton,
GlSprintf,
TablePagination,
},
directives: {
GlModal: GlModalDirective,
},
inject: {
2021-09-04 01:27:46 +05:30
userListPath: { default: '' },
2021-01-03 14:25:43 +05:30
newFeatureFlagPath: { default: '' },
2021-06-08 01:23:25 +05:30
canUserConfigure: {},
featureFlagsLimitExceeded: {},
featureFlagsLimit: {},
2021-01-03 14:25:43 +05:30
},
data() {
return {
page: getParameterByName('page') || '1',
shouldShowFeatureFlagsLimitWarning: this.featureFlagsLimitExceeded,
};
},
computed: {
...mapState([
2021-09-04 01:27:46 +05:30
'featureFlags',
2021-01-03 14:25:43 +05:30
'alerts',
'count',
'pageInfo',
'isLoading',
'hasError',
'options',
'instanceId',
'isRotating',
'hasRotateError',
]),
topAreaBaseClasses() {
return ['gl-display-flex', 'gl-flex-direction-column'];
},
canUserRotateToken() {
return this.rotateInstanceIdPath !== '';
},
shouldRenderPagination() {
return (
!this.isLoading &&
!this.hasError &&
2021-09-04 01:27:46 +05:30
this.featureFlags.length > 0 &&
this.pageInfo.total > this.pageInfo.perPage
2021-01-03 14:25:43 +05:30
);
},
shouldShowEmptyState() {
2021-09-04 01:27:46 +05:30
return !this.isLoading && !this.hasError && this.featureFlags.length === 0;
2021-01-03 14:25:43 +05:30
},
shouldRenderErrorState() {
return this.hasError && !this.isLoading;
},
shouldRenderFeatureFlags() {
2021-09-04 01:27:46 +05:30
return !this.isLoading && this.featureFlags.length > 0 && !this.hasError;
2021-01-03 14:25:43 +05:30
},
hasNewPath() {
return !isEmpty(this.newFeatureFlagPath);
},
},
created() {
2021-09-04 01:27:46 +05:30
this.setFeatureFlagsOptions({ page: this.page });
2021-01-03 14:25:43 +05:30
this.fetchFeatureFlags();
},
methods: {
...mapActions([
'setFeatureFlagsOptions',
'fetchFeatureFlags',
'rotateInstanceId',
'toggleFeatureFlag',
'clearAlert',
]),
onChangePage(page) {
this.updateFeatureFlagOptions({
/* URLS parameters are strings, we need to parse to match types */
page: Number(page).toString(),
});
},
updateFeatureFlagOptions(parameters) {
const queryString = Object.keys(parameters)
2021-03-08 18:12:59 +05:30
.map((parameter) => {
2021-01-03 14:25:43 +05:30
const value = parameters[parameter];
return `${parameter}=${encodeURIComponent(value)}`;
})
.join('&');
historyPushState(buildUrlWithCurrentLocation(`?${queryString}`));
this.setFeatureFlagsOptions(parameters);
2021-09-04 01:27:46 +05:30
this.fetchFeatureFlags();
2021-01-03 14:25:43 +05:30
},
onDismissFeatureFlagsLimitWarning() {
this.shouldShowFeatureFlagsLimitWarning = false;
},
onNewFeatureFlagCLick() {
if (this.featureFlagsLimitExceeded) {
this.shouldShowFeatureFlagsLimitWarning = true;
}
},
},
};
</script>
<template>
<div>
<gl-alert
v-if="shouldShowFeatureFlagsLimitWarning"
variant="warning"
@dismiss="onDismissFeatureFlagsLimitWarning"
>
<gl-sprintf
:message="
s__(
'FeatureFlags|Feature flags limit reached (%{featureFlagsLimit}). Delete one or more feature flags before adding new ones.',
)
"
>
<template #featureFlagsLimit>
<span>{{ featureFlagsLimit }}</span>
</template>
</gl-sprintf>
</gl-alert>
<configure-feature-flags-modal
v-if="canUserConfigure"
:instance-id="instanceId"
:is-rotating="isRotating"
:has-rotate-error="hasRotateError"
:can-user-rotate-token="canUserRotateToken"
modal-id="configure-feature-flags"
@token="rotateInstanceId()"
/>
<div :class="topAreaBaseClasses">
2021-03-11 19:13:27 +05:30
<div class="gl-display-flex gl-flex-direction-column gl-md-display-none!">
2021-09-04 01:27:46 +05:30
<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>
2021-01-03 14:25:43 +05:30
<gl-button
v-if="canUserConfigure"
v-gl-modal="'configure-feature-flags'"
2022-07-23 23:45:48 +05:30
variant="confirm"
2021-01-03 14:25:43 +05:30
category="secondary"
data-testid="ff-configure-button"
class="gl-mb-3"
>
{{ s__('FeatureFlags|Configure') }}
</gl-button>
<gl-button
v-if="hasNewPath"
:href="featureFlagsLimitExceeded ? '' : newFeatureFlagPath"
2021-04-17 20:07:23 +05:30
variant="confirm"
2021-01-03 14:25:43 +05:30
data-testid="ff-new-button"
@click="onNewFeatureFlagCLick"
>
{{ s__('FeatureFlags|New feature flag') }}
</gl-button>
</div>
2021-09-04 01:27:46 +05:30
<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">
2022-07-23 23:45:48 +05:30
<h2
data-testid="feature-flags-tab-title"
class="page-title gl-font-size-h-display gl-my-0"
>
2023-06-20 00:43:36 +05:30
{{ s__('FeatureFlags|Feature flags') }}
2021-09-04 01:27:46 +05:30
</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"
2021-01-03 14:25:43 +05:30
>
2021-09-04 01:27:46 +05:30
<gl-button
v-if="userListPath"
:href="userListPath"
variant="confirm"
category="tertiary"
2022-07-23 23:45:48 +05:30
class="gl-mb-0 gl-mr-3"
2021-09-04 01:27:46 +05:30
data-testid="ff-user-list-button"
2021-01-03 14:25:43 +05:30
>
2021-09-04 01:27:46 +05:30
{{ s__('FeatureFlags|View user lists') }}
</gl-button>
<gl-button
v-if="canUserConfigure"
v-gl-modal="'configure-feature-flags'"
2022-07-23 23:45:48 +05:30
variant="confirm"
2021-09-04 01:27:46 +05:30
category="secondary"
data-qa-selector="configure_feature_flags_button"
data-testid="ff-configure-button"
2022-07-23 23:45:48 +05:30
class="gl-mb-0 gl-mr-3"
2021-09-04 01:27:46 +05:30
>
{{ s__('FeatureFlags|Configure') }}
</gl-button>
2021-01-03 14:25:43 +05:30
2021-09-04 01:27:46 +05:30
<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>
2021-01-03 14:25:43 +05:30
</div>
2021-09-04 01:27:46 +05:30
<table-pagination v-if="shouldRenderPagination" :change="onChangePage" :page-info="pageInfo" />
2021-01-03 14:25:43 +05:30
</div>
</template>