diff --git a/e2e-tests/cypress/tests/support/api/on_prem_default_config.json b/e2e-tests/cypress/tests/support/api/on_prem_default_config.json index b46a6e244d..98bf109362 100644 --- a/e2e-tests/cypress/tests/support/api/on_prem_default_config.json +++ b/e2e-tests/cypress/tests/support/api/on_prem_default_config.json @@ -64,6 +64,7 @@ "EnableEmojiPicker": true, "PostEditTimeLimit": -1, "TimeBetweenUserTypingUpdatesMilliseconds": 5000, + "EnableCrossTeamSearch": true, "EnablePostSearch": true, "EnableFileSearch": true, "MinimumHashtagLength": 3, diff --git a/e2e-tests/playwright/support/server/default_config.ts b/e2e-tests/playwright/support/server/default_config.ts index 77e386eed7..e55832a8b1 100644 --- a/e2e-tests/playwright/support/server/default_config.ts +++ b/e2e-tests/playwright/support/server/default_config.ts @@ -151,6 +151,7 @@ const defaultServerConfig: AdminConfig = { EnableEmojiPicker: true, PostEditTimeLimit: -1, TimeBetweenUserTypingUpdatesMilliseconds: 5000, + EnableCrossTeamSearch: true, EnablePostSearch: true, EnableFileSearch: true, MinimumHashtagLength: 3, @@ -749,7 +750,6 @@ const defaultServerConfig: AdminConfig = { WebSocketEventScope: true, NotificationMonitoring: true, ExperimentalAuditSettingsSystemConsoleUI: false, - ExperimentalCrossTeamSearch: false, CustomProfileAttributes: false, }, ImportSettings: { diff --git a/e2e-tests/playwright/tests/functional/channels/search/team_selector.spec.ts b/e2e-tests/playwright/tests/functional/channels/search/team_selector.spec.ts index 8539b1afef..474f2a2297 100644 --- a/e2e-tests/playwright/tests/functional/channels/search/team_selector.spec.ts +++ b/e2e-tests/playwright/tests/functional/channels/search/team_selector.spec.ts @@ -5,8 +5,6 @@ import {createRandomTeam} from '@e2e-support/server'; import {expect, test} from '@e2e-support/test_fixture'; test('team selector must show all my teams', async ({pw}) => { - pw.skipIfFeatureFlagNotSet('ExperimentalCrossTeamSearch', true); - const {adminClient, user, team} = await pw.initSetup(); // # create 2 more teams and add the user to them diff --git a/server/config/client.go b/server/config/client.go index c5abb35daa..b51d93fa22 100644 --- a/server/config/client.go +++ b/server/config/client.go @@ -101,6 +101,10 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li props["DisableWakeUpReconnectHandler"] = strconv.FormatBool(*c.ExperimentalSettings.DisableWakeUpReconnectHandler) props["UsersStatusAndProfileFetchingPollIntervalMilliseconds"] = strconv.FormatInt(*c.ExperimentalSettings.UsersStatusAndProfileFetchingPollIntervalMilliseconds, 10) + // Here we set the new option, but we also send the old FeatureFlag property for backwards compatibility on mobile < 2.27 + props["EnableCrossTeamSearch"] = strconv.FormatBool(*c.ServiceSettings.EnableCrossTeamSearch) + props["FeatureFlagExperimentalCrossTeamSearch"] = strconv.FormatBool(*c.ServiceSettings.EnableCrossTeamSearch) + // Set default values for all options that require a license. props["ExperimentalEnableAuthenticationTransfer"] = "true" props["LdapNicknameAttributeSet"] = "false" diff --git a/server/platform/services/telemetry/telemetry.go b/server/platform/services/telemetry/telemetry.go index 27eacb1e69..40980ca081 100644 --- a/server/platform/services/telemetry/telemetry.go +++ b/server/platform/services/telemetry/telemetry.go @@ -526,6 +526,7 @@ func (ts *TelemetryService) trackConfig() { "enable_channel_viewed_messages": *cfg.ServiceSettings.EnableChannelViewedMessages, "time_between_user_typing_updates_milliseconds": *cfg.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds, "cluster_log_timeout_milliseconds": *cfg.ServiceSettings.ClusterLogTimeoutMilliseconds, + "enable_cross_team_search": *cfg.ServiceSettings.EnableCrossTeamSearch, "enable_post_search": *cfg.ServiceSettings.EnablePostSearch, "minimum_hashtag_length": *cfg.ServiceSettings.MinimumHashtagLength, "enable_user_statuses": *cfg.ServiceSettings.EnableUserStatuses, diff --git a/server/public/model/config.go b/server/public/model/config.go index 46382866c9..00a9e8dfdc 100644 --- a/server/public/model/config.go +++ b/server/public/model/config.go @@ -392,6 +392,7 @@ type ServiceSettings struct { EnableEmojiPicker *bool `access:"site_emoji"` PostEditTimeLimit *int `access:"user_management_permissions"` TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"` + EnableCrossTeamSearch *bool `access:"write_restrictable,cloud_restrictable"` EnablePostSearch *bool `access:"write_restrictable,cloud_restrictable"` EnableFileSearch *bool `access:"write_restrictable"` MinimumHashtagLength *int `access:"environment_database,write_restrictable,cloud_restrictable"` @@ -620,6 +621,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) { s.TimeBetweenUserTypingUpdatesMilliseconds = NewPointer(int64(5000)) } + if s.EnableCrossTeamSearch == nil { + s.EnableCrossTeamSearch = NewPointer(true) + } + if s.EnablePostSearch == nil { s.EnablePostSearch = NewPointer(true) } @@ -3645,9 +3650,11 @@ func (s *ExportSettings) SetDefaults() { type ConfigFunc func() *Config -const ConfigAccessTagType = "access" -const ConfigAccessTagWriteRestrictable = "write_restrictable" -const ConfigAccessTagCloudRestrictable = "cloud_restrictable" +const ( + ConfigAccessTagType = "access" + ConfigAccessTagWriteRestrictable = "write_restrictable" + ConfigAccessTagCloudRestrictable = "cloud_restrictable" +) // Allows read access if any PermissionSysconsoleRead* is allowed const ConfigAccessTagAnySysConsoleRead = "*_read" diff --git a/server/public/model/feature_flags.go b/server/public/model/feature_flags.go index d99820da0f..b0043b18a1 100644 --- a/server/public/model/feature_flags.go +++ b/server/public/model/feature_flags.go @@ -56,8 +56,6 @@ type FeatureFlags struct { ExperimentalAuditSettingsSystemConsoleUI bool - ExperimentalCrossTeamSearch bool - CustomProfileAttributes bool } @@ -82,7 +80,6 @@ func (f *FeatureFlags) SetDefaults() { f.WebSocketEventScope = true f.NotificationMonitoring = true f.ExperimentalAuditSettingsSystemConsoleUI = false - f.ExperimentalCrossTeamSearch = true f.CustomProfileAttributes = false } diff --git a/server/tests/test-config.json b/server/tests/test-config.json index 725ddce0e3..a9c4e799b6 100644 --- a/server/tests/test-config.json +++ b/server/tests/test-config.json @@ -47,6 +47,7 @@ "EnableEmojiPicker": true, "PostEditTimeLimit": -1, "TimeBetweenUserTypingUpdatesMilliseconds": 5000, + "EnableCrossTeamSearch": true, "EnablePostSearch": true, "MinimumHashtagLength": 3, "EnableUserTypingMessages": true, diff --git a/webapp/channels/src/components/new_search/new_search.tsx b/webapp/channels/src/components/new_search/new_search.tsx index 0b70f469a7..caae68caad 100644 --- a/webapp/channels/src/components/new_search/new_search.tsx +++ b/webapp/channels/src/components/new_search/new_search.tsx @@ -8,7 +8,7 @@ import styled from 'styled-components'; import {TrackCrossTeamSearchFeature, TrackCrossTeamSearchAllTeamsEvent, TrackCrossTeamSearchCurrentTeamEvent, TrackCrossTeamSearchDifferentTeamEvent} from 'mattermost-redux/constants/telemetry'; import {getCurrentChannelNameForSearchShortcut} from 'mattermost-redux/selectors/entities/channels'; -import {getFeatureFlagValue} from 'mattermost-redux/selectors/entities/general'; +import {getIsCrossTeamSearchEnabled} from 'mattermost-redux/selectors/entities/general'; import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; import {trackFeatureEvent} from 'actions/telemetry_actions'; @@ -25,8 +25,6 @@ import * as Keyboard from 'utils/keyboard'; import {isServerVersionGreaterThanOrEqualTo} from 'utils/server_version'; import {isDesktopApp, getDesktopVersion, isMacApp} from 'utils/user_agent'; -import type {GlobalState} from 'types/store'; - import SearchBox from './search_box'; const PopoverStyled = styled(Popover)` @@ -115,7 +113,7 @@ const NewSearch = (): JSX.Element => { const searchTeam = useSelector(getSearchTeam); const pluginSearch = useSelector(getSearchButtons); const currentTeamId = useSelector(getCurrentTeamId); - const crossTeamSearchEnabled = useSelector((state: GlobalState) => getFeatureFlagValue(state, 'ExperimentalCrossTeamSearch')) === 'true'; + const crossTeamSearchEnabled = useSelector(getIsCrossTeamSearchEnabled); const dispatch = useDispatch(); const [focused, setFocused] = useState(false); diff --git a/webapp/channels/src/components/search/index.tsx b/webapp/channels/src/components/search/index.tsx index 1fa6daa6a0..3f6b89fca6 100644 --- a/webapp/channels/src/components/search/index.tsx +++ b/webapp/channels/src/components/search/index.tsx @@ -10,7 +10,7 @@ import type {ServerError} from '@mattermost/types/errors'; import {getMorePostsForSearch, getMoreFilesForSearch} from 'mattermost-redux/actions/search'; import {getCurrentChannel} from 'mattermost-redux/selectors/entities/channels'; -import {getFeatureFlagValue} from 'mattermost-redux/selectors/entities/general'; +import {getIsCrossTeamSearchEnabled} from 'mattermost-redux/selectors/entities/general'; import {autocompleteChannelsForSearch} from 'actions/channel_actions'; import {autocompleteUsersInCurrentTeam} from 'actions/user_actions'; @@ -43,6 +43,7 @@ function mapStateToProps(state: GlobalState) { const currentChannel = getCurrentChannel(state); const isMobileView = getIsMobileView(state); const isRhsOpen = getIsRhsOpen(state); + const crossTeamSearchEnabled = getIsCrossTeamSearchEnabled(state); return { currentChannel, @@ -64,7 +65,7 @@ function mapStateToProps(state: GlobalState) { isPinnedPosts: rhsState === RHSStates.PIN, isChannelFiles: rhsState === RHSStates.CHANNEL_FILES, isMobileView, - crossTeamSearchEnabled: getFeatureFlagValue(state, 'ExperimentalCrossTeamSearch') === 'true', + crossTeamSearchEnabled, }; } diff --git a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/general.ts b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/general.ts index 214e4200a8..0f4fd2217a 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/general.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/general.ts @@ -159,3 +159,7 @@ export const getCustomProfileAttributes: (state: GlobalState) => UserPropertyFie return Object.values(fields).sort((a, b) => (a.attrs?.sort_order ?? 0) - (b.attrs?.sort_order ?? 0)); }, ); + +export function getIsCrossTeamSearchEnabled(state: GlobalState): boolean { + return state.entities.general.config.EnableCrossTeamSearch === 'true'; +} diff --git a/webapp/platform/types/src/config.ts b/webapp/platform/types/src/config.ts index af8601fa7a..ce7188d139 100644 --- a/webapp/platform/types/src/config.ts +++ b/webapp/platform/types/src/config.ts @@ -62,6 +62,7 @@ export type ClientConfig = { EnableUserStatuses: string; EnableLastActiveTime: string; EnableTimedDND: string; + EnableCrossTeamSearch: 'true' | 'false'; EnableCustomTermsOfService: string; EnableDeveloper: string; EnableDiagnostics: string; @@ -353,6 +354,7 @@ export type ServiceSettings = { GiphySdkKey: string; PostEditTimeLimit: number; TimeBetweenUserTypingUpdatesMilliseconds: number; + EnableCrossTeamSearch: boolean; EnablePostSearch: boolean; EnableFileSearch: boolean; MinimumHashtagLength: number;