mirror of
https://github.com/certd/certd.git
synced 2026-04-24 04:17:25 +08:00
perf: 创建证书任务可以选择lege插件
This commit is contained in:
@@ -9,12 +9,7 @@ const defaultInputDefine = {
|
||||
}
|
||||
};
|
||||
|
||||
export async function GetList(query: any) {
|
||||
const plugins = await request({
|
||||
url: apiPrefix + "/list",
|
||||
method: "post",
|
||||
params: query
|
||||
});
|
||||
function initPlugins(plugins: any) {
|
||||
for (const plugin of plugins) {
|
||||
for (const key in plugin.input) {
|
||||
const field = _.merge({}, defaultInputDefine, plugin.input[key]);
|
||||
@@ -24,7 +19,7 @@ export async function GetList(query: any) {
|
||||
//嵌套对象
|
||||
field.key = ["input", key];
|
||||
if (field.required) {
|
||||
delete field.required;
|
||||
// delete field.required;
|
||||
if (field.rules == null) {
|
||||
field.rules = [];
|
||||
}
|
||||
@@ -34,5 +29,28 @@ export async function GetList(query: any) {
|
||||
}
|
||||
}
|
||||
console.log("plugins", plugins);
|
||||
}
|
||||
|
||||
export async function GetList(query: any) {
|
||||
const plugins = await request({
|
||||
url: apiPrefix + "/list",
|
||||
method: "post",
|
||||
params: query
|
||||
});
|
||||
initPlugins(plugins);
|
||||
return plugins;
|
||||
}
|
||||
|
||||
export async function GetGroups(query: any) {
|
||||
const groups = await request({
|
||||
url: apiPrefix + "/groups",
|
||||
method: "post",
|
||||
params: query
|
||||
});
|
||||
const plugins: any = [];
|
||||
for (const groupKey in groups) {
|
||||
plugins.push(...groups[groupKey].plugins);
|
||||
}
|
||||
initPlugins(plugins);
|
||||
return groups;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,39 @@
|
||||
import { compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from "@fast-crud/fast-crud";
|
||||
import { Dicts } from "./dicts";
|
||||
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
|
||||
import { PluginGroup } from "@certd/pipeline";
|
||||
|
||||
export default function (certPluginGroup: PluginGroup, formWrapperRef: any): CreateCrudOptionsRet {
|
||||
const inputs: any = {};
|
||||
|
||||
for (const plugin of certPluginGroup.plugins) {
|
||||
for (const inputKey in plugin.input) {
|
||||
if (inputs[inputKey]) {
|
||||
inputs[inputKey].form.show = true;
|
||||
continue;
|
||||
}
|
||||
const inputDefine = plugin.input[inputKey];
|
||||
if (!inputDefine.required && !inputDefine.maybeNeed) {
|
||||
continue;
|
||||
}
|
||||
inputs[inputKey] = {
|
||||
title: inputDefine.title,
|
||||
form: {
|
||||
...inputDefine,
|
||||
show: compute((ctx) => {
|
||||
console.log(formWrapperRef);
|
||||
const form = formWrapperRef.value.getFormData();
|
||||
if (!form) {
|
||||
return false;
|
||||
}
|
||||
return form?.certApplyPlugin === plugin.name;
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
console.log(inputs);
|
||||
debugger;
|
||||
|
||||
export default function (): CreateCrudOptionsRet {
|
||||
return {
|
||||
crudOptions: {
|
||||
form: {
|
||||
@@ -10,143 +42,31 @@ export default function (): CreateCrudOptionsRet {
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
domains: {
|
||||
title: "域名",
|
||||
certApplyPlugin: {
|
||||
title: "证书申请插件",
|
||||
type: "dict-select",
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
name: "a-input"
|
||||
}
|
||||
},
|
||||
dict: dict({
|
||||
data: [
|
||||
{ value: "CertApply", label: "JS-ACME" },
|
||||
{ value: "CertApplyLego", label: "Lego-ACME" }
|
||||
]
|
||||
}),
|
||||
form: {
|
||||
col: {
|
||||
span: 24
|
||||
},
|
||||
wrapperCol: {
|
||||
span: null
|
||||
},
|
||||
component: {
|
||||
mode: "tags",
|
||||
open: false
|
||||
},
|
||||
order: 0,
|
||||
value: "CertApply",
|
||||
helper: {
|
||||
render: () => {
|
||||
return (
|
||||
<div>
|
||||
<div>支持通配符域名,例如: *.foo.com 、 *.test.handsfree.work</div>
|
||||
<div>支持多个域名、多个子域名、多个通配符域名打到一个证书上(域名必须是在同一个DNS提供商解析)</div>
|
||||
<div>多级子域名要分成多个域名输入(*.foo.com的证书不能用于xxx.yyy.foo.com)</div>
|
||||
<div>输入一个回车之后,再输入下一个</div>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商</li>
|
||||
<li>JS-ACME:如果你的域名DNS属于阿里云、腾讯云、Cloudflare可以选择用它来申请</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
},
|
||||
valueResolve({ form }) {
|
||||
if (form.domains instanceof String) {
|
||||
form.domains = form.domains?.join(",");
|
||||
}
|
||||
},
|
||||
rules: [{ required: true, message: "请填写域名" }]
|
||||
}
|
||||
},
|
||||
email: {
|
||||
title: "邮箱",
|
||||
type: "text",
|
||||
search: { show: false },
|
||||
form: {
|
||||
rules: [{ required: true, type: "email", message: "请填写邮箱" }]
|
||||
}
|
||||
},
|
||||
blank: {
|
||||
title: "占位",
|
||||
type: "text",
|
||||
form: {
|
||||
blank: true
|
||||
}
|
||||
},
|
||||
sslProvider: {
|
||||
title: "证书提供商",
|
||||
type: "dict-select",
|
||||
dict: Dicts.sslProviderDict
|
||||
},
|
||||
eabAccess: {
|
||||
title: "EAB授权",
|
||||
type: "dict-select",
|
||||
form: {
|
||||
component: {
|
||||
name: "PiAccessSelector",
|
||||
type: "eab",
|
||||
vModel: "modelValue"
|
||||
},
|
||||
helper: "如果是ZeroSSL,需要配置EAB授权,https://app.zerossl.com/developer 生成 'EAB' "
|
||||
}
|
||||
},
|
||||
dnsProviderType: {
|
||||
title: "DNS提供商",
|
||||
type: "dict-select",
|
||||
dict: Dicts.dnsProviderTypeDict,
|
||||
form: {
|
||||
value: "aliyun",
|
||||
rules: [{ required: true, message: "请选择DNS提供商" }],
|
||||
valueChange({ form }) {
|
||||
form.dnsProviderAccess = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
dnsProviderAccess: {
|
||||
title: "DNS授权",
|
||||
type: "text",
|
||||
form: {
|
||||
component: {
|
||||
name: "PiAccessSelector",
|
||||
type: compute(({ form }) => {
|
||||
return form.dnsProviderType;
|
||||
}),
|
||||
vModel: "modelValue"
|
||||
},
|
||||
rules: [{ required: true, message: "请选择DNS授权" }]
|
||||
}
|
||||
}
|
||||
// country: {
|
||||
// title: "国家",
|
||||
// type: "text",
|
||||
// form: {
|
||||
// value: "China"
|
||||
// }
|
||||
// },
|
||||
// state: {
|
||||
// title: "省份",
|
||||
// type: "text",
|
||||
// form: {
|
||||
// value: "GuangDong"
|
||||
// }
|
||||
// },
|
||||
// locality: {
|
||||
// title: "市区",
|
||||
// type: "text",
|
||||
// form: {
|
||||
// value: "NanShan"
|
||||
// }
|
||||
// },
|
||||
// organization: {
|
||||
// title: "单位",
|
||||
// type: "text",
|
||||
// form: {
|
||||
// value: "CertD"
|
||||
// }
|
||||
// },
|
||||
// organizationUnit: {
|
||||
// title: "部门",
|
||||
// type: "text",
|
||||
// form: {
|
||||
// value: "IT Dept"
|
||||
// }
|
||||
// },
|
||||
// remark: {
|
||||
// title: "备注",
|
||||
// type: "text"
|
||||
// }
|
||||
...inputs
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<fs-form-wrapper ref="formWrapperRef" />
|
||||
<fs-form-wrapper v-if="formWrapperOptions" ref="formWrapperRef" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -7,28 +7,37 @@ import { useColumns, useExpose } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud.jsx";
|
||||
import { ref } from "vue";
|
||||
import _ from "lodash-es";
|
||||
import * as api from "../api.plugin";
|
||||
import { PluginGroup, PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
|
||||
export default {
|
||||
name: "PiCertdForm",
|
||||
setup(props: any, ctx: any) {
|
||||
// 自定义表单配置
|
||||
const { buildFormOptions } = useColumns();
|
||||
//使用crudOptions结构来构建自定义表单配置
|
||||
let { crudOptions } = createCrudOptions();
|
||||
const doSubmitRef = ref();
|
||||
const formOptions = buildFormOptions(
|
||||
_.merge(crudOptions, {
|
||||
form: {
|
||||
doSubmit({ form }: any) {
|
||||
// 创建certd 的pipeline
|
||||
doSubmitRef.value({ form });
|
||||
}
|
||||
}
|
||||
}) as any
|
||||
);
|
||||
|
||||
const formWrapperRef = ref();
|
||||
const formWrapperOptions = ref();
|
||||
formWrapperOptions.value = formOptions;
|
||||
const doSubmitRef = ref();
|
||||
async function buildFormOptions() {
|
||||
const pluginGroups: { [key: string]: PluginGroup } = await api.GetGroups({});
|
||||
const certPluginGroup = pluginGroups.cert;
|
||||
|
||||
// 自定义表单配置
|
||||
const { buildFormOptions } = useColumns();
|
||||
//使用crudOptions结构来构建自定义表单配置
|
||||
let { crudOptions } = createCrudOptions(certPluginGroup, formWrapperRef);
|
||||
|
||||
const formOptions = buildFormOptions(
|
||||
_.merge(crudOptions, {
|
||||
form: {
|
||||
doSubmit({ form }: any) {
|
||||
// 创建certd 的pipeline
|
||||
doSubmitRef.value({ form });
|
||||
}
|
||||
}
|
||||
}) as any
|
||||
);
|
||||
|
||||
formWrapperOptions.value = formOptions;
|
||||
}
|
||||
buildFormOptions();
|
||||
function open(doSubmit: any) {
|
||||
doSubmitRef.value = doSubmit;
|
||||
formWrapperRef.value.open(formWrapperOptions.value);
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp
|
||||
strategy: {
|
||||
runStrategy: 0 // 正常执行
|
||||
},
|
||||
type: "CertApply"
|
||||
type: form.certApplyPlugin
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ import * as pluginApi from "./api.plugin";
|
||||
import * as historyApi from "./api.history";
|
||||
import * as api from "./api";
|
||||
import { useRoute } from "vue-router";
|
||||
import { PipelineDetail, PipelineOptions, RunHistory } from "./pipeline/type";
|
||||
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./pipeline/type";
|
||||
|
||||
export default defineComponent({
|
||||
name: "PipelineDetail",
|
||||
components: { PipelineEdit },
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const pipelineId:Ref = ref(route.query.id);
|
||||
const pipelineId: Ref = ref(route.query.id);
|
||||
|
||||
const pipelineOptions: PipelineOptions = {
|
||||
async getPipelineDetail({ pipelineId }) {
|
||||
@@ -43,9 +43,9 @@ export default defineComponent({
|
||||
return detail;
|
||||
},
|
||||
|
||||
async getPlugins() {
|
||||
const plugins = await pluginApi.GetList({});
|
||||
return plugins as any[];
|
||||
async getPluginGroups() {
|
||||
const groups = await pluginApi.GetGroups({});
|
||||
return new PluginGroups(groups);
|
||||
},
|
||||
|
||||
async doSave(pipelineConfig: any) {
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
<div class="title">我的流水线</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #actionbar-right>
|
||||
<!-- <span style="margin-left: 10px">出现<a-tag>Promise rejected attempt #18,retrying in 10000ms:No TXT recordsfound for name</a-tag>属于正常现象,多重试几次</span>-->
|
||||
</template>
|
||||
<template #actionbar-right> </template>
|
||||
<template #form-bottom>
|
||||
<div>
|
||||
申请证书
|
||||
</div>
|
||||
<div>申请证书</div>
|
||||
</template>
|
||||
<pi-certd-form ref="certdFormRef"></pi-certd-form>
|
||||
</fs-crud>
|
||||
|
||||
+6
-4
@@ -15,7 +15,7 @@ export default {
|
||||
}
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
setup(props:any, ctx:any) {
|
||||
setup(props: any, ctx: any) {
|
||||
const options = ref<any[]>([]);
|
||||
|
||||
const pipeline = inject("pipeline") as Ref<any>;
|
||||
@@ -23,8 +23,10 @@ export default {
|
||||
const currentStepIndex = inject("currentStepIndex") as Ref<number>;
|
||||
const currentTask = inject("currentTask") as Ref<any>;
|
||||
|
||||
const getPluginGroups = inject("getPluginGroups") as Ref<any>;
|
||||
const pluginGroups = getPluginGroups();
|
||||
function onCreate() {
|
||||
options.value = pluginManager.getPreStepOutputOptions({
|
||||
options.value = pluginGroups.getPreStepOutputOptions({
|
||||
pipeline: pipeline.value,
|
||||
currentStageIndex: currentStageIndex.value,
|
||||
currentStepIndex: currentStepIndex.value,
|
||||
@@ -40,14 +42,14 @@ export default {
|
||||
|
||||
watch(
|
||||
() => {
|
||||
return pluginManager.map;
|
||||
return pluginGroups.value.map;
|
||||
},
|
||||
() => {
|
||||
onCreate();
|
||||
}
|
||||
);
|
||||
|
||||
function onChanged(value:any) {
|
||||
function onChanged(value: any) {
|
||||
ctx.emit("update:modelValue", value);
|
||||
}
|
||||
return {
|
||||
|
||||
+38
-31
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-drawer v-model:open="stepDrawerVisible" placement="right" :closable="true" width="600px" @after-open-change="stepDrawerOnAfterVisibleChange">
|
||||
<a-drawer v-model:open="stepDrawerVisible" placement="right" :closable="true" width="700px" @after-open-change="stepDrawerOnAfterVisibleChange">
|
||||
<template #title>
|
||||
编辑步骤
|
||||
<a-button v-if="editMode" @click="stepDelete()">
|
||||
@@ -8,30 +8,36 @@
|
||||
</template>
|
||||
<template v-if="currentStep">
|
||||
<pi-container v-if="currentStep._isAdd" class="pi-step-form">
|
||||
<a-row :gutter="10">
|
||||
<a-col v-for="(item, index) of stepPluginDefineList" :key="index" class="step-plugin" :span="12">
|
||||
<a-card
|
||||
hoverable
|
||||
:class="{ current: item.name === currentStep.type }"
|
||||
@click="stepTypeSelected(item)"
|
||||
@dblclick="
|
||||
stepTypeSelected(item);
|
||||
stepTypeSave();
|
||||
"
|
||||
>
|
||||
<a-card-meta>
|
||||
<template #title>
|
||||
<a-avatar :src="item.icon || '/images/plugin.png'" />
|
||||
<span class="title">{{ item.title }}</span>
|
||||
</template>
|
||||
<template #description>
|
||||
<span :title="item.desc">{{ item.desc }}</span>
|
||||
</template>
|
||||
</a-card-meta>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button v-if="editMode" type="primary" @click="stepTypeSave"> 确定 </a-button>
|
||||
<a-tabs tab-position="left">
|
||||
<a-tab-pane v-for="group of pluginGroups.groups" :key="group.key" :tab="group.title">
|
||||
<a-row :gutter="10">
|
||||
<a-col v-for="item of group.plugins" :key="item.key" class="step-plugin" :span="12">
|
||||
<a-card
|
||||
hoverable
|
||||
:class="{ current: item.name === currentStep.type }"
|
||||
@click="stepTypeSelected(item)"
|
||||
@dblclick="
|
||||
stepTypeSelected(item);
|
||||
stepTypeSave();
|
||||
"
|
||||
>
|
||||
<a-card-meta>
|
||||
<template #title>
|
||||
<a-avatar :src="item.icon || '/images/plugin.png'" />
|
||||
<span class="title">{{ item.title }}</span>
|
||||
</template>
|
||||
<template #description>
|
||||
<span :title="item.desc">{{ item.desc }}</span>
|
||||
</template>
|
||||
</a-card-meta>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<div style="padding: 20px; margin-left: 100px">
|
||||
<a-button v-if="editMode" type="primary" @click="stepTypeSave"> 确定 </a-button>
|
||||
</div>
|
||||
</pi-container>
|
||||
<pi-container v-else class="pi-step-form">
|
||||
<a-form ref="stepFormRef" class="step-form" :model="currentStep" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
@@ -91,6 +97,8 @@ import { computed, inject, Ref, ref } from "vue";
|
||||
import _ from "lodash-es";
|
||||
import { nanoid } from "nanoid";
|
||||
import { CopyOutlined } from "@ant-design/icons-vue";
|
||||
import { PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
|
||||
|
||||
export default {
|
||||
name: "PiStepForm",
|
||||
components: { CopyOutlined },
|
||||
@@ -107,8 +115,8 @@ export default {
|
||||
* @returns
|
||||
*/
|
||||
function useStepForm() {
|
||||
const stepPluginDefineList: any = inject("plugins");
|
||||
|
||||
const getPluginGroups: any = inject("getPluginGroups");
|
||||
const pluginGroups: PluginGroups = getPluginGroups();
|
||||
const mode: Ref = ref("add");
|
||||
const callback: Ref = ref();
|
||||
const currentStep: Ref = ref({ title: undefined, input: {} });
|
||||
@@ -199,9 +207,8 @@ export default {
|
||||
|
||||
const changeCurrentPlugin = (step: any) => {
|
||||
const stepType = step.type;
|
||||
const pluginDefine = stepPluginDefineList.value.find((p: any) => {
|
||||
return p.name === stepType;
|
||||
});
|
||||
const pluginDefine = pluginGroups.get(stepType);
|
||||
debugger;
|
||||
if (pluginDefine) {
|
||||
step.type = stepType;
|
||||
step._isAdd = false;
|
||||
@@ -271,7 +278,7 @@ export default {
|
||||
return {
|
||||
stepTypeSelected,
|
||||
stepTypeSave,
|
||||
stepPluginDefineList,
|
||||
pluginGroups,
|
||||
stepFormRef,
|
||||
mode,
|
||||
stepAdd,
|
||||
|
||||
+18
-5
@@ -1,5 +1,12 @@
|
||||
<template>
|
||||
<a-drawer v-model:open="taskDrawerVisible" placement="right" :closable="true" width="600px" class="pi-task-form" @after-open-change="taskDrawerOnAfterVisibleChange">
|
||||
<a-drawer
|
||||
v-model:open="taskDrawerVisible"
|
||||
placement="right"
|
||||
:closable="true"
|
||||
width="700px"
|
||||
class="pi-task-form"
|
||||
@after-open-change="taskDrawerOnAfterVisibleChange"
|
||||
>
|
||||
<template #title>
|
||||
编辑任务
|
||||
<a-button v-if="editMode" @click="taskDelete()">
|
||||
@@ -24,7 +31,13 @@
|
||||
/>
|
||||
|
||||
<div class="steps">
|
||||
<a-form-item :value="currentTask.steps" name="steps" label="" :wrapper-col="{ span: 24 }" :rules="[{ required: true, message: '至少需要一个步骤,或者你可以点击标题右边删除按钮删除此任务' }]">
|
||||
<a-form-item
|
||||
:value="currentTask.steps"
|
||||
name="steps"
|
||||
label=""
|
||||
:wrapper-col="{ span: 24 }"
|
||||
:rules="[{ required: true, message: '至少需要一个步骤,或者你可以点击标题右边删除按钮删除此任务' }]"
|
||||
>
|
||||
<a-descriptions title="任务步骤" size="small">
|
||||
<template #extra>
|
||||
<a-button type="primary" @click="stepAdd(currentTask)">添加步骤</a-button>
|
||||
@@ -70,7 +83,7 @@ import { provide, Ref, ref } from "vue";
|
||||
import _ from "lodash-es";
|
||||
import { nanoid } from "nanoid";
|
||||
import PiStepForm from "../step-form/index.vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { CopyOutlined } from "@ant-design/icons-vue";
|
||||
|
||||
export default {
|
||||
@@ -88,7 +101,7 @@ export default {
|
||||
const stepFormRef: Ref<any> = ref(null);
|
||||
const currentStepIndex = ref(0);
|
||||
provide("currentStepIndex", currentStepIndex);
|
||||
const stepAdd = (task: any, stepDef: any) => {
|
||||
const stepAdd = (task: any, stepDef?: any) => {
|
||||
currentStepIndex.value = task.steps.length;
|
||||
stepFormRef.value.stepAdd((type: any, value: any) => {
|
||||
if (type === "save") {
|
||||
@@ -179,7 +192,7 @@ export default {
|
||||
|
||||
const taskAdd = (emit: any, taskMerge: any) => {
|
||||
mode.value = "add";
|
||||
const blankTask = { id: nanoid(), title: "新任务", steps: [], status: null };
|
||||
const blankTask: any = { id: nanoid(), title: "新任务", steps: [], status: null };
|
||||
const task: any = _.merge(blankTask, taskMerge);
|
||||
taskOpen(task, emit);
|
||||
};
|
||||
|
||||
@@ -223,7 +223,7 @@ import _ from "lodash-es";
|
||||
import { message, Modal, notification } from "ant-design-vue";
|
||||
import { pluginManager } from "/@/views/certd/pipeline/pipeline/plugin";
|
||||
import { nanoid } from "nanoid";
|
||||
import { PipelineDetail, PipelineOptions, RunHistory } from "./type";
|
||||
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./type";
|
||||
import type { Runnable } from "@certd/pipeline";
|
||||
import PiHistoryTimelineItem from "/@/views/certd/pipeline/pipeline/component/history-timeline-item.vue";
|
||||
export default defineComponent({
|
||||
@@ -348,17 +348,17 @@ export default defineComponent({
|
||||
}
|
||||
);
|
||||
|
||||
const plugins: Ref<any> = ref([]);
|
||||
const pluginGroupsRef: Ref<PluginGroups> = ref();
|
||||
|
||||
const fetchPlugins = async () => {
|
||||
const list = await props.options.getPlugins();
|
||||
plugins.value = list;
|
||||
pluginManager.init(list);
|
||||
pluginGroupsRef.value = await props.options.getPluginGroups();
|
||||
};
|
||||
fetchPlugins();
|
||||
|
||||
provide("pipeline", pipeline);
|
||||
provide("plugins", plugins);
|
||||
provide("getPluginGroups", () => {
|
||||
return pluginGroupsRef.value;
|
||||
});
|
||||
provide("currentHistory", currentHistory);
|
||||
|
||||
function useTask() {
|
||||
|
||||
@@ -17,49 +17,7 @@ export class PluginManager {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
get(name: string) {
|
||||
return this.map[name];
|
||||
}
|
||||
|
||||
getPreStepOutputOptions({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
|
||||
const steps = this.collectionPreStepOutputs({
|
||||
pipeline,
|
||||
currentStageIndex,
|
||||
currentStepIndex,
|
||||
currentTask
|
||||
});
|
||||
const options: any[] = [];
|
||||
for (const step of steps) {
|
||||
const stepDefine = this.get(step.type);
|
||||
for (const key in stepDefine?.output) {
|
||||
options.push({
|
||||
value: `step.${step.id}.${key}`,
|
||||
label: `${stepDefine.output[key].title}【from:${step.title}】`,
|
||||
type: step.type
|
||||
});
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
collectionPreStepOutputs({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
|
||||
const steps: any[] = [];
|
||||
// 开始放step
|
||||
for (let i = 0; i < currentStageIndex; i++) {
|
||||
const stage = pipeline.stages[i];
|
||||
for (const task of stage.tasks) {
|
||||
for (const step of task.steps) {
|
||||
steps.push(step);
|
||||
}
|
||||
}
|
||||
}
|
||||
//放当前任务下的step
|
||||
for (let i = 0; i < currentStepIndex; i++) {
|
||||
const step = currentTask.steps[i];
|
||||
steps.push(step);
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
}
|
||||
|
||||
export const pluginManager = new PluginManager();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Pipeline } from "@certd/pipeline";
|
||||
import { FormItemProps } from "@fast-crud/fast-crud";
|
||||
export type PipelineDetail = {
|
||||
pipeline: Pipeline;
|
||||
};
|
||||
@@ -10,6 +11,110 @@ export type RunHistory = {
|
||||
[id: string]: string[];
|
||||
};
|
||||
};
|
||||
export type PluginGroup = {
|
||||
key: string;
|
||||
title: string;
|
||||
desc?: string;
|
||||
order: number;
|
||||
plugins: any[];
|
||||
};
|
||||
|
||||
export type PluginDefine = {
|
||||
key: string;
|
||||
title: string;
|
||||
desc?: string;
|
||||
input: {
|
||||
[key: string]: FormItemProps;
|
||||
};
|
||||
output: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
export class PluginGroups {
|
||||
groups: { [key: string]: PluginGroup };
|
||||
map: { [key: string]: PluginDefine };
|
||||
constructor(groups: { [key: string]: PluginGroup }) {
|
||||
this.groups = groups;
|
||||
this.initGroup(groups);
|
||||
this.initMap();
|
||||
}
|
||||
|
||||
private initGroup(groups: { [p: string]: PluginGroup }) {
|
||||
const all: PluginGroup = {
|
||||
key: "all",
|
||||
title: "全部",
|
||||
order: 0,
|
||||
plugins: []
|
||||
};
|
||||
for (const key in groups) {
|
||||
all.plugins.push(...groups[key].plugins);
|
||||
}
|
||||
this.groups = {
|
||||
all,
|
||||
...groups
|
||||
};
|
||||
}
|
||||
|
||||
initMap() {
|
||||
const map: { [key: string]: PluginDefine } = {};
|
||||
for (const key in this.groups) {
|
||||
const group = this.groups[key];
|
||||
for (const plugin of group.plugins) {
|
||||
map[plugin.name] = plugin;
|
||||
}
|
||||
}
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
getGroups() {
|
||||
return this.groups;
|
||||
}
|
||||
|
||||
get(name: string) {
|
||||
return this.map[name];
|
||||
}
|
||||
|
||||
getPreStepOutputOptions({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
|
||||
const steps = this.collectionPreStepOutputs({
|
||||
pipeline,
|
||||
currentStageIndex,
|
||||
currentStepIndex,
|
||||
currentTask
|
||||
});
|
||||
const options: any[] = [];
|
||||
for (const step of steps) {
|
||||
const stepDefine = this.get(step.type);
|
||||
for (const key in stepDefine?.output) {
|
||||
options.push({
|
||||
value: `step.${step.id}.${key}`,
|
||||
label: `${stepDefine.output[key].title}【from:${step.title}】`,
|
||||
type: step.type
|
||||
});
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
collectionPreStepOutputs({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
|
||||
const steps: any[] = [];
|
||||
// 开始放step
|
||||
for (let i = 0; i < currentStageIndex; i++) {
|
||||
const stage = pipeline.stages[i];
|
||||
for (const task of stage.tasks) {
|
||||
for (const step of task.steps) {
|
||||
steps.push(step);
|
||||
}
|
||||
}
|
||||
}
|
||||
//放当前任务下的step
|
||||
for (let i = 0; i < currentStepIndex; i++) {
|
||||
const step = currentTask.steps[i];
|
||||
steps.push(step);
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
}
|
||||
|
||||
export type PipelineOptions = {
|
||||
doTrigger(options: { pipelineId: number }): Promise<void>;
|
||||
@@ -17,5 +122,5 @@ export type PipelineOptions = {
|
||||
getPipelineDetail(query: { pipelineId: number }): Promise<PipelineDetail>;
|
||||
getHistoryList(query: { pipelineId: number }): Promise<RunHistory[]>;
|
||||
getHistoryDetail(query: { historyId: number }): Promise<RunHistory>;
|
||||
getPlugins(): Promise<Pipeline[]>;
|
||||
getPluginGroups(): Promise<PluginGroups>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user