chore: switch to react-router v7
This commit is contained in:
parent
39504e2487
commit
aa9872a45b
101 changed files with 3825 additions and 6796 deletions
|
|
@ -1,122 +1,136 @@
|
|||
import React, { useEffect } from 'react'
|
||||
import Merge from 'react-codemirror-merge'
|
||||
import CodeMirror from '@uiw/react-codemirror'
|
||||
import * as shopify from '@shopify/lang-jsonc'
|
||||
import { ClientOnly } from 'remix-utils/client-only'
|
||||
import { ErrorBoundary } from 'react-error-boundary'
|
||||
import { githubDark, githubLight } from '@uiw/codemirror-theme-github'
|
||||
import { useState } from 'react'
|
||||
import { cn } from '~/utils/cn'
|
||||
import React, { useEffect } from 'react';
|
||||
import Merge from 'react-codemirror-merge';
|
||||
import CodeMirror from '@uiw/react-codemirror';
|
||||
import * as shopify from '@shopify/lang-jsonc';
|
||||
import { ClientOnly } from 'remix-utils/client-only';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { githubDark, githubLight } from '@uiw/codemirror-theme-github';
|
||||
import { useState } from 'react';
|
||||
import { cn } from '~/utils/cn';
|
||||
|
||||
import Fallback from './fallback'
|
||||
import Fallback from './fallback';
|
||||
|
||||
interface EditorProps {
|
||||
isDisabled?: boolean
|
||||
value: string
|
||||
onChange: (value: string) => void
|
||||
isDisabled?: boolean;
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
export function Editor(props: EditorProps) {
|
||||
const [light, setLight] = useState(false)
|
||||
const [light, setLight] = useState(false);
|
||||
useEffect(() => {
|
||||
const theme = window.matchMedia('(prefers-color-scheme: light)')
|
||||
setLight(theme.matches)
|
||||
const theme = window.matchMedia('(prefers-color-scheme: light)');
|
||||
setLight(theme.matches);
|
||||
theme.addEventListener('change', (theme) => {
|
||||
setLight(theme.matches)
|
||||
})
|
||||
})
|
||||
setLight(theme.matches);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
'border border-gray-200 dark:border-gray-700',
|
||||
'rounded-b-lg rounded-tr-lg mb-2 z-10 overflow-x-hidden',
|
||||
)}>
|
||||
<div
|
||||
className={cn(
|
||||
'border border-gray-200 dark:border-gray-700',
|
||||
'rounded-b-lg rounded-tr-lg mb-2 z-10 overflow-x-hidden',
|
||||
)}
|
||||
>
|
||||
<div className="overflow-y-scroll h-editor text-sm">
|
||||
<ErrorBoundary fallback={
|
||||
<p className={cn(
|
||||
'w-full h-full flex items-center justify-center',
|
||||
'text-gray-400 dark:text-gray-500 text-xl',
|
||||
)}>
|
||||
Failed to load the editor.
|
||||
</p>
|
||||
}>
|
||||
<ErrorBoundary
|
||||
fallback={
|
||||
<p
|
||||
className={cn(
|
||||
'w-full h-full flex items-center justify-center',
|
||||
'text-gray-400 dark:text-gray-500 text-xl',
|
||||
)}
|
||||
>
|
||||
Failed to load the editor.
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<ClientOnly fallback={<Fallback acl={props.value} />}>
|
||||
{() => (
|
||||
<CodeMirror
|
||||
value={props.value}
|
||||
height="100%"
|
||||
extensions={[shopify.jsonc()]}
|
||||
style={{ height: "100%" }}
|
||||
theme={light ? githubLight : githubDark}
|
||||
onChange={(value) => props.onChange(value)}
|
||||
/>
|
||||
)}
|
||||
{() => (
|
||||
<CodeMirror
|
||||
value={props.value}
|
||||
height="100%"
|
||||
extensions={[shopify.jsonc()]}
|
||||
style={{ height: '100%' }}
|
||||
theme={light ? githubLight : githubDark}
|
||||
onChange={(value) => props.onChange(value)}
|
||||
/>
|
||||
)}
|
||||
</ClientOnly>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
interface DifferProps {
|
||||
left: string
|
||||
right: string
|
||||
left: string;
|
||||
right: string;
|
||||
}
|
||||
|
||||
export function Differ(props: DifferProps) {
|
||||
const [light, setLight] = useState(false)
|
||||
const [light, setLight] = useState(false);
|
||||
useEffect(() => {
|
||||
const theme = window.matchMedia('(prefers-color-scheme: light)')
|
||||
setLight(theme.matches)
|
||||
const theme = window.matchMedia('(prefers-color-scheme: light)');
|
||||
setLight(theme.matches);
|
||||
theme.addEventListener('change', (theme) => {
|
||||
setLight(theme.matches)
|
||||
})
|
||||
})
|
||||
setLight(theme.matches);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
'border border-gray-200 dark:border-gray-700',
|
||||
'rounded-b-lg rounded-tr-lg mb-2 z-10 overflow-x-hidden',
|
||||
)}>
|
||||
<div
|
||||
className={cn(
|
||||
'border border-gray-200 dark:border-gray-700',
|
||||
'rounded-b-lg rounded-tr-lg mb-2 z-10 overflow-x-hidden',
|
||||
)}
|
||||
>
|
||||
<div className="overflow-y-scroll h-editor text-sm">
|
||||
{props.left === props.right ? (
|
||||
<p className={cn(
|
||||
'w-full h-full flex items-center justify-center',
|
||||
'text-gray-400 dark:text-gray-500 text-xl',
|
||||
)}>
|
||||
<p
|
||||
className={cn(
|
||||
'w-full h-full flex items-center justify-center',
|
||||
'text-gray-400 dark:text-gray-500 text-xl',
|
||||
)}
|
||||
>
|
||||
No changes
|
||||
</p>
|
||||
) : (
|
||||
<ErrorBoundary fallback={
|
||||
<p className={cn(
|
||||
'w-full h-full flex items-center justify-center',
|
||||
'text-gray-400 dark:text-gray-500 text-xl',
|
||||
)}>
|
||||
Failed to load the editor.
|
||||
</p>
|
||||
}>
|
||||
<ClientOnly fallback={<Fallback acl={props.right} />}>
|
||||
{() => (
|
||||
<Merge
|
||||
orientation="a-b"
|
||||
theme={light ? githubLight : githubDark}
|
||||
<ErrorBoundary
|
||||
fallback={
|
||||
<p
|
||||
className={cn(
|
||||
'w-full h-full flex items-center justify-center',
|
||||
'text-gray-400 dark:text-gray-500 text-xl',
|
||||
)}
|
||||
>
|
||||
<Merge.Original
|
||||
readOnly
|
||||
value={props.left}
|
||||
extensions={[shopify.jsonc()]}
|
||||
/>
|
||||
<Merge.Modified
|
||||
readOnly
|
||||
value={props.right}
|
||||
extensions={[shopify.jsonc()]}
|
||||
/>
|
||||
</Merge>
|
||||
)}
|
||||
Failed to load the editor.
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<ClientOnly fallback={<Fallback acl={props.right} />}>
|
||||
{() => (
|
||||
<Merge
|
||||
orientation="a-b"
|
||||
theme={light ? githubLight : githubDark}
|
||||
>
|
||||
<Merge.Original
|
||||
readOnly
|
||||
value={props.left}
|
||||
extensions={[shopify.jsonc()]}
|
||||
/>
|
||||
<Merge.Modified
|
||||
readOnly
|
||||
value={props.right}
|
||||
extensions={[shopify.jsonc()]}
|
||||
/>
|
||||
</Merge>
|
||||
)}
|
||||
</ClientOnly>
|
||||
</ErrorBoundary>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,25 @@
|
|||
import { cn } from '~/utils/cn'
|
||||
import { AlertIcon } from '@primer/octicons-react'
|
||||
import { cn } from '~/utils/cn';
|
||||
import { AlertIcon } from '@primer/octicons-react';
|
||||
|
||||
import Card from '~/components/Card'
|
||||
import Code from '~/components/Code'
|
||||
import Card from '~/components/Card';
|
||||
import Code from '~/components/Code';
|
||||
|
||||
interface Props {
|
||||
message: string
|
||||
message: string;
|
||||
}
|
||||
|
||||
export function ErrorView({ message }: Props) {
|
||||
return (
|
||||
<Card variant="flat" className="max-w-full mb-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Card.Title className="text-xl mb-0">
|
||||
Error
|
||||
</Card.Title>
|
||||
<AlertIcon className="w-8 h-8 text-red-500"/>
|
||||
<Card.Title className="text-xl mb-0">Error</Card.Title>
|
||||
<AlertIcon className="w-8 h-8 text-red-500" />
|
||||
</div>
|
||||
<Card.Text className="mt-4">
|
||||
Could not apply changes to your ACL policy
|
||||
due to the following error:
|
||||
Could not apply changes to your ACL policy due to the following error:
|
||||
<br />
|
||||
<Code>
|
||||
{message}
|
||||
</Code>
|
||||
<Code>{message}</Code>
|
||||
</Card.Text>
|
||||
</Card>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import Spinner from '~/components/Spinner'
|
||||
import { cn } from '~/utils/cn'
|
||||
import Spinner from '~/components/Spinner';
|
||||
import { cn } from '~/utils/cn';
|
||||
|
||||
interface Props {
|
||||
readonly acl: string
|
||||
readonly acl: string;
|
||||
}
|
||||
|
||||
export default function Fallback({ acl }: Props) {
|
||||
|
|
@ -20,5 +20,5 @@ export default function Fallback({ acl }: Props) {
|
|||
value={acl}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,39 @@
|
|||
import { cn } from '~/utils/cn'
|
||||
import { AlertIcon } from '@primer/octicons-react'
|
||||
import { cn } from '~/utils/cn';
|
||||
import { AlertIcon } from '@primer/octicons-react';
|
||||
|
||||
import Code from '~/components/Code'
|
||||
import Card from '~/components/Card'
|
||||
import Code from '~/components/Code';
|
||||
import Card from '~/components/Card';
|
||||
|
||||
interface Props {
|
||||
mode: 'file' | 'database'
|
||||
mode: 'file' | 'database';
|
||||
}
|
||||
|
||||
export function Unavailable({ mode }: Props) {
|
||||
return (
|
||||
<Card variant="flat" className="max-w-prose mt-12">
|
||||
<div className="flex items-center justify-between">
|
||||
<Card.Title className="text-xl mb-0">
|
||||
ACL Policy Unavailable
|
||||
</Card.Title>
|
||||
<AlertIcon className="w-8 h-8 text-red-500"/>
|
||||
<Card.Title className="text-xl mb-0">ACL Policy Unavailable</Card.Title>
|
||||
<AlertIcon className="w-8 h-8 text-red-500" />
|
||||
</div>
|
||||
<Card.Text className="mt-4">
|
||||
Unable to load a valid ACL policy configuration.
|
||||
This is most likely due to a misconfiguration in your
|
||||
Headscale configuration file.
|
||||
Unable to load a valid ACL policy configuration. This is most likely due
|
||||
to a misconfiguration in your Headscale configuration file.
|
||||
</Card.Text>
|
||||
|
||||
{mode !== 'file' ? (
|
||||
<p className="mt-4 text-sm">
|
||||
According to your configuration, the ACL policy mode
|
||||
is set to <Code>file</Code> but the ACL file is not
|
||||
available. Ensure that the <Code>policy.path</Code> is
|
||||
set to a valid path in your Headscale configuration.
|
||||
According to your configuration, the ACL policy mode is set to{' '}
|
||||
<Code>file</Code> but the ACL file is not available. Ensure that the{' '}
|
||||
<Code>policy.path</Code> is set to a valid path in your Headscale
|
||||
configuration.
|
||||
</p>
|
||||
) : (
|
||||
<p className="mt-4 text-sm">
|
||||
In order to fully utilize the ACL management features of
|
||||
Headplane, please set <Code>policy.mode</Code> to either
|
||||
{' '}<Code>file</Code> or <Code>database</Code> in your
|
||||
Headscale configuration.
|
||||
In order to fully utilize the ACL management features of Headplane,
|
||||
please set <Code>policy.mode</Code> to either <Code>file</Code> or{' '}
|
||||
<Code>database</Code> in your Headscale configuration.
|
||||
</p>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue