Remove Global Drafts Feature Flag (#23767)

* Remove global draft feature flag

* More removal - in progress

* Removed the rest in webapp

* Removed the rest in webapp

* Fix tests

* Update feature_flags.go

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Maria A Nunez 2023-07-05 12:18:30 -04:00 committed by GitHub
parent bf0e0ed45a
commit 5779bd49d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 14 additions and 77 deletions

View File

@ -677,7 +677,6 @@ const defaultServerConfig: AdminConfig = {
PeopleProduct: false,
ReduceOnBoardingTaskList: false,
ThreadsEverywhere: false,
GlobalDrafts: true,
OnboardingTourTips: true,
DeprecateCloudFree: false,
CloudReverseTrial: false,

View File

@ -25,7 +25,6 @@ func TestUpsertDraft(t *testing.T) {
defer th.TearDown()
// set config
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
client := th.Client
@ -95,7 +94,6 @@ func TestGetDrafts(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
client := th.Client
@ -120,7 +118,6 @@ func TestGetDrafts(t *testing.T) {
Message: "draft2",
}
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
// upsert draft1
@ -169,7 +166,6 @@ func TestDeleteDraft(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
client := th.Client

View File

@ -16,7 +16,7 @@ import (
)
func (a *App) GetDraft(userID, channelID, rootID string) (*model.Draft, *model.AppError) {
if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts {
if !*a.Config().ServiceSettings.AllowSyncedDrafts {
return nil, model.NewAppError("GetDraft", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented)
}
@ -35,7 +35,7 @@ func (a *App) GetDraft(userID, channelID, rootID string) (*model.Draft, *model.A
}
func (a *App) UpsertDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) {
if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts {
if !*a.Config().ServiceSettings.AllowSyncedDrafts {
return nil, model.NewAppError("CreateDraft", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented)
}
@ -75,7 +75,7 @@ func (a *App) UpsertDraft(c *request.Context, draft *model.Draft, connectionID s
}
func (a *App) GetDraftsForUser(userID, teamID string) ([]*model.Draft, *model.AppError) {
if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts {
if !*a.Config().ServiceSettings.AllowSyncedDrafts {
return nil, model.NewAppError("GetDraftsForUser", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented)
}
@ -118,7 +118,7 @@ func (a *App) getFileInfosForDraft(draft *model.Draft) ([]*model.FileInfo, *mode
}
func (a *App) DeleteDraft(userID, channelID, rootID, connectionID string) (*model.Draft, *model.AppError) {
if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts {
if !*a.Config().ServiceSettings.AllowSyncedDrafts {
return nil, model.NewAppError("DeleteDraft", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented)
}

View File

@ -26,7 +26,6 @@ func TestGetDraft(t *testing.T) {
th.Server.platform.SetConfigReadOnlyFF(false)
defer th.Server.platform.SetConfigReadOnlyFF(true)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
user := th.BasicUser
@ -57,10 +56,7 @@ func TestGetDraft(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false")
defer os.Unsetenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = false })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = false })
defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
_, err := th.App.GetDraft(user.Id, channel.Id, "")
@ -75,7 +71,6 @@ func TestUpsertDraft(t *testing.T) {
th.Server.platform.SetConfigReadOnlyFF(false)
defer th.Server.platform.SetConfigReadOnlyFF(true)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
user := th.BasicUser
@ -124,10 +119,7 @@ func TestUpsertDraft(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false")
defer os.Unsetenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = false })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = false })
defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
_, err := th.App.UpsertDraft(th.Context, draft, "")
@ -142,7 +134,6 @@ func TestCreateDraft(t *testing.T) {
th.Server.platform.SetConfigReadOnlyFF(false)
defer th.Server.platform.SetConfigReadOnlyFF(true)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
user := th.BasicUser
@ -201,7 +192,6 @@ func TestUpdateDraft(t *testing.T) {
th.Server.platform.SetConfigReadOnlyFF(false)
defer th.Server.platform.SetConfigReadOnlyFF(true)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
user := th.BasicUser
@ -247,7 +237,6 @@ func TestGetDraftsForUser(t *testing.T) {
th.Server.platform.SetConfigReadOnlyFF(false)
defer th.Server.platform.SetConfigReadOnlyFF(true)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
user := th.BasicUser
@ -325,10 +314,7 @@ func TestGetDraftsForUser(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false")
defer os.Unsetenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = false })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = false })
defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
_, err := th.App.GetDraftsForUser(user.Id, th.BasicTeam.Id)
@ -343,7 +329,6 @@ func TestDeleteDraft(t *testing.T) {
th.Server.platform.SetConfigReadOnlyFF(false)
defer th.Server.platform.SetConfigReadOnlyFF(true)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
user := th.BasicUser
@ -377,10 +362,7 @@ func TestDeleteDraft(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false")
defer os.Unsetenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = false })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = false })
defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true })
defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true })
_, err := th.App.DeleteDraft(user.Id, channel.Id, "", "")

View File

@ -55,8 +55,6 @@ type FeatureFlags struct {
PeopleProduct bool
GlobalDrafts bool
OnboardingTourTips bool
DeprecateCloudFree bool
@ -82,7 +80,6 @@ func (f *FeatureFlags) SetDefaults() {
f.CallsEnabled = true
f.PostPriority = true
f.PeopleProduct = false
f.GlobalDrafts = true
f.DeprecateCloudFree = false
f.WysiwygEditor = false
f.OnboardingTourTips = true

View File

@ -102,7 +102,6 @@ describe('draft actions', () => {
general: {
config: {
EnableCustomEmoji: 'true',
FeatureFlagGlobalDrafts: 'true',
AllowSyncedDrafts: 'true',
},
},

View File

@ -3068,12 +3068,6 @@ const AdminDefinition = {
help_text: t('admin.customization.allowSyncedDraftsDesc'),
help_text_default: 'When enabled, users message drafts will sync with the server so they can be accessed from any device. Users may opt out of this behaviour in Account settings.',
help_text_markdown: false,
isHidden: it.any(
it.configIsFalse('FeatureFlags', 'GlobalDrafts'),
),
isDisabled: it.any(
it.configIsFalse('FeatureFlags', 'GlobalDrafts'),
),
},
],
},

View File

@ -36,7 +36,6 @@ exports[`components/drafts/drafts should match snapshot 1`] = `
displayName="display_name"
draftRemotes={Object {}}
drafts={Array []}
localDraftsAreEnabled={true}
status={Object {}}
user={Object {}}
/>
@ -79,7 +78,6 @@ exports[`components/drafts/drafts should match snapshot for local drafts disable
displayName="display_name"
draftRemotes={Object {}}
drafts={Array []}
localDraftsAreEnabled={false}
status={Object {}}
user={Object {}}
/>

View File

@ -19,7 +19,6 @@ describe('components/drafts/drafts', () => {
user: {} as UserProfile,
displayName: 'display_name',
status: {} as UserStatus['status'],
localDraftsAreEnabled: true,
draftRemotes: {},
};
@ -41,7 +40,6 @@ describe('components/drafts/drafts', () => {
const props = {
...baseProps,
localDraftsAreEnabled: false,
};
const wrapper = shallow(

View File

@ -26,7 +26,6 @@ type Props = {
user: UserProfile;
displayName: string;
status: UserStatus['status'];
localDraftsAreEnabled: boolean;
draftRemotes: Record<string, boolean>;
}
@ -36,7 +35,6 @@ function Drafts({
draftRemotes,
status,
user,
localDraftsAreEnabled,
}: Props) {
const dispatch = useDispatch();
const {formatMessage} = useIntl();
@ -50,10 +48,6 @@ function Drafts({
};
}, []);
if (!localDraftsAreEnabled) {
return null;
}
return (
<div
id='app-content'

View File

@ -6,7 +6,7 @@ import {useSelector, useDispatch} from 'react-redux';
import {NavLink, useRouteMatch} from 'react-router-dom';
import {FormattedMessage} from 'react-intl';
import {localDraftsAreEnabled, syncedDraftsAreAllowedAndEnabled} from 'mattermost-redux/selectors/entities/preferences';
import {syncedDraftsAreAllowedAndEnabled} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {getDrafts} from 'actions/views/drafts';
@ -23,7 +23,6 @@ const getDraftsCount = makeGetDraftsCount();
function DraftsLink() {
const dispatch = useDispatch();
const localDraftsEnabled = useSelector(localDraftsAreEnabled);
const syncedDraftsAllowedAndEnabled = useSelector(syncedDraftsAreAllowedAndEnabled);
const count = useSelector(getDraftsCount);
const teamId = useSelector(getCurrentTeamId);
@ -37,7 +36,7 @@ function DraftsLink() {
}
}, [teamId, syncedDraftsAllowedAndEnabled]);
if (!localDraftsEnabled || (!count && !isDraftUrlMatch)) {
if (!count && !isDraftUrlMatch) {
return null;
}

View File

@ -4,7 +4,7 @@
import {connect} from 'react-redux';
import {getCurrentUser, getStatusForUserId} from 'mattermost-redux/selectors/entities/users';
import {localDraftsAreEnabled, getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
import {getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
import {displayUsername} from 'mattermost-redux/utils/user_utils';
import {GlobalState} from 'types/store';
@ -25,7 +25,6 @@ function makeMapStateToProps() {
draftRemotes: state.views.drafts.remotes,
status,
user,
localDraftsAreEnabled: localDraftsAreEnabled(state),
};
};
}

View File

@ -264,22 +264,14 @@ export function getHasDismissedSystemConsoleLimitReached(state: GlobalState): bo
}
export function syncedDraftsAreAllowed(state: GlobalState): boolean {
const isFeatureEnabled = getFeatureFlagValue(state, 'GlobalDrafts') === 'true';
const isConfiguredForFeature = getConfig(state).AllowSyncedDrafts === 'true';
return isFeatureEnabled && isConfiguredForFeature;
return getConfig(state).AllowSyncedDrafts === 'true';
}
export function syncedDraftsAreAllowedAndEnabled(state: GlobalState): boolean {
const isFeatureEnabled = getFeatureFlagValue(state, 'GlobalDrafts') === 'true';
const isConfiguredForFeature = getConfig(state).AllowSyncedDrafts === 'true';
const isConfiguredForUser = getBool(state, Preferences.CATEGORY_ADVANCED_SETTINGS, Preferences.ADVANCED_SYNC_DRAFTS, true);
return isFeatureEnabled && isConfiguredForFeature && isConfiguredForUser;
}
export function localDraftsAreEnabled(state: GlobalState): boolean {
return getFeatureFlagValue(state, 'GlobalDrafts') === 'true';
return isConfiguredForFeature && isConfiguredForUser;
}
export function getVisibleDmGmLimit(state: GlobalState) {

View File

@ -13,7 +13,6 @@ jest.mock('selectors/drafts', () => ({
jest.mock('mattermost-redux/selectors/entities/preferences', () => ({
insightsAreEnabled: jest.fn(),
isCollapsedThreadsEnabled: jest.fn(),
localDraftsAreEnabled: jest.fn(),
}));
beforeEach(() => {
@ -58,7 +57,6 @@ describe('Selectors.Lhs', () => {
it('handles nothing enabled', () => {
jest.spyOn(PreferencesSelectors, 'insightsAreEnabled').mockImplementationOnce(() => false);
jest.spyOn(PreferencesSelectors, 'isCollapsedThreadsEnabled').mockImplementationOnce(() => false);
jest.spyOn(PreferencesSelectors, 'localDraftsAreEnabled').mockImplementationOnce(() => false);
jest.spyOn(Lhs, 'getDraftsCount').mockImplementationOnce(() => 0);
const items = Lhs.getVisibleStaticPages(state as GlobalState);
expect(items).toEqual([]);
@ -67,7 +65,6 @@ describe('Selectors.Lhs', () => {
it('handles insights', () => {
jest.spyOn(PreferencesSelectors, 'insightsAreEnabled').mockImplementation(() => true);
jest.spyOn(PreferencesSelectors, 'isCollapsedThreadsEnabled').mockImplementation(() => false);
jest.spyOn(PreferencesSelectors, 'localDraftsAreEnabled').mockImplementation(() => false);
jest.spyOn(Lhs, 'getDraftsCount').mockImplementationOnce(() => 0);
const items = Lhs.getVisibleStaticPages(state as GlobalState);
expect(items).toEqual([
@ -81,7 +78,6 @@ describe('Selectors.Lhs', () => {
it('handles threads - default off', () => {
jest.spyOn(PreferencesSelectors, 'insightsAreEnabled').mockImplementation(() => false);
jest.spyOn(PreferencesSelectors, 'isCollapsedThreadsEnabled').mockImplementation(() => true);
jest.spyOn(PreferencesSelectors, 'localDraftsAreEnabled').mockImplementation(() => false);
jest.spyOn(Lhs, 'getDraftsCount').mockImplementationOnce(() => 0);
const items = Lhs.getVisibleStaticPages(state as GlobalState);
expect(items).toEqual([
@ -95,7 +91,6 @@ describe('Selectors.Lhs', () => {
it('should not return drafts when empty', () => {
jest.spyOn(PreferencesSelectors, 'insightsAreEnabled').mockImplementation(() => false);
jest.spyOn(PreferencesSelectors, 'isCollapsedThreadsEnabled').mockImplementation(() => false);
jest.spyOn(PreferencesSelectors, 'localDraftsAreEnabled').mockImplementation(() => true);
jest.spyOn(Lhs, 'getDraftsCount').mockImplementationOnce(() => 0);
const items = Lhs.getVisibleStaticPages(state as GlobalState);
expect(items).toEqual([]);
@ -104,7 +99,6 @@ describe('Selectors.Lhs', () => {
it('should return drafts when there are available', () => {
jest.spyOn(PreferencesSelectors, 'insightsAreEnabled').mockImplementation(() => false);
jest.spyOn(PreferencesSelectors, 'isCollapsedThreadsEnabled').mockImplementation(() => false);
jest.spyOn(PreferencesSelectors, 'localDraftsAreEnabled').mockImplementation(() => true);
jest.spyOn(Lhs, 'getDraftsCount').mockImplementationOnce(() => 1);
const items = Lhs.getVisibleStaticPages(state as GlobalState);
expect(items).toEqual([

View File

@ -9,7 +9,6 @@ import {makeGetDraftsCount} from 'selectors/drafts';
import {
insightsAreEnabled,
isCollapsedThreadsEnabled,
localDraftsAreEnabled,
} from 'mattermost-redux/selectors/entities/preferences';
export function getIsLhsOpen(state: GlobalState): boolean {
@ -26,9 +25,8 @@ export const getVisibleStaticPages = createSelector(
'getVisibleSidebarStaticPages',
insightsAreEnabled,
isCollapsedThreadsEnabled,
localDraftsAreEnabled,
getDraftsCount,
(insightsEnabled, collapsedThreadsEnabled, localDraftsEnabled, draftsCount) => {
(insightsEnabled, collapsedThreadsEnabled, draftsCount) => {
const staticPages: StaticPage[] = [];
if (insightsEnabled) {
@ -45,12 +43,10 @@ export const getVisibleStaticPages = createSelector(
});
}
if (localDraftsEnabled) {
staticPages.push({
id: 'drafts',
isVisible: draftsCount > 0,
});
}
staticPages.push({
id: 'drafts',
isVisible: draftsCount > 0,
});
return staticPages.filter((item) => item.isVisible);
},