mirror of https://github.com/certd/certd
perf: 增加向导
parent
babd5897ae
commit
6d9ef26eca
|
@ -132,6 +132,18 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
helper: {
|
||||
render() {
|
||||
const closeForm = () => {
|
||||
crudExpose.getFormWrapperRef().close();
|
||||
};
|
||||
return (
|
||||
<router-link to={"/sys/cname/provider"} onClick={closeForm}>
|
||||
前往设置CNAME服务
|
||||
</router-link>
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
column: {
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
<template>
|
||||
<fs-page class="page-cert">
|
||||
<template #header>
|
||||
<div class="title">CNAME记录管理</div>
|
||||
<div class="title">
|
||||
CNAME记录管理
|
||||
<span class="sub">
|
||||
<a href="https://certd.docmirror.cn/guide/feature/cname/" target="_blank">CNAME功能原理及使用说明</a>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #pagination-left>
|
||||
|
|
|
@ -1,79 +1,127 @@
|
|||
<template>
|
||||
<fs-page class="fs-pipeline-detail">
|
||||
<pipeline-edit v-model:edit-mode="editMode" :pipeline-id="pipelineId" :options="pipelineOptionsRef"></pipeline-edit>
|
||||
<a-tour v-model:current="tourCurrent" :open="tourOpen" :steps="tourSteps" @close="tourHandleOpen(false)" />
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, Ref, ref } from "vue";
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, Ref, ref } from "vue";
|
||||
import PipelineEdit from "./pipeline/index.vue";
|
||||
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, PluginGroups, RunHistory } from "./pipeline/type";
|
||||
import { TourProps } from "ant-design-vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "PipelineDetail",
|
||||
components: { PipelineEdit },
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const pipelineId: Ref = ref(route.query.id);
|
||||
|
||||
const pipelineOptions: PipelineOptions = {
|
||||
async getPipelineDetail({ pipelineId }) {
|
||||
const detail = await api.GetDetail(pipelineId);
|
||||
return {
|
||||
pipeline: {
|
||||
id: detail.pipeline.id,
|
||||
stages: [],
|
||||
triggers: [],
|
||||
...JSON.parse(detail.pipeline.content || "{}")
|
||||
}
|
||||
} as PipelineDetail;
|
||||
},
|
||||
|
||||
async getHistoryList({ pipelineId }) {
|
||||
const list: RunHistory[] = await historyApi.GetList({ pipelineId });
|
||||
return list;
|
||||
},
|
||||
|
||||
async getHistoryDetail({ historyId }): Promise<RunHistory> {
|
||||
const detail = await historyApi.GetDetail({ id: historyId });
|
||||
return detail;
|
||||
},
|
||||
|
||||
async getPluginGroups() {
|
||||
const groups = await pluginApi.GetGroups({});
|
||||
return new PluginGroups(groups);
|
||||
},
|
||||
|
||||
async doSave(pipelineConfig: any) {
|
||||
await api.Save({
|
||||
id: pipelineConfig.id,
|
||||
content: JSON.stringify(pipelineConfig)
|
||||
});
|
||||
},
|
||||
async doTrigger(options: { pipelineId: number; stepId?: string }) {
|
||||
const { pipelineId, stepId } = options;
|
||||
await api.Trigger(pipelineId, stepId);
|
||||
}
|
||||
};
|
||||
|
||||
const pipelineOptionsRef: Ref<PipelineOptions> = ref(pipelineOptions);
|
||||
|
||||
const editMode = ref(false);
|
||||
if (route.query.editMode !== "false") {
|
||||
editMode.value = true;
|
||||
}
|
||||
|
||||
return {
|
||||
pipelineOptionsRef,
|
||||
pipelineId,
|
||||
editMode
|
||||
};
|
||||
}
|
||||
defineOptions({
|
||||
name: "PipelineDetail"
|
||||
});
|
||||
const route = useRoute();
|
||||
const pipelineId: Ref = ref(route.query.id);
|
||||
|
||||
const pipelineOptions: PipelineOptions = {
|
||||
async getPipelineDetail({ pipelineId }) {
|
||||
const detail = await api.GetDetail(pipelineId);
|
||||
onLoaded();
|
||||
return {
|
||||
pipeline: {
|
||||
id: detail.pipeline.id,
|
||||
stages: [],
|
||||
triggers: [],
|
||||
...JSON.parse(detail.pipeline.content || "{}")
|
||||
}
|
||||
} as PipelineDetail;
|
||||
},
|
||||
|
||||
async getHistoryList({ pipelineId }) {
|
||||
const list: RunHistory[] = await historyApi.GetList({ pipelineId });
|
||||
return list;
|
||||
},
|
||||
|
||||
async getHistoryDetail({ historyId }): Promise<RunHistory> {
|
||||
const detail = await historyApi.GetDetail({ id: historyId });
|
||||
return detail;
|
||||
},
|
||||
|
||||
async getPluginGroups() {
|
||||
const groups = await pluginApi.GetGroups({});
|
||||
return new PluginGroups(groups);
|
||||
},
|
||||
|
||||
async doSave(pipelineConfig: any) {
|
||||
await api.Save({
|
||||
id: pipelineConfig.id,
|
||||
content: JSON.stringify(pipelineConfig)
|
||||
});
|
||||
},
|
||||
async doTrigger(options: { pipelineId: number; stepId?: string }) {
|
||||
const { pipelineId, stepId } = options;
|
||||
await api.Trigger(pipelineId, stepId);
|
||||
}
|
||||
};
|
||||
|
||||
const pipelineOptionsRef: Ref<PipelineOptions> = ref(pipelineOptions);
|
||||
|
||||
const editMode = ref(false);
|
||||
if (route.query.editMode !== "false") {
|
||||
editMode.value = true;
|
||||
}
|
||||
|
||||
function useTour() {
|
||||
const tourOpen = ref<boolean>(false);
|
||||
|
||||
const tourCurrent = ref(0);
|
||||
//@ts-ignore
|
||||
const tourSteps: TourProps["steps"] = ref([]);
|
||||
|
||||
const tourHandleOpen = (val: boolean): void => {
|
||||
initSteps();
|
||||
tourOpen.value = val;
|
||||
};
|
||||
|
||||
function initSteps() {
|
||||
//@ts-ignore
|
||||
tourSteps.value = [
|
||||
{
|
||||
title: "恭喜创建证书流水线成功",
|
||||
description: "这里就是我们刚创建的证书任务,点击可以修改证书申请参数",
|
||||
target: () => {
|
||||
return document.querySelector(".pipeline .stages .stage_0 .task");
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "添加部署证书任务",
|
||||
description: "证书申请成功之后还需要部署证书,点击这里可以添加部署任务",
|
||||
target: () => {
|
||||
return document.querySelector(".pipeline .stages .last-stage .tasks .task");
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "手动运行流水线",
|
||||
description: "点击此处可以手动运行流水线",
|
||||
target: () => {
|
||||
return document.querySelector(".pipeline .stages .first-stage .tasks .task");
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
tourOpen,
|
||||
tourCurrent,
|
||||
tourSteps,
|
||||
tourHandleOpen
|
||||
};
|
||||
}
|
||||
|
||||
const { tourOpen, tourCurrent, tourSteps, tourHandleOpen } = useTour();
|
||||
|
||||
async function onLoaded() {
|
||||
await nextTick();
|
||||
tourHandleOpen(true);
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.page-pipeline-detail {
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
</template>
|
||||
|
||||
<template #item="{ element: stage, index }">
|
||||
<div :key="stage.id" class="stage" :class="{ 'last-stage': isLastStage(index) }">
|
||||
<div :key="stage.id" class="stage" :class="{ 'last-stage': isLastStage(index), ['stage_' + index]: true }">
|
||||
<div class="title">
|
||||
<text-editable v-model="stage.title" :disabled="!editMode"></text-editable>
|
||||
<div v-plus class="icon-box stage-move-handle">
|
||||
|
@ -252,7 +252,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, provide, Ref, watch } from "vue";
|
||||
import { defineComponent, ref, provide, Ref, watch, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import PiTaskForm from "./component/task-form/index.vue";
|
||||
import PiTriggerForm from "./component/trigger-form/index.vue";
|
||||
|
@ -261,7 +261,7 @@ import PiTaskView from "./component/task-view/index.vue";
|
|||
import PiStatusShow from "./component/status-show.vue";
|
||||
import VDraggable from "vuedraggable";
|
||||
import _ from "lodash-es";
|
||||
import { message, Modal, notification } from "ant-design-vue";
|
||||
import { message, Modal, notification, TourProps } from "ant-design-vue";
|
||||
import { nanoid } from "nanoid";
|
||||
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./type";
|
||||
import type { Runnable, Stage } from "@certd/pipeline";
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
<div class="suggest">
|
||||
<div>
|
||||
<tutorial-button class="flex-center">
|
||||
<a-tag color="blue" class="flex-center">
|
||||
仅需3步,全自动申请部署证书<fs-icon class="font-size-16 ml-5" icon="mingcute:question-line"></fs-icon
|
||||
></a-tag>
|
||||
<a-tooltip title="点击查看详细教程">
|
||||
<a-tag color="blue" class="flex-center">
|
||||
仅需3步,全自动申请部署证书
|
||||
<fs-icon class="font-size-16 ml-5" icon="mingcute:question-line"></fs-icon>
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
</tutorial-button>
|
||||
<simple-steps></simple-steps>
|
||||
</div>
|
||||
|
@ -79,7 +82,7 @@
|
|||
支持的部署任务列表 <a-tag color="green">{{ pluginGroups.groups.all.plugins.length }}</a-tag>
|
||||
</template>
|
||||
<a-row :gutter="10">
|
||||
<a-col v-for="item of pluginGroups.groups.all.plugins" class="plugin-item-col" :span="4">
|
||||
<a-col v-for="item of pluginGroups.groups.all.plugins" :key="item.name" class="plugin-item-col" :span="4">
|
||||
<a-card>
|
||||
<a-tooltip :title="item.desc">
|
||||
<div class="plugin-item pointer">
|
||||
|
@ -165,7 +168,7 @@ function transformStatusCount() {
|
|||
async function loadCount() {
|
||||
count.value = await GetStatisticCount();
|
||||
transformStatusCount();
|
||||
count.value.historyCountPerDay = count.value.historyCountPerDay.map((item) => {
|
||||
count.value.historyCountPerDay = count.value.historyCountPerDay.map((item: any) => {
|
||||
return {
|
||||
name: item.date,
|
||||
value: item.count
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
CNAME服务配置
|
||||
<span class="sub">
|
||||
此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。
|
||||
<a href="https://certd.docmirror.cn/guide/feature/cname/" taget="_blank">CNAME功能原理及使用说明</a>
|
||||
<a href="https://certd.docmirror.cn/guide/feature/cname/" target="_blank">CNAME功能原理及使用说明</a>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue