updatePermissionTemplate,
} from '../../../api/permissions';
import { Router, withRouter } from '../../../components/hoc/withRouter';
-import QualifierIcon from '../../../components/icons/QualifierIcon';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { queryToSearch } from '../../../helpers/urls';
import { PermissionTemplate } from '../../../types/types';
this.renderSetDefaultLink(
qualifier,
<span>
- {translate('permission_templates.set_default_for')}{' '}
- <QualifierIcon qualifier={qualifier} /> {translate('qualifiers', qualifier)}
+ {translate('permission_templates.set_default_for')} {translate('qualifiers', qualifier)}
</span>,
),
);
return (
<>
<ActionsDropdown
+ allowResizing
id={`permission-template-actions-${t.id}`}
zLevel={PopupZLevel.Global}
toggleClassName="it__permission-actions"
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Badge } from 'design-system';
import { sortBy } from 'lodash';
import * as React from 'react';
import { translate, translateWithParameters } from '../../../helpers/l10n';
.map((qualifier) => translate('qualifiers', qualifier))
.join(', ');
- return (
- <div>
- <span className="badge spacer-right">
- {translateWithParameters('permission_template.default_for', qualifiers)}
- </span>
- </div>
- );
+ return <Badge>{translateWithParameters('permission_template.default_for', qualifiers)}</Badge>;
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { DangerButtonPrimary, Modal, Spinner } from 'design-system';
import * as React from 'react';
-import SimpleModal from '../../../components/controls/SimpleModal';
-import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
-import Spinner from '../../../components/ui/Spinner';
+import { useState } from 'react';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { PermissionTemplate } from '../../../types/types';
}
export default function DeleteForm({ onClose, onSubmit, permissionTemplate: t }: Props) {
+ const [submitting, setSubmitting] = useState(false);
const header = translate('permission_template.delete_confirm_title');
- return (
- <SimpleModal header={header} onClose={onClose} onSubmit={onSubmit}>
- {({ onCloseClick, onFormSubmit, submitting }) => (
- <form onSubmit={onFormSubmit}>
- <div className="modal-head">
- <h2>{header}</h2>
- </div>
-
- <div className="modal-body">
- {translateWithParameters(
- 'permission_template.do_you_want_to_delete_template_xxx',
- t.name,
- )}
- </div>
+ const handleClick = React.useCallback(() => {
+ setSubmitting(true);
+ onSubmit();
+ }, [onSubmit]);
- <div className="modal-foot">
- <Spinner className="spacer-right" loading={submitting} />
- <SubmitButton className="button-red" disabled={submitting}>
- {translate('delete')}
- </SubmitButton>
- <ResetButtonLink disabled={submitting} onClick={onCloseClick}>
- {translate('cancel')}
- </ResetButtonLink>
- </div>
- </form>
+ return (
+ <Modal
+ onClose={onClose}
+ headerTitle={header}
+ secondaryButtonLabel={translate('cancel')}
+ body={translateWithParameters(
+ 'permission_template.do_you_want_to_delete_template_xxx',
+ t.name,
)}
- </SimpleModal>
+ primaryButton={
+ <>
+ <Spinner loading={submitting} />
+ <DangerButtonPrimary onClick={handleClick} disabled={submitting}>
+ {translate('delete')}
+ </DangerButtonPrimary>
+ </>
+ }
+ />
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ButtonPrimary, FormField, InputField, InputTextArea, Modal, Spinner } from 'design-system';
import * as React from 'react';
-import SimpleModal from '../../../components/controls/SimpleModal';
-import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
-import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
-import Spinner from '../../../components/ui/Spinner';
import { translate } from '../../../helpers/l10n';
interface Props {
description: string;
name: string;
projectKeyPattern: string;
+ submitting: boolean;
}
export default class Form extends React.PureComponent<Props, State> {
name: (props.permissionTemplate && props.permissionTemplate.name) || '',
projectKeyPattern:
(props.permissionTemplate && props.permissionTemplate.projectKeyPattern) || '',
+ submitting: false,
};
}
- handleSubmit = () => {
+ handleSubmit = (e: React.SyntheticEvent<HTMLFormElement>) => {
+ e.preventDefault();
+ this.setState({ submitting: true });
return this.props
.onSubmit({
description: this.state.description,
};
render() {
- return (
- <SimpleModal
- header={this.props.header}
- onClose={this.props.onClose}
- onSubmit={this.handleSubmit}
- size="small"
- >
- {({ onCloseClick, onFormSubmit, submitting }) => (
- <form id="permission-template-form" onSubmit={onFormSubmit}>
- <div className="modal-head">
- <h2>{this.props.header}</h2>
- </div>
+ const formBody = (
+ <form id="permission-template-form" onSubmit={this.handleSubmit}>
+ <div>
+ <div className="sw-mb-4">
+ <MandatoryFieldsExplanation />
+ </div>
- <div className="modal-body">
- <MandatoryFieldsExplanation className="modal-field" />
- <div className="modal-field">
- <label htmlFor="permission-template-name">
- {translate('name')}
- <MandatoryFieldMarker />
- </label>
- <input
- autoFocus
- id="permission-template-name"
- maxLength={256}
- name="name"
- onChange={this.handleNameChange}
- required
- type="text"
- value={this.state.name}
- />
- <div className="modal-field-description">{translate('should_be_unique')}</div>
- </div>
+ <FormField
+ description={translate('should_be_unique')}
+ label={translate('name')}
+ htmlFor="permission-template-name"
+ required
+ >
+ <InputField
+ autoFocus
+ id="permission-template-name"
+ maxLength={256}
+ name="name"
+ onChange={this.handleNameChange}
+ required
+ type="text"
+ value={this.state.name}
+ size="full"
+ />
+ </FormField>
- <div className="modal-field">
- <label htmlFor="permission-template-description">{translate('description')}</label>
- <textarea
- id="permission-template-description"
- name="description"
- onChange={this.handleDescriptionChange}
- value={this.state.description}
- />
- </div>
+ <FormField label={translate('description')} htmlFor="permission-template-description">
+ <InputTextArea
+ id="permission-template-description"
+ name="description"
+ onChange={this.handleDescriptionChange}
+ value={this.state.description}
+ size="full"
+ />
+ </FormField>
- <div className="modal-field">
- <label htmlFor="permission-template-project-key-pattern">
- {translate('permission_template.key_pattern')}
- </label>
- <input
- id="permission-template-project-key-pattern"
- maxLength={500}
- name="projectKeyPattern"
- onChange={this.handleProjectKeyPatternChange}
- type="text"
- value={this.state.projectKeyPattern}
- />
- <div className="modal-field-description">
- {translate('permission_template.key_pattern.description')}
- </div>
- </div>
- </div>
+ <FormField
+ htmlFor="permission-template-project-key-pattern"
+ label={translate('permission_template.key_pattern')}
+ description={translate('permission_template.key_pattern.description')}
+ >
+ <InputField
+ id="permission-template-project-key-pattern"
+ maxLength={500}
+ name="projectKeyPattern"
+ onChange={this.handleProjectKeyPatternChange}
+ type="text"
+ value={this.state.projectKeyPattern}
+ size="full"
+ />
+ </FormField>
+ </div>
+ </form>
+ );
- <div className="modal-foot">
- <Spinner className="spacer-right" loading={submitting} />
- <SubmitButton disabled={submitting} id="permission-template-submit">
- {this.props.confirmButtonText}
- </SubmitButton>
- <ResetButtonLink
- disabled={submitting}
- id="permission-template-cancel"
- onClick={onCloseClick}
- >
- {translate('cancel')}
- </ResetButtonLink>
- </div>
- </form>
- )}
- </SimpleModal>
+ return (
+ <Modal
+ secondaryButtonLabel={translate('cancel')}
+ headerTitle={this.props.header}
+ onClose={this.props.onClose}
+ body={formBody}
+ primaryButton={
+ <>
+ <Spinner loading={this.state.submitting} />
+ <ButtonPrimary
+ disabled={this.state.submitting}
+ type="submit"
+ form="permission-template-form"
+ id="permission-template-submit"
+ >
+ {this.props.confirmButtonText}
+ </ButtonPrimary>
+ </>
+ }
+ />
);
}
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ButtonPrimary, FlagMessage, Title } from 'design-system';
import React, { useState } from 'react';
import { createPermissionTemplate } from '../../../api/permissions';
-import { Button } from '../../../components/controls/buttons';
import { Router, withRouter } from '../../../components/hoc/withRouter';
-import { Alert } from '../../../components/ui/Alert';
import Spinner from '../../../components/ui/Spinner';
import { throwGlobalError } from '../../../helpers/error';
import { translate } from '../../../helpers/l10n';
};
return (
- <>
- <header className="page-header" id="project-permissions-header">
- <h1 className="page-title">{translate('permission_templates.page')}</h1>
+ <header>
+ <div id="project-permissions-header">
+ <div className="sw-flex sw-justify-between">
+ <Title>{translate('permission_templates.page')}</Title>
+ <Spinner loading={!ready} />
- <Spinner loading={!ready} />
-
- <div className="page-actions">
- <Button onClick={() => setCreateModal(true)}>{translate('create')}</Button>
-
- {createModal && (
- <Form
- confirmButtonText={translate('create')}
- header={translate('permission_template.new_template')}
- onClose={() => setCreateModal(false)}
- onSubmit={handleCreateModalSubmit}
- />
- )}
+ <ButtonPrimary onClick={() => setCreateModal(true)}>{translate('create')}</ButtonPrimary>
</div>
-
- <p className="page-description">{translate('permission_templates.page.description')}</p>
- </header>
+ <div className="sw-mb-4">{translate('permission_templates.page.description')}</div>
+ </div>
{gitHubProvisioningStatus && (
- <Alert variant="warning" className="sw-w-fit">
- {translate('permission_templates.github_warning')}
- </Alert>
+ <span>
+ <FlagMessage variant="warning" className="sw-w-fit sw-mb-4">
+ {translate('permission_templates.github_warning')}
+ </FlagMessage>
+ </span>
+ )}
+
+ {createModal && (
+ <Form
+ confirmButtonText={translate('create')}
+ header={translate('permission_template.new_template')}
+ onClose={() => setCreateModal(false)}
+ onSubmit={handleCreateModalSubmit}
+ />
)}
- </>
+ </header>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system';
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
import { translate } from '../../../helpers/l10n';
export default function Home(props: Props) {
return (
- <div className="page page-limited">
- <Helmet defer={false} title={translate('permission_templates.page')} />
+ <LargeCenteredLayout id="users-page">
+ <PageContentFontWrapper className="sw-my-8 sw-body-sm">
+ <Helmet defer={false} title={translate('permission_templates.page')} />
- <Header ready={props.ready} refresh={props.refresh} />
+ <Header ready={props.ready} refresh={props.refresh} />
- <main>
- <List
- permissionTemplates={props.permissionTemplates}
- permissions={props.permissions}
- refresh={props.refresh}
- topQualifiers={props.topQualifiers}
- />
- </main>
- </div>
+ <main>
+ <List
+ permissionTemplates={props.permissionTemplates}
+ permissions={props.permissions}
+ refresh={props.refresh}
+ topQualifiers={props.topQualifiers}
+ />
+ </main>
+ </PageContentFontWrapper>
+ </LargeCenteredLayout>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Table } from 'design-system';
import * as React from 'react';
import { Permission, PermissionTemplate } from '../../../types/types';
import ListHeader from './ListHeader';
));
return (
- <div className="boxed-group boxed-group-inner">
- <table className="data zebra permissions-table" id="permission-templates">
- <ListHeader permissions={props.permissions} />
- <tbody>{permissionTemplates}</tbody>
- </table>
- </div>
+ <Table
+ columnCount={8}
+ header={<ListHeader permissions={props.permissions} />}
+ id="permission-templates"
+ >
+ {permissionTemplates}
+ </Table>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ContentCell, FlagMessage, HelperHintIcon, TableRow } from 'design-system';
import * as React from 'react';
import InstanceMessage from '../../../components/common/InstanceMessage';
import HelpTooltip from '../../../components/controls/HelpTooltip';
-import { Alert } from '../../../components/ui/Alert';
import { translate } from '../../../helpers/l10n';
import { Permission } from '../../../types/types';
return permission.key === 'user' || permission.key === 'codeviewer' ? (
<div>
<InstanceMessage message={translate('projects_role', permission.key, 'desc')} />
- <Alert className="spacer-top" variant="warning">
+ <FlagMessage className="sw-mt-2" variant="warning">
{translate('projects_role.public_projects_warning')}
- </Alert>
+ </FlagMessage>
</div>
) : (
<InstanceMessage message={translate('projects_role', permission.key, 'desc')} />
render() {
const cells = this.props.permissions.map((permission) => (
- <th className="permission-column little-padded-left little-padded-right" key={permission.key}>
- <div className="permission-column-inner">
- <span className="text-middle">{translate('projects_role', permission.key)}</span>
- <HelpTooltip className="spacer-left" overlay={this.renderTooltip(permission)} />
- </div>
- </th>
+ <ContentCell key={permission.key}>
+ <span>{translate('projects_role', permission.key)}</span>
+ <HelpTooltip overlay={this.renderTooltip(permission)}>
+ <HelperHintIcon className="sw-ml-2" />
+ </HelpTooltip>
+ </ContentCell>
));
return (
- <thead>
- <tr>
- <th className="little-padded-left little-padded-right"> </th>
- {cells}
- <th className="thin nowrap text-right little-padded-left little-padded-right"> </th>
- </tr>
- </thead>
+ <TableRow>
+ <ContentCell> </ContentCell>
+ {cells}
+ <ContentCell> </ContentCell>
+ </TableRow>
);
}
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ContentCell, TableRow } from 'design-system';
import * as React from 'react';
import { PermissionTemplate } from '../../../types/types';
import ActionsCell from './ActionsCell';
));
return (
- <tr data-id={props.template.id} data-name={props.template.name}>
+ <TableRow data-id={props.template.id} data-name={props.template.name}>
<NameCell template={props.template} />
{permissions}
- <td className="nowrap thin text-right little-padded-left little-padded-right">
+ <ContentCell>
<ActionsCell
permissionTemplate={props.template}
refresh={props.refresh}
topQualifiers={props.topQualifiers}
/>
- </td>
- </tr>
+ </ContentCell>
+ </TableRow>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { CodeSnippet, ContentCell, Link } from 'design-system';
import * as React from 'react';
-import Link from '../../../components/common/Link';
import { queryToSearch } from '../../../helpers/urls';
import { PermissionTemplate } from '../../../types/types';
import { PERMISSION_TEMPLATES_PATH } from '../utils';
const pathname = PERMISSION_TEMPLATES_PATH;
return (
- <td className="little-padded-left little-padded-right">
- <Link to={{ pathname, search: queryToSearch({ id: template.id }) }}>
- <strong className="js-name">{template.name}</strong>
- </Link>
+ <ContentCell>
+ <div className="sw-flex sw-flex-col">
+ <span>
+ <Link to={{ pathname, search: queryToSearch({ id: template.id }) }}>
+ <span className="js-name">{template.name}</span>
+ </Link>
+ </span>
- {template.defaultFor.length > 0 && (
- <div className="spacer-top js-defaults">
- <Defaults template={template} />
- </div>
- )}
+ {template.defaultFor.length > 0 && (
+ <div className="js-defaults sw-mt-2">
+ <Defaults template={template} />
+ </div>
+ )}
- {!!template.description && (
- <div className="spacer-top js-description">{template.description}</div>
- )}
+ {!!template.description && (
+ <div className="js-description sw-mt-2">{template.description}</div>
+ )}
- {!!template.projectKeyPattern && (
- <div className="spacer-top js-project-key-pattern">
- Project Key Pattern: <code>{template.projectKeyPattern}</code>
- </div>
- )}
- </td>
+ {!!template.projectKeyPattern && (
+ <div className="js-project-key-pattern sw-mt-2">
+ Project Key Pattern:{' '}
+ <CodeSnippet snippet={template.projectKeyPattern} isOneLine noCopy />
+ </div>
+ )}
+ </div>
+ </ContentCell>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ContentCell, HelperHintIcon } from 'design-system';
import * as React from 'react';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { translate } from '../../../helpers/l10n';
export default function PermissionCell({ permission: p }: Props) {
return (
- <td className="permission-column little-padded-left little-padded-right">
- <div className="permission-column-inner">
+ <ContentCell className="sw-px-2">
+ <div>
<ul>
{p.withProjectCreator && (
- <li className="little-spacer-bottom display-flex-center">
+ <li className="sw-mb-2">
{translate('permission_templates.project_creators')}
<HelpTooltip
- className="little-spacer-left"
+ className="sw-ml-2"
overlay={translate('permission_templates.project_creators.explanation')}
- />
+ >
+ <HelperHintIcon className="sw-ml-2" />
+ </HelpTooltip>
</li>
)}
- <li className="little-spacer-bottom">
+ <li className="sw-mb-2">
<strong>{p.usersCount}</strong>
{' user(s)'}
</li>
</li>
</ul>
</div>
- </td>
+ </ContentCell>
);
}
name:
qualifier === ComponentQualifier.Project
? 'permission_templates.set_default'
- : `permission_templates.set_default_for qualifier.${qualifier} qualifiers.${qualifier}`,
+ : `permission_templates.set_default_for qualifiers.${qualifier}`,
}),
};
exports[`rendering should render the list of templates: Permission Template 2: admin 1`] = `"0 user(s)0 group(s)"`;
-exports[`rendering should render the list of templates: Permission Template 2: codeviewer 1`] = `"permission_templates.project_creatorspermission_templates.project_creators.explanation0 user(s)0 group(s)"`;
+exports[`rendering should render the list of templates: Permission Template 2: codeviewer 1`] = `"permission_templates.project_creators0 user(s)0 group(s)"`;
exports[`rendering should render the list of templates: Permission Template 2: issueadmin 1`] = `"0 user(s)0 group(s)"`;
exports[`rendering should render the list of templates: Permission Template 2: securityhotspotadmin 1`] = `"0 user(s)0 group(s)"`;
-exports[`rendering should render the list of templates: Permission Template 2: user 1`] = `"permission_templates.project_creatorspermission_templates.project_creators.explanation0 user(s)0 group(s)"`;
+exports[`rendering should render the list of templates: Permission Template 2: user 1`] = `"permission_templates.project_creators0 user(s)0 group(s)"`;