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
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8f95656c8f
Коммит
f4a3a2ec07
@@ -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/';
|
||||
|
||||
Ссылка в новой задаче
Block a user