diff --git a/webapp/channels/src/components/admin_console/admin_definition.tsx b/webapp/channels/src/components/admin_console/admin_definition.tsx index 85cf579652..3757c19590 100644 --- a/webapp/channels/src/components/admin_console/admin_definition.tsx +++ b/webapp/channels/src/components/admin_console/admin_definition.tsx @@ -93,6 +93,7 @@ import SecureConnectionDetail from './secure_connections/secure_connection_detai import ServerLogs from './server_logs'; import {searchableStrings as serverLogsSearchableStrings} from './server_logs/logs'; import SessionLengthSettings, {searchableStrings as sessionLengthSearchableStrings} from './session_length_settings'; +import SystemProperties, {searchableStrings as systemPropertiesSearchableStrings} from './system_properties'; import SystemRoles from './system_roles'; import SystemRole from './system_roles/system_role'; import SystemUserDetail from './system_user_detail'; @@ -2172,6 +2173,19 @@ const AdminDefinition: AdminDefinitionType = { ], }, }, + system_properties: { + url: 'site_config/system_properties', + title: defineMessage({id: 'admin.sidebar.system_properties', defaultMessage: 'System Properties'}), + searchableStrings: systemPropertiesSearchableStrings, + isHidden: it.not(it.all( + it.licensedForSku(LicenseSkus.Enterprise), + it.configIsTrue('FeatureFlags', 'CustomProfileAttributes'), + )), + schema: { + id: 'SystemProperties', + component: SystemProperties, + }, + }, localization: { url: 'site_config/localization', title: defineMessage({id: 'admin.sidebar.localization', defaultMessage: 'Localization'}), diff --git a/webapp/channels/src/components/admin_console/blockable_button/blockable_button.tsx b/webapp/channels/src/components/admin_console/blockable_button/blockable_button.tsx new file mode 100644 index 0000000000..229cc0a3f5 --- /dev/null +++ b/webapp/channels/src/components/admin_console/blockable_button/blockable_button.tsx @@ -0,0 +1,45 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useCallback} from 'react'; +import type {MouseEvent} from 'react'; + +type Props = { + id?: string; + activeClassName?: string; + + // Bool whether navigation is blocked + blocked: boolean; + + actions: { + + // Function for deferring navigation while blocked + deferNavigation: (func: () => void) => void; + }; + children?: React.ReactNode; + className?: string; + onClick?: (e: React.MouseEvent) => void; + onCancelConfirmed: () => void; +}; + +const BlockableButton = ({blocked, actions, onClick, onCancelConfirmed, ...restProps}: Props) => { + const handleClick = useCallback((e: MouseEvent) => { + onClick?.(e); + + if (blocked) { + e.preventDefault(); + actions.deferNavigation(() => { + onCancelConfirmed(); + }); + } + }, [actions, blocked, onClick, onCancelConfirmed]); + + return ( +