Skip to content

Commit

Permalink
feat(editor): implement executions preview via the new executions tab…
Browse files Browse the repository at this point in the history
… in node view (#4311)

* ✨ Added main header tabs with current workflow execution count
* ⚡ feat(editor): header tab navigation (no-changelog) (#4244)
* ✨ Adding current workflow execution list to the Vuex store
* ✨ Updating current workflow executions after running a workflow from the node view
* ✨ Keeping the tab view content alive when switching tabs in main header
* ✨ Updating main header controls to work with current workflow regardless of active tab
* 🐛 Fixing a bug with previous WF executions still visible after creating a new WF
* ⚡ Updating saved status when new WF is created
* ✨ Implemented initial version of execution perview
* ✨ Keeping the WF view alive when switching to executions tab in new navigation
* ✨ Implemented executions landing page
* ✨ Simplifying node view navigation
* ✨ Updating executions view zoom and selection to work with the new layout
* ✨ Using N8nRadioButtons component for main header tabs
* 💄 Implementing executions page states. Minor refactoring.
* ⚡ Merge conflict fixes and pieces of code that were left behind
* ⚡ Fixing layout and scrolling changes introduced after sync with master branch
* ⚡ Removing keep-alive from node view which broke template opening and some more leftover code
* ✔️ Fixing linting errors
* ✔️ One more lint error
* ⚡ Implemented executions preview using iframes
* ⚡ Fixing zoom menu positioning in iframe and adding different loading types to workflow preview
* ⚡ Fixing navigation to and from WF templates and template loading
* ⚡ Updating and fixing navigation to and from node view
* 👌 Addressing previous PR comments
* 🐛 Fixing infinite loading when saving a new workflow
* 🐛 Handling opening already opened WF when not on Node view
* ✨ Implemented empty states for executions view
* ⚡ Adding execute button shake flag to the store so it doesn't mess up navigation by modifying route params
* 💄 Started adding new styles to execution sidebar
* 💄 Adding hover style for execution list
* ⚡ Added ExecutionsCard component and added executions helper mixin
* ✔️ Fixing leftover conflict
* ✔️ One more conflict
* ✨ Implemented retry execution menu and manual execution icon. Other minor updates
* ✨ Implemented executions filtering
* 💄 Updating running executions details in preview
* ⚡ Added info accordion to executions sidebar
* ✨ Implemented auto-refresh for executions sidebar
* 💄 Adding running execution landing page, minor fixes
* 💄 General refactoring
* ✔️ Adding leftover conflict changes
* ✔️ Updating `InfoTip` component test snapshots
* ✔️ Fixing linting error
* ✔️ Fixing lint errors in vuex store module
* 👌 Started addressing review feedback
* ⚡ Updating executions preview behaviour when filters are applied
* 🐛 Fixing a bug where nodes and connections disappear if something is saved from executions view before loading WF in the main NodeView
* 🐛 Fixing pasting in executions view and wrong workflow activator state
* ⚡ Improved workflow switching and navigation, updated error message when trying to paste into execution
* ⚡ Some more navigation updates
* 💄 Fixing tab centering, execution filter button layout, added auto-refresh checkbox
* 🐛 Fixing a bug when saving workflow using save button
* 💄 Addressing design feedback, added delete execution button
* ⚡ Moving main execution logic to the root executions view
* ⚡ Implemented execution delete function
* ⚡ Updating how switching tabs for new unsaved workflows work
* ⚡ Remembering active execution when switching tabs
* 💄 Addressing design feedback regarding info accordion
* 💄 Updating execution card styling
* ⚡ Resetting executions when creating new workflow
* Fixing lint error
* ⚡ Hiding executions preview is active execution is not in the results. Updated execution list spacing
* ⚡ Fixing navigation to and from templates and executions
* ⚡ Implemented execution lazy loading and added new background to execution preview
* 💄 Disabling import when on executions tab
* ⚡ Handling opening executions from different workflow
* ⚡ Updating active execution on route change
* ⚡ Updating execution tab detection
* ⚡ Simplifying and updating navigation. Adding new route for new workflows
* ⚡ Updating workflow saving logic to work with new routes
* 🐛 Fixing a bug when returning to executions from different workflow
* 💄 Updating executions info accordion and node details view modal in execution preview
* 💄 Updating workflow activated modal to point to new executions view
* ⚡ Implemented opening new executions view from execution modal
* ⚡ Handling jsplumb init errors, updating unknown executions style
* ⚡ Updating main sidebar after syncing branch
* ⚡ Opening new trigger menu from executions view
* 💄 Updating sidebar resize behaviour
* ✔️ Fixing lint errors
* ⚡ Loading executions when mounting executions view
* ⚡ Resetting execution data when creating a new workflow
* 💄 Minor wording updates
* ⚡ Not reloading node view when new workflows are saved
* Removing leftover console log
* 🐛 Fixed a bug with save dialog not appearing when leaving executions tab
* ⚡ Updating manual execution settings detection in info accordion
* 💄 Addressing UI issues found during bug bash
* Fixing workflow saving logic
* ⚡ Preventing navigation if clicked tab is already opened
* ⚡ Updating lazy loading behaviour
* ⚡ Updating delete executions flow
* ⚡ Added retry executions button to the execution preview
* ⚡ Adding empty execution state, updating trigger detection logic, removing listeners when node view is not active
* 💄 Cosmetic code improvements
* ⚡ Trying the performance fix for nodeBase
* ⚡ Removing the `NodeBase`fix
* 🐛 Fixing a bug when saving the current workflow
* 👌 Addressing code review feedback
  • Loading branch information
MiloradFilipovic authored Oct 26, 2022
1 parent 99157cf commit d833345
Show file tree
Hide file tree
Showing 46 changed files with 2,473 additions and 184 deletions.
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div :class="['action-dropdown-container', $style.actionDropdownContainer]">
<el-dropdown :placement="placement" :trigger="trigger" @command="onSelect">
<div :class="$style.activator">
<div :class="$style.activator" @click.prevent>
<n8n-icon :icon="activatorIcon"/>
</div>
<el-dropdown-menu slot="dropdown" :class="$style.userActionsMenu">
Expand All @@ -18,7 +18,7 @@
[item.customClass]: item.customClass !== undefined,
}">
<span v-if="item.icon" :class="$style.icon">
<n8n-icon :icon="item.icon"/>
<n8n-icon :icon="item.icon" :size="item.iconSize"/>
</span>
<span :class="$style.label">
{{ item.label }}
Expand Down Expand Up @@ -75,6 +75,12 @@ export default Vue.extend({
type: String,
default: 'ellipsis-v',
},
iconSize: {
type: String,
default: 'medium',
validator: (value: string): boolean =>
['small', 'medium', 'large'].includes(value),
},
trigger: {
type: String,
default: 'click',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
<template>
<div :class="['accordion', $style.container]" >
<div :class="{[$style.header]: true, [$style.expanded]: expanded}" @click="toggle">
<n8n-text color="text-base" size="small" align="left" bold>{{ title }}</n8n-text>

<n8n-icon
:icon="expanded? 'chevron-up' : 'chevron-down'"
bold
/>

<div :class="{[$style.header]: true, [$style.expanded]: expanded }" @click="toggle">
<n8n-icon v-if="headerIcon" :icon="headerIcon.icon" :color="headerIcon.color" size="small" class="mr-2xs"/>
<n8n-text :class="$style.headerText" color="text-base" size="small" align="left" bold>{{ title }}</n8n-text>
<n8n-icon :icon="expanded? 'chevron-up' : 'chevron-down'" bold />
</div>
<div v-if="expanded" :class="{[$style.description]: true, [$style.collapsed]: !expanded}" @click="onClick">
<!-- Info accordion can display list of items with icons or just a HTML description -->
<div v-if="items.length > 0" :class="$style.accordionItems">
<div v-for="item in items" :key="item.id" :class="$style.accordionItem">
<n8n-tooltip :disabled="!item.tooltip">
<div slot="content" v-html="item.tooltip" @click="onTooltipClick(item.id, $event)"></div>
<n8n-icon :icon="item.icon" :color="item.iconColor" size="small" class="mr-2xs"/>
</n8n-tooltip>
<n8n-text size="small" color="text-base">{{ item.label }}</n8n-text>
</div>
</div>
<n8n-text color="text-base" size="small" align="left">
<span v-html="description"></span>
</n8n-text>
</div>
</div>
</template>

<script>
<script lang="ts">
import N8nText from '../N8nText';
import N8nIcon from '../N8nIcon';
import Vue, { PropType } from 'vue';
import Vue from 'vue';
interface IAccordionItem {
id: string;
label: string;
icon: string;
}
export default Vue.extend({
name: 'n8n-info-accordion',
Expand All @@ -36,11 +47,26 @@ export default Vue.extend({
description: {
type: String,
},
items: {
type: Array as PropType<IAccordionItem[]>,
default() {
return [];
},
},
initiallyExpanded: {
type: Boolean,
default: false,
},
headerIcon: {
type: Object as () => { icon: string, color: string },
required: false,
},
},
mounted() {
this.$on('expand', () => {
this.expanded = true;
});
this.expanded = this.initiallyExpanded;
},
data() {
return {
Expand All @@ -54,6 +80,9 @@ export default Vue.extend({
onClick(e) {
this.$emit('click', e);
},
onTooltipClick(item: string, event: MouseEvent) {
this.$emit('tooltipClick', item, event);
},
},
});
</script>
Expand All @@ -67,8 +96,9 @@ export default Vue.extend({
cursor: pointer;
display: flex;
padding: var(--spacing-s);
align-items: center;
*:first-child {
.headerText {
flex-grow: 1;
}
}
Expand All @@ -77,6 +107,18 @@ export default Vue.extend({
padding: var(--spacing-s) var(--spacing-s) var(--spacing-2xs) var(--spacing-s);
}
.accordionItems {
display: flex;
flex-direction: column !important;
align-items: flex-start !important;
width: 100%;
}
.accordionItem {
display: block !important;
text-align: left;
}
.description {
display: flex;
padding: 0 var(--spacing-s) var(--spacing-s) var(--spacing-s);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Vitest Snapshot v1

exports[`N8nInfoTip > should render correctly as note 1`] = `"<div class=\\"n8n-info-tip _info_3egb8_33 _note_3egb8_16 _base_3egb8_1 _bold_3egb8_12\\"><span class=\\"_iconText_3egb8_28\\"><span class=\\"n8n-icon n8n-text _compact_odhsl_34 _size-medium_odhsl_19 _regular_odhsl_5\\"></span><span>Need help doing something?<a href=\\"/docs\\" target=\\"_blank\\">Open docs</a></span></span></div>"`;
exports[`N8nInfoTip > should render correctly as note 1`] = `"<div class=\\"n8n-info-tip _info_3egb8_33 _note_3egb8_16 _base_3egb8_1 _bold_3egb8_12\\"><span class=\\"_iconText_3egb8_28\\"><span class=\\"n8n-icon n8n-text _compact_e4k11_34 _size-medium_e4k11_19 _regular_e4k11_5\\"></span><span>Need help doing something?<a href=\\"/docs\\" target=\\"_blank\\">Open docs</a></span></span></div>"`;
exports[`N8nInfoTip > should render correctly as tooltip 1`] = `
"<div class=\\"n8n-info-tip _info_3egb8_33 _tooltip_3egb8_23 _base_3egb8_1 _bold_3egb8_12\\">
<n8n-tooltip-stub justifybuttons=\\"flex-end\\" buttons=\\"\\" placement=\\"top\\"><span class=\\"_iconText_3egb8_28\\"><span class=\\"n8n-icon n8n-text _compact_odhsl_34 _size-medium_odhsl_19 _regular_odhsl_5\\"></span></span><span>Need help doing something?<a href=\\"/docs\\" target=\\"_blank\\">Open docs</a></span></n8n-tooltip-stub>
<n8n-tooltip-stub justifybuttons=\\"flex-end\\" buttons=\\"\\" placement=\\"top\\"><span class=\\"_iconText_3egb8_28\\"><span class=\\"n8n-icon n8n-text _compact_e4k11_34 _size-medium_e4k11_19 _regular_e4k11_5\\"></span></span><span>Need help doing something?<a href=\\"/docs\\" target=\\"_blank\\">Open docs</a></span></n8n-tooltip-stub>
</div>"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export default Vue.extend({
color: var(--color-text-base);
transition: background-color 0.2s ease;
cursor: pointer;
user-select: none;
}
.disabled {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
v-bind="option"
:active="value === option.value"
:size="size"
:disabled="disabled"
@click="(e) => onClick(option.value, e)"
:disabled="disabled || option.disabled"
@click="(e) => onClick(option, e)"
/>
</div>
</template>
Expand Down Expand Up @@ -36,11 +36,11 @@ export default Vue.extend({
RadioButton,
},
methods: {
onClick(value: unknown) {
if (this.disabled) {
onClick(option: {label: string, value: string, disabled?: boolean}) {
if (this.disabled || option.disabled) {
return;
}
this.$emit('input', value);
this.$emit('input', option.value);
},
},
});
Expand Down
6 changes: 5 additions & 1 deletion packages/design-system/src/components/N8nText/Text.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default Vue.extend({
},
color: {
type: String,
validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight', 'danger', 'success'].includes(value),
validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight', 'danger', 'success', 'warning'].includes(value),
},
align: {
type: String,
Expand Down Expand Up @@ -126,6 +126,10 @@ export default Vue.extend({
color: var(--color-success);
}
.warning {
color: var(--color-warning);
}
.align-left {
text-align: left;
}
Expand Down
12 changes: 7 additions & 5 deletions packages/editor-ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
[$style.sidebarCollapsed]: sidebarMenuCollapsed
}"
>
<div id="header" :class="$style['header']">
<div id="header" :class="$style.header">
<router-view name="header"></router-view>
</div>
<div id="sidebar" :class="$style['sidebar']">
<div id="sidebar" :class="$style.sidebar">
<router-view name="sidebar"></router-view>
</div>
<div id="content" :class="$style['content']">
<router-view />
<div id="content" :class="$style.content">
<keep-alive include="NodeView" :max="1">
<router-view />
</keep-alive>
</div>
<Modals />
<Telemetry />
Expand All @@ -35,7 +37,7 @@ import { showMessage } from './components/mixins/showMessage';
import { IUser } from './Interface';
import { mapGetters } from 'vuex';
import { userHelpers } from './components/mixins/userHelpers';
import { addHeaders, loadLanguage } from './plugins/i18n';
import { loadLanguage } from './plugins/i18n';
import { restApi } from '@/components/mixins/restApi';
import { globalLinkActions } from '@/components/mixins/globalLinkActions';
Expand Down
16 changes: 15 additions & 1 deletion packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,9 @@ export interface IUiState {
isPageLoading: boolean;
currentView: string;
fakeDoorFeatures: IFakeDoor[];
nodeViewInitialized: boolean;
addFirstStepOnLoad: boolean;
executionSidebarAutoRefresh: boolean;
}

export type ILogLevel = 'info' | 'debug' | 'warn' | 'error' | 'verbose';
Expand Down Expand Up @@ -1088,7 +1091,12 @@ export interface IUsersState {
users: {[userId: string]: IUser};
}

export interface IWorkflowsMap {
export interface IWorkflowsState {
currentWorkflowExecutions: IExecutionsSummary[];
activeWorkflowExecution: IExecutionsSummary | null;
finishedExecutionsCount: number;
}
export interface IWorkflowsMap {
[name: string]: IWorkflowDb;
}

Expand Down Expand Up @@ -1145,6 +1153,12 @@ export interface ITab {
tooltip?: string;
}

export interface ITabBarItem {
value: string;
label: string;
disabled?: boolean;
}

export interface IResourceLocatorReqParams {
nodeTypeAndVersion: INodeTypeNameVersion;
path: string;
Expand Down
8 changes: 8 additions & 0 deletions packages/editor-ui/src/api/workflows.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IRestApiContext } from '@/Interface';
import { IDataObject } from 'n8n-workflow';
import { makeRestApiRequest } from './helpers';

export async function getNewWorkflow(context: IRestApiContext, name?: string) {
Expand All @@ -19,3 +20,10 @@ export async function getActiveWorkflows(context: IRestApiContext) {
return await makeRestApiRequest(context, 'GET', `/active`);
}

export async function getCurrentExecutions(context: IRestApiContext, filter: IDataObject) {
return await makeRestApiRequest(context, 'GET', '/executions-current', { filter });
}

export async function getFinishedExecutions(context: IRestApiContext, filter: IDataObject) {
return await makeRestApiRequest(context, 'GET', '/executions', { filter });
}
Loading

0 comments on commit d833345

Please sign in to comment.