diff --git a/app/routes/_data.acls._index/editor.tsx b/app/routes/_data.acls._index/editor.tsx index f1e5451..e7ef953 100644 --- a/app/routes/_data.acls._index/editor.tsx +++ b/app/routes/_data.acls._index/editor.tsx @@ -1,36 +1,33 @@ -import { json } from '@codemirror/lang-json' -import { yaml } from '@codemirror/lang-yaml' -import { useFetcher } from '@remix-run/react' -import { githubDark, githubLight } from '@uiw/codemirror-theme-github' -import CodeMirror from '@uiw/react-codemirror' -import clsx from 'clsx' -import { useEffect, useMemo, useState } from 'react' -import CodeMirrorMerge from 'react-codemirror-merge' +import Editor, { DiffEditor, Monaco } from '@monaco-editor/react' +import { useEffect, useState } from 'react' +import { ClientOnly } from 'remix-utils/client-only' -import Button from '~/components/Button' -import Spinner from '~/components/Spinner' -import { toast } from '~/components/Toaster' +import Fallback from '~/routes/_data.acls._index/fallback' +import { cn } from '~/utils/cn' -import Fallback from './fallback' - -interface EditorProperties { - readonly acl: string - readonly setAcl: (acl: string) => void - readonly mode: 'edit' | 'diff' - - readonly data: { - hasAclWrite: boolean - currentAcl: string - aclType: string - } +interface MonacoProps { + variant: 'editor' | 'diff' + language: 'json' | 'yaml' + value: string + onChange: (value: string) => void + original?: string } -export default function Editor({ data, acl, setAcl, mode }: EditorProperties) { - const [light, setLight] = useState(false) - const [loading, setLoading] = useState(true) +function monacoCallback(monaco: Monaco) { + monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ + validate: true, + allowComments: true, + schemas: [], + enableSchemaRequest: true, + trailingCommas: 'ignore', + }) - const fetcher = useFetcher() - const aclType = useMemo(() => data.aclType === 'json' ? json() : yaml(), [data.aclType]) + monaco.languages.register({ id: 'json' }) + monaco.languages.register({ id: 'yaml' }) +} + +export default function MonacoEditor({ value, onChange, variant, original, language }: MonacoProps) { + const [light, setLight] = useState(false) useEffect(() => { const theme = window.matchMedia('(prefers-color-scheme: light)') @@ -39,87 +36,62 @@ export default function Editor({ data, acl, setAcl, mode }: EditorProperties) { theme.addEventListener('change', (theme) => { setLight(theme.matches) }) - - // Prevents the FOUC - setLoading(false) }, []) return ( <> -
- {loading - ? ( - - ) - : ( - mode === 'edit' - ? ( - { - setAcl(value) - }} - /> - ) - : ( - - - - - ) - )} + }> + {() => variant === 'editor' + ? ( + { + if (!updated) { + return + } + + if (updated !== value) { + onChange(updated) + } + }} + loading={} + beforeMount={monacoCallback} + options={{ + wordWrap: 'on', + minimap: { enabled: false }, + fontSize: 14, + }} + /> + ) + : ( + } + beforeMount={monacoCallback} + options={{ + wordWrap: 'on', + minimap: { enabled: false }, + fontSize: 13, + }} + /> + )} +
- - ) } diff --git a/app/routes/_data.acls._index/fallback.tsx b/app/routes/_data.acls._index/fallback.tsx index 7f98197..2a3a1c5 100644 --- a/app/routes/_data.acls._index/fallback.tsx +++ b/app/routes/_data.acls._index/fallback.tsx @@ -1,43 +1,24 @@ -import clsx from 'clsx' +import Spinner from '~/components/Spinner' +import { cn } from '~/utils/cn' -import Button from '~/components/Button' - -type FallbackProperties = { - readonly acl: string; - readonly where: 'client' | 'server'; +interface FallbackProps { + readonly acl: string } -export default function Fallback({ acl, where }: FallbackProperties) { +export default function Fallback({ acl }: FallbackProps) { return ( - <> -
-