Skip to content

Commit 6bac689

Browse files
committed
feat: migrate the admin panel
1 parent 3a3e113 commit 6bac689

File tree

27 files changed

+572
-702
lines changed

27 files changed

+572
-702
lines changed

packages/core/admin/components/CopyLinkButton/index.tsx

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,33 @@ const CopyLinkButton: React.FC<Props> = ({ url }) => {
1616
const { toggleNotification } = useNotification();
1717

1818
return (
19-
<CopyToClipboard
20-
text={url}
21-
onCopy={() => {
22-
toggleNotification({
23-
type: 'success',
24-
message: formatMessage({
25-
id: getTrad('notification.success.permalink_copied'),
26-
defaultMessage: 'Permalink copied to the clipboard',
27-
}),
28-
});
29-
}}
30-
>
31-
<LinkButton
32-
size="S"
33-
startIcon={<LinkIcon />}
34-
variant="secondary"
35-
style={{ width: '100%' }}
19+
<>
20+
{/* @ts-ignore */}
21+
<CopyToClipboard
22+
text={url}
23+
onCopy={() => {
24+
toggleNotification({
25+
type: 'success',
26+
message: formatMessage({
27+
id: getTrad('notification.success.permalink_copied'),
28+
defaultMessage: 'Permalink copied to the clipboard',
29+
}),
30+
});
31+
}}
3632
>
37-
{ formatMessage({
38-
id: getTrad('settings.button.copy_permalink'),
39-
defaultMessage: 'Copy permalink',
40-
}) }
41-
</LinkButton>
42-
</CopyToClipboard>
33+
<LinkButton
34+
size="S"
35+
startIcon={<LinkIcon />}
36+
variant="secondary"
37+
style={{ width: '100%' }}
38+
>
39+
{ formatMessage({
40+
id: getTrad('settings.button.copy_permalink'),
41+
defaultMessage: 'Copy permalink',
42+
}) }
43+
</LinkButton>
44+
</CopyToClipboard>
45+
</>
4346
);
4447
};
4548

packages/core/admin/components/LabelField/index.tsx

Lines changed: 0 additions & 101 deletions
This file was deleted.

packages/core/admin/components/LanguageCheckboxes/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ const LanguageCheckboxes = ({
4949
<Checkbox
5050
aria-label={`Select ${contentType.name}`}
5151
// @ts-ignore
52-
value={selectedLanguages.includes(contentType.uid)}
53-
onValueChange={() => {
52+
checked={selectedLanguages.includes(contentType.uid)}
53+
onCheckedChange={() => {
54+
console.log('change');
5455
if (selectedLanguages.includes(contentType.uid)) {
5556
const newContentTypes = selectedLanguages
5657
.filter((uid) => uid !== contentType.uid);

packages/core/admin/components/PatternField/index.tsx

Lines changed: 56 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import React, {
2-
useState, useRef, FC,
3-
useEffect,
2+
FC,
3+
useRef,
44
} from 'react';
55
import { useIntl } from 'react-intl';
66
import styled from 'styled-components';
77
import { FormikErrors } from 'formik';
8+
import { useQuery } from 'react-query';
89

910
import {
10-
TextInput, Popover, Flex, Box, Loader, Typography,
11+
TextInput, Popover, Box, Loader, Typography,
1112
Field,
1213
} from '@strapi/design-system';
1314
import { getFetchClient } from '@strapi/strapi/admin';
1415
import { PatternFormValues } from '../../types/url-patterns';
1516
import { Theme } from '../../types/theme';
17+
import useActiveElement from '../../helpers/useActiveElement';
1618

1719
type Props = {
1820
uid: string;
@@ -27,37 +29,15 @@ const PatternField: FC<Props> = ({
2729
error = null,
2830
setFieldValue,
2931
}) => {
30-
const patternRef = useRef<HTMLDivElement>(null);
31-
const [loading, setLoading] = useState(false);
32-
const [loadingError, setLoadingError] = useState(false);
33-
const [allowedFields, setAllowedFields] = useState<Record<string, string[]> | null>(null);
34-
const { formatMessage } = useIntl();
3532
const { get } = getFetchClient();
36-
37-
const [popoverDismissed, setPopoverDismissed] = useState(false);
38-
39-
useEffect(() => {
40-
const fetchAllowedFields = async () => {
41-
try {
42-
setLoading(true);
43-
const data = await get<Record<string, string[]>>('/webtools/url-pattern/allowed-fields');
44-
setAllowedFields(data.data);
45-
setLoading(false);
46-
} catch (err) {
47-
setLoading(false);
48-
setLoadingError(true);
49-
}
50-
};
51-
52-
fetchAllowedFields().catch(() => {
53-
console.error('Failed to fetch allowed fields:', error);
54-
setLoadingError(true);
55-
setLoading(false);
56-
});
57-
}, [error]);
33+
const fields = useQuery('fields', async () => get<Record<string, string[]>>('/webtools/url-pattern/allowed-fields'));
34+
const { formatMessage } = useIntl();
35+
const inputRef = useRef<HTMLInputElement>();
36+
const popoverRef = useRef();
5837

5938
const HoverBox = styled(Box)`
6039
cursor: pointer;
40+
font-size: 16px;
6141
&:hover:not([aria-disabled="true"]) {
6242
background: ${({ theme }: { theme: Theme }) => theme.colors.primary100};
6343
}
@@ -69,15 +49,15 @@ const PatternField: FC<Props> = ({
6949
defaultMessage: 'Create a URL alias pattern',
7050
});
7151
let suffix = '';
72-
if (allowedFields?.[uid]) {
52+
if (fields.data.data?.[uid]) {
7353
suffix = ` ${formatMessage({
7454
id: 'webtools.settings.form.pattern.description_2',
7555
defaultMessage: 'using',
7656
})} `;
77-
allowedFields[uid].forEach((fieldName, i) => {
57+
fields.data.data[uid].forEach((fieldName, i) => {
7858
if (i === 0) {
7959
suffix = `${suffix}[${fieldName}]`;
80-
} else if (allowedFields[uid].length !== i + 1) {
60+
} else if (fields.data.data[uid].length !== i + 1) {
8161
suffix = `${suffix}, [${fieldName}]`;
8262
} else {
8363
suffix = `${suffix} ${formatMessage({
@@ -92,66 +72,58 @@ const PatternField: FC<Props> = ({
9272
};
9373

9474

95-
if (loading) {
75+
if (fields.isLoading) {
9676
return <Loader>{formatMessage({ id: 'webtools.settings.loading', defaultMessage: 'Loading content...' })}</Loader>;
9777
}
9878

99-
if (loadingError || !allowedFields) {
79+
if (fields.isError || !fields.data) {
10080
return <div>{formatMessage({ id: 'webtools.pattern.allowedFields.fetchError', defaultMessage: 'An error occurred while fetching allowed fields' })}</div>;
10181
}
10282

10383
return (
10484
<div>
105-
<Typography variant="pi">{patternHint()}</Typography>
106-
{values.pattern.endsWith('[') && !popoverDismissed && (
107-
<Popover.Root>
108-
<Popover.Trigger>
109-
<div>
110-
<Field.Root
111-
// @ts-ignore
112-
error={error}
113-
>
114-
<Field.Label>
115-
{formatMessage({
116-
id: 'webtools.settings.form.pattern.label',
117-
defaultMessage: 'Pattern',
118-
})}
119-
</Field.Label>
120-
<TextInput
121-
name="pattern"
122-
value={values.pattern}
123-
placeholder="/en/pages/[id]"
124-
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
125-
setPopoverDismissed(false);
126-
if (e.target.value.match(/^[A-Za-z0-9-_.~[\]/]*$/)) {
127-
return setFieldValue('pattern', e.target.value);
128-
}
85+
<Popover.Root open={values.pattern.endsWith('[')}>
86+
<Popover.Trigger>
87+
<Field.Root error={error} hint={patternHint()}>
88+
<Field.Label>
89+
{formatMessage({
90+
id: 'webtools.settings.form.pattern.label',
91+
defaultMessage: 'Pattern',
92+
})}
93+
</Field.Label>
94+
<TextInput
95+
ref={inputRef}
96+
name="pattern"
97+
value={values.pattern}
98+
placeholder="/en/pages/[id]"
99+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
100+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
101+
if (e.target.value.match(/^[A-Za-z0-9-_.~[\]/]*$/)) {
102+
return setFieldValue('pattern', e.target.value);
103+
}
129104

130-
return null;
131-
}}
132-
/>
133-
<Field.Error />
134-
</Field.Root>
135-
</div>
136-
</Popover.Trigger>
137-
<Popover.Content>
138-
<Flex>
139-
{allowedFields[uid].map((fieldName) => (
140-
<HoverBox
141-
key={fieldName}
142-
padding={2}
143-
onClick={() => {
144-
const newPattern = `${values.pattern}${fieldName}]`;
145-
return setFieldValue('pattern', newPattern);
146-
}}
147-
>
148-
{fieldName}
149-
</HoverBox>
150-
))}
151-
</Flex>
152-
</Popover.Content>
153-
</Popover.Root>
154-
)}
105+
return null;
106+
}}
107+
/>
108+
<Field.Hint />
109+
<Field.Error />
110+
</Field.Root>
111+
</Popover.Trigger>
112+
<Popover.Content ref={popoverRef}>
113+
{fields.data.data[uid].map((fieldName) => (
114+
<HoverBox
115+
key={fieldName}
116+
padding={2}
117+
onClick={() => {
118+
const newPattern = `${values.pattern}${fieldName}]`;
119+
return setFieldValue('pattern', newPattern);
120+
}}
121+
>
122+
{fieldName}
123+
</HoverBox>
124+
))}
125+
</Popover.Content>
126+
</Popover.Root>
155127
</div>
156128
);
157129
};

packages/core/admin/components/Select/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ const SelectComponent: FC<Props> = ({
3535
return (
3636
<Field.Root
3737
hint={hint}
38-
// @ts-ignore
3938
error={error}
39+
width="100%"
4040
>
4141
<Field.Label>
4242
{label}

packages/core/admin/containers/App/index.tsx

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,7 @@ const App = () => {
6666
<Route path="/patterns" element={<PatternsListPage />} />
6767
<Route path="/patterns/new" element={<PatternsCreatePage />} />
6868
<Route path="/patterns/:id" element={<PatternsEditPage />} />
69-
{routerComponents.map(({ Component }) => {
70-
console.log(Component);
71-
return (
72-
<Route
73-
path={Component.path}
74-
element={<Component.element />}
75-
/>
76-
);
77-
// @ts-ignore
78-
// eslint-disable-next-line react/jsx-pascal-case
79-
return <Component.type />;
80-
})}
69+
8170
{/* <Route path="" component={NotFound} /> */}
8271
</Routes>
8372
</Layouts.Root>

0 commit comments

Comments
 (0)