From e6073ba2e7f7661329315f3fe9dd67cce32c13e6 Mon Sep 17 00:00:00 2001
From: DDurandDTI <45204737+DDurandDTI@users.noreply.github.com>
Date: Thu, 20 Dec 2018 14:09:49 -0500
Subject: [PATCH] Feature/modul 582 arbo multinode select (#612)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Checkboxes and recursive node select
* Refactoring and completion of logic
* Fixed recursivity between elements
* Moved tree sub-components, updated broken unit tests
* Unit tests for tree-icon
* Made interminated state for checkboxes and revised tree prop name
* Intégration du partially-checked
* Refactored multiple tree nodes code
* Added a few states for multiple-node selection
* Merged integration branch, adjusted autoselect multinode's behavior
* Fine-tuned code, started unit testing
* Updated unit tests
* Changes prior to yet another small refactor
* Finished correcting checkboxes behavior
* Prior to new tree being added to sandbox
* Prior to selectedParentNodes prop
* Button auto-select feature completed
* Added more tests and checkbox states
* Updated tests and added descriptions to trees
* Light refactor
* MODUL-582 Added new behaviors (parent-checkbox auto-select) and new tests
* MODUL-582 Removed the ability to show selection button when checkboxes are hidden
* MODUL-582 Added conditional icon class name rendering to prevent all snapshots to be updated
* MODUL-582 Updated behaviors and tests
* MODUL-582 Fixed multinode tree's behavior
* MODUL-582 Simplified indeterminated checkbox state
* MODUL-582 Removed consective blank lines from Checkbox.spec
* MODUL-582 Updated sandbox to improve terminology comprehension
* MODUL-582 Prior to checkbox display condition refactor
* MODUL-582 Prior to dev merge
* MODUL-582 Merged develop, updated tree unit tests, refactored, added comments
* MODUL-582 Slight var names improvement
* MODUL-582 Simplified tree-node code
* MODUL-582 TreeNode light refactor
* MODUL-582 Removed treeNode and TreeIcon module export
* MODUL-582 Fixed tree plugin
---
package-lock.json | 3 +-
.../__snapshots__/checkbox.spec.ts.snap | 24 +-
src/components/checkbox/checkbox.html | 14 +-
src/components/checkbox/checkbox.sandbox.html | 16 +-
src/components/checkbox/checkbox.scss | 78 +++++-
src/components/checkbox/checkbox.spec.ts | 34 +++
src/components/checkbox/checkbox.ts | 11 +
src/components/component-names.ts | 2 -
src/components/components-plugin.ts | 4 -
src/components/icon-file/icon-file.html | 7 +-
src/components/icon/icon.html | 11 +-
src/components/icon/icon.ts | 7 +
src/components/tree-icon/tree-icon.html | 2 -
src/components/tree-icon/tree-icon.scss | 5 -
src/components/tree-icon/tree-icon.spec.ts | 75 ------
src/components/tree-icon/tree-icon.ts | 45 ----
.../__snapshots__/tree-node.spec.ts.snap | 40 ---
src/components/tree-node/tree-node.html | 22 --
.../tree-node/tree-node.lang.en.json | 5 -
.../tree-node/tree-node.lang.fr.json | 5 -
src/components/tree-node/tree-node.ts | 114 --------
.../tree/__snapshots__/tree.spec.ts.snap | 30 ++-
src/components/tree/component-names.ts | 2 +
src/components/tree/tree-icon/tree-icon.html | 16 ++
src/components/tree/tree-icon/tree-icon.scss | 10 +
.../tree/tree-icon/tree-icon.spec.ts | 96 +++++++
src/components/tree/tree-icon/tree-icon.ts | 37 +++
.../__snapshots__/tree-node.spec.ts.snap | 93 +++++++
src/components/tree/tree-node/tree-node.html | 61 +++++
.../{ => tree}/tree-node/tree-node.scss | 37 ++-
.../{ => tree}/tree-node/tree-node.spec.ts | 195 +++++++++++++-
src/components/tree/tree-node/tree-node.ts | 251 ++++++++++++++++++
src/components/tree/tree.html | 29 +-
src/components/tree/tree.lang.en.json | 3 +
src/components/tree/tree.lang.fr.json | 3 +
src/components/tree/tree.sandbox.html | 144 +++++++++-
src/components/tree/tree.sandbox.ts | 84 +++++-
src/components/tree/tree.spec.ts | 169 ++++++++----
src/components/tree/tree.ts | 109 ++++++--
src/lang/fr.ts | 1 -
40 files changed, 1430 insertions(+), 464 deletions(-)
delete mode 100644 src/components/tree-icon/tree-icon.html
delete mode 100644 src/components/tree-icon/tree-icon.scss
delete mode 100644 src/components/tree-icon/tree-icon.spec.ts
delete mode 100644 src/components/tree-icon/tree-icon.ts
delete mode 100644 src/components/tree-node/__snapshots__/tree-node.spec.ts.snap
delete mode 100644 src/components/tree-node/tree-node.html
delete mode 100644 src/components/tree-node/tree-node.lang.en.json
delete mode 100644 src/components/tree-node/tree-node.lang.fr.json
delete mode 100644 src/components/tree-node/tree-node.ts
create mode 100644 src/components/tree/component-names.ts
create mode 100644 src/components/tree/tree-icon/tree-icon.html
create mode 100644 src/components/tree/tree-icon/tree-icon.scss
create mode 100644 src/components/tree/tree-icon/tree-icon.spec.ts
create mode 100644 src/components/tree/tree-icon/tree-icon.ts
create mode 100644 src/components/tree/tree-node/__snapshots__/tree-node.spec.ts.snap
create mode 100644 src/components/tree/tree-node/tree-node.html
rename src/components/{ => tree}/tree-node/tree-node.scss (72%)
rename src/components/{ => tree}/tree-node/tree-node.spec.ts (53%)
create mode 100644 src/components/tree/tree-node/tree-node.ts
diff --git a/package-lock.json b/package-lock.json
index 8fb2a0a4d..146ff580b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2761,8 +2761,7 @@
"es6-promise": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
- "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
- "dev": true
+ "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ=="
},
"es6-promisify": {
"version": "5.0.0",
diff --git a/src/components/checkbox/__snapshots__/checkbox.spec.ts.snap b/src/components/checkbox/__snapshots__/checkbox.spec.ts.snap
index 7551ecdc7..7c4dc387e 100644
--- a/src/components/checkbox/__snapshots__/checkbox.spec.ts.snap
+++ b/src/components/checkbox/__snapshots__/checkbox.spec.ts.snap
@@ -32,6 +32,28 @@ exports[`MCheckbox should render correctly when disabled 1`] = `
`;
+exports[`MCheckbox should render correctly when disabled and checked 1`] = `
+
+
+
+
+
+
+
+`;
+
+exports[`MCheckbox should render correctly when indeterminated (with correct classes) 1`] = `
+
+
+
+
+
+
+
+`;
+
exports[`MCheckbox should render correctly when position prop is right 1`] = `
@@ -46,7 +68,7 @@ exports[`MCheckbox should render correctly when position prop is right 1`] = `
exports[`MCheckbox should render correctly when readonly 1`] = `
-
diff --git a/src/components/tree/tree.sandbox.ts b/src/components/tree/tree.sandbox.ts
index 19c8bf0b3..88896da25 100644
--- a/src/components/tree/tree.sandbox.ts
+++ b/src/components/tree/tree.sandbox.ts
@@ -1,6 +1,5 @@
import Vue, { PluginObject } from 'vue';
import Component from 'vue-class-component';
-
import { TREE_NAME } from '../component-names';
import { TreeNode } from './tree';
import WithRender from './tree.sandbox.html';
@@ -18,6 +17,13 @@ export class MRootTreeSandbox extends Vue {
public currentFile: string[] = ['/folder 1/folder 2/index.html'];
public currentFile2: string[] = ['/1/2'];
public wrongCurrentFile: string[] = ['/3/4'];
+ public currentNodesBasic: string[] = [];
+ public currentNodesCheckboxes: string[] = ['/3/11'];
+ public disabledNodesCheckboxes: string[] = ['/3/11'];
+ public currentNodesCheckboxesParent: string[] = [];
+ public currentNodesCheckboxesButtonAutoselect: string[] = [];
+ public currentNodesCheckboxesNone: string[] = ['/1/11/444/1111'];
+ public disabledNodesCheckboxesNone: string[] = ['/3', '/1/11/444/2222'];
public emptyTree: TreeNode[] = [];
@@ -256,8 +262,82 @@ export class MRootTreeSandbox extends Vue {
}
];
+ public multiNodeTree: TreeNode[] = [
+ {
+ id: '1',
+ label: 'UL - Université Laval',
+ hasChildren: true,
+ children: [
+ {
+ id: '11',
+ label: 'FSG - Faculté de Sciences et Génie',
+ children: [
+ {
+ id: '111',
+ label: 'ACT - Actuariat'
+ },
+ {
+ id: '222',
+ label: 'BIO - Biologie'
+ },
+ {
+ id: '333',
+ label: 'CHM - Chimie'
+ },
+ {
+ id: '444',
+ label: 'GMCN - Génie Mécanique',
+ children: [
+ {
+ id: '1111',
+ label: 'PRS - Personne'
+ },
+ {
+ id: '2222',
+ label: 'SMT - Something'
+ }
+ ]
+ }
+ ]
+ },
+ {
+ id: '22',
+ label: 'LLI - Lettres et sciences humaines',
+ children: [
+ {
+ id: '111',
+ label: 'JPN - Japonais'
+ },
+ {
+ id: '222',
+ label: 'EN - Anglais'
+ }
+ ]
+ }
+ ]
+ },
+ {
+ id: '2',
+ label: 'CSF - Cégep Sainte-Foy'
+ },
+ {
+ id: '3',
+ label: 'UQAM - Université du Québec à Montréal',
+ children: [
+ {
+ id: '11',
+ label: 'CHM - Chimie'
+ },
+ {
+ id: '22',
+ label: 'GMCN - Génie Mécanique'
+ }
+ ]
+ }
+ ];
+
public onSelect(): void {
- console.error('modUL - New file selected');
+ console.error('modUL - New node selected');
}
}
diff --git a/src/components/tree/tree.spec.ts b/src/components/tree/tree.spec.ts
index 65a3bc632..59198e178 100644
--- a/src/components/tree/tree.spec.ts
+++ b/src/components/tree/tree.spec.ts
@@ -1,15 +1,18 @@
-import { RefSelector, shallow, Wrapper } from '@vue/test-utils';
-
+import { mount, RefSelector, shallow, Wrapper } from '@vue/test-utils';
import { renderComponent } from '../../../tests/helpers/render';
-import { MSelectionMode, MTree, TreeNode } from './tree';
+import uuid from '../../utils/uuid/uuid';
+import { MCheckboxes, MSelectionMode, MTree, TreeNode } from './tree';
+
+jest.mock('../../utils/uuid/uuid');
+(uuid.generate as jest.Mock).mockReturnValue('uuid');
-const TREE_NODE_REF: RefSelector = { ref: 'tree-node' };
-const EMPTY_TREE_REF: RefSelector = { ref: 'empty-tree-txt' };
const ERROR_TREE_REF: RefSelector = { ref: 'error-tree-txt' };
-const SELECTED_NODES: string[] = ['/medias/Videos'];
-const SELECTED_NODES_INVALID: string[] = ['/medias/Videos/video-dog.mov'];
+const SELECTED_NODE: string[] = ['/medias/Videos'];
+const SELECTED_NODES: string[] = ['/index.html', '/medias/Videos'];
const NEW_TREE_NODE_SELECTED: string[] = ['/index.html'];
+const NEW_TREE_NODES_SELECTED: string[] = ['/index.html', '/medias/Videos'];
+const SELECTED_NODE_CLASS: string = '.m--is-selected';
const EMPTY_TREE: TreeNode[] = [];
const TREE_WITH_DATA: TreeNode[] = [
@@ -28,7 +31,7 @@ const TREE_WITH_DATA: TreeNode[] = [
]
}
];
-const TREE_WITH_NIVALID_DATA: TreeNode[] = [
+const TREE_WITH_INVALID_DATA: TreeNode[] = [
{
label: 'index.html',
id: ''
@@ -45,17 +48,12 @@ const TREE_WITH_NIVALID_DATA: TreeNode[] = [
}
];
-let wrapper: Wrapper;
-
let tree: TreeNode[] = TREE_WITH_DATA;
let selectionMode: MSelectionMode = MSelectionMode.Single;
-let selectedNodes: string[] = SELECTED_NODES;
+let selectedNodes: string[] = SELECTED_NODE;
+let checkboxes: MCheckboxes;
-afterEach(() => {
- tree = [];
- selectionMode = MSelectionMode.Single;
- selectedNodes = SELECTED_NODES;
-});
+let wrapper: Wrapper;
const initializeShallowWrapper: any = () => {
wrapper = shallow(MTree, {
@@ -67,76 +65,133 @@ const initializeShallowWrapper: any = () => {
});
};
-describe(`MTree`, () => {
-
- describe(`Given an empty tree`, () => {
-
- beforeEach(() => {
- tree = EMPTY_TREE;
- initializeShallowWrapper();
- });
+const initializeMountWrapper: any = () => {
+ wrapper = mount(MTree, {
+ propsData: {
+ tree,
+ selectedNodes,
+ selectionMode,
+ checkboxes
+ }
+ });
+};
- it(`Should render correctly`, () => {
- expect(renderComponent(wrapper.vm)).resolves.toMatchSnapshot();
- });
+describe(`MTree`, () => {
- it(`Should be empty`, () => {
- expect(wrapper.vm.propTreeEmpty).toBeTruthy();
+ describe('Given a single node selection', () => {
+ afterEach(() => {
+ tree = [];
+ selectionMode = MSelectionMode.Single;
+ selectedNodes = SELECTED_NODE;
});
- });
- describe(`Given a tree with some data`, () => {
+ describe(`Given an empty tree`, () => {
- beforeEach(() => {
- tree = TREE_WITH_DATA;
- initializeShallowWrapper();
- });
+ beforeEach(() => {
+ tree = EMPTY_TREE;
+ initializeShallowWrapper();
+ });
- it(`Should render correctly`, () => {
- expect(renderComponent(wrapper.vm)).resolves.toMatchSnapshot();
- });
+ it(`Should render correctly`, () => {
+ expect(renderComponent(wrapper.vm)).resolves.toMatchSnapshot();
+ });
- it(`Should not be empty`, () => {
- expect(wrapper.vm.propTreeEmpty).toBeFalsy();
+ it(`Should be empty`, () => {
+ expect(wrapper.vm.propTreeEmpty).toBeTruthy();
+ });
});
- describe(`When a node is selected`, () => {
+ describe(`Given a tree with some data`, () => {
beforeEach(() => {
- wrapper.vm.onClick(NEW_TREE_NODE_SELECTED[0]);
+ tree = TREE_WITH_DATA;
+ initializeShallowWrapper();
});
- it(`Call onClick`, () => {
- wrapper.setMethods({ onClick: jest.fn() });
- wrapper.find(TREE_NODE_REF).trigger('click');
+ it(`Should render correctly`, () => {
+ expect(renderComponent(wrapper.vm)).resolves.toMatchSnapshot();
+ });
- expect(wrapper.vm.onClick).toHaveBeenCalled();
+ it(`Should not be empty`, () => {
+ expect(wrapper.vm.propTreeEmpty).toBeFalsy();
});
- it(`Emit select`, () => {
- expect(wrapper.emitted('select')).toBeTruthy();
+ describe(`When a node is selected`, () => {
+
+ beforeEach(() => {
+ wrapper.vm.onClick(NEW_TREE_NODE_SELECTED[0]);
+ });
+
+ it(`Emit select`, () => {
+ expect(wrapper.emitted('select')).toBeTruthy();
+ });
+
+ it(`A new node is selected`, () => {
+ expect(wrapper.vm.propSelectedNodes).toEqual(NEW_TREE_NODE_SELECTED);
+ });
+
});
- it(`A new node is selected`, () => {
- expect(wrapper.vm.propSelectedNodes).toEqual(NEW_TREE_NODE_SELECTED);
+ describe(`When there is an error in the tree`, () => {
+
+ beforeEach(() => {
+ tree = TREE_WITH_INVALID_DATA;
+ initializeShallowWrapper();
+ });
+
+ it(`Should generate an error`, () => {
+ expect(wrapper.vm.errorTree).toBeTruthy();
+ });
+
+ it(`Should show an error message`, () => {
+ expect(wrapper.find(ERROR_TREE_REF).exists()).toBeTruthy();
+ });
+
});
});
+ });
+
+ describe(`Given a tree with multiple selection`, () => {
+
+ afterEach(() => {
+ tree = [];
+ selectedNodes = [];
+ checkboxes = MCheckboxes.False;
+ });
- describe(`When there is an error in the tree`, () => {
+ describe(`Given a tree with no node selected`, () => {
beforeEach(() => {
- tree = TREE_WITH_NIVALID_DATA;
- initializeShallowWrapper();
+ tree = TREE_WITH_DATA;
+ selectedNodes = [];
+ selectionMode = MSelectionMode.Multiple;
+ initializeMountWrapper();
});
- it(`Should generate an error`, () => {
- expect(wrapper.vm.errorTree).toBeTruthy();
+ it(`Should allow multiple selection`, () => {
+ wrapper.vm.onClick(NEW_TREE_NODES_SELECTED[0]);
+ wrapper.vm.onClick(NEW_TREE_NODES_SELECTED[1]);
+ expect(wrapper.vm.propSelectedNodes).toEqual(NEW_TREE_NODES_SELECTED);
});
+ });
- it(`Should show an error message`, () => {
- expect(wrapper.find(ERROR_TREE_REF).exists()).toBeTruthy();
+ describe(`Given a tree with two nodes selected`, () => {
+
+ beforeEach(() => {
+ tree = TREE_WITH_DATA;
+ selectedNodes = [];
+ selectionMode = MSelectionMode.Multiple;
+ selectedNodes = SELECTED_NODES;
+ initializeMountWrapper();
});
+ it(`Should render correctly`, () => {
+ expect(renderComponent(wrapper.vm)).resolves.toMatchSnapshot();
+ });
+
+ it(`Should render with two selected nodes`, () => {
+ expect(wrapper.findAll(SELECTED_NODE_CLASS).length).toBe(2);
+ });
});
});
});
diff --git a/src/components/tree/tree.ts b/src/components/tree/tree.ts
index c843670a7..acb8c3cb2 100644
--- a/src/components/tree/tree.ts
+++ b/src/components/tree/tree.ts
@@ -1,13 +1,18 @@
import { PluginObject } from 'vue';
import Component from 'vue-class-component';
-import { Prop, Watch } from 'vue-property-decorator';
-
+import { Emit, Prop, Watch } from 'vue-property-decorator';
import { ModulVue } from '../../utils/vue/vue';
+import AccordionTransitionPlugin from '../accordion/accordion-transition';
+import CheckboxPlugin from '../checkbox/checkbox';
import { TREE_NAME } from '../component-names';
import I18nPlugin from '../i18n/i18n';
-import TreeNodePlugin from '../tree-node/tree-node';
+import IconFilePlugin from '../icon-file/icon-file';
+import IconPlugin from '../icon/icon';
+import MessagePlugin from '../message/message';
+import PlusPlugin from '../plus/plus';
+import { TREE_NODE_NAME } from './component-names';
+import { MTreeNode } from './tree-node/tree-node';
import WithRender from './tree.html?style=./tree.scss';
-
export interface TreeNode {
id: string;
label?: string;
@@ -18,13 +23,24 @@ export interface TreeNode {
}
export enum MSelectionMode {
- None = '0',
- Single = '1',
- Multiple = '2'
+ None = 'none',
+ Single = 'single',
+ Multiple = 'multiple'
}
+export enum MCheckboxes {
+ True = 'true', // Fully independant checkbox selection
+ False = 'false', // No Checkboxes
+ WithButtonAutoSelect = 'with-button-auto-select', // Fully independat, but a button can handle mass-selection
+ WithCheckboxAutoSelect = 'with-checkbox-auto-select', // Selection of parents is 100% related to children
+ WithParentAutoSelect = 'with-parent-auto-select' // Children can be selected by parent & children can unselect parent
+}
@WithRender
-@Component
+@Component({
+ components: {
+ [TREE_NODE_NAME]: MTreeNode
+ }
+})
export class MTree extends ModulVue {
@Prop()
public tree: TreeNode[];
@@ -38,36 +54,46 @@ export class MTree extends ModulVue {
})
public selectionMode: MSelectionMode;
+ @Prop({
+ default: MCheckboxes.False,
+ validator: value =>
+ value === MCheckboxes.False ||
+ value === MCheckboxes.True ||
+ value === MCheckboxes.WithButtonAutoSelect ||
+ value === MCheckboxes.WithCheckboxAutoSelect ||
+ value === MCheckboxes.WithParentAutoSelect
+ })
+ public checkboxes: MCheckboxes;
+
@Prop()
public selectedNodes: string[];
@Prop()
- public icons: boolean;
+ public useFilesIcons: boolean;
+
+ @Prop()
+ public disabledNodes: string[];
public propSelectedNodes: string[] = this.selectedNodes || [];
+
public errorTree: boolean = false;
private selectedNodesFound: string[] = [];
- public onClick(path: string): void {
- if (this.propSelectedNodes.indexOf(path) === -1) {
- if (this.selectionMode === MSelectionMode.Multiple) {
- this.propSelectedNodes.push(path);
- } else {
- this.propSelectedNodes = [path];
+ @Emit('select')
+ public onClick(path: string): string {
+ if (!this.pathIsDisabled(path)) {
+ if (this.propSelectedNodes.indexOf(path) === -1) {
+ if (this.selectionMode === MSelectionMode.Multiple) {
+ this.propSelectedNodes.push(path);
+ } else {
+ this.propSelectedNodes = [path];
+ }
+ } else if (this.selectionMode === MSelectionMode.Multiple) {
+ this.propSelectedNodes.splice(this.propSelectedNodes.indexOf(path), 1);
}
- } else if (this.selectionMode === MSelectionMode.Multiple) {
- this.propSelectedNodes.splice(this.propSelectedNodes.indexOf(path), 1);
}
- this.$emit('select', path);
- }
-
- public get propTreeEmpty(): boolean {
- return !this.tree.length;
- }
-
- public get selectable(): boolean {
- return this.selectionMode !== MSelectionMode.None;
+ return path;
}
protected created(): void {
@@ -87,6 +113,10 @@ export class MTree extends ModulVue {
});
}
+ private pathIsDisabled(path: string): boolean {
+ return this.propDisabledNodes.indexOf(path) !== -1;
+ }
+
private browseNode(node: TreeNode, path: string = ''): void {
if (node.id.trim() === '') {
this.errorTree = true;
@@ -101,13 +131,38 @@ export class MTree extends ModulVue {
});
}
}
+
+ public get propTreeEmpty(): boolean {
+ return !this.tree.length;
+ }
+
+ public get propDisabledNodes(): string[] {
+ return this.disabledNodes || [];
+ }
+
+ public get selectable(): boolean {
+ return this.selectionMode !== MSelectionMode.None;
+ }
+
+ public get isMultipleSelectWithCheckboxes(): boolean {
+ return this.selectionMode === MSelectionMode.Multiple && this.withCheckboxes;
+ }
+
+ public get withCheckboxes(): boolean {
+ return this.checkboxes !== MCheckboxes.False;
+ }
}
const TreePlugin: PluginObject = {
install(v, options): void {
v.prototype.$log.debug(TREE_NAME, 'plugin.install');
- v.use(TreeNodePlugin);
v.use(I18nPlugin);
+ v.use(CheckboxPlugin);
+ v.use(IconFilePlugin);
+ v.use(IconPlugin);
+ v.use(PlusPlugin);
+ v.use(MessagePlugin);
+ v.use(AccordionTransitionPlugin);
v.component(TREE_NAME, MTree);
}
};
diff --git a/src/lang/fr.ts b/src/lang/fr.ts
index 2538ebe18..0aef59b66 100644
--- a/src/lang/fr.ts
+++ b/src/lang/fr.ts
@@ -40,7 +40,6 @@ const FrenchPlugin: PluginObject = {
require('../components/rich-text-editor/rich-text-editor.lang.fr.json'),
require('../components/table/table.lang.fr.json'),
require('../components/toast/toast.lang.fr.json'),
- require('../components/tree-node/tree-node.lang.fr.json'),
require('../components/tree/tree.lang.fr.json'),
require('../components/scroll-top/scroll-top.lang.fr.json'),
require('../components/session-expired/session-expired.lang.fr.json'),