Updated types.

This commit is contained in:
Mike Cao 2023-11-13 14:12:05 -08:00
parent bdf2fa4f05
commit 366ef35d3d
14 changed files with 136 additions and 59 deletions

View File

@ -11,24 +11,36 @@ const contentSecurityPolicy = [
`connect-src 'self' api.umami.is`,
];
const cspHeader = (values = []) => ({
key: 'Content-Security-Policy',
value: values
.join(';')
.replace(/\s{2,}/g, ' ')
.trim(),
});
const headers = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
!process.env.ALLOWED_FRAME_URLS && {
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
].filter(n => n);
cspHeader(contentSecurityPolicy),
];
const cspHeader = (values = []) => ({
key: 'Content-Security-Policy',
value: [...contentSecurityPolicy, ...values]
.join(';')
.replace(/\s{2,}/g, ' ')
.trim(),
});
const shareHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
cspHeader([
...contentSecurityPolicy,
`frame-ancestors 'self' ${process.env.ALLOWED_FRAME_URLS || ''}`,
]),
];
if (process.env.FORCE_SSL) {
headers.push({
@ -127,14 +139,11 @@ const config = {
return [
{
source: '/:path*',
headers: [
...headers,
cspHeader([`frame-ancestors 'self' ${process.env.ALLOWED_FRAME_URLS || ''}`]),
],
headers,
},
{
source: '/share/:path*',
headers: [...headers, cspHeader()],
headers: shareHeaders,
},
];
},

View File

@ -98,7 +98,7 @@
"npm-run-all": "^4.1.5",
"prisma": "5.4.2",
"react": "^18.2.0",
"react-basics": "^0.105.0",
"react-basics": "^0.106.0",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.4",
@ -125,9 +125,9 @@
"@rollup/plugin-replace": "^5.0.2",
"@svgr/rollup": "^8.1.0",
"@svgr/webpack": "^8.1.0",
"@types/node": "^18.11.9",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"@types/node": "^20.9.0",
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3",
"cross-env": "^7.0.3",

View File

@ -11,22 +11,22 @@ import useApi from 'components/hooks/useApi';
import { DOMAIN_REGEX } from 'lib/constants';
import useMessages from 'components/hooks/useMessages';
export function WebsiteAddForm({ onSave, onClose }) {
export function WebsiteAddForm({ onSave, onClose }: { onSave?: () => void; onClose?: () => void }) {
const { formatMessage, labels, messages } = useMessages();
const { post, useMutation } = useApi();
const { mutate, error, isLoading } = useMutation(data => post('/websites', data));
const handleSubmit = async data => {
const handleSubmit = async (data: any) => {
mutate(data, {
onSuccess: async () => {
onSave();
onClose();
onSave?.();
onClose?.();
},
});
};
return (
<Form onSubmit={handleSubmit} error={error}>
<Form onSubmit={handleSubmit} error={error as string}>
<FormRow label={formatMessage(labels.name)}>
<FormInput name="name" rules={{ required: formatMessage(labels.required) }}>
<TextField autoComplete="off" />
@ -47,9 +47,11 @@ export function WebsiteAddForm({ onSave, onClose }) {
<SubmitButton variant="primary" disabled={false}>
{formatMessage(labels.save)}
</SubmitButton>
<Button disabled={isLoading} onClick={onClose}>
{formatMessage(labels.cancel)}
</Button>
{onClose && (
<Button disabled={isLoading} onClick={onClose}>
{formatMessage(labels.cancel)}
</Button>
)}
</FormButtons>
</Form>
);

View File

@ -2,7 +2,13 @@ import { useState } from 'react';
import { Button, LoadingButton, Form, FormButtons } from 'react-basics';
import useMessages from 'components/hooks/useMessages';
export function ConfirmDeleteForm({ name, onConfirm, onClose }) {
export interface ConfirmDeleteFormProps {
name: string;
onConfirm?: () => void;
onClose?: () => void;
}
export function ConfirmDeleteForm({ name, onConfirm, onClose }: ConfirmDeleteFormProps) {
const [loading, setLoading] = useState(false);
const { formatMessage, labels, messages, FormattedMessage } = useMessages();

View File

@ -1,6 +1,6 @@
import classNames from 'classnames';
import styles from './Empty.module.css';
import useMessages from 'components/hooks/useMessages';
import styles from './Empty.module.css';
export interface EmptyProps {
message?: string;

View File

@ -1,6 +1,12 @@
import { ReactNode } from 'react';
import { Icon, Text, Flexbox } from 'react-basics';
import Logo from 'assets/logo.svg';
export interface EmptyPlaceholderProps {
message: string;
children?: ReactNode;
}
export function EmptyPlaceholder({ message, children }) {
return (
<Flexbox direction="column" alignItems="center" justifyContent="center" gap={60} height={600}>

View File

@ -1,14 +1,19 @@
/* eslint-disable no-console */
import { ErrorInfo, ReactNode } from 'react';
import { ErrorBoundary as Boundary } from 'react-error-boundary';
import { Button } from 'react-basics';
import useMessages from 'components/hooks/useMessages';
import styles from './ErrorBoundry.module.css';
const logError = (error, info) => {
const logError = (error: Error, info: ErrorInfo) => {
console.error(error, info.componentStack);
};
export function ErrorBoundary({ children }) {
export interface ErrorBoundaryProps {
children: ReactNode;
}
export function ErrorBoundary({ children }: ErrorBoundaryProps) {
const { formatMessage, messages } = useMessages();
const fallbackRender = ({ error, resetErrorBoundary }) => {

View File

@ -1,6 +1,6 @@
import styles from './Favicon.module.css';
function getHostName(url) {
function getHostName(url: string) {
const match = url.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:/\n?=]+)/im);
return match && match.length > 1 ? match[1] : null;
}

View File

@ -1,13 +0,0 @@
import { ButtonGroup, Button, Flexbox } from 'react-basics';
export function FilterButtons({ items, selectedKey, onSelect }) {
return (
<Flexbox justifyContent="center">
<ButtonGroup items={items} selectedKey={selectedKey} onSelect={onSelect}>
{({ key, label }) => <Button key={key}>{label}</Button>}
</ButtonGroup>
</Flexbox>
);
}
export default FilterButtons;

View File

@ -0,0 +1,20 @@
import { Key } from 'react';
import { ButtonGroup, Button, Flexbox } from 'react-basics';
export interface FilterButtonsProps {
items: any[];
selectedKey?: Key;
onSelect: () => void;
}
export function FilterButtons({ items, selectedKey, onSelect }: FilterButtonsProps) {
return (
<Flexbox justifyContent="center">
<ButtonGroup items={items} selectedKey={selectedKey as any} onSelect={onSelect}>
{({ key, label }) => <Button key={key}>{label}</Button>}
</ButtonGroup>
</Flexbox>
);
}
export default FilterButtons;

View File

@ -1,3 +1,4 @@
import { ReactNode } from 'react';
import { Icon, Icons } from 'react-basics';
import classNames from 'classnames';
import Link from 'next/link';
@ -6,7 +7,23 @@ import useNavigation from 'components/hooks/useNavigation';
import useMessages from 'components/hooks/useMessages';
import styles from './FilterLink.module.css';
export function FilterLink({ id, value, label, externalUrl, children, className }) {
export interface FilterLinkProps {
id: string;
value: string;
label: string;
externalUrl: string;
className: string;
children: ReactNode;
}
export function FilterLink({
id,
value,
label,
externalUrl,
children,
className,
}: FilterLinkProps) {
const { formatMessage, labels } = useMessages();
const { makeUrl, query } = useNavigation();
const active = query[id] !== undefined;

View File

@ -2,8 +2,17 @@ import classNames from 'classnames';
import Link from 'next/link';
import { useLocale } from 'components/hooks';
import styles from './LinkButton.module.css';
import { ReactNode } from 'react';
export function LinkButton({ href, className, variant, scroll = true, children }) {
export interface LinkButtonProps {
href: string;
className: string;
variant?: string;
scroll?: boolean;
children?: ReactNode;
}
export function LinkButton({ href, className, variant, scroll = true, children }: LinkButtonProps) {
const { dir } = useLocale();
return (

View File

@ -2393,10 +2393,12 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
"@types/node@^18.11.9":
version "18.18.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.6.tgz#26da694f75cdb057750f49d099da5e3f3824cb3e"
integrity sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==
"@types/node@^20.9.0":
version "20.9.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298"
integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==
dependencies:
undici-types "~5.26.4"
"@types/normalize-package-data@^2.4.0":
version "2.4.3"
@ -2408,10 +2410,10 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d"
integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==
"@types/react-dom@^18.0.8":
version "18.2.14"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539"
integrity sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==
"@types/react-dom@^18.2.15":
version "18.2.15"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.15.tgz#921af67f9ee023ac37ea84b1bc0cc40b898ea522"
integrity sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==
dependencies:
"@types/react" "*"
@ -2425,7 +2427,7 @@
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@^18.0.25":
"@types/react@*", "@types/react@16 || 17 || 18":
version "18.2.30"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.30.tgz#b84f786864fc46f18545364a54d5e1316308e59b"
integrity sha512-OfqdJnDsSo4UNw0bqAjFCuBpLYQM7wvZidz0hVxHRjrEkzRlvZL1pJVyOSY55HMiKvRNEo9DUBRuEl7FNlJ/Vg==
@ -2434,6 +2436,15 @@
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/react@^18.2.37":
version "18.2.37"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.37.tgz#0f03af69e463c0f19a356c2660dbca5d19c44cae"
integrity sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/resolve@1.20.2":
version "1.20.2"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975"
@ -7455,10 +7466,10 @@ rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-basics@^0.105.0:
version "0.105.0"
resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.105.0.tgz#94eda703b3c0728e817b6e9d086e5d1c6c68f25c"
integrity sha512-iKYtfB0A2vsmO+X4jaX64XdmHE836w8TG2jFQ0pi5Qp0ktL0lAL9/q0IrWUjNr86hi0apg46aeJWxY+qQO+T1g==
react-basics@^0.106.0:
version "0.106.0"
resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.106.0.tgz#28ba95a06e6d36adcdb303e1556e6c731b505991"
integrity sha512-CD1qxFu4wrBeNubNo/SkBfWH0BuTErBueNJCCk04IC3qM9poUr3evYfs2S4sfql7dlorcOJ2GflKC1NJ8qPvmw==
dependencies:
"@react-spring/web" "^9.7.3"
classnames "^2.3.1"
@ -8893,6 +8904,11 @@ undici-types@~5.25.1:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3"
integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
unenv@^1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.7.4.tgz#a0e5a78de2c7c3c4563c06ba9763c96c59db3333"