first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
import React, {MutableRefObject, ReactNode, Suspense, useState} from 'react';
import {Dialog} from '../ui/overlays/dialog/dialog';
import {DialogHeader} from '../ui/overlays/dialog/dialog-header';
import {Trans} from '../i18n/trans';
import {DialogBody} from '../ui/overlays/dialog/dialog-body';
import {ProgressCircle} from '../ui/progress/progress-circle';
import {useDialogContext} from '../ui/overlays/dialog/dialog-context';
import {DialogFooter} from '../ui/overlays/dialog/dialog-footer';
import {Button} from '../ui/buttons/button';
import type ReactAce from 'react-ace';
const AceEditor = React.lazy(() => import('./ace-editor'));
interface TextEditorSourcecodeDialogProps {
defaultValue: string;
mode?: 'css' | 'html' | 'php_laravel_blade';
title: ReactNode;
onSave?: (value?: string) => void;
isSaving?: boolean;
footerStartAction?: ReactNode;
beautify?: boolean;
editorRef?: MutableRefObject<ReactAce | null>;
}
export function AceDialog({
defaultValue,
mode = 'html',
title,
onSave,
isSaving,
footerStartAction,
beautify,
editorRef,
}: TextEditorSourcecodeDialogProps) {
const [value, setValue] = useState(defaultValue);
const [isValid, setIsValid] = useState<boolean>(true);
return (
<Dialog size="fullscreen" className="h-full w-full">
<DialogHeader>{title}</DialogHeader>
<DialogBody className="relative flex-auto" padding="p-0">
<Suspense
fallback={
<div className="flex h-400 w-full items-center justify-center">
<ProgressCircle
aria-label="Loading editor..."
isIndeterminate
size="md"
/>
</div>
}
>
<AceEditor
beautify={beautify}
mode={mode}
onChange={newValue => setValue(newValue)}
defaultValue={value || ''}
onIsValidChange={setIsValid}
editorRef={editorRef}
/>
</Suspense>
</DialogBody>
<Footer
disabled={!isValid || isSaving}
value={value}
onSave={onSave}
startAction={footerStartAction}
/>
</Dialog>
);
}
interface FooterProps {
disabled: boolean | undefined;
value?: string;
onSave?: (value?: string) => void;
startAction?: ReactNode;
}
function Footer({disabled, value, onSave, startAction}: FooterProps) {
const {close} = useDialogContext();
return (
<DialogFooter dividerTop startAction={startAction}>
<Button onClick={() => close()}>
<Trans message="Cancel" />
</Button>
<Button
disabled={disabled}
variant="flat"
color="primary"
onClick={() => {
if (onSave) {
onSave(value);
} else {
close(value);
}
}}
>
<Trans message="Save" />
</Button>
</DialogFooter>
);
}

View File

@@ -0,0 +1,73 @@
import ace from 'ace-builds/src-noconflict/ace';
import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css?url';
import htmlWorkerUrl from 'ace-builds/src-noconflict/worker-html?url';
import phpWorkerUrl from 'ace-builds/src-noconflict/worker-php?url';
import javascriptWorkerUrl from 'ace-builds/src-noconflict/worker-javascript?url';
import React, {MutableRefObject, useEffect, useRef} from 'react';
import AceEditorRender from 'react-ace';
import ReactAce from 'react-ace';
import 'ace-builds/src-noconflict/mode-css';
import 'ace-builds/src-noconflict/mode-html';
import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/mode-php_laravel_blade';
import 'ace-builds/src-noconflict/theme-chrome';
import 'ace-builds/src-noconflict/theme-tomorrow_night';
import 'ace-builds/src-noconflict/ext-language_tools';
import Beautify from 'ace-builds/src-noconflict/ext-beautify';
import {useIsDarkMode} from '../ui/themes/use-is-dark-mode';
ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);
ace.config.setModuleUrl('ace/mode/html_worker', htmlWorkerUrl);
ace.config.setModuleUrl('ace/mode/php_worker', phpWorkerUrl);
ace.config.setModuleUrl('ace/mode/javascript_worker', javascriptWorkerUrl);
interface Props {
mode: 'css' | 'html' | 'javascript' | 'php_laravel_blade';
onChange: (value: string) => void;
onIsValidChange: (isValid: boolean) => void;
defaultValue: string;
beautify?: boolean;
editorRef?: MutableRefObject<ReactAce | null>;
}
export default function AceEditor({
mode,
onChange,
onIsValidChange,
defaultValue,
beautify = true,
editorRef: propsEditorRef,
}: Props) {
const isDarkMode = useIsDarkMode();
const defaultRef = useRef<ReactAce | null>(null);
const editorRef = propsEditorRef || defaultRef;
useEffect(() => {
if (beautify && editorRef.current) {
Beautify.beautify(editorRef.current.editor.session);
}
}, [beautify, editorRef]);
return (
<AceEditorRender
ref={editorRef}
width="auto"
height="auto"
wrapEnabled
className="absolute inset-0"
focus
mode={mode}
theme={isDarkMode ? 'tomorrow_night' : 'chrome'}
enableBasicAutocompletion
enableLiveAutocompletion
defaultValue={defaultValue}
onChange={onChange}
editorProps={{$blockScrolling: true}}
commands={Beautify.commands}
onValidate={annotations => {
const isValid =
annotations.filter(a => a.type === 'error').length === 0;
onIsValidChange(isValid);
}}
/>
);
}