mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Merge pull request #3866 from RaenonX/master
Some checks are pending
Node.js CI / build (push) Waiting to run
Some checks are pending
Node.js CI / build (push) Waiting to run
Added custom slug for links
This commit is contained in:
commit
5213e04f44
2 changed files with 76 additions and 80 deletions
91
.gitignore
vendored
91
.gitignore
vendored
|
|
@ -1,45 +1,46 @@
|
||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
node_modules
|
node_modules
|
||||||
.pnp
|
.pnp
|
||||||
.pnp.js
|
.pnp.js
|
||||||
.pnpm-store
|
.pnpm-store
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
# testing
|
# testing
|
||||||
/coverage
|
/coverage
|
||||||
|
|
||||||
# next.js
|
# next.js
|
||||||
/.next
|
/.next
|
||||||
/out
|
/out
|
||||||
|
|
||||||
# production
|
# production
|
||||||
/build
|
/build
|
||||||
/public/script.js
|
/public/script.js
|
||||||
/geo
|
/geo
|
||||||
/dist
|
/dist
|
||||||
/generated
|
/generated
|
||||||
/src/generated
|
/src/generated
|
||||||
|
pm2.yml
|
||||||
# misc
|
|
||||||
.DS_Store
|
# misc
|
||||||
.idea
|
.DS_Store
|
||||||
.yarn
|
.idea
|
||||||
*.iml
|
.yarn
|
||||||
*.log
|
*.iml
|
||||||
.vscode
|
*.log
|
||||||
.tool-versions
|
.vscode
|
||||||
|
.tool-versions
|
||||||
# debug
|
|
||||||
npm-debug.log*
|
# debug
|
||||||
yarn-debug.log*
|
npm-debug.log*
|
||||||
yarn-error.log*
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
# local env files
|
|
||||||
.env
|
# local env files
|
||||||
.env.*
|
.env
|
||||||
*.env.*
|
.env.*
|
||||||
|
*.env.*
|
||||||
*.dev.yml
|
|
||||||
|
*.dev.yml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ import {
|
||||||
Form,
|
Form,
|
||||||
FormField,
|
FormField,
|
||||||
FormSubmitButton,
|
FormSubmitButton,
|
||||||
|
Grid,
|
||||||
Icon,
|
Icon,
|
||||||
Label,
|
Label,
|
||||||
Loading,
|
Loading,
|
||||||
Row,
|
Row,
|
||||||
TextField,
|
TextField,
|
||||||
} from '@umami/react-zen';
|
} from '@umami/react-zen';
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useConfig, useLinkQuery, useMessages } from '@/components/hooks';
|
import { useConfig, useLinkQuery, useMessages } from '@/components/hooks';
|
||||||
import { useUpdateQuery } from '@/components/hooks/queries/useUpdateQuery';
|
import { useUpdateQuery } from '@/components/hooks/queries/useUpdateQuery';
|
||||||
import { RefreshCw } from '@/components/icons';
|
import { RefreshCw } from '@/components/icons';
|
||||||
|
|
@ -42,7 +43,7 @@ export function LinkEditForm({
|
||||||
const { linksUrl } = useConfig();
|
const { linksUrl } = useConfig();
|
||||||
const hostUrl = linksUrl || LINKS_URL;
|
const hostUrl = linksUrl || LINKS_URL;
|
||||||
const { data, isLoading } = useLinkQuery(linkId);
|
const { data, isLoading } = useLinkQuery(linkId);
|
||||||
const [slug, setSlug] = useState(generateId());
|
const [defaultSlug] = useState(generateId());
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
await mutateAsync(data, {
|
await mutateAsync(data, {
|
||||||
|
|
@ -55,14 +56,6 @@ export function LinkEditForm({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSlug = () => {
|
|
||||||
const slug = generateId();
|
|
||||||
|
|
||||||
setSlug(slug);
|
|
||||||
|
|
||||||
return slug;
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkUrl = (url: string) => {
|
const checkUrl = (url: string) => {
|
||||||
if (!isValidUrl(url)) {
|
if (!isValidUrl(url)) {
|
||||||
return formatMessage(labels.invalidUrl);
|
return formatMessage(labels.invalidUrl);
|
||||||
|
|
@ -70,19 +63,19 @@ export function LinkEditForm({
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (data) {
|
|
||||||
setSlug(data.slug);
|
|
||||||
}
|
|
||||||
}, [data]);
|
|
||||||
|
|
||||||
if (linkId && isLoading) {
|
if (linkId && isLoading) {
|
||||||
return <Loading placement="absolute" />;
|
return <Loading placement="absolute" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={handleSubmit} error={getErrorMessage(error)} defaultValues={{ slug, ...data }}>
|
<Form
|
||||||
{({ setValue }) => {
|
onSubmit={handleSubmit}
|
||||||
|
error={getErrorMessage(error)}
|
||||||
|
defaultValues={{ slug: defaultSlug, ...data }}
|
||||||
|
>
|
||||||
|
{({ setValue, watch }) => {
|
||||||
|
const slug = watch('slug');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormField
|
<FormField
|
||||||
|
|
@ -101,15 +94,25 @@ export function LinkEditForm({
|
||||||
<TextField placeholder="https://example.com" autoComplete="off" />
|
<TextField placeholder="https://example.com" autoComplete="off" />
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField
|
<Grid columns="1fr auto" alignItems="end" gap>
|
||||||
name="slug"
|
<FormField
|
||||||
rules={{
|
name="slug"
|
||||||
required: formatMessage(labels.required),
|
label={formatMessage({ id: 'label.slug', defaultMessage: 'Slug' })}
|
||||||
}}
|
rules={{
|
||||||
style={{ display: 'none' }}
|
required: formatMessage(labels.required),
|
||||||
>
|
}}
|
||||||
<input type="hidden" />
|
>
|
||||||
</FormField>
|
<TextField autoComplete="off" />
|
||||||
|
</FormField>
|
||||||
|
<Button
|
||||||
|
variant="quiet"
|
||||||
|
onPress={() => setValue('slug', generateId(), { shouldDirty: true })}
|
||||||
|
>
|
||||||
|
<Icon>
|
||||||
|
<RefreshCw />
|
||||||
|
</Icon>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Column>
|
<Column>
|
||||||
<Label>{formatMessage(labels.link)}</Label>
|
<Label>{formatMessage(labels.link)}</Label>
|
||||||
|
|
@ -121,14 +124,6 @@ export function LinkEditForm({
|
||||||
allowCopy
|
allowCopy
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
/>
|
/>
|
||||||
<Button
|
|
||||||
variant="quiet"
|
|
||||||
onPress={() => setValue('slug', handleSlug(), { shouldDirty: true })}
|
|
||||||
>
|
|
||||||
<Icon>
|
|
||||||
<RefreshCw />
|
|
||||||
</Icon>
|
|
||||||
</Button>
|
|
||||||
</Row>
|
</Row>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue