Skip to content

Commit aafc07f

Browse files
committed
refactor: compose the app register dialog from shared steps
Sharing one dialog component meant the administration screen borrowed the organization screen's translation keys, so admin-specific wording had nowhere to live. The dialog is now a set of presentational blocks — shell, manifest-URL step, consent step — plus a state hook, none of which hold strings. Each screen composes them and passes its own literal-keyed labels and data-cy values, so the administration screen gets administration_apps_register_* keys while the organization screen keeps its existing, already-translated ones.
1 parent e7bf412 commit aafc07f

7 files changed

Lines changed: 430 additions & 296 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React from 'react';
2+
import {
3+
Box,
4+
Button,
5+
DialogActions,
6+
DialogContent,
7+
Typography,
8+
} from '@mui/material';
9+
10+
import LoadingButton from 'tg.component/common/form/LoadingButton';
11+
12+
import { AppSummary } from './AppSummary';
13+
import { AppChips } from './AppChips';
14+
import { AppManifestPreviewModel } from './useAppRegisterState';
15+
16+
type Props = {
17+
preview: AppManifestPreviewModel;
18+
intro: React.ReactNode;
19+
noScopesLabel: React.ReactNode;
20+
backLabel: React.ReactNode;
21+
submitLabel: React.ReactNode;
22+
loading: boolean;
23+
onBack: () => void;
24+
onSubmit: () => void;
25+
contentDataCy: string;
26+
noScopesDataCy: string;
27+
scopesDataCy: string;
28+
backDataCy: string;
29+
submitDataCy: string;
30+
};
31+
32+
/** Second registration step: what the fetched manifest asks for, before it is approved. */
33+
export const AppRegisterConsentStep = ({
34+
preview,
35+
intro,
36+
noScopesLabel,
37+
backLabel,
38+
submitLabel,
39+
loading,
40+
onBack,
41+
onSubmit,
42+
contentDataCy,
43+
noScopesDataCy,
44+
scopesDataCy,
45+
backDataCy,
46+
submitDataCy,
47+
}: Props) => (
48+
<>
49+
<DialogContent data-cy={contentDataCy}>
50+
<Box mb={2}>
51+
<AppSummary
52+
name={preview.name}
53+
version={preview.version}
54+
url={preview.baseUrl}
55+
/>
56+
</Box>
57+
58+
<Typography variant="body2" mb={1}>
59+
{intro}
60+
</Typography>
61+
62+
{preview.requestedScopes.length === 0 && (
63+
<Typography
64+
variant="body2"
65+
color="text.secondary"
66+
data-cy={noScopesDataCy}
67+
>
68+
{noScopesLabel}
69+
</Typography>
70+
)}
71+
72+
<AppChips items={preview.requestedScopes} dataCy={scopesDataCy} />
73+
</DialogContent>
74+
<DialogActions>
75+
<Button data-cy={backDataCy} onClick={onBack} disabled={loading}>
76+
{backLabel}
77+
</Button>
78+
<LoadingButton
79+
data-cy={submitDataCy}
80+
variant="contained"
81+
color="primary"
82+
loading={loading}
83+
onClick={onSubmit}
84+
>
85+
{submitLabel}
86+
</LoadingButton>
87+
</DialogActions>
88+
</>
89+
);

webapp/src/component/apps/AppRegisterDialog.tsx

Lines changed: 0 additions & 212 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
import { Dialog, DialogTitle } from '@mui/material';
3+
4+
type Props = {
5+
open: boolean;
6+
onClose: () => void;
7+
title: React.ReactNode;
8+
dataCy: string;
9+
children: React.ReactNode;
10+
};
11+
12+
/** Dialog frame for the app registration steps. */
13+
export const AppRegisterDialogShell = ({
14+
open,
15+
onClose,
16+
title,
17+
dataCy,
18+
children,
19+
}: Props) => (
20+
<Dialog
21+
open={open}
22+
onClose={onClose}
23+
maxWidth="sm"
24+
fullWidth
25+
data-cy={dataCy}
26+
>
27+
<DialogTitle>{title}</DialogTitle>
28+
{children}
29+
</Dialog>
30+
);

0 commit comments

Comments
 (0)