Unverified Commit ce8b39b6 authored by Martin Kraft's avatar Martin Kraft Committed by GitHub
Browse files

MM-10402: Adds view for unstarted and in-progress permissions phase 2… (#1246)

* MM-10402: Adds view for unstarted and in-progress permissions phase 2 migrations.

* MM-10402: Typo corrections.

* MM-10402: Changes from FormattedHTMLMessage to FormattedMessage.
parent 58aac948
......@@ -6,12 +6,18 @@ import {bindActionCreators} from 'redux';
import {getSchemeTeams as loadSchemeTeams, getSchemes as loadSchemes} from 'mattermost-redux/actions/schemes';
import {getSchemes} from 'mattermost-redux/selectors/entities/schemes';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import PermissionSchemesSettings from './permission_schemes_settings.jsx';
function mapStateToProps(state) {
const schemes = getSchemes(state);
const config = getConfig(state);
return {
schemes: getSchemes(state),
schemes: typeof schemes === 'object' ? [] : schemes,
jobsAreEnabled: config.RunJobs === 'true',
clusterIsEnabled: config.EnableCluster === 'true',
};
}
......
......@@ -11,10 +11,13 @@ import LoadingScreen from 'components/loading_screen.jsx';
import PermissionsSchemeSummary from './permissions_scheme_summary';
const PAGE_SIZE = 30;
const PHASE_2_MIGRATION_IMCOMPLETE_STATUS_CODE = 501;
export default class PermissionSchemesSettings extends React.PureComponent {
static propTypes = {
schemes: PropTypes.array.isRequired,
jobsAreEnabled: PropTypes.bool,
clusterIsEnabled: PropTypes.bool,
actions: PropTypes.shape({
loadSchemes: PropTypes.func.isRequired,
loadSchemeTeams: PropTypes.func.isRequired,
......@@ -27,6 +30,7 @@ export default class PermissionSchemesSettings extends React.PureComponent {
loading: true,
loadingMore: false,
page: 0,
phase2MigrationIsComplete: false,
};
}
......@@ -34,14 +38,22 @@ export default class PermissionSchemesSettings extends React.PureComponent {
schemes: [],
};
componentDidMount() {
this.props.actions.loadSchemes('team', 0, PAGE_SIZE).then((schemes) => {
async componentWillMount() {
let schemes;
let phase2MigrationIsComplete = true; // Assume migration is complete unless HTTP status code says otherwise.
try {
schemes = await this.props.actions.loadSchemes('team', 0, PAGE_SIZE);
if (schemes.error.status_code === PHASE_2_MIGRATION_IMCOMPLETE_STATUS_CODE) {
phase2MigrationIsComplete = false;
}
const promises = [];
for (const scheme of schemes.data) {
promises.push(this.props.actions.loadSchemeTeams(scheme.id));
}
Promise.all(promises).then(() => this.setState({loading: false}));
});
Promise.all(promises).then(() => this.setState({loading: false, phase2MigrationIsComplete}));
} catch (err) {
this.setState({loading: false, phase2MigrationIsComplete});
}
}
loadMoreSchemes = () => {
......@@ -55,6 +67,58 @@ export default class PermissionSchemesSettings extends React.PureComponent {
});
}
// |RunJobs && !EnableCluster|(*App).IsPhase2MigrationCompleted|View |
// |-------------------------|---------------------------------|-------------------------------------------------------|
// |true |true |null |
// |false |true |null (Jobs were disabled after a successful migration.)|
// |false |false |On hold view. |
// |true |false |In progress view. |
teamOverrideSchemesMigrationView = () => {
if (this.state.phase2MigrationIsComplete) {
return null;
}
const docLink = (
<Link
to='https://docs.mattermost.com/administration/config-settings.html#jobs'
target='_blank'
>
<FormattedMessage
id='admin.permissions.documentationLinkText'
defaultMessage='documentation'
/>
</Link>
);
if (this.props.jobsAreEnabled && !this.props.clusterIsEnabled) {
return this.teamOverrideUnavalableView(
'admin.permissions.teamOverrideSchemesInProgress',
'Migration job in progress: Team Override Schemes are not available until the job server completes the permissions migration. Learn more in the {documentationLink}.',
docLink
);
}
return this.teamOverrideUnavalableView(
'admin.permissions.teamOverrideSchemesNoJobsEnabled',
'Migration job on hold: Team Override Schemes are not available until the job server can execute the permissions migration. The job will be automatically started when the job server is enabled. Learn more in the {documentationLink}.',
docLink,
);
}
teamOverrideUnavalableView = (id, defaultMsg, documentationLink) => {
return (
<div className='team-override-unavailable'>
<div className='team-override-unavailable__inner'>
<FormattedMessage
id={id}
defaultMessage={defaultMsg}
values={{documentationLink}}
/>
</div>
</div>
);
};
render = () => {
if (this.state.loading) {
return (<LoadingScreen/>);
......@@ -66,6 +130,8 @@ export default class PermissionSchemesSettings extends React.PureComponent {
/>
));
const teamOverrideView = this.teamOverrideSchemesMigrationView();
return (
<div className='wrapper--fixed'>
<h3 className='admin-console-header'>
......@@ -136,6 +202,14 @@ export default class PermissionSchemesSettings extends React.PureComponent {
<Link
className='btn btn-primary'
to='/admin_console/permissions/team-override-scheme'
disabled={teamOverrideView !== null}
onClick={(e) => {
if (teamOverrideView !== null) {
e.preventDefault();
return false;
}
return true;
}}
>
<FormattedMessage
id='admin.permissions.teamOverrideSchemesNewButton'
......@@ -144,13 +218,14 @@ export default class PermissionSchemesSettings extends React.PureComponent {
</Link>
</div>
</div>
{schemes.length === 0 &&
{schemes.length === 0 && teamOverrideView === null &&
<div className='no-team-schemes'>
<FormattedMessage
id='admin.permissions.teamOverrideSchemesNoSchemes'
defaultMessage='No team override schemes created.'
/>
</div> }
</div>}
{teamOverrideView}
{schemes.length > 0 && schemes}
{!this.state.loadingMore && schemes.length === (PAGE_SIZE * (this.state.page + 1)) &&
<button
......
......@@ -261,6 +261,9 @@
"admin.permissions.teamOverrideSchemesBannerText": "Use when specific teams need permission exceptions to the System Scheme.",
"admin.permissions.teamOverrideSchemesNewButton": "New Team Override Scheme",
"admin.permissions.teamOverrideSchemesNoSchemes": "No team override schemes created.",
"admin.permissions.teamOverrideSchemesNoJobsEnabled": "Migration job on hold: Team Override Schemes are not available until the job server can execute the permissions migration. The job will be automatically started when the job server is enabled. Learn more in the {documentationLink}.",
"admin.permissions.teamOverrideSchemesInProgress": "Migration job in progress: Team Override Schemes are not available until the job server completes the permissions migration. Learn more in the {documentationLink}.",
"admin.permissions.documentationLinkText": "documentation",
"admin.permissions.loadMoreSchemes": "Load more schemes",
"admin.permissions.loadingMoreSchemes": "Loading...",
"admin.permissions.permissionsSchemeSummary.deleteSchemeTitle": "Delete {scheme} scheme?",
......
This diff is collapsed.
......@@ -82,6 +82,15 @@
color: $gray;
text-align: center;
}
.team-override-unavailable {
padding: 20px;
color: #3333337d;
opacity: 50%;
.team-override-unavailable__inner {
padding: 20px;
background-color: $white;
}
}
}
.permissions-tree {
......
......@@ -101,6 +101,8 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes
>
<Link
className="btn btn-primary"
disabled={false}
onClick={[Function]}
replace={false}
to="/admin_console/permissions/team-override-scheme"
>
......@@ -240,6 +242,8 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes
>
<Link
className="btn btn-primary"
disabled={false}
onClick={[Function]}
replace={false}
to="/admin_console/permissions/team-override-scheme"
>
......@@ -263,3 +267,480 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes
</div>
</div>
`;
exports[`components/admin_console/permission_schemes_settings/permission_schemes_settings should show migration in-progress view 1`] = `
<div
className="wrapper--fixed"
>
<h3
className="admin-console-header"
>
<FormattedMessage
defaultMessage="Permission Schemes"
id="admin.permissions.permissionSchemes"
values={Object {}}
/>
</h3>
<div
className="banner info"
>
<div
className="banner__content"
>
<span>
<FormattedMessage
defaultMessage="Permission Schemes set the default permissions for Team Admins, Channel Admins and everyone else. Learn more about permission schemes in our documentation."
id="admin.permissions.introBanner"
values={Object {}}
/>
</span>
</div>
</div>
<div
className="permissions-block"
>
<div
className="header"
>
<div>
<h3>
<FormattedMessage
defaultMessage="System Scheme"
id="admin.permissions.systemSchemeBannerTitle"
values={Object {}}
/>
</h3>
<span>
<FormattedMessage
defaultMessage="Set the default permissions inherited by all teams unless a Team Override Scheme is applied."
id="admin.permissions.systemSchemeBannerText"
values={Object {}}
/>
</span>
</div>
<div
className="button"
>
<Link
className="btn btn-primary"
replace={false}
to="/admin_console/permissions/system-scheme"
>
<FormattedMessage
defaultMessage="Edit Scheme"
id="admin.permissions.systemSchemeBannerButton"
values={Object {}}
/>
</Link>
</div>
</div>
</div>
<div
className="permissions-block"
>
<div
className="header"
>
<div>
<h3>
<FormattedMessage
defaultMessage="Team Override Schemes"
id="admin.permissions.teamOverrideSchemesTitle"
values={Object {}}
/>
</h3>
<span>
<FormattedMessage
defaultMessage="Use when specific teams need permission exceptions to the System Scheme."
id="admin.permissions.teamOverrideSchemesBannerText"
values={Object {}}
/>
</span>
</div>
<div
className="button"
>
<Link
className="btn btn-primary"
disabled={true}
onClick={[Function]}
replace={false}
to="/admin_console/permissions/team-override-scheme"
>
<FormattedMessage
defaultMessage="New Team Override Scheme"
id="admin.permissions.teamOverrideSchemesNewButton"
values={Object {}}
/>
</Link>
</div>
</div>
<div
className="team-override-unavailable"
>
<div
className="team-override-unavailable__inner"
>
<FormattedMessage
defaultMessage="Migration job in progress: Team Override Schemes are not available until the job server completes the permissions migration. Learn more in the {documentationLink}."
id="admin.permissions.teamOverrideSchemesInProgress"
values={
Object {
"documentationLink": <Link
replace={false}
target="_blank"
to="https://docs.mattermost.com/administration/config-settings.html#jobs"
>
<FormattedMessage
defaultMessage="documentation"
id="admin.permissions.documentationLinkText"
values={Object {}}
/>
</Link>,
}
}
/>
</div>
</div>
<Connect(PermissionsSchemeSummary)
key="id-1"
scheme={
Object {
"description": "Test description 1",
"id": "id-1",
"name": "Test 1",
}
}
/>
<Connect(PermissionsSchemeSummary)
key="id-2"
scheme={
Object {
"description": "Test description 2",
"id": "id-2",
"name": "Test 2",
}
}
/>
<Connect(PermissionsSchemeSummary)
key="id-3"
scheme={
Object {
"description": "Test description 3",
"id": "id-3",
"name": "Test 3",
}
}
/>
</div>
</div>
`;
exports[`components/admin_console/permission_schemes_settings/permission_schemes_settings should show migration on hold view 1`] = `
<div
className="wrapper--fixed"
>
<h3
className="admin-console-header"
>
<FormattedMessage
defaultMessage="Permission Schemes"
id="admin.permissions.permissionSchemes"
values={Object {}}
/>
</h3>
<div
className="banner info"
>
<div
className="banner__content"
>
<span>
<FormattedMessage
defaultMessage="Permission Schemes set the default permissions for Team Admins, Channel Admins and everyone else. Learn more about permission schemes in our documentation."
id="admin.permissions.introBanner"
values={Object {}}
/>
</span>
</div>
</div>
<div
className="permissions-block"
>
<div
className="header"
>
<div>
<h3>
<FormattedMessage
defaultMessage="System Scheme"
id="admin.permissions.systemSchemeBannerTitle"
values={Object {}}
/>
</h3>
<span>
<FormattedMessage
defaultMessage="Set the default permissions inherited by all teams unless a Team Override Scheme is applied."
id="admin.permissions.systemSchemeBannerText"
values={Object {}}
/>
</span>
</div>
<div
className="button"
>
<Link
className="btn btn-primary"
replace={false}
to="/admin_console/permissions/system-scheme"
>
<FormattedMessage
defaultMessage="Edit Scheme"
id="admin.permissions.systemSchemeBannerButton"
values={Object {}}
/>
</Link>
</div>
</div>
</div>
<div
className="permissions-block"
>
<div
className="header"
>
<div>
<h3>
<FormattedMessage
defaultMessage="Team Override Schemes"
id="admin.permissions.teamOverrideSchemesTitle"
values={Object {}}
/>
</h3>
<span>
<FormattedMessage
defaultMessage="Use when specific teams need permission exceptions to the System Scheme."
id="admin.permissions.teamOverrideSchemesBannerText"
values={Object {}}
/>
</span>
</div>
<div
className="button"
>
<Link
className="btn btn-primary"
disabled={true}
onClick={[Function]}
replace={false}
to="/admin_console/permissions/team-override-scheme"
>
<FormattedMessage
defaultMessage="New Team Override Scheme"
id="admin.permissions.teamOverrideSchemesNewButton"
values={Object {}}
/>
</Link>
</div>
</div>
<div
className="team-override-unavailable"
>
<div
className="team-override-unavailable__inner"
>
<FormattedMessage
defaultMessage="Migration job on hold: Team Override Schemes are not available until the job server can execute the permissions migration. The job will be automatically started when the job server is enabled. Learn more in the {documentationLink}."
id="admin.permissions.teamOverrideSchemesNoJobsEnabled"
values={
Object {
"documentationLink": <Link
replace={false}
target="_blank"
to="https://docs.mattermost.com/administration/config-settings.html#jobs"
>
<FormattedMessage
defaultMessage="documentation"
id="admin.permissions.documentationLinkText"
values={Object {}}
/>
</Link>,
}
}
/>
</div>
</div>
<Connect(PermissionsSchemeSummary)
key="id-1"
scheme={
Object {
"description": "Test description 1",
"id": "id-1",
"name": "Test 1",
}
}
/>
<Connect(PermissionsSchemeSummary)
key="id-2"
scheme={
Object {
"description": "Test description 2",
"id": "id-2",
"name": "Test 2",
}
}
/>
<Connect(PermissionsSchemeSummary)
key="id-3"
scheme={
Object {
"description": "Test description 3",
"id": "id-3",
"name": "Test 3",
}
}
/>
</div>
</div>
`;
exports[`components/admin_console/permission_schemes_settings/permission_schemes_settings should show normal view (jobs disabled after migration) 1`] = `
<div
className="wrapper--fixed"
>
<h3
className="admin-console-header"
>
<FormattedMessage
defaultMessage="Permission Schemes"
id="admin.permissions.permissionSchemes"
values={Object {}}
/>
</h3>
<div
className="banner info"
>
<div
className="banner__content"
>
<span>
<FormattedMessage
defaultMessage="Permission Schemes set the default permissions for Team Admins, Channel Admins and everyone else. Learn more about permission schemes in our documentation."
id="admin.permissions.introBanner"
values={Object {}}
/>
</span>