diff --git a/webapp/channels/src/components/widgets/menu/menu_items/menu_item.scss b/webapp/channels/src/components/widgets/menu/menu_items/menu_item.scss index ac0e2747f6..b56ade7dd0 100644 --- a/webapp/channels/src/components/widgets/menu/menu_items/menu_item.scss +++ b/webapp/channels/src/components/widgets/menu/menu_items/menu_item.scss @@ -333,13 +333,15 @@ } } - .start_trial_content { + .editionText { position: relative; width: 100%; - } - - .editionName { - text-transform: capitalize; + a { + color: var(--link-color); + &:hover { + background: none; + } + } } } } diff --git a/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.test.tsx b/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.test.tsx index e608556ed3..e205e79b75 100644 --- a/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.test.tsx +++ b/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.test.tsx @@ -4,8 +4,6 @@ import React from 'react'; import * as reactRedux from 'react-redux'; -import {Permissions} from 'mattermost-redux/constants'; - import {mountWithIntl} from 'tests/helpers/intl-test-helper'; import mockStore from 'tests/test_store'; @@ -18,7 +16,7 @@ describe('components/widgets/menu/menu_items/menu_start_trial', () => { useDispatchMock.mockClear(); }); - test('should render when no trial license has ever been used and there is no license currently loaded', () => { + test('should render null there is no license currently loaded', () => { const state = { entities: { users: { @@ -31,99 +29,22 @@ describe('components/widgets/menu/menu_items/menu_start_trial', () => { }, }, general: { - config: { - EnableTutorial: 'true', - BuildEnterpriseReady: 'true', - }, - license: { - IsLicensed: 'false', - }, - }, - admin: { - prevTrialLicense: { - IsLicensed: 'false', - }, - }, - roles: { - roles: { - system_user: { - permissions: [Permissions.SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE], - }, - }, - }, - preferences: { - myPreferences: { - 'tutorial_step-test_id': { - user_id: 'test_id', - category: 'tutorial_step', - name: 'test_id', - value: '6', - }, - }, - }, - }, - }; - const store = mockStore(state); - const dummyDispatch = jest.fn(); - useDispatchMock.mockReturnValue(dummyDispatch); - const wrapper = mountWithIntl(); - expect(wrapper.find('button').exists()).toEqual(true); - }); - - test('should render null when prevTrialLicense was used and there is no license currently loaded', () => { - const state = { - entities: { - users: { - currentUserId: 'test_id', - profiles: { - test_id: { - id: 'test_id', - roles: 'system_user', - }, - }, - }, - general: { - config: { - EnableTutorial: 'true', - BuildEnterpriseReady: 'true', - }, + config: {}, license: { IsLicensed: 'false', IsTrial: 'false', }, }, - admin: { - prevTrialLicense: { - IsLicensed: 'true', - }, - }, - roles: { - roles: { - system_user: { - permissions: [Permissions.SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE], - }, - }, - }, - preferences: { - myPreferences: { - 'tutorial_step-test_id': { - user_id: 'test_id', - category: 'tutorial_step', - name: 'test_id', - value: '6', - }, - }, - }, }, }; const store = mockStore(state); const dummyDispatch = jest.fn(); useDispatchMock.mockReturnValue(dummyDispatch); const wrapper = mountWithIntl(); - expect(wrapper.find('button').exists()).toEqual(false); + expect(wrapper.find('.editionText').exists()).toBe(true); }); - test('should render null when no trial license has ever been used but there is a license currently loaded', () => { + test('should render null when there is a license currently loaded', () => { const state = { entities: { users: { @@ -136,151 +57,18 @@ describe('components/widgets/menu/menu_items/menu_start_trial', () => { }, }, general: { - config: { - EnableTutorial: 'true', - BuildEnterpriseReady: 'true', - }, + config: {}, license: { IsLicensed: 'true', IsTrial: 'false', }, }, - admin: { - prevTrialLicense: { - IsLicensed: 'false', - }, - }, - roles: { - roles: { - system_user: { - permissions: [Permissions.SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE], - }, - }, - }, - preferences: { - myPreferences: { - 'tutorial_step-test_id': { - user_id: 'test_id', - category: 'tutorial_step', - name: 'test_id', - value: '6', - }, - }, - }, }, }; const store = mockStore(state); const dummyDispatch = jest.fn(); useDispatchMock.mockReturnValue(dummyDispatch); const wrapper = mountWithIntl(); - expect(wrapper.find('button').exists()).toEqual(false); - }); - - test('should render null when is current licensed but is trial and you have no permissions to load the trial', () => { - const state = { - entities: { - users: { - currentUserId: 'test_id', - profiles: { - test_id: { - id: 'test_id', - roles: 'system_user', - }, - }, - }, - general: { - config: { - EnableTutorial: 'true', - BuildEnterpriseReady: 'true', - }, - license: { - IsLicensed: 'true', - IsTrial: 'true', - }, - }, - admin: { - prevTrialLicense: { - IsLicensed: 'false', - }, - }, - roles: { - roles: { - system_user: { - permissions: [], - }, - }, - }, - preferences: { - myPreferences: { - 'tutorial_step-test_id': { - user_id: 'test_id', - category: 'tutorial_step', - name: 'test_id', - value: '6', - }, - }, - }, - }, - }; - const store = mockStore(state); - const dummyDispatch = jest.fn(); - useDispatchMock.mockReturnValue(dummyDispatch); - const wrapper = mountWithIntl(); - expect(wrapper.find('button').exists()).toEqual(false); - }); - - test('should render menu option that open the start trial modal when has no license and no previous license and you have permissions to load the trial', () => { - const state = { - entities: { - users: { - currentUserId: 'test_id', - profiles: { - test_id: { - id: 'test_id', - roles: 'system_user', - }, - }, - }, - general: { - config: { - EnableTutorial: 'true', - BuildEnterpriseReady: 'true', - }, - license: { - IsLicensed: 'false', - IsTrial: 'false', - }, - }, - admin: { - prevTrialLicense: { - IsLicensed: 'false', - }, - }, - roles: { - roles: { - system_user: { - permissions: [Permissions.SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE], - }, - }, - }, - preferences: { - myPreferences: { - 'tutorial_step-test_id': { - user_id: 'test_id', - category: 'tutorial_step', - name: 'test_id', - value: '6', - }, - }, - }, - }, - }; - const store = mockStore(state); - const dummyDispatch = jest.fn(); - useDispatchMock.mockReturnValue(dummyDispatch); - const wrapper = mountWithIntl(); - expect(wrapper.find('button').exists()).toEqual(true); - expect(wrapper.find('div.start_trial_content').text()).toEqual('This is the free edition of Mattermost, ideal for evaluation and small teams.'); - expect(wrapper.find('button').text()).toEqual('Start an Enterprise trial'); + expect(wrapper.find('.editionText').exists()).toBe(false); }); }); diff --git a/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.tsx b/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.tsx index efcb11d8a1..35646539c4 100644 --- a/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.tsx +++ b/webapp/channels/src/components/widgets/menu/menu_items/menu_start_trial.tsx @@ -1,29 +1,19 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useEffect} from 'react'; +import React from 'react'; import {useIntl} from 'react-intl'; -import {useDispatch, useSelector} from 'react-redux'; +import {useSelector} from 'react-redux'; import styled from 'styled-components'; -import type {GlobalState} from '@mattermost/types/store'; +import {getLicense} from 'mattermost-redux/selectors/entities/general'; -import {getPrevTrialLicense} from 'mattermost-redux/actions/admin'; -import {Permissions} from 'mattermost-redux/constants'; -import {getLicense, getConfig} from 'mattermost-redux/selectors/entities/general'; -import {haveISystemPermission} from 'mattermost-redux/selectors/entities/roles'; +import ExternalLink from 'components/external_link'; -import {trackEvent} from 'actions/telemetry_actions'; -import {openModal} from 'actions/views/modals'; - -import {makeAsyncComponent} from 'components/async_load'; - -import {ModalIdentifiers, TELEMETRY_CATEGORIES} from 'utils/constants'; +import {LicenseLinks} from 'utils/constants'; import './menu_item.scss'; -const LearnMoreTrialModal = makeAsyncComponent('LearnMoreTrialModal', React.lazy(() => import('components/learn_more_trial_modal/learn_more_trial_modal'))); - const FreeVersionBadge = styled.div` position: relative; top: 1px; @@ -46,37 +36,14 @@ type Props = { const MenuStartTrial = (props: Props): JSX.Element | null => { const {formatMessage} = useIntl(); - const dispatch = useDispatch(); - useEffect(() => { - dispatch(getPrevTrialLicense()); - }, []); - - const config = useSelector(getConfig); - const isE0 = config.BuildEnterpriseReady === 'true'; - const hasPermissionForStartTrial = useSelector((state: GlobalState) => haveISystemPermission(state, {permission: Permissions.SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE})); - - const openLearnMoreTrialModal = () => { - trackEvent( - TELEMETRY_CATEGORIES.SELF_HOSTED_START_TRIAL_MODAL, - 'open_learn_more_trial_modal', - ); - dispatch(openModal({ - modalId: ModalIdentifiers.LEARN_MORE_TRIAL_MODAL, - dialogType: LearnMoreTrialModal, - })); - }; - const prevTrialLicense = useSelector((state: GlobalState) => state.entities.admin.prevTrialLicense); const license = useSelector(getLicense); - const isPrevLicensed = prevTrialLicense?.IsLicensed; const isCurrentLicensed = license?.IsLicensed; if (isCurrentLicensed === 'true') { return null; } - const showTrialButton = isCurrentLicensed === 'false' && isPrevLicensed === 'false' && hasPermissionForStartTrial && isE0; - return (
  • { id={props.id} > {'FREE EDITION'} - {isE0 && -
    - {formatMessage({ - id: 'navbar_dropdown.versionTextE0', - defaultMessage: 'This is the free edition of Mattermost, ideal for evaluation and small teams.', - })} -
    } - {!isE0 && -
    - {formatMessage({ - id: 'navbar_dropdown.versionTextTeamEdition', - defaultMessage: 'This is the free open source edition of Mattermost, ideal for evaluation and small teams.', - })} -
    } - {showTrialButton && - } +
    + {formatMessage( + { + id: 'navbar_dropdown.versionText', + defaultMessage: 'This is the free unsupported edition of Mattermost.', + }, + { + link: (msg: React.ReactNode) => ( + + {msg} + + ), + }, + )} +
  • ); }; diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 2e454d0337..bc07bdd6f5 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -4236,7 +4236,6 @@ "navbar_dropdown.nativeApps": "Download Apps", "navbar_dropdown.profileSettings": "Profile", "navbar_dropdown.report": "Report a Problem", - "navbar_dropdown.startAnEnterpriseTrial": "Start an Enterprise trial", "navbar_dropdown.switchTo": "Switch to ", "navbar_dropdown.teamSettings": "Team Settings", "navbar_dropdown.userGroups": "User Groups", @@ -4247,8 +4246,7 @@ "navbar_dropdown.userGroups.modal.titleAdminPreTrial": "Try unlimited user groups with a free trial", "navbar_dropdown.userGroups.modal.titleEndUser": "User groups available in paid plans", "navbar_dropdown.userGroups.tooltip.cloudFreeTrial": "During your trial you are able to create user groups. These user groups will be archived after your trial.", - "navbar_dropdown.versionTextE0": "This is the free edition of Mattermost, ideal for evaluation and small teams.", - "navbar_dropdown.versionTextTeamEdition": "This is the free open source edition of Mattermost, ideal for evaluation and small teams.", + "navbar_dropdown.versionText": "This is the free unsupported edition of Mattermost.", "navbar_dropdown.viewMembers": "View Members", "navbar.addGroups": "Add Groups", "navbar.addMembers": "Add Members", diff --git a/webapp/channels/src/utils/constants.tsx b/webapp/channels/src/utils/constants.tsx index c4b8520f39..d91b9fbad0 100644 --- a/webapp/channels/src/utils/constants.tsx +++ b/webapp/channels/src/utils/constants.tsx @@ -1114,6 +1114,7 @@ export const LicenseLinks = { EMBARGOED_COUNTRIES: 'https://mattermost.com/pl/limitations-for-embargoed-countries', SOFTWARE_SERVICES_LICENSE_AGREEMENT: 'https://mattermost.com/pl/software-and-services-license-agreement', SOFTWARE_SERVICES_LICENSE_AGREEMENT_TEXT: 'Software Services and License Agreement', + UNSUPPORTED: 'https://mattermost.com/pricing/', }; export const MattermostLink = 'https://mattermost.com/';