aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorDavid Cho-Lerat <david.cho-lerat@sonarsource.com>2024-09-18 14:52:23 +0200
committersonartech <sonartech@sonarsource.com>2024-09-24 20:03:04 +0000
commit9f80a169ea2c85db1cd8479c42ce609b80aeafaf (patch)
tree26dcfcc6d66a2e08e81b470fc69325d19b9e07a1 /server
parent7869ce9d4981e5ce428aef07bed9e99ca7506f47 (diff)
downloadsonarqube-9f80a169ea2c85db1cd8479c42ce609b80aeafaf.tar.gz
sonarqube-9f80a169ea2c85db1cd8479c42ce609b80aeafaf.zip
SONAR-23030 Use Heading component
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/account/notifications/Notifications.tsx15
-rw-r--r--server/sonar-web/src/main/js/apps/account/notifications/Projects.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/account/security/Security.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/account/security/Tokens.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx21
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx60
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx6
11 files changed, 112 insertions, 68 deletions
diff --git a/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.tsx b/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.tsx
index 700f7f6e08a..aa7f9a13d9c 100644
--- a/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.tsx
+++ b/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.tsx
@@ -18,7 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { PageTitle, Table } from 'design-system';
+import { Heading } from '@sonarsource/echoes-react';
+import { Table } from 'design-system';
import * as React from 'react';
import { translate } from '../../../helpers/l10n';
import { Notification, NotificationGlobalType } from '../../../types/notifications';
@@ -36,7 +37,9 @@ interface Props {
export default function GlobalNotifications(props: Readonly<Props>) {
return (
<>
- <PageTitle className="sw-mb-4" text={translate('my_profile.overall_notifications.title')} />
+ <Heading as="h2" hasMarginBottom>
+ {translate('my_profile.overall_notifications.title')}
+ </Heading>
{!props.header && (
<div className="sw-body-sm-highlight sw-mb-2">{translate('notifications.send_email')}</div>
diff --git a/server/sonar-web/src/main/js/apps/account/notifications/Notifications.tsx b/server/sonar-web/src/main/js/apps/account/notifications/Notifications.tsx
index c3f60c9cce3..cce33e291ee 100644
--- a/server/sonar-web/src/main/js/apps/account/notifications/Notifications.tsx
+++ b/server/sonar-web/src/main/js/apps/account/notifications/Notifications.tsx
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { FlagMessage, GreySeparator, Spinner, Title } from 'design-system';
-import { partition } from 'lodash';
+import { Heading, Spinner } from '@sonarsource/echoes-react';
+import { FlagMessage, GreySeparator } from 'design-system';
+import { isEmpty, partition } from 'lodash';
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
import {
@@ -39,7 +40,9 @@ export function Notifications({
perProjectTypes,
removeNotification,
}: WithNotificationsProps) {
- const [globalNotifications, projectNotifications] = partition(notifications, (n) => !n.project);
+ const [globalNotifications, projectNotifications] = partition(notifications, (n) =>
+ isEmpty(n.project),
+ );
const emailOnly = channels.length === 1 && channels[0] === 'EmailNotificationChannel';
@@ -59,13 +62,15 @@ export function Notifications({
<div className="it__account-body">
<Helmet defer={false} title={translate('my_account.notifications')} />
- <Title>{translate('my_account.notifications')}</Title>
+ <Heading as="h1" hasMarginBottom>
+ {translate('my_account.notifications')}
+ </Heading>
<FlagMessage className="sw-my-2" variant="info">
{translate('notification.dispatcher.information')}
</FlagMessage>
- <Spinner loading={loading}>
+ <Spinner isLoading={loading}>
{notifications && (
<>
<GreySeparator className="sw-mb-4 sw-mt-6" />
diff --git a/server/sonar-web/src/main/js/apps/account/notifications/Projects.tsx b/server/sonar-web/src/main/js/apps/account/notifications/Projects.tsx
index fe009cb6d60..c18e1181ea5 100644
--- a/server/sonar-web/src/main/js/apps/account/notifications/Projects.tsx
+++ b/server/sonar-web/src/main/js/apps/account/notifications/Projects.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { Button, ButtonVariety } from '@sonarsource/echoes-react';
+import { Button, ButtonVariety, Heading } from '@sonarsource/echoes-react';
import { InputSearch, Note } from 'design-system';
import { groupBy, sortBy, uniqBy } from 'lodash';
import * as React from 'react';
@@ -120,9 +120,9 @@ export default class Projects extends React.PureComponent<Props, State> {
return (
<section data-test="account__project-notifications">
<div className="sw-flex sw-justify-between">
- <h2 className="sw-body-md-highlight sw-mb-4">
+ <Heading as="h2" hasMarginBottom>
{translate('my_profile.per_project_notifications.title')}
- </h2>
+ </Heading>
<Button onClick={this.openModal} variety={ButtonVariety.Primary}>
<span data-test="account__add-project-notification">
diff --git a/server/sonar-web/src/main/js/apps/account/security/Security.tsx b/server/sonar-web/src/main/js/apps/account/security/Security.tsx
index b1ea17b4c5e..0539ef8aff4 100644
--- a/server/sonar-web/src/main/js/apps/account/security/Security.tsx
+++ b/server/sonar-web/src/main/js/apps/account/security/Security.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { PageTitle } from 'design-system';
+import { Heading } from '@sonarsource/echoes-react';
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
import { useCurrentLoginUser } from '../../../app/components/current-user/CurrentUserContext';
@@ -36,10 +36,9 @@ export default function Security() {
{currentUser.local && (
<>
- <PageTitle
- className="sw-heading-md sw-my-6"
- text={translate('my_profile.password.title')}
- />
+ <Heading as="h2" className="sw-mt-6" hasMarginBottom>
+ {translate('my_profile.password.title')}
+ </Heading>
<ResetPasswordForm user={currentUser} />
</>
diff --git a/server/sonar-web/src/main/js/apps/account/security/Tokens.tsx b/server/sonar-web/src/main/js/apps/account/security/Tokens.tsx
index 27d6728c85e..f177b304a49 100644
--- a/server/sonar-web/src/main/js/apps/account/security/Tokens.tsx
+++ b/server/sonar-web/src/main/js/apps/account/security/Tokens.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { Title } from 'design-system';
+import { Heading } from '@sonarsource/echoes-react';
import * as React from 'react';
import InstanceMessage from '../../../components/common/InstanceMessage';
import { translate } from '../../../helpers/l10n';
@@ -31,15 +31,15 @@ interface Props {
export default function Tokens({ login }: Readonly<Props>) {
return (
<>
- <Title>{translate('my_account.security')}</Title>
+ <Heading as="h1" hasMarginBottom>
+ {translate('my_account.security')}
+ </Heading>
- <div>
- <div className="sw-body-md sw-mb-4 sw-mr-4">
- <InstanceMessage message={translate('my_account.tokens_description')} />
- </div>
-
- <TokensForm deleteConfirmation="modal" login={login} displayTokenTypeInput />
+ <div className="sw-body-md sw-mb-4 sw-mr-4">
+ <InstanceMessage message={translate('my_account.tokens_description')} />
</div>
+
+ <TokensForm deleteConfirmation="modal" login={login} displayTokenTypeInput />
</>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
index b366a9ca956..0a2ea49e239 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
@@ -19,7 +19,7 @@
*/
import styled from '@emotion/styled';
-import { Spinner } from '@sonarsource/echoes-react';
+import { Heading, Spinner } from '@sonarsource/echoes-react';
import {
LAYOUT_FOOTER_HEIGHT,
LargeCenteredLayout,
@@ -109,7 +109,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
const { isFavorite, isLegacy } = this.props;
const { pageIndex, projects, query } = this.state;
- if (pageIndex && projects && Object.keys(query).length !== 0) {
+ if (isDefined(pageIndex) && pageIndex !== 0 && projects && Object.keys(query).length !== 0) {
this.setState({ loading: true });
fetchProjects({ isFavorite, query, pageIndex: pageIndex + 1, isLegacy }).then((response) => {
@@ -309,22 +309,25 @@ export class AllProjects extends React.PureComponent<Props, State> {
<StyledWrapper id="projects-page">
<Helmet defer={false} title={translate('projects.page')} />
- <h1 className="sw-sr-only">{translate('projects.page')}</h1>
+ <Heading as="h1" className="sw-sr-only">
+ {translate('projects.page')}
+ </Heading>
<LargeCenteredLayout>
<PageContentFontWrapper className="sw-flex sw-w-full sw-body-md">
{this.renderSide()}
- <div
- role="main"
- className="sw-flex sw-flex-col sw-box-border sw-min-w-0 sw-pl-12 sw-pt-6 sw-flex-1"
- >
+ <main className="sw-flex sw-flex-col sw-box-border sw-min-w-0 sw-pl-12 sw-pt-6 sw-flex-1">
<A11ySkipTarget anchor="projects_main" />
- <h2 className="sw-sr-only">{translate('list_of_projects')}</h2>
+ <Heading as="h2" className="sw-sr-only">
+ {translate('list_of_projects')}
+ </Heading>
+
{this.renderHeader()}
+
{this.renderMain()}
- </div>
+ </main>
</PageContentFontWrapper>
</LargeCenteredLayout>
</StyledWrapper>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx
index 735bf38a28d..4b3080b4499 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx
@@ -17,10 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
+import { Heading } from '@sonarsource/echoes-react';
import { DiscreetLink, FlagMessage, Note } from 'design-system';
import { sortBy } from 'lodash';
import * as React from 'react';
import { useIntl } from 'react-intl';
+import { isDefined } from '../../../helpers/types';
import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls';
import { Profile } from '../types';
import { getProfilePath } from '../utils';
@@ -49,9 +52,10 @@ export default function EvolutionDeprecated({ profiles }: Readonly<Props>) {
return (
<section aria-label={intl.formatMessage({ id: 'quality_profiles.deprecated_rules' })}>
- <h2 className="sw-heading-md sw-mb-6">
+ <Heading as="h2" hasMarginBottom>
{intl.formatMessage({ id: 'quality_profiles.deprecated_rules' })}
- </h2>
+ </Heading>
+
<FlagMessage variant="error" className="sw-mb-3">
{intl.formatMessage(
{ id: 'quality_profiles.deprecated_rules_are_still_activated' },
@@ -70,7 +74,9 @@ export default function EvolutionDeprecated({ profiles }: Readonly<Props>) {
<Note>
{profile.languageName}
+
{', '}
+
<DiscreetLink
className="link-no-underline"
to={getDeprecatedActiveRulesUrl({ qprofile: profile.key })}
@@ -85,6 +91,7 @@ export default function EvolutionDeprecated({ profiles }: Readonly<Props>) {
)}
</DiscreetLink>
</Note>
+
<EvolutionDeprecatedInherited
profile={profile}
profilesWithDeprecations={profilesWithDeprecations}
@@ -104,31 +111,34 @@ function EvolutionDeprecatedInherited(
) {
const { profile, profilesWithDeprecations } = props;
const intl = useIntl();
+
const rules = React.useMemo(
() => getDeprecatedRulesInheritanceChain(profile, profilesWithDeprecations),
[profile, profilesWithDeprecations],
);
- if (rules.length) {
- return (
- <>
- {rules.map((rule) => {
- if (rule.from.key === profile.key) {
- return null;
- }
-
- return (
- <Note key={rule.from.key}>
- {intl.formatMessage(
- { id: 'coding_rules.filters.inheritance.x_inherited_from_y' },
- { count: rule.count, name: rule.from.name },
- )}
- </Note>
- );
- })}
- </>
- );
+
+ if (rules.length === 0) {
+ return null;
}
- return null;
+
+ return (
+ <>
+ {rules.map((rule) => {
+ if (rule.from.key === profile.key) {
+ return null;
+ }
+
+ return (
+ <Note key={rule.from.key}>
+ {intl.formatMessage(
+ { id: 'coding_rules.filters.inheritance.x_inherited_from_y' },
+ { count: rule.count, name: rule.from.name },
+ )}
+ </Note>
+ );
+ })}
+ </>
+ );
}
function getDeprecatedRulesInheritanceChain(profile: Profile, profilesWithDeprecations: Profile[]) {
@@ -139,14 +149,16 @@ function getDeprecatedRulesInheritanceChain(profile: Profile, profilesWithDeprec
return rules;
}
- if (profile.parentKey) {
+ if (isDefined(profile.parentKey) && profile.parentKey !== '') {
const parentProfile = profilesWithDeprecations.find((p) => p.key === profile.parentKey);
+
if (parentProfile) {
const parentRules = getDeprecatedRulesInheritanceChain(
parentProfile,
profilesWithDeprecations,
);
- if (parentRules.length) {
+
+ if (parentRules.length !== 0) {
count -= parentRules.reduce((n, rule) => n + rule.count, 0);
rules = rules.concat(parentRules);
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx
index 125155c9f42..0e680661200 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx
@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
+import { Heading } from '@sonarsource/echoes-react';
import { DiscreetLink, Link, Note } from 'design-system';
import { noop, sortBy } from 'lodash';
import * as React from 'react';
@@ -26,6 +28,7 @@ import { MetricType } from '~sonar-aligned/types/metrics';
import { listRules } from '../../../api/rules';
import { toShortISO8601String } from '../../../helpers/dates';
import { translateWithParameters } from '../../../helpers/l10n';
+import { isDefined } from '../../../helpers/types';
import { getRulesUrl } from '../../../helpers/urls';
import { Rule, RuleActivation } from '../../../types/types';
@@ -39,6 +42,7 @@ export default function EvolutionRules() {
const intl = useIntl();
const [latestRules, setLatestRules] = React.useState<ExtendedRule[]>();
const [latestRulesTotal, setLatestRulesTotal] = React.useState<number>();
+
const periodStartDate = React.useMemo(() => {
const startDate = new Date();
startDate.setFullYear(startDate.getFullYear() - 1);
@@ -60,21 +64,23 @@ export default function EvolutionRules() {
}, noop);
}, [periodStartDate]);
- if (!latestRulesTotal || !latestRules) {
+ if (!(isDefined(latestRulesTotal) && latestRulesTotal !== 0) || !latestRules) {
return null;
}
return (
<section aria-label={intl.formatMessage({ id: 'quality_profiles.latest_new_rules' })}>
- <h2 className="sw-heading-md sw-mb-6">
+ <Heading as="h2" hasMarginBottom>
{intl.formatMessage({ id: 'quality_profiles.latest_new_rules' })}
- </h2>
+ </Heading>
+
<ul className="sw-flex sw-flex-col sw-gap-4 sw-body-sm">
{latestRules.map((rule) => (
<li className="sw-flex sw-flex-col sw-gap-1" key={rule.key}>
<div className="sw-truncate">
<DiscreetLink to={getRulesUrl({ rule_key: rule.key })}>{rule.name}</DiscreetLink>
</div>
+
<Note className="sw-truncate">
{rule.activations
? translateWithParameters(
@@ -90,6 +96,7 @@ export default function EvolutionRules() {
</li>
))}
</ul>
+
{latestRulesTotal > RULES_LIMIT && (
<div className="sw-mt-6 sw-body-sm-highlight">
<Link to={getRulesUrl({ available_since: periodStartDate })}>
@@ -107,6 +114,7 @@ export default function EvolutionRules() {
function parseRules(rules: Rule[], actives?: Record<string, RuleActivation[]>): ExtendedRule[] {
return rules.map((rule) => {
const activations = actives?.[rule.key]?.length ?? 0;
+
return { ...rule, activations };
});
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx
index e41b60b349d..d44fe4cab52 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx
@@ -17,10 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
+import { Heading } from '@sonarsource/echoes-react';
import { DiscreetLink, FlagMessage, Note } from 'design-system';
import * as React from 'react';
import { useIntl } from 'react-intl';
import DateFormatter from '../../../components/intl/DateFormatter';
+import { isDefined } from '../../../helpers/types';
import { Profile } from '../types';
import { getProfilePath, isStagnant } from '../utils';
@@ -28,7 +31,7 @@ interface Props {
profiles: Profile[];
}
-export default function EvolutionStagnant(props: Props) {
+export default function EvolutionStagnant(props: Readonly<Props>) {
const intl = useIntl();
const outdated = props.profiles.filter((profile) => !profile.isBuiltIn && isStagnant(profile));
@@ -38,13 +41,14 @@ export default function EvolutionStagnant(props: Props) {
return (
<section aria-label={intl.formatMessage({ id: 'quality_profiles.stagnant_profiles' })}>
- <h2 className="sw-heading-md sw-mb-6">
+ <Heading as="h2" hasMarginBottom>
{intl.formatMessage({ id: 'quality_profiles.stagnant_profiles' })}
- </h2>
+ </Heading>
<FlagMessage variant="warning" className="sw-mb-3">
{intl.formatMessage({ id: 'quality_profiles.not_updated_more_than_year' })}
</FlagMessage>
+
<ul className="sw-flex sw-flex-col sw-gap-4 sw-body-sm">
{outdated.map((profile) => (
<li className="sw-flex sw-flex-col sw-gap-1" key={profile.key}>
@@ -53,7 +57,8 @@ export default function EvolutionStagnant(props: Props) {
{profile.name}
</DiscreetLink>
</div>
- {profile.rulesUpdatedAt && (
+
+ {isDefined(profile.rulesUpdatedAt) && profile.rulesUpdatedAt !== '' && (
<Note>
<DateFormatter date={profile.rulesUpdatedAt} long>
{(formattedDate) =>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx
index 55043a09630..1fd5d6c299a 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx
@@ -17,8 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { Button, ButtonGroup, ButtonVariety } from '@sonarsource/echoes-react';
-import { FlagMessage, Link } from 'design-system';
+
+import { Button, ButtonGroup, ButtonVariety, Heading, Link } from '@sonarsource/echoes-react';
+import { FlagMessage } from 'design-system';
import * as React from 'react';
import { useIntl } from 'react-intl';
import { useLocation, useRouter } from '~sonar-aligned/components/hoc/withRouter';
@@ -61,7 +62,10 @@ export default function PageHeader(props: Readonly<Props>) {
return (
<header className="sw-grid sw-grid-cols-3 sw-gap-12">
<div className="sw-col-span-2">
- <h1 className="sw-heading-lg sw-mb-4">{translate('quality_profiles.page')}</h1>
+ <Heading as="h1" hasMarginBottom>
+ {translate('quality_profiles.page')}
+ </Heading>
+
<div className="sw-body-sm">
{intl.formatMessage({ id: 'quality_profiles.intro' })}
@@ -70,6 +74,7 @@ export default function PageHeader(props: Readonly<Props>) {
</Link>
</div>
</div>
+
{actions.create && (
<div className="sw-flex sw-flex-col sw-items-end">
<ButtonGroup>
@@ -81,10 +86,12 @@ export default function PageHeader(props: Readonly<Props>) {
>
{intl.formatMessage({ id: 'create' })}
</Button>
+
<Button id="quality-profiles-restore" onClick={() => setModal('restoreProfile')}>
{intl.formatMessage({ id: 'restore' })}
</Button>
</ButtonGroup>
+
{languages.length === 0 && (
<FlagMessage className="sw-mt-2" variant="warning">
{intl.formatMessage({ id: 'quality_profiles.no_languages_available' })}
diff --git a/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx b/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx
index 1fd491db24f..d7914cb8807 100644
--- a/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx
+++ b/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx
@@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Heading } from '@sonarsource/echoes-react';
import {
ButtonPrimary,
ContentCell,
@@ -25,7 +26,6 @@ import {
InputField,
InputSelect,
Spinner,
- SubHeading,
Table,
TableRow,
} from 'design-system';
@@ -197,7 +197,9 @@ export function TokensForm(props: Readonly<Props>) {
<>
<GreySeparator className="sw-mb-4 sw-mt-6" />
- <SubHeading as="h2">{translate('users.tokens.generate')}</SubHeading>
+ <Heading as="h2" hasMarginBottom>
+ {translate('users.tokens.generate')}
+ </Heading>
<form autoComplete="off" className="sw-flex sw-items-center" onSubmit={handleGenerateToken}>
<div className="sw-flex sw-flex-col sw-mr-2">