Commit 749a3f0b authored by Jason Goodman's avatar Jason Goodman Committed by Natalia Tepluhina

Display feature flag internal ids

Return feature flag internal id from backend
Remove featureFlagIid feature flag
parent 3688aa18
---
title: Display operations feature flag internal ids
merge_request: 23914
author:
type: added
...@@ -42,13 +42,10 @@ export default { ...@@ -42,13 +42,10 @@ export default {
'active', 'active',
]), ]),
title() { title() {
return this.hasFeatureFlagsIID return this.iid
? `^${this.iid} ${this.name}` ? `^${this.iid} ${this.name}`
: sprintf(s__('Edit %{name}'), { name: this.name }); : sprintf(s__('Edit %{name}'), { name: this.name });
}, },
hasFeatureFlagsIID() {
return this.glFeatures.featureFlagIID && this.iid;
},
}, },
created() { created() {
this.setPath(this.path); this.setPath(this.path);
......
...@@ -37,9 +37,6 @@ export default { ...@@ -37,9 +37,6 @@ export default {
permissions() { permissions() {
return this.glFeatures.featureFlagPermissions; return this.glFeatures.featureFlagPermissions;
}, },
hasIIDs() {
return this.glFeatures.featureFlagIID;
},
modalTitle() { modalTitle() {
return sprintf( return sprintf(
s__('FeatureFlags|Delete %{name}?'), s__('FeatureFlags|Delete %{name}?'),
...@@ -83,6 +80,9 @@ export default { ...@@ -83,6 +80,9 @@ export default {
return `${displayName}${displayPercentage}`; return `${displayName}${displayPercentage}`;
}, },
featureFlagIidText(featureFlag) {
return featureFlag.iid ? `^${featureFlag.iid}` : '';
},
canDeleteFlag(flag) { canDeleteFlag(flag) {
return !this.permissions || (flag.scopes || []).every(scope => scope.can_update); return !this.permissions || (flag.scopes || []).every(scope => scope.can_update);
}, },
...@@ -107,7 +107,7 @@ export default { ...@@ -107,7 +107,7 @@ export default {
<template> <template>
<div class="table-holder js-feature-flag-table"> <div class="table-holder js-feature-flag-table">
<div class="gl-responsive-table-row table-row-header" role="row"> <div class="gl-responsive-table-row table-row-header" role="row">
<div v-if="hasIIDs" class="table-section section-10"> <div class="table-section section-10">
{{ s__('FeatureFlags|ID') }} {{ s__('FeatureFlags|ID') }}
</div> </div>
<div class="table-section section-10" role="columnheader"> <div class="table-section section-10" role="columnheader">
...@@ -123,9 +123,11 @@ export default { ...@@ -123,9 +123,11 @@ export default {
<template v-for="featureFlag in featureFlags"> <template v-for="featureFlag in featureFlags">
<div :key="featureFlag.id" class="gl-responsive-table-row" role="row"> <div :key="featureFlag.id" class="gl-responsive-table-row" role="row">
<div v-if="hasIIDs" class="table-section section-10" role="gridcell"> <div class="table-section section-10" role="gridcell">
<div class="table-mobile-header" role="rowheader">{{ s__('FeatureFlags|ID') }}</div> <div class="table-mobile-header" role="rowheader">{{ s__('FeatureFlags|ID') }}</div>
<div class="table-mobile-content js-feature-flag-id">^{{ featureFlag.iid }}</div> <div class="table-mobile-content js-feature-flag-id">
{{ featureFlagIidText(featureFlag) }}
</div>
</div> </div>
<div class="table-section section-10" role="gridcell"> <div class="table-section section-10" role="gridcell">
<div class="table-mobile-header" role="rowheader">{{ s__('FeatureFlags|Status') }}</div> <div class="table-mobile-header" role="rowheader">{{ s__('FeatureFlags|Status') }}</div>
......
...@@ -4,6 +4,7 @@ class FeatureFlagEntity < Grape::Entity ...@@ -4,6 +4,7 @@ class FeatureFlagEntity < Grape::Entity
include RequestAwareEntity include RequestAwareEntity
expose :id expose :id
expose :iid
expose :active expose :active
expose :created_at expose :created_at
expose :updated_at expose :updated_at
......
...@@ -121,6 +121,14 @@ describe Projects::FeatureFlagsController do ...@@ -121,6 +121,14 @@ describe Projects::FeatureFlagsController do
expect(feature_flag_json['active']).to eq(false) expect(feature_flag_json['active']).to eq(false)
end end
it 'returns the feature flag iid' do
subject
feature_flag_json = json_response['feature_flags'].first
expect(feature_flag_json['iid']).to eq(feature_flag_active.iid)
end
context 'when scope is specified' do context 'when scope is specified' do
let(:view_params) do let(:view_params) do
{ namespace_id: project.namespace, project_id: project, scope: scope } { namespace_id: project.namespace, project_id: project, scope: scope }
......
...@@ -29,6 +29,7 @@ describe 'User sees feature flag list', :js do ...@@ -29,6 +29,7 @@ describe 'User sees feature flag list', :js do
it 'user sees the first flag' do it 'user sees the first flag' do
within_feature_flag_row(1) do within_feature_flag_row(1) do
expect(page.find('.js-feature-flag-id')).to have_content('^1')
expect(page.find('.feature-flag-name')).to have_content('ci_live_trace') expect(page.find('.feature-flag-name')).to have_content('ci_live_trace')
expect(page).to have_css('.js-feature-flag-status button:not(.is-checked)') expect(page).to have_css('.js-feature-flag-status button:not(.is-checked)')
...@@ -43,6 +44,7 @@ describe 'User sees feature flag list', :js do ...@@ -43,6 +44,7 @@ describe 'User sees feature flag list', :js do
it 'user sees the second flag' do it 'user sees the second flag' do
within_feature_flag_row(2) do within_feature_flag_row(2) do
expect(page.find('.js-feature-flag-id')).to have_content('^2')
expect(page.find('.feature-flag-name')).to have_content('drop_legacy_artifacts') expect(page.find('.feature-flag-name')).to have_content('drop_legacy_artifacts')
expect(page).to have_css('.js-feature-flag-status button:not(.is-checked)') expect(page).to have_css('.js-feature-flag-status button:not(.is-checked)')
...@@ -55,6 +57,7 @@ describe 'User sees feature flag list', :js do ...@@ -55,6 +57,7 @@ describe 'User sees feature flag list', :js do
it 'user sees the third flag' do it 'user sees the third flag' do
within_feature_flag_row(3) do within_feature_flag_row(3) do
expect(page.find('.js-feature-flag-id')).to have_content('^3')
expect(page.find('.feature-flag-name')).to have_content('mr_train') expect(page.find('.feature-flag-name')).to have_content('mr_train')
expect(page).to have_css('.js-feature-flag-status button.is-checked') expect(page).to have_css('.js-feature-flag-status button.is-checked')
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
], ],
"properties" : { "properties" : {
"id": { "type": "integer" }, "id": { "type": "integer" },
"iid": { "type": ["integer", "null"] },
"created_at": { "type": "date" }, "created_at": { "type": "date" },
"updated_at": { "type": "date" }, "updated_at": { "type": "date" },
"name": { "type": "string" }, "name": { "type": "string" },
......
...@@ -29,11 +29,6 @@ describe('Edit feature flag form', () => { ...@@ -29,11 +29,6 @@ describe('Edit feature flag form', () => {
path: '/feature_flags', path: '/feature_flags',
environmentsEndpoint: 'environments.json', environmentsEndpoint: 'environments.json',
}, },
provide: {
glFeatures: {
featureFlagIID: true,
},
},
store, store,
}); });
}; };
......
...@@ -12,6 +12,7 @@ const getDefaultProps = () => ({ ...@@ -12,6 +12,7 @@ const getDefaultProps = () => ({
featureFlags: [ featureFlags: [
{ {
id: 1, id: 1,
iid: 1,
active: true, active: true,
name: 'flag name', name: 'flag name',
description: 'flag description', description: 'flag description',
...@@ -56,10 +57,7 @@ describe('Feature flag table', () => { ...@@ -56,10 +57,7 @@ describe('Feature flag table', () => {
describe('with an active scope and a standard rollout strategy', () => { describe('with an active scope and a standard rollout strategy', () => {
beforeEach(() => { beforeEach(() => {
props.featureFlags[0].iid = 1; createWrapper(props);
createWrapper(props, {
provide: { glFeatures: { featureFlagIID: true } },
});
}); });
it('Should render a table', () => { it('Should render a table', () => {
...@@ -160,4 +158,12 @@ describe('Feature flag table', () => { ...@@ -160,4 +158,12 @@ describe('Feature flag table', () => {
expect(trimText(envColumn.find('.badge-inactive').text())).toBe('scope'); expect(trimText(envColumn.find('.badge-inactive').text())).toBe('scope');
}); });
}); });
it('renders a feature flag without an iid', () => {
delete props.featureFlags[0].iid;
createWrapper(props);
expect(wrapper.find('.js-feature-flag-id').exists()).toBe(true);
expect(trimText(wrapper.find('.js-feature-flag-id').text())).toBe('');
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment