[MM-51844 & MM-51843] Work template permissions check (#22825)

Этот коммит содержится в:
Julien Tant
2023-04-10 09:51:20 -07:00
коммит произвёл GitHub
родитель fbe7323079
Коммит 6e7759b314
7 изменённых файлов: 67 добавлений и 18 удалений

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

@@ -42,7 +42,7 @@ content:
template: "Product Release"
name: "Feature release"
id: product-release-playbook
illustration: "/static/worktemplates/product_teams/feature_release/playbook.png"
illustration: "/static/worktemplates/playbooks/product_release.png"
- integration:
id: jira
- integration:
@@ -61,7 +61,7 @@ description:
board:
id: worktemplate.product_teams.goals_and_okrs.board
defaultMessage: >-
Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.
Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.
integration:
id: worktemplate.product_teams.goals_and_okrs.integration
defaultMessage: >-
@@ -134,7 +134,7 @@ description:
board:
id: worktemplate.product_teams.sprint_planning.board
defaultMessage: >-
Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments.
Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments.
integration:
id: worktemplate.product_teams.sprint_planning.integration
defaultMessage: >-
@@ -263,7 +263,7 @@ description:
board:
id: worktemplate.companywide.goals_and_okrs.board
defaultMessage: >-
Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.
Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.
integration:
id: worktemplate.companywide.goals_and_okrs.integration
defaultMessage: >-
@@ -337,7 +337,7 @@ description:
board:
id: worktemplate.leadership.goals_and_okrs.board
defaultMessage: >-
Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.
Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.
integration:
id: worktemplate.leadership.goals_and_okrs.integration
defaultMessage: >-

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

@@ -143,7 +143,7 @@ var wt00a1b44a5831c0a3acb14787b3fdd352 = &WorkTemplate{
Template: "Product Release",
Name: "Feature release",
ID: "product-release-playbook",
Illustration: "/static/worktemplates/product_teams/feature_release/playbook.png",
Illustration: "/static/worktemplates/playbooks/product_release.png",
},
},
{
@@ -174,7 +174,7 @@ var wt5baa68055bf9ea423273662e01ccc575 = &WorkTemplate{
},
Board: &TranslatableString{
ID: "worktemplate.product_teams.goals_and_okrs.board",
DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. ",
DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.",
Illustration: "",
},
@@ -286,7 +286,7 @@ var wt8d2ef53deac5517eb349dc5de6150196 = &WorkTemplate{
},
Board: &TranslatableString{
ID: "worktemplate.product_teams.sprint_planning.board",
DefaultMessage: "Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments. ",
DefaultMessage: "Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments.",
Illustration: "",
},
@@ -487,7 +487,7 @@ var wtf7b846d35810f8272eeb9a1a562025b5 = &WorkTemplate{
},
Board: &TranslatableString{
ID: "worktemplate.companywide.goals_and_okrs.board",
DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. ",
DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.",
Illustration: "",
},
@@ -601,7 +601,7 @@ var wt32ab773bfe021e3d4913931041552559 = &WorkTemplate{
},
Board: &TranslatableString{
ID: "worktemplate.leadership.goals_and_okrs.board",
DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. ",
DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board.",
Illustration: "",
},

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

@@ -11,9 +11,12 @@ import {trackEvent} from 'actions/telemetry_actions';
import Constants, {TELEMETRY_CATEGORIES} from 'utils/constants';
import {isEnterpriseOrE20License} from 'utils/license_utils';
import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {haveICurrentTeamPermission} from 'mattermost-redux/selectors/entities/roles';
import {Permissions} from 'mattermost-redux/constants';
import {GlobalState} from 'types/store';
import {Visibility, WorkTemplate} from '@mattermost/types/work_templates';
import {ChannelType} from '@mattermost/types/channels';
export interface CustomizeProps {
className?: string;
name: string;
@@ -38,6 +41,10 @@ const Customize = ({
const templateHasChannels = template.content.findIndex((item) => item.channel) !== -1;
const templateHasBoards = template.content.findIndex((item) => item.board) !== -1;
const templateHasPlaybooks = template.content.findIndex((item) => item.playbook) !== -1;
const canCreatePublicChannel = useSelector((state: GlobalState) => haveICurrentTeamPermission(state, Permissions.CREATE_PUBLIC_CHANNEL));
const canCreatePrivateChannel = useSelector((state: GlobalState) => haveICurrentTeamPermission(state, Permissions.CREATE_PRIVATE_CHANNEL));
const canCreatePublicPlaybook = useSelector((state: GlobalState) => haveICurrentTeamPermission(state, Permissions.PLAYBOOK_PUBLIC_CREATE));
const canCreatePrivatePlaybook = useSelector((state: GlobalState) => haveICurrentTeamPermission(state, Permissions.PLAYBOOK_PRIVATE_CREATE));
useEffect(() => {
trackEvent(TELEMETRY_CATEGORIES.WORK_TEMPLATES, 'pageview_customize');
@@ -49,10 +56,39 @@ const Customize = ({
};
let privateButtonProps = {};
if (templateHasPlaybooks && !licenseIsEnterprise) {
if (visibility === Visibility.Private) {
onVisibilityChanged(Visibility.Public);
let publicButtonProps = {};
if (templateHasPlaybooks) {
if (!canCreatePublicPlaybook) {
publicButtonProps = {
tooltip: formatMessage({id: 'work_templates.customize.public_playbook_permission_issue', defaultMessage: 'You do not have permission to create public playbooks.'}),
disabled: true,
};
}
if (!canCreatePrivatePlaybook) {
privateButtonProps = {
tooltip: formatMessage({id: 'work_templates.customize.private_playbook_permission_issue', defaultMessage: 'You do not have permission to create private playbooks.'}),
disabled: true,
};
}
}
if (templateHasChannels) {
if (!canCreatePublicChannel) {
publicButtonProps = {
tooltip: formatMessage({id: 'work_templates.customize.public_channel_permission_issue', defaultMessage: 'You do not have permission to create public channels.'}),
disabled: true,
};
}
if (!canCreatePrivateChannel) {
privateButtonProps = {
tooltip: formatMessage({id: 'work_templates.customize.private_channel_permission_issue', defaultMessage: 'You do not have permission to create private channels.'}),
disabled: true,
};
}
}
// leave this rule last as it has priority
if (templateHasPlaybooks && !licenseIsEnterprise) {
privateButtonProps = {
tooltip: formatMessage({id: 'work_templates.customize.private_playbook_license_issue', defaultMessage: 'Private playbooks requires an Enterprise license.'}),
locked: true,
@@ -98,6 +134,7 @@ const Customize = ({
selected={privacySelectorValue}
onChange={onPrivacySelectorChanged}
privateButtonProps={privateButtonProps}
publicButtonProps={publicButtonProps}
/>
</div>
</div>
@@ -146,4 +183,3 @@ const StyledCustomized = styled(Customize)`
`;
export default StyledCustomized;

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

@@ -5699,7 +5699,11 @@
"work_templates.customize.name_label_all": "Name your channel, board, and playbook",
"work_templates.customize.name_label_channels_boards": "Name your channel and board",
"work_templates.customize.name_label_channels_playbooks": "Name your channel and playbook",
"work_templates.customize.private_channel_permission_issue": "You do not have permission to create private channels.",
"work_templates.customize.private_playbook_license_issue": "Private playbooks requires an Enterprise license.",
"work_templates.customize.private_playbook_permission_issue": "You do not have permission to create private playbooks.",
"work_templates.customize.public_channel_permission_issue": "You do not have permission to create public channels.",
"work_templates.customize.public_playbook_permission_issue": "You do not have permission to create public playbooks.",
"work_templates.customize.visibility_title": "Who should have access to this?",
"work_templates.menu.modal_title": "Create from a template",
"work_templates.menu.quick_use": "Quick use",

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 516 KiB

После

Ширина:  |  Высота:  |  Размер: 516 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 516 KiB

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

@@ -3,14 +3,23 @@
import {createSelector} from 'reselect';
import {getFeatureFlagValue} from 'mattermost-redux/selectors/entities/general';
import {getFeatureFlagValue, getLicense} from 'mattermost-redux/selectors/entities/general';
import {GlobalState} from 'types/store';
import {haveICurrentTeamPermission} from 'mattermost-redux/selectors/entities/roles';
import {Permissions} from 'mattermost-redux/constants';
import {isEnterpriseOrE20License} from 'utils/license_utils';
export const areWorkTemplatesEnabled = createSelector(
'areWorktemplatesEnabled',
(state: GlobalState) => getFeatureFlagValue(state, 'WorkTemplate') === 'true',
(workTemplateFF) => {
return workTemplateFF;
(state: GlobalState) => getLicense(state),
(state: GlobalState) => haveICurrentTeamPermission(state, Permissions.CREATE_PUBLIC_CHANNEL) || haveICurrentTeamPermission(state, Permissions.CREATE_PRIVATE_CHANNEL),
(state: GlobalState) => haveICurrentTeamPermission(state, Permissions.PLAYBOOK_PUBLIC_CREATE),
(state: GlobalState) => haveICurrentTeamPermission(state, Permissions.PLAYBOOK_PRIVATE_CREATE),
(workTemplateFF, license, canCreateChannel, canCreatePublicPlaybook, canCreatePrivatePlaybook) => {
const licenseIsEnterprise = isEnterpriseOrE20License(license);
const canCreatePlaybook = canCreatePublicPlaybook || (canCreatePrivatePlaybook && licenseIsEnterprise);
return workTemplateFF && canCreateChannel && canCreatePlaybook;
},
);