Skip to content

Commit

Permalink
feat: add support for multiple blueprint kinds
Browse files Browse the repository at this point in the history
  • Loading branch information
fhussonnois committed Jan 23, 2025
1 parent 6b4e1ca commit ad719a9
Show file tree
Hide file tree
Showing 23 changed files with 313 additions and 135 deletions.
105 changes: 65 additions & 40 deletions ui/src/components/flows/blueprints/BlueprintDetail.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<top-nav-bar v-if="!embed && blueprint" :title="blueprint.title" :breadcrumb="breadcrumb" v-loading="!blueprint">
<template #additional-right>
<ul v-if="userCanCreateFlow">
<ul v-if="userCanCreateFlow && kind === 'flow' ">
<router-link :to="{name: 'flows/create', query: {blueprintId: blueprint.id, blueprintSource: embedFriendlyBlueprintBaseUri.includes('community') ? 'community' : 'custom'}}">
<el-button type="primary" v-if="!embed">
{{ $t('use') }}
Expand Down Expand Up @@ -47,7 +47,7 @@
:input="true"
:full-height="false"
:minimap="false"
:model-value="blueprint.flow"
:model-value="blueprint.source"
lang="yaml"
:navbar="false"
>
Expand All @@ -68,7 +68,7 @@
<markdown :source="blueprint.description" />
</template>
</el-col>
<el-col :md="24" :lg="embed ? 24 : 6">
<el-col :md="24" :lg="embed ? 24 : 6" v-if="blueprint?.includedTasks?.length > 0">
<h4>Plugins</h4>
<div class="plugins-container">
<div v-for="task in [...new Set(blueprint.includedTasks)]" :key="task">
Expand Down Expand Up @@ -129,7 +129,11 @@
blueprintBaseUri: {
type: String,
default: undefined,
}
},
kind: {
type: String,
default: "flow",
},
},
methods: {
goBack() {
Expand All @@ -147,43 +151,64 @@
}
},
async created() {
this.blueprint = (await this.$http.get(`${this.embedFriendlyBlueprintBaseUri}/${this.blueprintId}`)).data;
try {
if (this.embedFriendlyBlueprintBaseUri.endsWith("community")) {
this.flowGraph = (await this.$http.get(`${this.embedFriendlyBlueprintBaseUri}/${this.blueprintId}/graph`, {
validateStatus: (status) => {
return status === 200;
}
}))?.data;
} else {
this.flowGraph = await this.$store.dispatch("flow/getGraphFromSourceResponse", {
flow: this.blueprint.flow, config: {
validateStatus: (status) => {
return status === 200;
this.$store.dispatch("blueprints/getBlueprint", {type: this.blueprintType, kind: this.blueprintKind, id: this.blueprintId})
.then(data => {
this.blueprint = data;
if (this.kind === "flow") {
try {
if (this.embedFriendlyBlueprintBaseUri.endsWith("community")) {
this.$store.dispatch(
"blueprints/getBlueprintGraph",
{
type: this.blueprintType,
kind: this.blueprintKind,
id: this.blueprintId,
validateStatus: (status) => {
return status === 200;
}
})
.then(data => {
this.flowGraph = data;
});
} else {
this.$store.dispatch("flow/getGraphFromSourceResponse", {
flow: this.blueprint.source, config: {
validateStatus: (status) => {
return status === 200;
}
}
}).then(data => {
this.flowGraph = data ;
});
}
} catch (e) {
console.error("Unable to create the blueprint's topology : " + e);
}
});
}
} catch (e) {
console.error("Unable to create the blueprint's topology : " + e);
}
}
});
},
computed: {
...mapState("auth", ["user"]),
...mapState("plugin", ["icons"]),
...mapState("blueprints", ["blueprint"]),
userCanCreateFlow() {
return this.user.hasAnyAction(permission.FLOW, action.CREATE);
},
parsedFlow() {
return {
...YamlUtils.parse(this.blueprint.flow),
source: this.blueprint.flow
...YamlUtils.parse(this.blueprint.source),
source: this.blueprint.source
}
},
embedFriendlyBlueprintBaseUri() {
return this.blueprintBaseUri ?? (`${apiUrl(this.$store)}/blueprints/` + (this?.$route?.params?.tab ?? "community"))
}
},
blueprintType() {
return this.tab ?? this?.$route?.params?.tab ?? "community";
},
blueprintKind() {
return this.blueprintType === "community" ? this.kind : undefined;
},
}
};
</script>
Expand Down Expand Up @@ -280,21 +305,21 @@
}
}
.tags {
margin: 10px 0;
display: flex;
.tags {
margin: 10px 0;
display: flex;
.el-tag.el-tag--info {
background-color: var(--ks-background-card);
padding: 15px 10px;
color: var(--ks-content-primary);
text-transform: capitalize;
font-size: var(--el-font-size-small);
border: 1px solid var(--ks-border-primary);
}
.el-tag.el-tag--info {
background-color: var(--ks-background-card);
padding: 15px 10px;
color: var(--ks-content-primary);
text-transform: capitalize;
font-size: var(--el-font-size-small);
border: 1px solid var(--ks-border-primary);
}
.tag-box {
margin-right: calc($spacer / 3);
}
.tag-box {
margin-right: calc($spacer / 3);
}
}
</style>
17 changes: 15 additions & 2 deletions ui/src/override/components/flows/blueprints/Blueprints.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
<top-nav-bar v-if="!embed" :title="routeInfo.title" />
<dotted-layout
:embed="embed"
:phrase="$t('blueprints.header.catch phrase.2')"
:phrase="$t('blueprints.header.catch phrase.2', {kind: kind})"
:alt="$t('blueprints.header.alt')"
:image="headerImage"
:image-dark="headerImageDark"
>
<section class="main-container" v-bind="$attrs">
<blueprint-detail v-if="selectedBlueprintId" :embed="embed" :blueprint-id="selectedBlueprintId" @back="selectedBlueprintId = undefined" :blueprint-base-uri="blueprintUri" />
<blueprints-browser @loaded="$emit('loaded', $event)" :class="{'d-none': !!selectedBlueprintId}" :embed="embed" :blueprint-base-uri="blueprintUri" @go-to-detail="blueprintId => selectedBlueprintId = blueprintId" />
<blueprints-browser
@loaded="$emit('loaded', $event)"
:class="{'d-none': !!selectedBlueprintId}"
:embed="embed"
:blueprint-base-uri="blueprintUri"
:blueprint-kind="kind"
@go-to-detail="blueprintId => selectedBlueprintId = blueprintId"
/>
</section>
</dotted-layout>
</template>
Expand All @@ -36,6 +43,12 @@
emits: [
"loaded"
],
props: {
kind: {
type: String,
required: true
},
},
data() {
return {
selectedBlueprintId: undefined,
Expand Down
50 changes: 28 additions & 22 deletions ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<component
class="blueprint-link"
:is="embed ? 'div' : 'router-link'"
:to="embed ? undefined : {name: 'blueprints/view', params: {blueprintId: blueprint.id, tab}}"
:to="embed ? undefined : {name: 'blueprints/view', params: {blueprintId: blueprint.id, tab, kind: blueprintKind}}"
>
<div class="left">
<div class="blueprint">
Expand Down Expand Up @@ -85,7 +85,7 @@
{{ $t('copy') }}
</el-button>
</el-tooltip>
<el-button v-else type="primary" size="default" @click.prevent.stop="blueprintToEditor(blueprint.id)">
<el-button v-else-if="blueprintKind === 'flow'" type="primary" size="default" @click.prevent.stop="blueprintToEditor(blueprint.id)">
{{ $t('use') }}
</el-button>
</div>
Expand Down Expand Up @@ -126,6 +126,10 @@
type: String,
default: undefined,
},
blueprintKind: {
type: String,
default: "flow",
},
embed: {
type: Boolean,
default: false
Expand Down Expand Up @@ -153,12 +157,15 @@
}
},
methods: {
kind() {
return this.blueprintType === "community" ? this.blueprintKind : undefined;
},
initSelectedTag() {
return this.$route?.query?.selectedTag ?? 0
},
async copy(blueprintId) {
async copy(id) {
await Utils.copy(
(await this.$http.get(`${this.embedFriendlyBlueprintBaseUri}/${blueprintId}/flow`)).data
(await this.$store.dispatch("blueprints/getBlueprintSource", {type: this.blueprintType, kind: this.kind(), id: id}))
);
},
async blueprintToEditor(blueprintId) {
Expand All @@ -181,17 +188,13 @@
if (this.$route.query.q || this.q) {
query.q = this.$route.query.q || this.q;
}
return this.$http
.get(beforeLoadBlueprintBaseUri + "/tags", {
params: query
})
.then(response => {
return this.$store.dispatch("blueprints/getBlueprintTagsForQuery", {type: this.blueprintType, kind: this.kind(), ...query})
.then(data => {
// Handle switch tab while fetching data
if (this.embedFriendlyBlueprintBaseUri === beforeLoadBlueprintBaseUri) {
this.tags = this.tagsResponseMapper(response.data);
this.tags = this.tagsResponseMapper(data);
}
})
});
},
loadBlueprints(beforeLoadBlueprintBaseUri) {
const query = {}
Expand All @@ -200,7 +203,6 @@
query.page = parseInt(this.$route.query.page || this.internalPageNumber);
}
if (this.$route.query.size || this.internalPageSize) {
query.size = parseInt(this.$route.query.size || this.internalPageSize);
}
Expand All @@ -215,16 +217,13 @@
query.tags = this.$route.query.selectedTag || this.selectedTag;
}
return this.$http
.get(beforeLoadBlueprintBaseUri, {
params: query
})
.then(response => {
return this.$store
.dispatch("blueprints/getBlueprintsForQuery", {type: this.blueprintType, kind: this.kind(), ...query})
.then(data => {
// Handle switch tab while fetching data
if (this.embedFriendlyBlueprintBaseUri === beforeLoadBlueprintBaseUri) {
const blueprintsResponse = response.data;
this.total = blueprintsResponse.total;
this.blueprints = blueprintsResponse.results;
this.total = data.total;
this.blueprints = data.results;
}
});
},
Expand Down Expand Up @@ -258,6 +257,7 @@
computed: {
...mapState("auth", ["user"]),
...mapState("plugin", ["icons"]),
...mapState("blueprint", ["blueprints"]),
userCanCreateFlow() {
return this.user.hasAnyAction(permission.FLOW, action.CREATE);
},
Expand All @@ -268,6 +268,9 @@
return base
? (base.endsWith("/undefined") ? base.replace("/undefined", `/${tab}`) : base)
: `${apiUrl(this.$store)}/blueprints/${tab}`;
},
blueprintType() {
return this.tab ?? this?.$route?.params?.tab ?? "community";
}
},
watch: {
Expand Down Expand Up @@ -308,7 +311,10 @@
this.loadData();
},
tab() {
this.loadData()
this.loadData();
},
blueprintKind() {
this.loadData();
}
}
};
Expand Down
12 changes: 11 additions & 1 deletion ui/src/override/components/useLeftMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,23 @@ export function useLeftMenu() {
}
},
{
href: {name: "blueprints"},
href: {name: "blueprints", params: {kind: "flow"}},
routes: routeStartWith("blueprints"),
title: t("blueprints.title"),
icon: {
element: shallowRef(BallotOutline),
class: "menu-icon"
},
child: [
{
title: t("homeDashboard.title"),
icon: {
element: shallowRef(ViewDashboardVariantOutline),
class: "menu-icon"
},
href: {name: "blueprints", params: {kind: "dashboard"}},
},
]
},
{
href: {name: "plugins/list"},
Expand Down
4 changes: 2 additions & 2 deletions ui/src/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default [
{name: "taskruns/list", path: "/:tenant?/taskruns", component: () => import("../components/taskruns/TaskRuns.vue")},

//Blueprints
{name: "blueprints", path: "/:tenant?/blueprints", component: () => import("override/components/flows/blueprints/Blueprints.vue"), props: {topNavbar: false}},
{name: "blueprints/view", path: "/:tenant?/blueprints/:blueprintId", component: () => import("../components/flows/blueprints/BlueprintDetail.vue"), props: true},
{name: "blueprints", path: "/:tenant?/blueprints/:kind", component: () => import("override/components/flows/blueprints/Blueprints.vue"), props: {topNavbar: false}},
{name: "blueprints/view", path: "/:tenant?/blueprints/:kind/:blueprintId", component: () => import("../components/flows/blueprints/BlueprintDetail.vue"), props: true},

//Documentation
{name: "plugins/list", path: "/:tenant?/plugins", component: () => import("../components/plugins/Plugin.vue")},
Expand Down
Loading

0 comments on commit ad719a9

Please sign in to comment.