From 4923905b8e3368e5fcde41d1caa8cbcf9ecf9381 Mon Sep 17 00:00:00 2001 From: Maciej Krol Date: Sat, 5 Dec 2020 16:26:38 +0000 Subject: [PATCH] Kill Switch for Flags --- README.md | 2 +- common/dispatcher/action-constants.js | 1 + common/dispatcher/app-actions.js | 5 +- common/project.js | 11 ++-- common/providers/ConfigProvider.js | 4 +- common/stores/config-store.js | 5 +- common/stores/identity-store.js | 7 +-- package-lock.json | 10 ++-- package.json | 2 +- tests/index.test.js | 1 - web/components/modals/CreateFlag.js | 72 +++++++++++++++++++++------ web/project/api.js | 10 ++-- web/project/libs.js | 4 +- 13 files changed, 89 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index db416e4f..468e6df0 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ If you have any questions about our projects you can email { + changeSegment = (items) => { + const { enabledSegment } = this.state; items.forEach((item) => { - item.enabled = false; + item.enabled = enabledSegment; }); this.props.updateSegments(items); + this.setState({ enabledSegment: !enabledSegment }); } - disableIdentity = (items) => { + changeIdentity = (items) => { const { environmentId } = this.props; - items.forEach((item) => { + const { enabledIndentity } = this.state; + + Promise.all(items.map(item => new Promise((resolve) => { AppActions.changeUserFlag({ identityFlag: item.id, identity: item.identity.id, environmentId, + onSuccess: resolve, payload: { id: item.identity.id, - enabled: false, + enabled: enabledIndentity, value: item.identity.identifier, }, }); + }))).then(() => { + this.userOverridesPage(1); + }); + + this.setState({ enabledIndentity: !enabledIndentity }); + } + + toggleUserFlag = ({ id, feature_state_value, enabled, identity }) => { + const { environmentId } = this.props; + + AppActions.changeUserFlag({ + identityFlag: id, + identity: identity.id, + environmentId, + onSuccess: () => { + this.userOverridesPage(1); + }, + payload: { + id: identity.id, + enabled: !enabled, + value: identity.identifier, + }, }); - this.userOverridesPage(1); } render() { - const { name, initial_value, hide_from_client, default_enabled, featureType, type, description } = this.state; + const { + name, + initial_value, + hide_from_client, + default_enabled, + featureType, + type, + description, + enabledSegment, + enabledIndentity, + } = this.state; const { isEdit, hasFeature, projectFlag, environmentFlag, identity, identityName } = this.props; const Provider = identity ? IdentityProvider : FeatureListProvider; const valueString = isEdit ? 'Value' : 'Initial value'; @@ -304,8 +342,8 @@ const CreateFlag = class extends Component { )} action={ this.props.hasFeature('killswitch') && ( - ) } @@ -347,10 +385,11 @@ const CreateFlag = class extends Component { )} action={ this.props.hasFeature('killswitch') && ( - - )} + ) + } className="no-pad" icon="ion-md-person" items={this.state.userOverrides} @@ -361,8 +400,13 @@ const CreateFlag = class extends Component { renderRow={({ id, feature_state_value, enabled, identity }) => ( { - this.close(); - this.props.router.history.push(`/project/${this.props.projectId}/environment/${this.props.environmentId}/users/${identity.identifier}/${identity.id}`); + if (type === 'FLAG') { + this.toggleUserFlag({ id, feature_state_value, enabled, identity }); + } else { + // todo: allow for editing from this screen + this.close(); + this.props.router.history.push(`/project/${this.props.projectId}/environment/${this.props.environmentId}/users/${identity.identifier}/${identity.id}`); + } }} space className="list-item cursor-pointer" key={id} > diff --git a/web/project/api.js b/web/project/api.js index 0ad75b44..7d03b0eb 100644 --- a/web/project/api.js +++ b/web/project/api.js @@ -139,8 +139,8 @@ global.API = { .set('email', id); amplitude.getInstance().identify(identify); } - bulletTrain.identify(id); - bulletTrain.setTrait('email', id); + flagsmith.identify(id); + flagsmith.setTrait('email', id); }, identify(id, user = {}) { if (id === Project.excludeAnalytics) return; @@ -168,8 +168,8 @@ global.API = { amplitude.getInstance().identify(identify); } - bulletTrain.identify(id); - bulletTrain.setTrait('email', id); + flagsmith.identify(id); + flagsmith.setTrait('email', id); if (window.$crisp) { $crisp.push(['set', 'user:email', id]); $crisp.push(['set', 'user:nickname', `${user.first_name} ${user.last_name}`]); @@ -195,7 +195,7 @@ global.API = { if (Project.mixpanel) { mixpanel.reset(); } - bulletTrain.logout(); + flagsmith.logout(); }, log() { console.log.apply(this, arguments); diff --git a/web/project/libs.js b/web/project/libs.js index 8dd6dee0..a09e9df0 100644 --- a/web/project/libs.js +++ b/web/project/libs.js @@ -1,4 +1,4 @@ -import bulletTrain from 'bullet-train-client'; // Add this line if you're using bulletTrain via npm +import flagsmith from 'flagsmith'; // Add this line if you're using flagsmith via npm import 'ionicons/dist/css/ionicons.min.css'; @@ -26,7 +26,7 @@ import Project from '../../common/project'; window.isMobile = isMobile || $(window).width() <= 576; -window.bulletTrain = bulletTrain; +window.flagsmith = flagsmith; window.moment = require('moment/min/moment.min'); window._ = { each,intersection, sortBy, orderBy, filter, find, partial, findIndex, range, map, cloneDeep, keyBy, throttle, every, get };