diff --git a/packages/design-system/src/components/N8nTree/Tree.stories.ts b/packages/design-system/src/components/N8nTree/Tree.stories.ts new file mode 100644 index 0000000000..e558d8f1c5 --- /dev/null +++ b/packages/design-system/src/components/N8nTree/Tree.stories.ts @@ -0,0 +1,57 @@ +/* tslint:disable:variable-name */ + +import N8nTree from './Tree.vue'; +import {StoryFn} from "@storybook/vue"; + +export default { + title: 'Atoms/Tree', + component: N8nTree, +}; + +export const Default: StoryFn = (args, {argTypes}) => ({ + props: Object.keys(argTypes), + components: { + N8nTree, + }, + template: ` + + + `, +}); + +Default.args = { + value: { + objectKey: { + nestedArrayKey: [ + 'in progress', + 33958053, + ], + stringKey: 'word', + aLongKey: 'Lorem ipsum dolor sit consectetur adipiscing elit. Sed dignissim aliquam ipsum mattis pellentesque. Phasellus ut ligula fermentum orci elementum dignissim. Vivamus interdum risus eget nibh placerat ultrices. Vivamus orci arcu, iaculis in nulla non, blandit molestie magna. Praesent tristique feugiat odio non vehicula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse fermentum purus diam, nec auctor elit consectetur nec. Vestibulum ultrices diam magna, in faucibus odio bibendum id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sollicitudin lacus neque.', + objectKey: { + myKey: 'what\'s for lunch', + yourKey: 'prolle rewe wdyt', + }, + id: 123, + }, + hello: "world", + test: { + label: "A cool folder", + children: [ + { + label: "A cool sub-folder 1", + children: [ + { label: "A cool sub-sub-folder 1" }, + { label: "A cool sub-sub-folder 2" }, + ], + }, + { label: "This one is not that cool" }, + ], + }, + }, +}; + diff --git a/packages/design-system/src/components/N8nTree/Tree.vue b/packages/design-system/src/components/N8nTree/Tree.vue new file mode 100644 index 0000000000..f6a67f16ae --- /dev/null +++ b/packages/design-system/src/components/N8nTree/Tree.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/packages/design-system/src/components/N8nTree/__tests__/Tree.spec.ts b/packages/design-system/src/components/N8nTree/__tests__/Tree.spec.ts new file mode 100644 index 0000000000..a5d8d60c56 --- /dev/null +++ b/packages/design-system/src/components/N8nTree/__tests__/Tree.spec.ts @@ -0,0 +1,74 @@ +import { render } from '@testing-library/vue'; +import N8nTree from '../Tree.vue'; + +describe('components', () => { + describe('N8nTree', () => { + it('should render simple tree', () => { + const wrapper = render(N8nTree, { + props: { + value: { + "hello": "world", + }, + }, + }); + expect(wrapper.html()).toMatchSnapshot(); + }); + + it('should render tree', () => { + const wrapper = render(N8nTree, { + props: { + value: { + "hello": { + "test": "world", + }, + "options": [ + "yes", + "no", + ], + }, + }, + }); + expect(wrapper.html()).toMatchSnapshot(); + }); + + it('should render tree with slots', () => { + const wrapper = render(N8nTree, { + props: { + value: { + "hello": { + "test": "world", + }, + "options": [ + "yes", + "no", + ], + }, + }, + slots: { + label: "label", + value: "value", + }, + }); + expect(wrapper.html()).toMatchSnapshot(); + }); + + + it('should render each tree with node class', () => { + const wrapper = render(N8nTree, { + props: { + value: { + "hello": { + "test": "world", + }, + "options": [ + "yes", + "no", + ], + }, + nodeClass: "nodeClass", + }, + }); + expect(wrapper.html()).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/design-system/src/components/N8nTree/__tests__/__snapshots__/Tree.spec.ts.snap b/packages/design-system/src/components/N8nTree/__tests__/__snapshots__/Tree.spec.ts.snap new file mode 100644 index 0000000000..4911913d31 --- /dev/null +++ b/packages/design-system/src/components/N8nTree/__tests__/__snapshots__/Tree.spec.ts.snap @@ -0,0 +1,87 @@ +// Vitest Snapshot v1 + +exports[`components > N8nTree > should render each tree with node class 1`] = ` +"
+
+
hello +
+
+
test:world
+
+
+
+
+
+
options +
+
+
0:yes
+
+
+
1:no
+
+
+
+
+
" +`; + +exports[`components > N8nTree > should render simple tree 1`] = ` +"
+
+
hello:world
+
+
" +`; + +exports[`components > N8nTree > should render tree 1`] = ` +"
+
+
hello +
+
+
test:world
+
+
+
+
+
+
options +
+
+
0:yes
+
+
+
1:no
+
+
+
+
+
" +`; + +exports[`components > N8nTree > should render tree with slots 1`] = ` +"
+
+
label +
+
+
label:value
+
+
+
+
+
+
label +
+
+
label:value
+
+
+
label:value
+
+
+
+
+
" +`; diff --git a/packages/design-system/src/components/N8nTree/index.ts b/packages/design-system/src/components/N8nTree/index.ts new file mode 100644 index 0000000000..eb6e49c351 --- /dev/null +++ b/packages/design-system/src/components/N8nTree/index.ts @@ -0,0 +1,3 @@ +import Tree from './Tree.vue'; + +export default Tree; diff --git a/packages/design-system/src/plugins/n8nComponents.ts b/packages/design-system/src/plugins/n8nComponents.ts index a68d8db403..547b371421 100644 --- a/packages/design-system/src/plugins/n8nComponents.ts +++ b/packages/design-system/src/plugins/n8nComponents.ts @@ -35,6 +35,7 @@ import N8nTabs from '../components/N8nTabs'; import N8nTag from '../components/N8nTag'; import N8nText from '../components/N8nText'; import N8nTooltip from '../components/N8nTooltip'; +import N8nTree from '../components/N8nTree'; import N8nUsersList from '../components/N8nUsersList'; import N8nUserSelect from '../components/N8nUserSelect'; @@ -76,6 +77,7 @@ export default { app.component('n8n-tag', N8nTag); app.component('n8n-text', N8nText); app.component('n8n-tooltip', N8nTooltip); + app.component('n8n-tree', N8nTree); app.component('n8n-users-list', N8nUsersList); app.component('n8n-user-select', N8nUserSelect); }, diff --git a/packages/design-system/src/styleguide/colors.stories.mdx b/packages/design-system/src/styleguide/colors.stories.mdx index f9015b59b3..74e4a0c0bd 100644 --- a/packages/design-system/src/styleguide/colors.stories.mdx +++ b/packages/design-system/src/styleguide/colors.stories.mdx @@ -31,7 +31,7 @@ import ColorCircles from './ColorCircles.vue'; {{ - template: ``, + template: ``, components: { ColorCircles, }, diff --git a/packages/design-system/theme/src/_tokens.scss b/packages/design-system/theme/src/_tokens.scss index aa8884bc35..5a8d984d0d 100644 --- a/packages/design-system/theme/src/_tokens.scss +++ b/packages/design-system/theme/src/_tokens.scss @@ -384,8 +384,8 @@ --color-json-default: #5045A1; --color-json-null: var(--color-danger); - --color-json-boolean: #1d8ce0; - --color-json-number: #1d8ce0; + --color-json-boolean: var(--color-success); + --color-json-number: var(--color-success); --color-json-string: #5045A1; --color-json-key: var(--color-text-dark); --color-json-brackets: var(--color-text-dark); diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index c478c015e8..1d88fe5cf4 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -221,6 +221,7 @@ export interface IRunDataUi { export interface ITableData { columns: string[]; data: GenericValue[][]; + hasJson: {[key: string]: boolean}; } export interface IVariableItemSelected { diff --git a/packages/editor-ui/src/components/Draggable.vue b/packages/editor-ui/src/components/Draggable.vue index 9773d6f486..7e1f771f84 100644 --- a/packages/editor-ui/src/components/Draggable.vue +++ b/packages/editor-ui/src/components/Draggable.vue @@ -1,7 +1,8 @@