refactor(editor): Migrate header WorkflowDetails to composition api (no-changelog) (#9186)

This commit is contained in:
Alex Grozav
2024-04-29 07:53:42 +03:00
committed by GitHub
parent 442aaba116
commit 1c261f85a3
11 changed files with 756 additions and 635 deletions

View File

@@ -19,3 +19,28 @@ Range.prototype.getClientRects = vi.fn(() => ({
length: 0,
[Symbol.iterator]: vi.fn(),
}));
export class IntersectionObserver {
root = null;
rootMargin = '';
thresholds = [];
disconnect() {
return null;
}
observe() {
return null;
}
takeRecords() {
return [];
}
unobserve() {
return null;
}
}
window.IntersectionObserver = IntersectionObserver;
global.IntersectionObserver = IntersectionObserver;

View File

@@ -2,7 +2,7 @@
<div>
<div :class="{ 'main-header': true, expanded: !uiStore.sidebarMenuCollapsed }">
<div v-show="!hideMenuBar" class="top-menu">
<WorkflowDetails :read-only="readOnly" />
<WorkflowDetails v-if="workflow?.name" :workflow="workflow" :read-only="readOnly" />
<TabBar
v-if="onWorkflowPage"
:items="tabBarItems"
@@ -27,7 +27,7 @@ import {
STICKY_NODE_TYPE,
VIEWS,
} from '@/constants';
import type { INodeUi, ITabBarItem } from '@/Interface';
import type { INodeUi, ITabBarItem, IWorkflowDb } from '@/Interface';
import { useNDVStore } from '@/stores/ndv.store';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useUIStore } from '@/stores/ui.store';
@@ -75,6 +75,9 @@ export default defineComponent({
hideMenuBar(): boolean {
return Boolean(this.activeNode && this.activeNode.type !== STICKY_NODE_TYPE);
},
workflow(): IWorkflowDb {
return this.workflowsStore.workflow;
},
workflowName(): string {
return this.workflowsStore.workflowName;
},

View File

@@ -0,0 +1,115 @@
import WorkflowDetails from '@/components/MainHeader/WorkflowDetails.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { STORES } from '@/constants';
import { createTestingPinia } from '@pinia/testing';
import { fireEvent } from '@testing-library/vue';
vi.mock('vue-router', async () => {
const actual = await import('vue-router');
return {
...actual,
useRoute: () => ({
value: {
params: {
id: '1',
},
},
}),
};
});
const initialState = {
[STORES.SETTINGS]: {
settings: {
enterprise: {
sharing: true,
},
},
areTagsEnabled: true,
},
[STORES.TAGS]: {
tags: {
1: {
id: '1',
name: 'tag1',
},
2: {
id: '2',
name: 'tag2',
},
},
},
};
const renderComponent = createComponentRenderer(WorkflowDetails, {
pinia: createTestingPinia({ initialState }),
});
describe('WorkflowDetails', () => {
it('renders workflow name and tags', async () => {
const workflow = {
id: '1',
name: 'Test Workflow',
tags: ['1', '2'],
};
const { getByTestId, getByText } = renderComponent({
props: {
workflow,
readOnly: false,
},
});
const workflowName = getByTestId('workflow-name-input');
const workflowNameInput = workflowName.querySelector('input');
expect(workflowNameInput).toHaveValue('Test Workflow');
expect(getByText('tag1')).toBeInTheDocument();
expect(getByText('tag2')).toBeInTheDocument();
});
it('calls save function on save button click', async () => {
const onSaveButtonClick = vi.fn();
const { getByTestId } = renderComponent({
props: {
workflow: {
id: '1',
name: 'Test Workflow',
tags: [],
},
readOnly: false,
},
global: {
mocks: {
onSaveButtonClick,
},
},
});
await fireEvent.click(getByTestId('workflow-save-button'));
expect(onSaveButtonClick).toHaveBeenCalled();
});
it('opens share modal on share button click', async () => {
const onShareButtonClick = vi.fn();
const { getByTestId } = renderComponent({
props: {
workflow: {
id: '1',
name: 'Test Workflow',
tags: [],
},
readOnly: false,
},
global: {
mocks: {
onShareButtonClick,
},
},
});
await fireEvent.click(getByTestId('workflow-share-button'));
expect(onShareButtonClick).toHaveBeenCalled();
});
});

View File

@@ -318,7 +318,7 @@ export default defineComponent({
}
.el-tag {
padding: 1px var(--spacing-4xs);
padding: var(--spacing-5xs) var(--spacing-4xs);
color: var(--color-text-dark);
background-color: var(--color-background-base);
border-radius: var(--border-radius-base);

View File

@@ -1,10 +1,9 @@
import type { XYPosition } from '@/Interface';
import type { ActionDropdownItem, XYPosition } from '@/Interface';
import { NOT_DUPLICATABE_NODE_TYPES, STICKY_NODE_TYPE } from '@/constants';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import type { IActionDropdownItem } from 'n8n-design-system/src/components/N8nActionDropdown/ActionDropdown.vue';
import type { INode, INodeTypeDescription } from 'n8n-workflow';
import { computed, ref, watch } from 'vue';
import { getMousePosition } from '../utils/nodeViewUtils';
@@ -34,7 +33,7 @@ export type ContextMenuAction =
const position = ref<XYPosition>([0, 0]);
const isOpen = ref(false);
const target = ref<ContextMenuTarget>({ source: 'canvas' });
const actions = ref<IActionDropdownItem[]>([]);
const actions = ref<ActionDropdownItem[]>([]);
const actionCallback = ref<ContextMenuActionCallback>(() => {});
export const useContextMenu = (onAction: ContextMenuActionCallback = () => {}) => {
@@ -147,7 +146,7 @@ export const useContextMenu = (onAction: ContextMenuActionCallback = () => {}) =
...selectionActions,
];
} else {
const menuActions: IActionDropdownItem[] = [
const menuActions: ActionDropdownItem[] = [
!onlyStickies && {
id: 'toggle_activation',
label: nodes.every((node) => node.disabled)
@@ -183,7 +182,7 @@ export const useContextMenu = (onAction: ContextMenuActionCallback = () => {}) =
shortcut: { keys: ['Del'] },
disabled: isReadOnly.value,
},
].filter(Boolean) as IActionDropdownItem[];
].filter(Boolean) as ActionDropdownItem[];
if (nodes.length === 1) {
const singleNodeActions = onlyStickies

View File

@@ -354,7 +354,7 @@
font-size: 12px;
font-weight: 400;
display: flex;
align-items: flex-end;
align-items: center;
&.is-closable {
overflow-y: hidden;
@@ -363,7 +363,7 @@
.el-tag__close {
max-height: 15px;
max-width: 15px;
margin-right: 6px;
margin-left: var(--spacing-4xs);
&:hover {
background-color: $tag-close-background-hover-color !important;