From 20b4a91122e9b5db5ccc0546c06783a6c08fa247 Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Mon, 17 Oct 2022 14:59:44 -0700 Subject: [PATCH] chore: Add feature flags in the settings console (#5657) --- .../dashboard/components/layout/Sidebar.vue | 10 +++---- .../layout/config/sidebarItems/settings.js | 28 +++++++++++++------ .../layout/sidebarComponents/Secondary.vue | 17 ++++++++--- .../sidebarComponents/SecondaryNavItem.vue | 6 ++-- .../widgets/WootWriter/ReplyBottomPanel.vue | 15 ++++++++-- app/javascript/dashboard/featureFlags.js | 13 +++++++++ .../dashboard/commands/goToCommandHotKeys.js | 22 ++++++++++++++- .../settings/account/account.routes.js | 2 +- .../dashboard/settings/settings.routes.js | 2 +- .../FluentIcon/dashboard-icons.json | 1 + .../account_features_field/_form.html.erb | 1 + config/features.yml | 18 ++++++++++++ ...20221017201914_add_features_to_accounts.rb | 20 +++++++++++++ db/schema.rb | 2 +- 14 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 app/javascript/dashboard/featureFlags.js create mode 100644 db/migrate/20221017201914_add_features_to_accounts.rb diff --git a/app/javascript/dashboard/components/layout/Sidebar.vue b/app/javascript/dashboard/components/layout/Sidebar.vue index 314b594d2..b919be2cd 100644 --- a/app/javascript/dashboard/components/layout/Sidebar.vue +++ b/app/javascript/dashboard/components/layout/Sidebar.vue @@ -73,14 +73,14 @@ export default { computed: { ...mapGetters({ - currentUser: 'getCurrentUser', - globalConfig: 'globalConfig/get', - isACustomBrandedInstance: 'globalConfig/isACustomBrandedInstance', - isOnChatwootCloud: 'globalConfig/isOnChatwootCloud', - inboxes: 'inboxes/getInboxes', accountId: 'getCurrentAccountId', currentRole: 'getCurrentRole', + currentUser: 'getCurrentUser', + globalConfig: 'globalConfig/get', + inboxes: 'inboxes/getInboxes', + isACustomBrandedInstance: 'globalConfig/isACustomBrandedInstance', isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', + isOnChatwootCloud: 'globalConfig/isOnChatwootCloud', labels: 'labels/getLabelsOnSidebar', teams: 'teams/getMyTeams', }), diff --git a/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js b/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js index 83a0c2309..768e42ea5 100644 --- a/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js +++ b/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js @@ -1,3 +1,4 @@ +import { FEATURE_FLAGS } from '../../../../featureFlags'; import { frontendURL } from '../../../../helper/URLHelper'; const settings = accountId => ({ @@ -38,12 +39,20 @@ const settings = accountId => ({ 'settings_teams_new', ], menuItems: [ + { + icon: 'briefcase', + label: 'ACCOUNT_SETTINGS', + hasSubMenu: false, + toState: frontendURL(`accounts/${accountId}/settings/general`), + toStateName: 'general_settings_index', + }, { icon: 'people', label: 'AGENTS', hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/agents/list`), toStateName: 'agent_list', + featureFlag: FEATURE_FLAGS.AGENT_MANAGEMENT, }, { icon: 'people-team', @@ -51,6 +60,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/teams/list`), toStateName: 'settings_teams_list', + featureFlag: FEATURE_FLAGS.TEAM_MANAGEMENT, }, { icon: 'mail-inbox-all', @@ -58,6 +68,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/inboxes/list`), toStateName: 'settings_inbox_list', + featureFlag: FEATURE_FLAGS.INBOX_MANAGEMENT, }, { icon: 'tag', @@ -65,6 +76,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/labels/list`), toStateName: 'labels_list', + featureFlag: FEATURE_FLAGS.LABELS, }, { icon: 'code', @@ -74,6 +86,7 @@ const settings = accountId => ({ `accounts/${accountId}/settings/custom-attributes/list` ), toStateName: 'attributes_list', + featureFlag: FEATURE_FLAGS.CUSTOM_ATTRIBUTES, }, { icon: 'automation', @@ -82,6 +95,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/automation/list`), toStateName: 'automation_list', + featureFlag: FEATURE_FLAGS.AUTOMATIONS, }, { icon: 'bot', @@ -90,7 +104,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/agent-bots`), toStateName: 'agent_bots', - featureFlagKey: 'agent_bots', + featureFlag: FEATURE_FLAGS.AGENT_BOTS, }, { icon: 'flash-settings', @@ -99,7 +113,7 @@ const settings = accountId => ({ toState: frontendURL(`accounts/${accountId}/settings/macros`), toStateName: 'macros_wrapper', beta: true, - featureFlagKey: 'macros', + featureFlag: FEATURE_FLAGS.MACROS, }, { icon: 'chat-multiple', @@ -109,6 +123,7 @@ const settings = accountId => ({ `accounts/${accountId}/settings/canned-response/list` ), toStateName: 'canned_list', + featureFlag: FEATURE_FLAGS.CANNED_RESPONSES, }, { icon: 'flash-on', @@ -116,6 +131,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/integrations`), toStateName: 'settings_integrations', + featureFlag: FEATURE_FLAGS.INTEGRATIONS, }, { icon: 'star-emphasis', @@ -123,6 +139,7 @@ const settings = accountId => ({ hasSubMenu: false, toState: frontendURL(`accounts/${accountId}/settings/applications`), toStateName: 'settings_applications', + featureFlag: FEATURE_FLAGS.INTEGRATIONS, }, { icon: 'credit-card-person', @@ -132,13 +149,6 @@ const settings = accountId => ({ toStateName: 'billing_settings_index', showOnlyOnCloud: true, }, - { - icon: 'settings', - label: 'ACCOUNT_SETTINGS', - hasSubMenu: false, - toState: frontendURL(`accounts/${accountId}/settings/general`), - toStateName: 'general_settings_index', - }, ], }); diff --git a/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue b/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue index e68fcc3a4..b8aa21b30 100644 --- a/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue +++ b/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue @@ -20,6 +20,8 @@ import { frontendURL } from '../../../helper/URLHelper'; import SecondaryNavItem from './SecondaryNavItem.vue'; import AccountContext from './AccountContext.vue'; +import { mapGetters } from 'vuex'; +import { FEATURE_FLAGS } from '../../../featureFlags'; export default { components: { @@ -61,6 +63,10 @@ export default { }, }, computed: { + ...mapGetters({ + accountId: 'getCurrentAccountId', + isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', + }), hasSecondaryMenu() { return this.menuConfig.menuItems && this.menuConfig.menuItems.length; }, @@ -89,7 +95,7 @@ export default { icon: 'folder', label: 'INBOXES', hasSubMenu: true, - newLink: true, + newLink: this.showNewLink(FEATURE_FLAGS.INBOX_MANAGEMENT), newLinkTag: 'NEW_INBOX', key: 'inbox', toState: frontendURL(`accounts/${this.accountId}/settings/inboxes/new`), @@ -117,7 +123,7 @@ export default { icon: 'number-symbol', label: 'LABELS', hasSubMenu: true, - newLink: true, + newLink: this.showNewLink(FEATURE_FLAGS.TEAM_MANAGEMENT), newLinkTag: 'NEW_LABEL', key: 'label', toState: frontendURL(`accounts/${this.accountId}/settings/labels`), @@ -141,7 +147,7 @@ export default { label: 'TAGGED_WITH', hasSubMenu: true, key: 'label', - newLink: true, + newLink: this.showNewLink(FEATURE_FLAGS.TEAM_MANAGEMENT), newLinkTag: 'NEW_LABEL', toState: frontendURL(`accounts/${this.accountId}/settings/labels`), toStateName: 'labels_list', @@ -163,7 +169,7 @@ export default { icon: 'people-team', label: 'TEAMS', hasSubMenu: true, - newLink: true, + newLink: this.showNewLink(FEATURE_FLAGS.TEAM_MANAGEMENT), newLinkTag: 'NEW_TEAM', key: 'team', toState: frontendURL(`accounts/${this.accountId}/settings/teams/new`), @@ -238,6 +244,9 @@ export default { toggleAccountModal() { this.$emit('toggle-accounts'); }, + showNewLink(featureFlag) { + return this.isFeatureEnabledonAccount(this.accountId, featureFlag); + }, }, }; diff --git a/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue b/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue index cd155bce8..8661a488f 100644 --- a/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue +++ b/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue @@ -123,12 +123,12 @@ export default { return !!this.menuItem.children; }, isMenuItemVisible() { - if (!this.menuItem.featureFlagKey) { + if (!this.menuItem.featureFlag) { return true; } return this.isFeatureEnabledonAccount( this.accountId, - this.menuItem.featureFlagKey + this.menuItem.featureFlag ); }, isInboxConversation() { @@ -217,7 +217,7 @@ export default { } }, showItem(item) { - return this.isAdmin && item.newLink !== undefined; + return this.isAdmin && !!item.newLink; }, onClickOpen() { this.$emit('open'); diff --git a/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue b/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue index 9ace1ceb2..d26264cc2 100644 --- a/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue +++ b/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue @@ -110,13 +110,15 @@ import { hasPressedAltAndAKey } from 'shared/helpers/KeyboardHelpers'; import eventListenerMixins from 'shared/mixins/eventListenerMixins'; import uiSettingsMixin from 'dashboard/mixins/uiSettings'; import inboxMixin from 'shared/mixins/inboxMixin'; - +import { FEATURE_FLAGS } from 'dashboard/featureFlags'; import { ALLOWED_FILE_TYPES, ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP, } from 'shared/constants/messages'; import { REPLY_EDITOR_MODES } from './constants'; +import { mapGetters } from 'vuex'; + export default { name: 'ReplyBottomPanel', components: { FileUpload }, @@ -200,6 +202,10 @@ export default { }, }, computed: { + ...mapGetters({ + accountId: 'getCurrentAccountId', + isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', + }), isNote() { return this.mode === REPLY_EDITOR_MODES.NOTE; }, @@ -217,7 +223,12 @@ export default { return this.showFileUpload || this.isNote; }, showAudioRecorderButton() { - return this.showAudioRecorder; + return ( + this.isFeatureEnabledonAccount( + this.accountId, + FEATURE_FLAGS.VOICE_RECORDER + ) && this.showAudioRecorder + ); }, showAudioPlayStopButton() { return this.showAudioRecorder && this.isRecordingAudio; diff --git a/app/javascript/dashboard/featureFlags.js b/app/javascript/dashboard/featureFlags.js new file mode 100644 index 000000000..c6bc736cf --- /dev/null +++ b/app/javascript/dashboard/featureFlags.js @@ -0,0 +1,13 @@ +export const FEATURE_FLAGS = { + AGENT_BOTS: 'agent_bots', + AGENT_MANAGEMENT: 'agent_management', + AUTOMATIONS: 'automations', + CANNED_RESPONSES: 'canned_responses', + CUSTOM_ATTRIBUTES: 'custom_attributes', + INBOX_MANAGEMENT: 'inbox_management', + INTEGRATIONS: 'integrations', + LABELS: 'labels', + MACROS: 'macros', + TEAM_MANAGEMENT: 'team_management', + VOICE_RECORDER: 'voice_recorder', +}; diff --git a/app/javascript/dashboard/routes/dashboard/commands/goToCommandHotKeys.js b/app/javascript/dashboard/routes/dashboard/commands/goToCommandHotKeys.js index 9a5b09f2e..b1d17dcbb 100644 --- a/app/javascript/dashboard/routes/dashboard/commands/goToCommandHotKeys.js +++ b/app/javascript/dashboard/routes/dashboard/commands/goToCommandHotKeys.js @@ -16,6 +16,8 @@ import { ICON_CONVERSATION_REPORTS, } from './CommandBarIcons'; import { frontendURL } from '../../../helper/URLHelper'; +import { mapGetters } from 'vuex'; +import { FEATURE_FLAGS } from '../../../featureFlags'; const GO_TO_COMMANDS = [ { @@ -86,6 +88,7 @@ const GO_TO_COMMANDS = [ id: 'open_agent_settings', section: 'COMMAND_BAR.SECTIONS.SETTINGS', title: 'COMMAND_BAR.COMMANDS.GO_TO_SETTINGS_AGENTS', + featureFlag: FEATURE_FLAGS.AGENT_MANAGEMENT, icon: ICON_AGENT_REPORTS, path: accountId => `accounts/${accountId}/settings/agents/list`, role: ['administrator'], @@ -93,6 +96,7 @@ const GO_TO_COMMANDS = [ { id: 'open_team_settings', title: 'COMMAND_BAR.COMMANDS.GO_TO_SETTINGS_TEAMS', + featureFlag: FEATURE_FLAGS.TEAM_MANAGEMENT, section: 'COMMAND_BAR.SECTIONS.SETTINGS', icon: ICON_TEAM_REPORTS, path: accountId => `accounts/${accountId}/settings/teams/list`, @@ -101,6 +105,7 @@ const GO_TO_COMMANDS = [ { id: 'open_inbox_settings', title: 'COMMAND_BAR.COMMANDS.GO_TO_SETTINGS_INBOXES', + featureFlag: FEATURE_FLAGS.INBOX_MANAGEMENT, section: 'COMMAND_BAR.SECTIONS.SETTINGS', icon: ICON_INBOXES, path: accountId => `accounts/${accountId}/settings/inboxes/list`, @@ -109,6 +114,7 @@ const GO_TO_COMMANDS = [ { id: 'open_label_settings', title: 'COMMAND_BAR.COMMANDS.GO_TO_SETTINGS_LABELS', + featureFlag: FEATURE_FLAGS.LABELS, section: 'COMMAND_BAR.SECTIONS.SETTINGS', icon: ICON_LABELS, path: accountId => `accounts/${accountId}/settings/labels/list`, @@ -117,6 +123,7 @@ const GO_TO_COMMANDS = [ { id: 'open_canned_response_settings', title: 'COMMAND_BAR.COMMANDS.GO_TO_SETTINGS_CANNED_RESPONSES', + featureFlag: FEATURE_FLAGS.CANNED_RESPONSES, section: 'COMMAND_BAR.SECTIONS.SETTINGS', icon: ICON_CANNED_RESPONSE, path: accountId => `accounts/${accountId}/settings/canned-response/list`, @@ -125,6 +132,7 @@ const GO_TO_COMMANDS = [ { id: 'open_applications_settings', title: 'COMMAND_BAR.COMMANDS.GO_TO_SETTINGS_APPLICATIONS', + featureFlag: FEATURE_FLAGS.INTEGRATIONS, section: 'COMMAND_BAR.SECTIONS.SETTINGS', icon: ICON_APPS, path: accountId => `accounts/${accountId}/settings/applications`, @@ -158,8 +166,20 @@ const GO_TO_COMMANDS = [ export default { computed: { + ...mapGetters({ + accountId: 'getCurrentAccountId', + isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', + }), goToCommandHotKeys() { - let commands = GO_TO_COMMANDS; + let commands = GO_TO_COMMANDS.filter(cmd => { + if (cmd.featureFlag) { + return this.isFeatureEnabledonAccount( + this.accountId, + cmd.featureFlag + ); + } + return true; + }); if (!this.isAdmin) { commands = commands.filter(command => command.role.includes('agent')); diff --git a/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js b/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js index c2ef17129..5e3df43b4 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js @@ -10,7 +10,7 @@ export default { component: SettingsContent, props: { headerTitle: 'GENERAL_SETTINGS.TITLE', - icon: 'settings', + icon: 'briefcase', showNewButton: false, }, children: [ diff --git a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js index 7c8cc11fa..794451e79 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js @@ -25,7 +25,7 @@ export default { roles: ['administrator', 'agent'], redirect: () => { if (store.getters.getCurrentRole === 'administrator') { - return frontendURL('accounts/:accountId/settings/agents'); + return frontendURL('accounts/:accountId/settings/general'); } return frontendURL('accounts/:accountId/settings/canned-response'); }, diff --git a/app/javascript/shared/components/FluentIcon/dashboard-icons.json b/app/javascript/shared/components/FluentIcon/dashboard-icons.json index 9a5eaa893..bf6f4127d 100644 --- a/app/javascript/shared/components/FluentIcon/dashboard-icons.json +++ b/app/javascript/shared/components/FluentIcon/dashboard-icons.json @@ -31,6 +31,7 @@ "book-open-globe-outline": "M3.5 5.75a.25.25 0 0 1 .25-.25H10c.69 0 1.25.56 1.25 1.25v8.959a6.49 6.49 0 0 1 1.5-2.646V6.75c0-.69.56-1.25 1.25-1.25h6.25a.25.25 0 0 1 .25.25v5.982A6.518 6.518 0 0 1 22 12.81V5.75A1.75 1.75 0 0 0 20.25 4H14c-.788 0-1.499.331-2 .863A2.742 2.742 0 0 0 10 4H3.75A1.75 1.75 0 0 0 2 5.75v12.5c0 .966.784 1.75 1.75 1.75H10c.495 0 .96-.13 1.36-.36a6.473 6.473 0 0 1-.343-1.663A1.248 1.248 0 0 1 10 18.5H3.75a.25.25 0 0 1-.25-.25V5.75ZM16.007 17c.04-1.415.248-2.669.553-3.585.171-.513.364-.893.554-1.134.195-.247.329-.281.386-.281.057 0 .192.034.386.281.19.241.383.62.554 1.134.305.916.513 2.17.553 3.585h-2.986Zm-.396-3.9c.108-.323.23-.622.368-.887A5.504 5.504 0 0 0 12.023 17h2.984c.04-1.5.26-2.866.604-3.9Zm3.778 0a6.133 6.133 0 0 0-.368-.887A5.504 5.504 0 0 1 22.978 17h-2.985c-.04-1.5-.26-2.866-.604-3.9Zm.604 4.9h2.985a5.504 5.504 0 0 1-3.957 4.787c.138-.265.26-.564.368-.886.345-1.035.564-2.4.604-3.901Zm-2.107 4.719c-.194.247-.329.281-.386.281-.057 0-.191-.034-.386-.281-.19-.241-.383-.62-.554-1.135-.305-.915-.513-2.17-.553-3.584h2.986c-.04 1.415-.248 2.669-.553 3.584-.171.514-.364.894-.554 1.135ZM12.023 18a5.504 5.504 0 0 0 3.956 4.787 6.133 6.133 0 0 1-.367-.886c-.346-1.035-.565-2.4-.605-3.901h-2.984Z", "bot-outline": "M17.753 14a2.25 2.25 0 0 1 2.25 2.25v.905a3.75 3.75 0 0 1-1.307 2.846C17.13 21.345 14.89 22 12 22c-2.89 0-5.128-.656-6.691-2a3.75 3.75 0 0 1-1.306-2.843v-.908A2.25 2.25 0 0 1 6.253 14h11.5Zm0 1.5h-11.5a.75.75 0 0 0-.75.75v.908c0 .655.286 1.278.784 1.706C7.545 19.945 9.44 20.502 12 20.502c2.56 0 4.458-.557 5.719-1.64a2.25 2.25 0 0 0 .784-1.706v-.906a.75.75 0 0 0-.75-.75ZM11.898 2.008 12 2a.75.75 0 0 1 .743.648l.007.102V3.5h3.5a2.25 2.25 0 0 1 2.25 2.25v4.505a2.25 2.25 0 0 1-2.25 2.25h-8.5a2.25 2.25 0 0 1-2.25-2.25V5.75A2.25 2.25 0 0 1 7.75 3.5h3.5v-.749a.75.75 0 0 1 .648-.743L12 2l-.102.007ZM16.25 5h-8.5a.75.75 0 0 0-.75.75v4.505c0 .414.336.75.75.75h8.5a.75.75 0 0 0 .75-.75V5.75a.75.75 0 0 0-.75-.75Zm-6.5 1.5a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5Zm4.492 0a1.25 1.25 0 1 1 0 2.499 1.25 1.25 0 0 1 0-2.499Z", "building-bank-outline": "M13.032 2.325a1.75 1.75 0 0 0-2.064 0L3.547 7.74c-.978.713-.473 2.26.736 2.26H4.5v5.8A2.75 2.75 0 0 0 3 18.25v1.5c0 .413.336.75.75.75h16.5a.75.75 0 0 0 .75-.75v-1.5a2.75 2.75 0 0 0-1.5-2.45V10h.217c1.21 0 1.713-1.547.736-2.26l-7.421-5.416Zm-1.18 1.211a.25.25 0 0 1 .295 0L18.95 8.5H5.05l6.803-4.964ZM18 10v5.5h-2V10h2Zm-3.5 0v5.5h-1.75V10h1.75Zm-3.25 0v5.5H9.5V10h1.75Zm-5.5 7h12.5c.69 0 1.25.56 1.25 1.25V19h-15v-.75c0-.69.56-1.25 1.25-1.25ZM6 15.5V10h2v5.5H6Z", + "briefcase-outline": "M8.75 3h6.5a.75.75 0 0 1 .743.648L16 3.75V7h1.75A3.25 3.25 0 0 1 21 10.25v6.5A3.25 3.25 0 0 1 17.75 20H6.25A3.25 3.25 0 0 1 3 16.75v-6.5A3.25 3.25 0 0 1 6.25 7H8V3.75a.75.75 0 0 1 .648-.743L8.75 3h6.5-6.5Zm9 5.5H6.25a1.75 1.75 0 0 0-1.75 1.75v6.5c0 .966.784 1.75 1.75 1.75h11.5a1.75 1.75 0 0 0 1.75-1.75v-6.5a1.75 1.75 0 0 0-1.75-1.75Zm-3.25-4h-5V7h5V4.5Z", "calendar-clock-outline": [ "M21 6.25A3.25 3.25 0 0 0 17.75 3H6.25A3.25 3.25 0 0 0 3 6.25v11.5A3.25 3.25 0 0 0 6.25 21h5.772a6.471 6.471 0 0 1-.709-1.5H6.25a1.75 1.75 0 0 1-1.75-1.75V8.5h15v2.813a6.471 6.471 0 0 1 1.5.709V6.25ZM6.25 4.5h11.5c.966 0 1.75.784 1.75 1.75V7h-15v-.75c0-.966.784-1.75 1.75-1.75Z", "M23 17.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Zm-5.5 0h2a.5.5 0 0 1 0 1H17a.5.5 0 0 1-.5-.491v-3.01a.5.5 0 0 1 1 0V17.5Z" diff --git a/app/views/fields/account_features_field/_form.html.erb b/app/views/fields/account_features_field/_form.html.erb index 823a043a6..c067e81c1 100644 --- a/app/views/fields/account_features_field/_form.html.erb +++ b/app/views/fields/account_features_field/_form.html.erb @@ -4,5 +4,6 @@
<% field.data.each do |key,val| %> <%= key %>: <%= check_box "enabled_features", "feature_#{key}", { checked: val }, true, false %> +
<% end %>
diff --git a/config/features.yml b/config/features.yml index ec779cd08..77d594fcf 100644 --- a/config/features.yml +++ b/config/features.yml @@ -19,3 +19,21 @@ enabled: false - name: macros enabled: false +- name: agent_management + enabled: true +- name: team_management + enabled: true +- name: inbox_management + enabled: true +- name: labels + enabled: true +- name: custom_attributes + enabled: true +- name: automations + enabled: true +- name: canned_responses + enabled: true +- name: integrations + enabled: true +- name: voice_recorder + enabled: true diff --git a/db/migrate/20221017201914_add_features_to_accounts.rb b/db/migrate/20221017201914_add_features_to_accounts.rb new file mode 100644 index 000000000..60f47f7d3 --- /dev/null +++ b/db/migrate/20221017201914_add_features_to_accounts.rb @@ -0,0 +1,20 @@ +class AddFeaturesToAccounts < ActiveRecord::Migration[6.1] + def change + Account.find_in_batches do |account_batch| + account_batch.each do |account| + account.enable_features( + 'agent_management', + 'automations', + 'canned_responses', + 'custom_attributes', + 'inbox_management', + 'integrations', + 'labels', + 'team_management', + 'voice_recorder' + ) + account.save! + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d719bc9f7..d989b754b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_10_10_212946) do +ActiveRecord::Schema.define(version: 2022_10_17_201914) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements"