Skip to content

Commit 51a9200

Browse files
committed
feat: make the edit view form work
1 parent 9e34d70 commit 51a9200

File tree

18 files changed

+198
-396
lines changed

18 files changed

+198
-396
lines changed

packages/core/admin/api/url-alias.ts

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

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

Lines changed: 104 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,127 @@
1+
/* eslint-disable @typescript-eslint/no-floating-promises */
12
import * as React from 'react';
23
import { useIntl } from 'react-intl';
34

4-
import { unstable_useContentManagerContext } from '@strapi/strapi/admin';
5+
import { unstable_useContentManagerContext, useFetchClient } from '@strapi/strapi/admin';
6+
import { useMutation, useQuery, useQueryClient } from 'react-query';
57

68
import {
79
Box,
8-
Flex,
910
TextInput,
1011
Checkbox,
11-
Link,
12-
Accordion,
1312
Field,
13+
Typography,
14+
Modal,
15+
Button,
1416
} from '@strapi/design-system';
17+
import { Form, Formik } from 'formik';
1518

1619
import getTrad from '../../helpers/getTrad';
1720
import { UrlAliasEntity } from '../../types/url-aliases';
1821

1922
const EditForm = () => {
20-
const { form } = unstable_useContentManagerContext();
23+
const context = unstable_useContentManagerContext();
24+
const [open, setOpen] = React.useState(false);
2125

22-
const { values, onChange } = form;
26+
const { id, model } = context;
27+
const { get, put } = useFetchClient();
28+
const queryClient = useQueryClient();
29+
const aliases = useQuery(`aliases-${model}-${id}`, async () => get<UrlAliasEntity[]>(`/webtools/url-alias/findFrom?model=${model}&documentId=${id}`));
30+
const mutation = useMutation((updatedAlias: Partial<UrlAliasEntity>) => put(`/webtools/url-alias/update/${aliases.data.data[0].documentId}`, {
31+
data: updatedAlias,
32+
}));
2333

24-
const modifiedDataUrlAliases =
25-
(values.url_alias as UrlAliasEntity[])?.length
26-
? values.url_alias as UrlAliasEntity[]
27-
: [{
28-
generated: true,
29-
}] as UrlAliasEntity[];
30-
const { formatMessage } = useIntl();
31-
32-
const updateValue = (index: number, name: string, value: string | number) => {
33-
const updatedUrlAliases = [...modifiedDataUrlAliases];
34+
// Re-fetch the aliases when the modal is opened.
35+
React.useEffect(() => {
36+
if (open) queryClient.invalidateQueries(`aliases-${model}-${id}`);
37+
}, [open, queryClient, model, id]);
3438

35-
updatedUrlAliases[index] = {
36-
...updatedUrlAliases[index],
37-
[name]: value,
38-
};
39-
onChange('url_alias', updatedUrlAliases);
40-
};
41-
42-
const [expanded, setExpanded] = React.useState<number | null>(0);
43-
// eslint-disable-next-line max-len
44-
const toggle = (index: number) => setExpanded((prevExpanded) => (prevExpanded === index ? null : index));
39+
const { formatMessage } = useIntl();
4540

4641
return (
47-
<Flex>
48-
<Accordion.Root
49-
size="S"
50-
>
51-
{modifiedDataUrlAliases?.map((alias, index) => (
52-
<Accordion.Item
53-
key={alias.id}
54-
value={`acc-${alias.id}`}
55-
>
56-
<Accordion.Header>
57-
<Accordion.Trigger
58-
description={alias.url_path ? alias.url_path : 'Initial URL alias'}
59-
>
60-
{`Alias #${index + 1}`}
61-
</Accordion.Trigger>
62-
</Accordion.Header>
63-
<Accordion.Content>
64-
<Box>
65-
<Checkbox
66-
onValueChange={(value: string) => {
67-
updateValue(index, 'generated', value);
68-
}}
69-
// @ts-ignore
70-
value={alias.generated !== undefined ? alias.generated : true}
71-
name={`generated-${index}`}
72-
hint="Uncheck this to create a custom alias below."
73-
>
74-
{formatMessage({
75-
id: getTrad('EditView.ExcludeFromSitemap'),
76-
defaultMessage: ' Generate automatic URL alias',
77-
})}
78-
</Checkbox>
79-
<Link href="/admin/plugins/webtools/patterns">Configure URL alias patterns.</Link>
80-
</Box>
81-
<Box paddingTop={4}>
82-
<Field.Root
83-
hint='Specify a path by which this data can be accessed in the browser. For example, type "/about" when writing an about page.'
84-
>
85-
<Field.Label>
86-
URL alias
87-
</Field.Label>
88-
<TextInput
89-
name={`path-${index}`}
90-
disabled={alias.generated !== undefined ? alias.generated : true}
91-
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
92-
if (e.target.value.match(/^[A-Za-z0-9-_.~[\]/]*$/)) {
93-
updateValue(index, 'url_path', e.target.value);
94-
}
95-
}}
96-
value={alias.url_path}
97-
/>
98-
<Field.Hint />
99-
</Field.Root>
100-
</Box>
101-
</Accordion.Content>
102-
</Accordion.Item>
103-
))}
104-
</Accordion.Root>
105-
</Flex>
42+
<Formik
43+
initialValues={{
44+
generated: aliases.data?.data?.[0]?.generated,
45+
url_path: aliases.data?.data?.[0]?.url_path,
46+
}}
47+
onSubmit={async (values) => {
48+
await mutation.mutateAsync(values);
49+
setOpen(false);
50+
}}
51+
enableReinitialize
52+
>
53+
{({ setFieldValue, values, handleSubmit }) => (
54+
<Modal.Root open={open} onOpenChange={setOpen}>
55+
<Modal.Trigger>
56+
<Button
57+
size="S"
58+
variant="secondary"
59+
style={{ width: '100%' }}
60+
disabled={aliases.data.data.length === 0}
61+
>
62+
Edit URL alias
63+
</Button>
64+
</Modal.Trigger>
65+
<Modal.Content>
66+
<Modal.Header>
67+
<Typography fontWeight="bold" textColor="neutral800" id="title">
68+
test
69+
</Typography>
70+
</Modal.Header>
71+
<Modal.Body>
72+
{/** @ts-ignore */}
73+
<Form>
74+
<Box>
75+
<Field.Root hint="Uncheck this to create a custom alias below.">
76+
<Checkbox
77+
onCheckedChange={(value) => {
78+
setFieldValue('generated', value);
79+
}}
80+
checked={values.generated !== undefined ? values.generated : true}
81+
name="generated"
82+
>
83+
{formatMessage({
84+
id: getTrad('EditView.ExcludeFromSitemap'),
85+
defaultMessage: ' Generate automatic URL alias',
86+
})}
87+
</Checkbox>
88+
<Field.Hint />
89+
</Field.Root>
90+
</Box>
91+
<Box paddingTop={4}>
92+
<Field.Root
93+
hint='Specify a path by which this data can be accessed in the browser. For example, type "/about" when writing an about page.'
94+
>
95+
<Field.Label>
96+
URL alias
97+
</Field.Label>
98+
<TextInput
99+
name="path"
100+
disabled={values.generated !== undefined ? values.generated : true}
101+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
102+
if (e.target.value.match(/^[A-Za-z0-9-_.~[\]/]*$/)) {
103+
setFieldValue('url_path', e.target.value);
104+
}
105+
}}
106+
value={values.url_path}
107+
/>
108+
<Field.Hint />
109+
</Field.Root>
110+
</Box>
111+
</Form>
112+
</Modal.Body>
113+
<Modal.Footer>
114+
<Modal.Close>
115+
<Button variant="tertiary">
116+
Cancel
117+
</Button>
118+
</Modal.Close>
119+
<Button onClick={() => handleSubmit()}>Save</Button>
120+
</Modal.Footer>
121+
</Modal.Content>
122+
</Modal.Root>
123+
)}
124+
</Formik>
106125
);
107126
};
108127

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,21 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React from 'react';
22
import { getFetchClient } from '@strapi/strapi/admin';
3-
4-
import { Config } from '../../../../server/admin-api/config';
3+
import { useQuery } from 'react-query';
54

65
import CopyLinkButton from '../../CopyLinkButton';
6+
import { Config } from '../../../../server/config';
77

88
interface Props {
99
path: string
1010
}
1111

1212
const EditViewRightLinks: React.FC<Props> = ({ path }) => {
13-
const [url, setUrl] = useState<string>();
1413
const { get } = getFetchClient();
14+
const config = useQuery('config', async () => get<Config>('/webtools/info/config'));
1515

16-
useEffect(() => {
17-
get<Config>('/webtools/info/config')
18-
.then((response) => {
19-
const configData = response.data;
20-
setUrl(configData.website_url);
21-
})
22-
.catch((error) => {
23-
console.error('Failed to fetch config:', error);
24-
});
25-
}, [get]);
26-
27-
if (!url) return null;
16+
if (config.isLoading || config.isError || !config.data.data.website_url) return null;
2817

29-
return <CopyLinkButton url={`${url}${path}`} />;
18+
return <CopyLinkButton url={`${config.data.data.website_url}${path}`} />;
3019
};
3120

3221
export default EditViewRightLinks;

0 commit comments

Comments
 (0)