1
This commit is contained in:
parent
6b1e9c6b4c
commit
ee70c571e8
@ -13,5 +13,54 @@ loader.config({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 注册 Groovy 语言支持
|
||||||
|
loader.init().then((monaco) => {
|
||||||
|
monaco.languages.register({ id: 'groovy' });
|
||||||
|
monaco.languages.setMonarchTokensProvider('groovy', {
|
||||||
|
keywords: [
|
||||||
|
'def', 'class', 'interface', 'trait', 'extends', 'implements',
|
||||||
|
'package', 'import', 'new', 'null', 'true', 'false',
|
||||||
|
'if', 'else', 'for', 'while', 'do', 'switch', 'case',
|
||||||
|
'break', 'continue', 'return', 'throw', 'try', 'catch',
|
||||||
|
'finally', 'this', 'super', 'abstract', 'static', 'final',
|
||||||
|
'public', 'protected', 'private', 'void'
|
||||||
|
],
|
||||||
|
operators: [
|
||||||
|
'=', '>', '<', '!', '~', '?', ':',
|
||||||
|
'==', '<=', '>=', '!=', '&&', '||', '++', '--',
|
||||||
|
'+', '-', '*', '/', '&', '|', '^', '%', '<<',
|
||||||
|
'>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=',
|
||||||
|
'^=', '%=', '<<=', '>>=', '>>>='
|
||||||
|
],
|
||||||
|
symbols: /[=><!~?:&|+\-*\/\^%]+/,
|
||||||
|
tokenizer: {
|
||||||
|
root: [
|
||||||
|
[/[a-zA-Z_$][\w$]*/, {
|
||||||
|
cases: {
|
||||||
|
'@keywords': 'keyword',
|
||||||
|
'@default': 'identifier'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
[/".*?"/, 'string'],
|
||||||
|
[/'.*?'/, 'string'],
|
||||||
|
[/\/\/.*$/, 'comment'],
|
||||||
|
[/\/\*/, 'comment', '@comment'],
|
||||||
|
[/[0-9]+/, 'number'],
|
||||||
|
[/@symbols/, {
|
||||||
|
cases: {
|
||||||
|
'@operators': 'operator',
|
||||||
|
'@default': ''
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
],
|
||||||
|
comment: [
|
||||||
|
[/[^/*]+/, 'comment'],
|
||||||
|
[/\*\//, 'comment', '@pop'],
|
||||||
|
[/[/*]/, 'comment']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
export const Editor = MonacoEditor;
|
export const Editor = MonacoEditor;
|
||||||
export default Editor;
|
export default Editor;
|
||||||
@ -26,11 +26,12 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import {PlusCircle, X} from 'lucide-react';
|
import {PlusCircle, X, Maximize2} from 'lucide-react';
|
||||||
import {useForm, useFieldArray} from "react-hook-form";
|
import {useForm, useFieldArray} from "react-hook-form";
|
||||||
import {getApplicationList} from '../../../Application/List/service';
|
import {getApplicationList} from '../../../Application/List/service';
|
||||||
import {getExternalSystemList, getJenkinsViewList, getJenkinsJobList} from '../service';
|
import {getExternalSystemList, getJenkinsViewList, getJenkinsJobList} from '../service';
|
||||||
import type {ExternalSystem} from '@/pages/Deploy/External/types';
|
import type {ExternalSystem} from '@/pages/Deploy/External/types';
|
||||||
|
import { Editor } from "@/components/Editor";
|
||||||
|
|
||||||
interface Application {
|
interface Application {
|
||||||
id: number;
|
id: number;
|
||||||
@ -58,6 +59,7 @@ interface FormValues {
|
|||||||
viewId?: number;
|
viewId?: number;
|
||||||
jobId?: number;
|
jobId?: number;
|
||||||
envs: EnvVariable[];
|
envs: EnvVariable[];
|
||||||
|
script: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DeploymentConfigModalProps {
|
interface DeploymentConfigModalProps {
|
||||||
@ -71,6 +73,8 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({open, onCa
|
|||||||
const [externalSystems, setExternalSystems] = useState<ExternalSystem[]>([]);
|
const [externalSystems, setExternalSystems] = useState<ExternalSystem[]>([]);
|
||||||
const [jenkinsViews, setJenkinsViews] = useState<JenkinsView[]>([]);
|
const [jenkinsViews, setJenkinsViews] = useState<JenkinsView[]>([]);
|
||||||
const [jenkinsJobs, setJenkinsJobs] = useState<JenkinsJob[]>([]);
|
const [jenkinsJobs, setJenkinsJobs] = useState<JenkinsJob[]>([]);
|
||||||
|
const [fullscreenEditor, setFullscreenEditor] = useState(false);
|
||||||
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
|
|
||||||
const form = useForm<FormValues>({
|
const form = useForm<FormValues>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@ -79,6 +83,7 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({open, onCa
|
|||||||
viewId: undefined,
|
viewId: undefined,
|
||||||
jobId: undefined,
|
jobId: undefined,
|
||||||
envs: [{key: '', value: ''}],
|
envs: [{key: '', value: ''}],
|
||||||
|
script: '',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -137,15 +142,16 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({open, onCa
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Dialog open={open} onOpenChange={(open) => !open && onCancel()}>
|
<Dialog open={open} onOpenChange={(open) => !open && onCancel()}>
|
||||||
<DialogContent className="max-w-[800px] h-[75vh]">
|
<DialogContent className="max-w-[800px] h-[90vh] flex flex-col">
|
||||||
<DialogHeader className="pb-4">
|
<DialogHeader className="flex-shrink-0">
|
||||||
<DialogTitle>部署配置</DialogTitle>
|
<DialogTitle>部署配置</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form onSubmit={handleSubmit} className="space-y-4 flex flex-col h-full">
|
<form onSubmit={handleSubmit} className="flex flex-col flex-1 overflow-hidden">
|
||||||
<ScrollArea className="flex-1 -mx-6">
|
<ScrollArea className="flex-1 -mr-6 pr-6">
|
||||||
<div className="px-6 space-y-4">
|
<div className="space-y-6">
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
@ -321,9 +327,61 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({open, onCa
|
|||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="script"
|
||||||
|
render={({field}) => (
|
||||||
|
<FormItem className="relative">
|
||||||
|
<FormLabel>部署脚本</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<div className="relative">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="absolute right-2 top-2 z-10"
|
||||||
|
onClick={() => setIsFullscreen(true)}
|
||||||
|
>
|
||||||
|
<Maximize2 className="h-4 w-4"/>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="absolute right-14 top-2 z-10"
|
||||||
|
>
|
||||||
|
生成配置
|
||||||
|
</Button>
|
||||||
|
<Editor
|
||||||
|
height="300px"
|
||||||
|
language="groovy"
|
||||||
|
theme="vs-dark"
|
||||||
|
value={field.value}
|
||||||
|
onChange={field.onChange}
|
||||||
|
options={{
|
||||||
|
minimap: { enabled: false },
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
fontSize: 14,
|
||||||
|
lineNumbers: 'on',
|
||||||
|
renderLineHighlight: 'all',
|
||||||
|
automaticLayout: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage/>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
<DialogFooter className="flex-shrink-0">
|
<div className="flex-shrink-0 border-t bg-background mt-6">
|
||||||
|
<DialogFooter className="pt-4">
|
||||||
<Button variant="outline" onClick={onCancel}>
|
<Button variant="outline" onClick={onCancel}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
@ -331,10 +389,46 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({open, onCa
|
|||||||
确定
|
确定
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
{isFullscreen && (
|
||||||
|
<Dialog open={isFullscreen} onOpenChange={setIsFullscreen}>
|
||||||
|
<DialogContent className="max-w-[100vw] w-[100vw] h-[100vh] p-0">
|
||||||
|
<div className="h-full flex flex-col">
|
||||||
|
<div className="flex-shrink-0 p-4 border-b">
|
||||||
|
<DialogTitle>部署脚本编辑</DialogTitle>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1 p-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="script"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Editor
|
||||||
|
height="calc(100vh - 120px)"
|
||||||
|
language="groovy"
|
||||||
|
theme="vs-dark"
|
||||||
|
value={field.value}
|
||||||
|
onChange={(value) => field.onChange(value ?? '')}
|
||||||
|
options={{
|
||||||
|
minimap: { enabled: true },
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
fontSize: 14,
|
||||||
|
lineNumbers: 'on',
|
||||||
|
folding: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user