前端添加代码编辑器主题 缩略图
This commit is contained in:
parent
6eb66b4c18
commit
7b556668d2
@ -29,3 +29,11 @@ export function saveFileContent(data: Api.File.SaveFileRequest) {
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchInitProject(data: Api.File.InitProjectRequest) {
|
||||
return request<Api.File.FileContent>({
|
||||
url: '/file/init/project',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
@ -8,18 +8,16 @@ export function runPythonCommand(data: Api.Python.SaveFileRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
export function pythonCommand3(data: Api.Python.SaveFileRequest) {
|
||||
export function pythonCommand3() {
|
||||
return request<boolean>({
|
||||
url: '/python/stop',
|
||||
method: 'post',
|
||||
data
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchPythonStatus(data: Api.Python.SaveFileRequest) {
|
||||
export function fetchPythonStatus() {
|
||||
return request<boolean>({
|
||||
url: '/python/status',
|
||||
method: 'get',
|
||||
data
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
5
src/typings/api.d.ts
vendored
5
src/typings/api.d.ts
vendored
@ -1260,6 +1260,11 @@ declare namespace Api {
|
||||
filePath: string;
|
||||
content: string;
|
||||
}>;
|
||||
|
||||
type InitProjectRequest = Common.CommonRecord<{
|
||||
projectName: string;
|
||||
projectUrl: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
namespace Python {
|
||||
|
@ -5,6 +5,7 @@ import { Folder, FolderOpenOutline } from '@vicons/ionicons5';
|
||||
import { NIcon } from 'naive-ui';
|
||||
import MonacoEditor from '@/components/common/monaco-editor.vue';
|
||||
import {
|
||||
fetchInitProject,
|
||||
fetchListFiles,
|
||||
fetchPythonStatus,
|
||||
fetchViewFile,
|
||||
@ -14,26 +15,66 @@ import {
|
||||
} from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { fetchQuickPublish } from '@/service/api/docker';
|
||||
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
||||
|
||||
const code = ref(`Hello SnailJob`);
|
||||
const dataRef = ref(createData());
|
||||
const dataRef = ref();
|
||||
const curFile = ref<TreeOption>();
|
||||
const pyStatus = ref<boolean>(false);
|
||||
const theme = ref('vs');
|
||||
const eol = ref(0);
|
||||
const wordWrap = ref('on');
|
||||
const minimap = ref('true');
|
||||
const themes = [
|
||||
{
|
||||
label: 'Visual Studio',
|
||||
value: 'vs'
|
||||
},
|
||||
{
|
||||
label: 'Visual Studio Dark',
|
||||
value: 'vs-dark'
|
||||
},
|
||||
{
|
||||
label: 'High Contrast Dark',
|
||||
value: 'hc-black'
|
||||
}
|
||||
];
|
||||
|
||||
function createData() {
|
||||
return [
|
||||
{
|
||||
label: 'snail-job-python',
|
||||
key: 'snail-job-python',
|
||||
isLeaf: false,
|
||||
prefix: () => {
|
||||
return h(NIcon, null, {
|
||||
default: () => h(Folder)
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
const eols = [
|
||||
{
|
||||
label: 'LF (Linux)',
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: 'CRLF (Windows)',
|
||||
value: 1
|
||||
}
|
||||
];
|
||||
|
||||
const wordWraps = [
|
||||
{
|
||||
label: '启用',
|
||||
value: 'on'
|
||||
},
|
||||
{
|
||||
label: '关闭',
|
||||
value: 'off'
|
||||
}
|
||||
];
|
||||
|
||||
const minimaps = [
|
||||
{
|
||||
label: '启用',
|
||||
value: 'true'
|
||||
},
|
||||
{
|
||||
label: '关闭',
|
||||
value: 'false'
|
||||
}
|
||||
];
|
||||
|
||||
const pyStatus = defineModel<boolean>('pyStatus', {
|
||||
default: false
|
||||
});
|
||||
|
||||
const updatePrefixWithExpaned = (
|
||||
_keys: Array<string | number>,
|
||||
@ -60,6 +101,22 @@ const updatePrefixWithExpaned = (
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const { formRef, validate } = useNaiveForm();
|
||||
const { defaultRequiredRule } = useFormRules();
|
||||
|
||||
type Model = Pick<Api.File.InitProjectRequest, 'projectName' | 'projectUrl'>;
|
||||
type RuleKey = Extract<keyof Model, 'projectName' | 'projectUrl'>;
|
||||
const rules: Record<RuleKey, App.Global.FormRule> = {
|
||||
projectName: defaultRequiredRule,
|
||||
projectUrl: defaultRequiredRule
|
||||
};
|
||||
|
||||
const model: Model = reactive({
|
||||
projectName: 'project',
|
||||
projectUrl: 'https://github.com/open-snail/python-client/archive/refs/tags/v0.0.1.zip'
|
||||
});
|
||||
|
||||
const nodeProps = ({ option }: { option: TreeOption }) => {
|
||||
return {
|
||||
onClick() {
|
||||
@ -71,6 +128,14 @@ const nodeProps = ({ option }: { option: TreeOption }) => {
|
||||
};
|
||||
};
|
||||
|
||||
async function handleSubmit() {
|
||||
await validate();
|
||||
const { projectName, projectUrl } = model;
|
||||
const { error } = await fetchInitProject({ projectName, projectUrl });
|
||||
if (error) return;
|
||||
window.$message?.success($t('common.addSuccess'));
|
||||
}
|
||||
|
||||
async function getViewFile(option: TreeOption) {
|
||||
if (option.isLeaf) {
|
||||
const res = await fetchViewFile(option.key as string);
|
||||
@ -141,65 +206,18 @@ async function onLoad(node: TreeOption) {
|
||||
});
|
||||
}
|
||||
|
||||
type Model = Pick<Api.File.SaveFileRequest, 'fileName' | 'filePath' | 'content'>;
|
||||
|
||||
const model: Model = reactive(createDefaultModel());
|
||||
|
||||
function createDefaultModel(): Model {
|
||||
return {
|
||||
fileName: curFile.value?.key as string,
|
||||
filePath: curFile.value?.label as string,
|
||||
content: code.value
|
||||
};
|
||||
}
|
||||
|
||||
async function saveFile() {
|
||||
model.fileName = curFile.value?.key as string;
|
||||
model.filePath = curFile.value?.label as string;
|
||||
model.content = code.value;
|
||||
|
||||
const { fileName, filePath, content } = model;
|
||||
const { error } = await saveFileContent({ fileName, filePath, content });
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
window.$message?.success($t('common.updateSuccess'));
|
||||
}
|
||||
}
|
||||
|
||||
type PythonModel = Pick<Api.Python.SaveFileRequest, 'pythonPath' | 'command'>;
|
||||
|
||||
const pythonModel: PythonModel = reactive(createPythonModelModel());
|
||||
|
||||
function createPythonModelModel(): PythonModel {
|
||||
return {
|
||||
pythonPath: '',
|
||||
command: 'pip3 install -r && python3 ' /// ToDo 这里需要做配置
|
||||
};
|
||||
}
|
||||
|
||||
function codeUpdate(content: string) {
|
||||
code.value = content;
|
||||
}
|
||||
|
||||
function saveFileClick() {
|
||||
saveFile();
|
||||
}
|
||||
|
||||
async function runPython() {
|
||||
pythonModel.pythonPath = curFile.value?.key as string;
|
||||
|
||||
const { pythonPath, command } = pythonModel;
|
||||
const { error } = await runPythonCommand({ pythonPath, command });
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
window.$message?.success($t('common.updateSuccess'));
|
||||
}
|
||||
}
|
||||
|
||||
async function stopPython() {
|
||||
const { error } = await pythonCommand3(pythonModel);
|
||||
async function saveFileClick() {
|
||||
const { error } = await saveFileContent(
|
||||
reactive<Api.File.SaveFileRequest>({
|
||||
fileName: curFile.value?.key as string,
|
||||
filePath: curFile.value?.label as string,
|
||||
content: code.value
|
||||
})
|
||||
);
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
@ -208,7 +226,7 @@ async function stopPython() {
|
||||
}
|
||||
|
||||
async function pythonStatus() {
|
||||
const { error, data } = await fetchPythonStatus(pythonModel);
|
||||
const { error, data } = await fetchPythonStatus();
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
@ -216,20 +234,40 @@ async function pythonStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
type ContainerRequestModel = Pick<Api.Docker.CreateContainerRequest, 'groupName' | 'namespaceId' | 'imageName'>;
|
||||
|
||||
const containerRequestModel: ContainerRequestModel = reactive(createContainerRequestModelModel());
|
||||
|
||||
function createContainerRequestModelModel(): ContainerRequestModel {
|
||||
return {
|
||||
groupName: 'snail_job_demo_group',
|
||||
namespaceId: '764d604ec6fc45f68cd92514c40e9e1a', /// ToDo 这里需要做配置
|
||||
imageName: ''
|
||||
};
|
||||
async function runPythonClick() {
|
||||
const { error } = await runPythonCommand(
|
||||
reactive<Api.Python.SaveFileRequest>({
|
||||
pythonPath: curFile.value?.key as string,
|
||||
command: 'pip3 install -r && python3 ' /// ToDo 这里需要做配置
|
||||
})
|
||||
);
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
window.$message?.success($t('common.updateSuccess'));
|
||||
pyStatus.value = true;
|
||||
}
|
||||
// pythonStatus();
|
||||
}
|
||||
|
||||
async function quickPublish() {
|
||||
const { error } = await fetchQuickPublish(containerRequestModel);
|
||||
async function stopPythonClick() {
|
||||
const { error } = await pythonCommand3();
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
window.$message?.success($t('common.updateSuccess'));
|
||||
}
|
||||
pythonStatus();
|
||||
}
|
||||
|
||||
async function quickPublishClick() {
|
||||
const { error } = await fetchQuickPublish(
|
||||
reactive<Api.Docker.CreateContainerRequest>({
|
||||
groupName: 'snail_job_demo_group',
|
||||
namespaceId: '764d604ec6fc45f68cd92514c40e9e1a', /// ToDo 这里需要做配置
|
||||
imageName: ''
|
||||
})
|
||||
);
|
||||
if (error) {
|
||||
window.$message?.success($t('common.updateFailed'));
|
||||
} else {
|
||||
@ -237,41 +275,57 @@ async function quickPublish() {
|
||||
}
|
||||
}
|
||||
|
||||
function runPythonClick() {
|
||||
runPython();
|
||||
pythonStatus();
|
||||
}
|
||||
|
||||
function stopPythonClick() {
|
||||
stopPython();
|
||||
pythonStatus();
|
||||
}
|
||||
|
||||
function quickPublishClick() {
|
||||
quickPublish();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
pythonStatus();
|
||||
onMounted(async () => {
|
||||
const res = await fetchListFiles('');
|
||||
const files = res.data as Api.File.FileInfo[];
|
||||
dataRef.value = [
|
||||
{
|
||||
label: files[0].fileName,
|
||||
key: files[0].fileName,
|
||||
isLeaf: false,
|
||||
prefix: () => {
|
||||
return h(NIcon, null, {
|
||||
default: () => h(Folder)
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
await pythonStatus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="code-editor">
|
||||
<NSpace>
|
||||
<NButton strong secondary type="primary" @click="saveFileClick">保存</NButton>
|
||||
<NButton v-if="pyStatus" strong secondary type="primary" @click="stopPythonClick">停止</NButton>
|
||||
<NButton v-else strong secondary type="primary" @click="runPythonClick">运行</NButton>
|
||||
<NButton strong secondary type="primary" @click="quickPublishClick">一键发布</NButton>
|
||||
</NSpace>
|
||||
|
||||
<div v-if="dataRef">
|
||||
<NCard>
|
||||
<NGrid x-gap="12" :cols="4">
|
||||
<NGi>
|
||||
主题: <NSelect v-model:value="theme" :options="themes" />
|
||||
</NGi>
|
||||
<NGi>
|
||||
<NSelect v-model:value="eol" :options="eols" />
|
||||
</NGi>
|
||||
<NGi>
|
||||
<NSelect v-model:value="wordWrap" :options="wordWraps" />
|
||||
</NGi>
|
||||
<NGi>
|
||||
<NSelect v-model:value="minimap" :options="minimaps" />
|
||||
</NGi>
|
||||
</NGrid>
|
||||
<br/>
|
||||
<NSpace reverse>
|
||||
<NButton strong secondary type="success" @click="quickPublishClick">一键发布</NButton>
|
||||
<NButton v-if="pyStatus" strong secondary type="error" @click="stopPythonClick">停止</NButton>
|
||||
<NButton v-else strong secondary type="info" @click="runPythonClick">运行</NButton>
|
||||
<NButton strong secondary type="warning" @click="saveFileClick">保存</NButton>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
<NLayout has-sider>
|
||||
<NLayoutSider
|
||||
collapse-mode="transform"
|
||||
:collapsed-width="120"
|
||||
:width="240"
|
||||
show-trigger="bar"
|
||||
content-style="padding: 24px;"
|
||||
content-style="padding-top: 12px;"
|
||||
bordered
|
||||
>
|
||||
<NTree
|
||||
@ -297,6 +351,23 @@ onMounted(() => {
|
||||
</NLayoutContent>
|
||||
</NLayout>
|
||||
</div>
|
||||
<div v-else>
|
||||
<NForm ref="formRef" :model="model" :rules="rules">
|
||||
<NFormItem path="projectName" label="项目名称">
|
||||
<NInput v-model:value="model.projectName" />
|
||||
</NFormItem>
|
||||
<NFormItem path="项目地址" label="项目地址">
|
||||
<NInput v-model:value="model.projectUrl" />
|
||||
</NFormItem>
|
||||
<NRow :gutter="[0, 24]">
|
||||
<NCol :span="24">
|
||||
<div style="display: flex; justify-content: flex-end">
|
||||
<NButton type="primary" @click="handleSubmit">{{ $t('common.save') }}</NButton>
|
||||
</div>
|
||||
</NCol>
|
||||
</NRow>
|
||||
</NForm>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
Loading…
Reference in New Issue
Block a user