mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
implement versions modal
This commit is contained in:
parent
efbee533d1
commit
df32a7bbb6
|
@ -25,6 +25,7 @@
|
||||||
"test:unit": "vue-cli-service test:unit"
|
"test:unit": "vue-cli-service test:unit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"timeago.js": "^4.0.2",
|
||||||
"v-click-outside": "^3.1.2"
|
"v-click-outside": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -546,6 +546,34 @@ export interface ITagRow {
|
||||||
delete?: boolean;
|
delete?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IVersion {
|
||||||
|
name: string;
|
||||||
|
nodes: Array<{
|
||||||
|
name: string;
|
||||||
|
displayName: string;
|
||||||
|
icon: string;
|
||||||
|
iconData: {
|
||||||
|
type: string;
|
||||||
|
icon?: string;
|
||||||
|
fileBuffer?: string;
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
createdAt: string;
|
||||||
|
description: string;
|
||||||
|
documentationUrl: string;
|
||||||
|
hasBreakingChange: boolean;
|
||||||
|
hasBugFixes: boolean;
|
||||||
|
hasCoreChanges: boolean;
|
||||||
|
hasNewNodes: boolean;
|
||||||
|
hasNodeEnhancements: boolean;
|
||||||
|
hasSecurityFix: boolean;
|
||||||
|
hasSecurityIssue: boolean;
|
||||||
|
isAvailableOnCloud: boolean;
|
||||||
|
isStable: boolean;
|
||||||
|
securityIssueFixVersion: string;
|
||||||
|
showReleaseNotification: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IRootState {
|
export interface IRootState {
|
||||||
activeExecutions: IExecutionsCurrentSummaryExtended[];
|
activeExecutions: IExecutionsCurrentSummaryExtended[];
|
||||||
activeWorkflows: string[];
|
activeWorkflows: string[];
|
||||||
|
@ -604,6 +632,11 @@ export interface IUiState {
|
||||||
isPageLoading: boolean;
|
isPageLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IVersionsState {
|
||||||
|
nextVersions: IVersion[];
|
||||||
|
currentVersion: IVersion | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IWorkflowsState {
|
export interface IWorkflowsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
packages/editor-ui/src/api/versions.ts
Normal file
7
packages/editor-ui/src/api/versions.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { IVersion } from '@/Interface';
|
||||||
|
import { get } from './helpers';
|
||||||
|
import { VERSIONS_BASE_URL } from '@/constants';
|
||||||
|
|
||||||
|
export async function getNextVersions(version: string): Promise<IVersion[]> {
|
||||||
|
return await get(VERSIONS_BASE_URL, version);
|
||||||
|
}
|
36
packages/editor-ui/src/components/Drawer.vue
Normal file
36
packages/editor-ui/src/components/Drawer.vue
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<SlideTransition>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</SlideTransition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from "vue";
|
||||||
|
import SlideTransition from "./transitions/SlideTransition.vue";
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
name: "Modal",
|
||||||
|
props: ['name'],
|
||||||
|
components: {
|
||||||
|
SlideTransition,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
/deep/ *, *:before, *:after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
position: fixed;
|
||||||
|
width: 480px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: $--drawer-background-color;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -128,9 +128,9 @@
|
||||||
<MenuItemsIterator :items="sidebarMenuBottomItems" :root="true"/>
|
<MenuItemsIterator :items="sidebarMenuBottomItems" :root="true"/>
|
||||||
|
|
||||||
<div class="foot-menu-items">
|
<div class="foot-menu-items">
|
||||||
<el-menu-item index="updates" class="updates">
|
<el-menu-item index="updates" class="updates" v-if="hasVersionUpdates" @click="openVersionsModal">
|
||||||
<i><font-awesome-icon icon="gift"/></i>
|
<i><font-awesome-icon icon="gift"/></i>
|
||||||
<span slot="title" class="item-title-root">Updates available</span>
|
<span slot="title" class="item-title-root">{{nextVersions.length}} update{{nextVersions.length > 1? 's': ''}} available</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</div>
|
</div>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
|
@ -238,6 +238,10 @@ export default mixins(
|
||||||
...mapGetters('ui', {
|
...mapGetters('ui', {
|
||||||
isCollapsed: 'sidebarMenuCollapsed',
|
isCollapsed: 'sidebarMenuCollapsed',
|
||||||
}),
|
}),
|
||||||
|
...mapGetters('versions', [
|
||||||
|
'hasVersionUpdates',
|
||||||
|
'nextVersions',
|
||||||
|
]),
|
||||||
exeuctionId (): string | undefined {
|
exeuctionId (): string | undefined {
|
||||||
return this.$route.params.id;
|
return this.$route.params.id;
|
||||||
},
|
},
|
||||||
|
@ -317,6 +321,9 @@ export default mixins(
|
||||||
openTagManager() {
|
openTagManager() {
|
||||||
this.$store.dispatch('ui/openTagsManagerModal');
|
this.$store.dispatch('ui/openTagsManagerModal');
|
||||||
},
|
},
|
||||||
|
openVersionsModal() {
|
||||||
|
this.$store.dispatch('ui/openVersionsModal');
|
||||||
|
},
|
||||||
async stopExecution () {
|
async stopExecution () {
|
||||||
const executionId = this.$store.getters.activeExecutionId;
|
const executionId = this.$store.getters.activeExecutionId;
|
||||||
if (executionId === null) {
|
if (executionId === null) {
|
||||||
|
@ -592,6 +599,7 @@ a.logo {
|
||||||
|
|
||||||
.el-menu-item.updates {
|
.el-menu-item.updates {
|
||||||
color: $--sidebar-inactive-color;
|
color: $--sidebar-inactive-color;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $--sidebar-active-color;
|
color: $--sidebar-active-color;
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="dialogVisible">
|
<div v-if="dialogVisible">
|
||||||
|
<el-drawer
|
||||||
|
v-if="drawer"
|
||||||
|
:direction="drawerDirection"
|
||||||
|
:visible="dialogVisible"
|
||||||
|
:size="drawerWidth"
|
||||||
|
>
|
||||||
|
<template v-slot:title>
|
||||||
|
<slot name="header" />
|
||||||
|
</template>
|
||||||
|
<template>
|
||||||
|
<slot name="content"/>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
|
v-else
|
||||||
:visible="dialogVisible"
|
:visible="dialogVisible"
|
||||||
:before-close="closeDialog"
|
:before-close="closeDialog"
|
||||||
:title="title"
|
:title="title"
|
||||||
|
@ -23,6 +37,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
|
import Drawer from "./Drawer.vue";
|
||||||
|
|
||||||
const sizeMap: {[size: string]: string} = {
|
const sizeMap: {[size: string]: string} = {
|
||||||
xl: '80%',
|
xl: '80%',
|
||||||
|
@ -32,7 +47,10 @@ const sizeMap: {[size: string]: string} = {
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: "Modal",
|
name: "Modal",
|
||||||
props: ['name', 'title', 'eventBus', 'size'],
|
components: {
|
||||||
|
Drawer,
|
||||||
|
},
|
||||||
|
props: ['name', 'title', 'eventBus', 'size', 'drawer', 'drawerDirection', 'drawerWidth'],
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('keydown', this.onWindowKeydown);
|
window.addEventListener('keydown', this.onWindowKeydown);
|
||||||
|
|
||||||
|
@ -84,6 +102,11 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.el-drawer__header {
|
||||||
|
margin: 0;
|
||||||
|
padding: 30px 30px 0 30px;; //todo
|
||||||
|
}
|
||||||
|
|
||||||
.dialog-wrapper {
|
.dialog-wrapper {
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
@ -24,17 +24,25 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</ModalRoot>
|
</ModalRoot>
|
||||||
|
<ModalRoot :name="VERSIONS_MODAL_KEY">
|
||||||
|
<template v-slot="{ modalName }">
|
||||||
|
<VersionsModal
|
||||||
|
:modalName="modalName"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ModalRoot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import { DUPLICATE_MODAL_KEY, TAGS_MANAGER_MODAL_KEY, WORKLOW_OPEN_MODAL_KEY } from '@/constants';
|
import { DUPLICATE_MODAL_KEY, TAGS_MANAGER_MODAL_KEY, WORKLOW_OPEN_MODAL_KEY, VERSIONS_MODAL_KEY } from '@/constants';
|
||||||
|
|
||||||
import TagsManager from "@/components/TagsManager/TagsManager.vue";
|
import TagsManager from "@/components/TagsManager/TagsManager.vue";
|
||||||
import DuplicateWorkflowDialog from "@/components/DuplicateWorkflowDialog.vue";
|
import DuplicateWorkflowDialog from "@/components/DuplicateWorkflowDialog.vue";
|
||||||
import WorkflowOpen from "@/components/WorkflowOpen.vue";
|
import WorkflowOpen from "@/components/WorkflowOpen.vue";
|
||||||
import ModalRoot from "./ModalRoot.vue";
|
import ModalRoot from "./ModalRoot.vue";
|
||||||
|
import VersionsModal from "./VersionsModal.vue";
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: "Modals",
|
name: "Modals",
|
||||||
|
@ -43,11 +51,13 @@ export default Vue.extend({
|
||||||
DuplicateWorkflowDialog,
|
DuplicateWorkflowDialog,
|
||||||
WorkflowOpen,
|
WorkflowOpen,
|
||||||
ModalRoot,
|
ModalRoot,
|
||||||
|
VersionsModal,
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
DUPLICATE_MODAL_KEY,
|
DUPLICATE_MODAL_KEY,
|
||||||
TAGS_MANAGER_MODAL_KEY,
|
TAGS_MANAGER_MODAL_KEY,
|
||||||
WORKLOW_OPEN_MODAL_KEY,
|
WORKLOW_OPEN_MODAL_KEY,
|
||||||
|
VERSIONS_MODAL_KEY,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="node-icon-wrapper" :style="iconStyleData" :class="{shrink: isSvgIcon && shrink, full: !shrink}">
|
<div class="node-icon-wrapper" :style="iconStyleData" :class="{shrink: isSvgIcon && shrink, full: !shrink}">
|
||||||
<div v-if="nodeIconData !== null" class="icon">
|
<div v-if="nodeIconData !== null" class="icon">
|
||||||
<img :src="nodeIconData.path" style="max-width: 100%; max-height: 100%;" v-if="nodeIconData.type === 'file'"/>
|
<img :src="nodeIconData.fileBuffer || nodeIconData.path" style="max-width: 100%; max-height: 100%;" v-if="nodeIconData.type === 'file'"/>
|
||||||
<font-awesome-icon :icon="nodeIconData.path" v-else-if="nodeIconData.type === 'fa'" />
|
<font-awesome-icon :icon="nodeIconData.icon || nodeIconData.path" v-else />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="node-icon-placeholder">
|
<div v-else class="node-icon-placeholder">
|
||||||
{{nodeType !== null ? nodeType.displayName.charAt(0) : '?' }}
|
{{nodeType !== null ? nodeType.displayName.charAt(0) : '?' }}
|
||||||
|
@ -54,6 +54,10 @@ export default Vue.extend({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.nodeType.iconData) {
|
||||||
|
return this.nodeType.iconData;
|
||||||
|
}
|
||||||
|
|
||||||
const restUrl = this.$store.getters.getRestUrl;
|
const restUrl = this.$store.getters.getRestUrl;
|
||||||
|
|
||||||
if (this.nodeType.icon) {
|
if (this.nodeType.icon) {
|
||||||
|
|
83
packages/editor-ui/src/components/VersionCard.vue
Normal file
83
packages/editor-ui/src/components/VersionCard.vue
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<a :href="version.documentationUrl" :class="$style.card">
|
||||||
|
<div :class="$style.header">
|
||||||
|
<div :class="$style.name">
|
||||||
|
Version {{version.name}}
|
||||||
|
</div>
|
||||||
|
<div :class="$style.released">
|
||||||
|
Released {{releaseDate}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div v-html="version.description" :class="$style.description">
|
||||||
|
</div>
|
||||||
|
<div :class="$style.nodes" v-if="version.nodes && version.nodes.length > 0">
|
||||||
|
<NodeIcon
|
||||||
|
v-for="node in version.nodes"
|
||||||
|
:key="node.name"
|
||||||
|
:nodeType="node"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { format } from 'timeago.js';
|
||||||
|
import NodeIcon from './NodeIcon.vue';
|
||||||
|
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: { NodeIcon },
|
||||||
|
name: 'VersionsModal',
|
||||||
|
props: ['version'],
|
||||||
|
computed: {
|
||||||
|
releaseDate() {
|
||||||
|
return format(this.version.createdAt);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style module lang="scss">
|
||||||
|
.card {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px #DBDFE7 solid;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: block;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #DBDFE7;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
flex-grow: 1;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 19px;
|
||||||
|
color: #7D7D87;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.released {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodes {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
89
packages/editor-ui/src/components/VersionsModal.vue
Normal file
89
packages/editor-ui/src/components/VersionsModal.vue
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
:name="modalName"
|
||||||
|
:drawer="true"
|
||||||
|
drawerDirection="ltr"
|
||||||
|
drawerWidth="480px"
|
||||||
|
>
|
||||||
|
<template slot="header">
|
||||||
|
<p :class="$style.title"> We’ve been busy ✨</p>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<section :class="$style['header-content']">
|
||||||
|
<p>You’re on {{ currentVersion.name }}, which is <strong>{{currentReleaseDate}}</strong> and {{ nextVersions.length }} version{{nextVersions.length > 1 ? 's' : ''}} behind the latest and greatest n8n</p>
|
||||||
|
<a><font-awesome-icon icon="info-circle"></font-awesome-icon>How to update your n8n version</a>
|
||||||
|
</section>
|
||||||
|
<section :class="$style.versions">
|
||||||
|
<VersionCard
|
||||||
|
v-for="version in nextVersions"
|
||||||
|
:key="version.name"
|
||||||
|
:version="version"
|
||||||
|
:class="$style['versions-card']"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import { format } from 'timeago.js';
|
||||||
|
|
||||||
|
import Modal from './Modal.vue';
|
||||||
|
import VersionCard from './VersionCard.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
name: 'VersionsModal',
|
||||||
|
components: {
|
||||||
|
Modal,
|
||||||
|
VersionCard,
|
||||||
|
},
|
||||||
|
props: ['modalName'],
|
||||||
|
computed: {
|
||||||
|
...mapGetters('versions', [
|
||||||
|
'nextVersions',
|
||||||
|
'currentVersion',
|
||||||
|
]),
|
||||||
|
currentReleaseDate() {
|
||||||
|
return format(this.currentVersion.createdAt).replace('ago', 'old');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style module lang="scss">
|
||||||
|
.header-content {
|
||||||
|
padding: 0px 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #7D7D87;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #555555;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versions {
|
||||||
|
background-color: #F8F9FB;
|
||||||
|
border-top: 1px #DBDFE7 solid;
|
||||||
|
height: 100%;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versions-card {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -14,6 +14,7 @@ export const MAX_TAG_NAME_LENGTH = 24;
|
||||||
export const DUPLICATE_MODAL_KEY = 'duplicate';
|
export const DUPLICATE_MODAL_KEY = 'duplicate';
|
||||||
export const TAGS_MANAGER_MODAL_KEY = 'tagsManager';
|
export const TAGS_MANAGER_MODAL_KEY = 'tagsManager';
|
||||||
export const WORKLOW_OPEN_MODAL_KEY = 'workflowOpen';
|
export const WORKLOW_OPEN_MODAL_KEY = 'workflowOpen';
|
||||||
|
export const VERSIONS_MODAL_KEY = 'versions';
|
||||||
|
|
||||||
// breakpoints
|
// breakpoints
|
||||||
export const BREAKPOINT_SM = 768;
|
export const BREAKPOINT_SM = 768;
|
||||||
|
@ -48,3 +49,6 @@ export const HIDDEN_NODES = ['n8n-nodes-base.start'];
|
||||||
export const WEBHOOK_NODE_NAME = 'n8n-nodes-base.webhook';
|
export const WEBHOOK_NODE_NAME = 'n8n-nodes-base.webhook';
|
||||||
export const HTTP_REQUEST_NODE_NAME = 'n8n-nodes-base.httpRequest';
|
export const HTTP_REQUEST_NODE_NAME = 'n8n-nodes-base.httpRequest';
|
||||||
export const REQUEST_NODE_FORM_URL = 'https://n8n-community.typeform.com/to/K1fBVTZ3';
|
export const REQUEST_NODE_FORM_URL = 'https://n8n-community.typeform.com/to/K1fBVTZ3';
|
||||||
|
|
||||||
|
// versions
|
||||||
|
export const VERSIONS_BASE_URL = `https://api-staging.n8n.io/versions/`;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { DUPLICATE_MODAL_KEY, TAGS_MANAGER_MODAL_KEY, WORKLOW_OPEN_MODAL_KEY } from '@/constants';
|
import { DUPLICATE_MODAL_KEY, TAGS_MANAGER_MODAL_KEY, VERSIONS_MODAL_KEY, WORKLOW_OPEN_MODAL_KEY } from '@/constants';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { ActionContext, Module } from 'vuex';
|
import { ActionContext, Module } from 'vuex';
|
||||||
import {
|
import {
|
||||||
|
@ -19,6 +19,9 @@ const module: Module<IUiState, IRootState> = {
|
||||||
[WORKLOW_OPEN_MODAL_KEY]: {
|
[WORKLOW_OPEN_MODAL_KEY]: {
|
||||||
open: false,
|
open: false,
|
||||||
},
|
},
|
||||||
|
[VERSIONS_MODAL_KEY]: {
|
||||||
|
open: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
modalStack: [],
|
modalStack: [],
|
||||||
sidebarMenuCollapsed: true,
|
sidebarMenuCollapsed: true,
|
||||||
|
@ -58,6 +61,9 @@ const module: Module<IUiState, IRootState> = {
|
||||||
openDuplicateModal: async (context: ActionContext<IUiState, IRootState>) => {
|
openDuplicateModal: async (context: ActionContext<IUiState, IRootState>) => {
|
||||||
context.commit('openModal', DUPLICATE_MODAL_KEY);
|
context.commit('openModal', DUPLICATE_MODAL_KEY);
|
||||||
},
|
},
|
||||||
|
openVersionsModal: async (context: ActionContext<IUiState, IRootState>) => {
|
||||||
|
context.commit('openModal', VERSIONS_MODAL_KEY);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
42
packages/editor-ui/src/modules/versions.ts
Normal file
42
packages/editor-ui/src/modules/versions.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import { getNextVersions } from '@/api/versions';
|
||||||
|
import { versions } from 'process';
|
||||||
|
import { ActionContext, Module } from 'vuex';
|
||||||
|
import {
|
||||||
|
IRootState,
|
||||||
|
IVersion,
|
||||||
|
IVersionsState,
|
||||||
|
} from '../Interface';
|
||||||
|
|
||||||
|
const module: Module<IVersionsState, IRootState> = {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
nextVersions: [],
|
||||||
|
currentVersion: undefined,
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
hasVersionUpdates(state: IVersionsState) {
|
||||||
|
return state.nextVersions.length > 0;
|
||||||
|
},
|
||||||
|
nextVersions(state: IVersionsState) {
|
||||||
|
return state.nextVersions;
|
||||||
|
},
|
||||||
|
currentVersion(state: IVersionsState) {
|
||||||
|
return state.currentVersion;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setVersions(state: IVersionsState, {versions, currentVersion}: {versions: IVersion[], currentVersion: string}) {
|
||||||
|
state.nextVersions = versions.filter((version) => version.name !== currentVersion);
|
||||||
|
state.currentVersion = versions.find((version) => version.name === currentVersion);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
async fetchVersions(context: ActionContext<IVersionsState, IRootState>) {
|
||||||
|
const currentVersion = context.rootState.versionCli;
|
||||||
|
const versions = await getNextVersions(currentVersion);
|
||||||
|
context.commit('setVersions', {versions, currentVersion});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default module;
|
|
@ -87,3 +87,6 @@ $--node-creator-description-color: #7d7d87;
|
||||||
// trigger icon
|
// trigger icon
|
||||||
$--trigger-icon-border-color: #dcdfe6;
|
$--trigger-icon-border-color: #dcdfe6;
|
||||||
$--trigger-icon-background-color: #fff;
|
$--trigger-icon-background-color: #fff;
|
||||||
|
|
||||||
|
// drawer
|
||||||
|
$--drawer-background-color: #fff;
|
||||||
|
|
|
@ -36,6 +36,7 @@ import {
|
||||||
import tags from './modules/tags';
|
import tags from './modules/tags';
|
||||||
import ui from './modules/ui';
|
import ui from './modules/ui';
|
||||||
import workflows from './modules/workflows';
|
import workflows from './modules/workflows';
|
||||||
|
import versions from './modules/versions';
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
@ -92,6 +93,7 @@ const modules = {
|
||||||
tags,
|
tags,
|
||||||
ui,
|
ui,
|
||||||
workflows,
|
workflows,
|
||||||
|
versions,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = new Vuex.Store({
|
export const store = new Vuex.Store({
|
||||||
|
|
|
@ -2234,6 +2234,10 @@ export default mixins(
|
||||||
this.$showError(error, 'Init Problem', 'There was a problem initializing the workflow:');
|
this.$showError(error, 'Init Problem', 'There was a problem initializing the workflow:');
|
||||||
}
|
}
|
||||||
this.stopLoading();
|
this.stopLoading();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$store.dispatch('versions/fetchVersions');
|
||||||
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$externalHooks().run('nodeView.mount');
|
this.$externalHooks().run('nodeView.mount');
|
||||||
|
|
Loading…
Reference in a new issue