Adding unsupported text into the team/e0 edition menu (#27038)

* Adding unsupported text into the team/e0 edition menu

* Fixing CI

* Addressing PR review comments

* Removing start trial from the product menu

* Fixing tests

* Updating i18n
Этот коммит содержится в:
Jesús Espino
2024-05-22 21:24:38 +02:00
коммит произвёл GitHub
родитель 8f95656c8f
Коммит f4a3a2ec07
5 изменённых файлов: 38 добавлений и 282 удалений

Просмотреть файл

@@ -333,13 +333,15 @@
}
}
.start_trial_content {
.editionText {
position: relative;
width: 100%;
}
.editionName {
text-transform: capitalize;
a {
color: var(--link-color);
&:hover {
background: none;
}
}
}
}
}

Просмотреть файл

@@ -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(<reactRedux.Provider store={store}><MenuStartTrial id='startTrial'/></reactRedux.Provider>);
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(<reactRedux.Provider store={store}><MenuStartTrial id='startTrial'/></reactRedux.Provider>);
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(<reactRedux.Provider store={store}><MenuStartTrial id='startTrial'/></reactRedux.Provider>);
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(<reactRedux.Provider store={store}><MenuStartTrial id='startTrial'/></reactRedux.Provider>);
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(<reactRedux.Provider store={store}><MenuStartTrial id='startTrial'/></reactRedux.Provider>);
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);
});
});

Просмотреть файл

@@ -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 (
<li
className={'MenuStartTrial'}
@@ -84,24 +51,24 @@ const MenuStartTrial = (props: Props): JSX.Element | null => {
id={props.id}
>
<FreeVersionBadge>{'FREE EDITION'}</FreeVersionBadge>
{isE0 &&
<div className='start_trial_content'>
{formatMessage({
id: 'navbar_dropdown.versionTextE0',
defaultMessage: 'This is the free edition of Mattermost, ideal for evaluation and small teams.',
})}
</div>}
{!isE0 &&
<div className='start_trial_content'>
{formatMessage({
id: 'navbar_dropdown.versionTextTeamEdition',
defaultMessage: 'This is the free open source edition of Mattermost, ideal for evaluation and small teams.',
})}
</div>}
{showTrialButton &&
<button onClick={openLearnMoreTrialModal}>
{formatMessage({id: 'navbar_dropdown.startAnEnterpriseTrial', defaultMessage: 'Start an Enterprise trial'})}
</button>}
<div className='editionText'>
{formatMessage(
{
id: 'navbar_dropdown.versionText',
defaultMessage: 'This is the free <link>unsupported</link> edition of Mattermost.',
},
{
link: (msg: React.ReactNode) => (
<ExternalLink
location='menu_start_trial.unsupported-link'
href={LicenseLinks.UNSUPPORTED}
>
{msg}
</ExternalLink>
),
},
)}
</div>
</li>
);
};

Просмотреть файл

@@ -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 <link>unsupported</link> edition of Mattermost.",
"navbar_dropdown.viewMembers": "View Members",
"navbar.addGroups": "Add Groups",
"navbar.addMembers": "Add Members",

Просмотреть файл

@@ -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/';