Fixed #3802 - Improve folder structure for nuxt configurations

This commit is contained in:
mertsincan 2023-03-26 06:22:57 +01:00
parent 851950270b
commit f5fe822afb
563 changed files with 1703 additions and 1095 deletions

View file

@ -0,0 +1,164 @@
/**
*
* OrganizationChart visualizes hierarchical organization data.
*
* [Live Demo](https://primevue.org/organizationchart)
*
* @module organizationchart
*
*/
import { VNode } from 'vue';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
/**
* Defines valid properties in OrganizationChartNode.
*/
export interface OrganizationChartNode {
/**
* Unique identifier of the node. (required)
*/
key: any;
/**
* Type of the node to match a template.
*/
type?: string;
/**
* Style class of the node content.
*/
styleClass?: string;
/**
* Data represented by the node.
*/
data?: any;
/**
* Whether node is selectable when selection is enabled.
* @defaultValue true
*/
selectable?: boolean;
/**
* Whether node is collapsible when node expansion is enabled.
* @defaultValue true
*/
collapsible?: boolean;
/**
* Children nodes array.
*/
children?: OrganizationChartNode[];
/**
* Optional keys
*/
[key: string]: any;
}
export interface OrganizationChartSelectionKeys {
/**
* Optional keys
*/
[key: string]: any;
}
export interface OrganizationChartCollapsedKeys {
/**
* Optional keys
*/
[key: string]: any;
}
/**
* Defines valid properties in OrganizationChart component.
*/
export interface OrganizationChartProps {
/**
* Value of the component.
*/
value?: OrganizationChartNode;
/**
* A map instance of key-value pairs to represented the selected nodes.
*/
selectionKeys?: OrganizationChartSelectionKeys;
/**
* Type of the selection.
*/
selectionMode?: 'single' | 'multiple' | undefined;
/**
* A map instance of key-value pairs to represented the collapsed nodes.
*/
collapsedKeys?: OrganizationChartCollapsedKeys;
/**
* Whether the nodes can be expanded or toggled.
* @defaultValue false
*/
collapsible?: boolean;
}
/**
* Defines valid slots in OrganizationChart component.
*/
export interface OrganizationChartSlots {
/**
* Custom content template.
*/
default(node: any): VNode[];
/**
* Dynamic content template.
* @todo
*/
[key: string]: (node: any) => VNode[];
}
/**
* Defines valid emits in OrganizationChart component.
*/
export interface OrganizationChartEmits {
/**
* Emitted when the value changes.
* @param {*} value - New value.
*/
'update:selectionKeys'(value: any): void;
/**
* Emitted when the value changes.
* @param {boolean} value - New value.
*/
'update:collapsedKeys'(value: boolean): void;
/**
* Callback to invoke when a suggestion is selected.
* @param {OrganizationChartNode} node - Node instance.
*/
'node-select'(node: OrganizationChartNode): void;
/**
* Callback to invoke when a node is unselected.
* @param {OrganizationChartNode} node - Node instance.
*/
'node-unselect'(node: OrganizationChartNode): void;
/**
* Callback to invoke when a node is expanded.
* @param {OrganizationChartNode} node - Node instance.
*/
'node-expand'(node: OrganizationChartNode): void;
/**
* Callback to invoke when a node is collapsed.
* @param {OrganizationChartNode} node - Node instance.
*/
'node-collapsed'(node: OrganizationChartNode): void;
}
/**
* **PrimeVue - OrganizationChart**
*
* _OrganizationChart visualizes hierarchical organization data._
*
* [Live Demo](https://www.primevue.org/organizationchart/)
* --- ---
* ![PrimeVue](https://primefaces.org/cdn/primevue/images/logo-100.png)
*
* @group Component
*/
declare class OrganizationChart extends ClassComponent<OrganizationChartProps, OrganizationChartSlots, OrganizationChartEmits> {}
declare module '@vue/runtime-core' {
interface GlobalComponents {
OrganizationChart: GlobalComponentConstructor<OrganizationChart>;
}
}
export default OrganizationChart;

View file

@ -0,0 +1,167 @@
import { mount } from '@vue/test-utils';
import OrganizationChart from './OrganizationChart.vue';
describe('OrganizationChart.vue', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(OrganizationChart, {
props: {
value: {
key: '0',
type: 'person',
styleClass: 'p-person',
data: { label: 'CEO', name: 'Walter White', avatar: 'walter.jpg' },
children: [
{
key: '0_0',
type: 'person',
styleClass: 'p-person',
data: { label: 'CFO', name: 'Saul Goodman', avatar: 'saul.jpg' },
children: [
{
key: '0_0_0',
data: { label: 'Tax' },
selectable: false,
styleClass: 'department-cfo'
},
{
key: '0_0_1',
data: { label: 'Legal' },
selectable: false,
styleClass: 'department-cfo'
}
]
},
{
key: '0_1',
type: 'person',
styleClass: 'p-person',
data: { label: 'COO', name: 'Mike E.', avatar: 'mike.jpg' },
children: [
{
key: '0_1_0',
data: { label: 'Operations' },
selectable: false,
styleClass: 'department-coo'
}
]
},
{
key: '0_2',
type: 'person',
styleClass: 'p-person',
data: { label: 'CTO', name: 'Jesse Pinkman', avatar: 'jesse.jpg' },
children: [
{
key: '0_2_0',
data: { label: 'Development' },
selectable: false,
styleClass: 'department-cto',
children: [
{
key: '0_2_0_0',
data: { label: 'Analysis' },
selectable: false,
styleClass: 'department-cto'
},
{
key: '0_2_0_1',
data: { label: 'Front End' },
selectable: false,
styleClass: 'department-cto'
},
{
key: '0_2_0_2',
data: { label: 'Back End' },
selectable: false,
styleClass: 'department-cto'
}
]
},
{
key: '0_2_1',
data: { label: 'QA' },
selectable: false,
styleClass: 'department-cto'
},
{
key: '0_2_2',
data: { label: 'R&D' },
selectable: false,
styleClass: 'department-cto'
}
]
}
]
},
collapsible: true,
selectionMode: 'single',
selectionKeys: {}
},
slots: {
slots: {
default: `
<template #default="slotProps">
<span>{{slotProps.node.data.label}}</span>
</template>
`,
person: `
<template #person="slotProps">
<div class="node-header ui-corner-top">{{slotProps.node.data.label}}</div>
<div class="node-content">
<img :src="'images/organization/' + slotProps.node.data.avatar" width="32">
<div>{{slotProps.node.data.name}}</div>
</div>
</template>
`
}
}
});
});
it('should exist', () => {
expect(wrapper.find('.p-organizationchart.p-component').exists()).toBe(true);
expect(wrapper.find('table.p-organizationchart-table').exists()).toBe(true);
expect(wrapper.findAll('.p-node-toggler-icon').length).toBe(5);
expect(wrapper.find('.p-node-toggler-icon').classes()).toContain('pi-chevron-down');
});
it('should collapsed and expand', async () => {
await wrapper.vm.onNodeToggle(wrapper.vm.value);
expect(wrapper.find('.p-node-toggler-icon').classes()).toContain('pi-chevron-up');
expect(wrapper.emitted()['node-collapse'][0]).toEqual([wrapper.vm.value]);
expect(wrapper.emitted()['update:collapsedKeys'][0]).toEqual([{ 0: true }]);
expect(wrapper.vm.d_collapsedKeys).toEqual({ 0: true });
await wrapper.vm.onNodeToggle(wrapper.vm.value);
expect(wrapper.find('.p-node-toggler-icon').classes()).toContain('pi-chevron-down');
expect(wrapper.emitted()['node-expand'][0]).toEqual([wrapper.vm.value]);
expect(wrapper.emitted()['update:collapsedKeys'][0]).toEqual([{}]);
expect(wrapper.vm.d_collapsedKeys).toEqual({});
});
it('should item select and unselect', async () => {
const contents = wrapper.findAll('.p-organizationchart-node-content');
await wrapper.vm.onNodeClick(wrapper.vm.value);
expect(wrapper.emitted()['node-select'][0]).toEqual([wrapper.vm.value]);
expect(wrapper.emitted()['update:selectionKeys'][0]).toEqual([{ 0: true }]);
await wrapper.setProps({ selectionKeys: { 0: true } });
expect(contents[0].classes()).toContain('p-highlight');
await wrapper.vm.onNodeClick(wrapper.vm.value);
expect(wrapper.emitted()['node-unselect'][0]).toEqual([wrapper.vm.value]);
expect(wrapper.emitted()['update:selectionKeys'][1]).toEqual([{}]);
await wrapper.setProps({ selectionKeys: {} });
expect(contents[0].classes()).not.toContain('p-highlight');
});
});

View file

@ -0,0 +1,141 @@
<template>
<div class="p-organizationchart p-component">
<OrganizationChartNode :node="value" :templates="$slots" @node-toggle="onNodeToggle" :collapsedKeys="d_collapsedKeys" :collapsible="collapsible" @node-click="onNodeClick" :selectionMode="selectionMode" :selectionKeys="selectionKeys" />
</div>
</template>
<script>
import OrganizationChartNode from './OrganizationChartNode.vue';
export default {
name: 'OrganizationChart',
emits: ['node-unselect', 'node-select', 'update:selectionKeys', 'node-expand', 'node-collapse', 'update:collapsedKeys'],
props: {
value: {
type: null,
default: null
},
selectionKeys: {
type: null,
default: null
},
selectionMode: {
type: String,
default: null
},
collapsible: {
type: Boolean,
default: false
},
collapsedKeys: {
type: null,
default: null
}
},
data() {
return {
d_collapsedKeys: this.collapsedKeys || {}
};
},
watch: {
collapsedKeys(newValue) {
this.d_collapsedKeys = newValue;
}
},
methods: {
onNodeClick(node) {
const key = node.key;
if (this.selectionMode) {
let _selectionKeys = this.selectionKeys ? { ...this.selectionKeys } : {};
if (_selectionKeys[key]) {
delete _selectionKeys[key];
this.$emit('node-unselect', node);
} else {
if (this.selectionMode === 'single') {
_selectionKeys = {};
}
_selectionKeys[key] = true;
this.$emit('node-select', node);
}
this.$emit('update:selectionKeys', _selectionKeys);
}
},
onNodeToggle(node) {
const key = node.key;
if (this.d_collapsedKeys[key]) {
delete this.d_collapsedKeys[key];
this.$emit('node-expand', node);
} else {
this.d_collapsedKeys[key] = true;
this.$emit('node-collapse', node);
}
this.d_collapsedKeys = { ...this.d_collapsedKeys };
this.$emit('update:collapsedKeys', this.d_collapsedKeys);
}
},
components: {
OrganizationChartNode: OrganizationChartNode
}
};
</script>
<style>
.p-organizationchart-table {
border-spacing: 0;
border-collapse: separate;
margin: 0 auto;
}
.p-organizationchart-table > tbody > tr > td {
text-align: center;
vertical-align: top;
padding: 0 0.75rem;
}
.p-organizationchart-node-content {
display: inline-block;
position: relative;
}
.p-organizationchart-node-content .p-node-toggler {
position: absolute;
bottom: -0.75rem;
margin-left: -0.75rem;
z-index: 2;
left: 50%;
user-select: none;
cursor: pointer;
width: 1.5rem;
height: 1.5rem;
text-decoration: none;
}
.p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon {
position: relative;
top: 0.25rem;
}
.p-organizationchart-line-down {
margin: 0 auto;
height: 20px;
width: 1px;
}
.p-organizationchart-line-right {
border-radius: 0px;
}
.p-organizationchart-line-left {
border-radius: 0;
}
.p-organizationchart-selectable-node {
cursor: pointer;
}
</style>

View file

@ -0,0 +1,137 @@
<template>
<table class="p-organizationchart-table">
<tbody>
<tr v-if="node">
<td :colspan="colspan">
<div :class="nodeContentClass" @click="onNodeClick">
<component :is="templates[node.type] || templates['default']" :node="node" />
<a v-if="toggleable" tabindex="0" class="p-node-toggler" @click="toggleNode" @keydown="onKeydown">
<i class="p-node-toggler-icon pi" :class="{ 'pi-chevron-down': expanded, 'pi-chevron-up': !expanded }"></i>
</a>
</div>
</td>
</tr>
<tr :style="childStyle" class="p-organizationchart-lines">
<td :colspan="colspan">
<div class="p-organizationchart-line-down"></div>
</td>
</tr>
<tr :style="childStyle" class="p-organizationchart-lines">
<template v-if="node.children && node.children.length === 1">
<td :colspan="colspan">
<div class="p-organizationchart-line-down"></div>
</td>
</template>
<template v-if="node.children && node.children.length > 1">
<template v-for="(child, i) of node.children" :key="child.key">
<td class="p-organizationchart-line-left" :class="{ 'p-organizationchart-line-top': !(i === 0) }">&nbsp;</td>
<td class="p-organizationchart-line-right" :class="{ 'p-organizationchart-line-top': !(i === node.children.length - 1) }">&nbsp;</td>
</template>
</template>
</tr>
<tr :style="childStyle" class="p-organizationchart-nodes">
<td v-for="child of node.children" :key="child.key" colspan="2">
<OrganizationChartNode
:node="child"
:templates="templates"
:collapsedKeys="collapsedKeys"
@node-toggle="onChildNodeToggle"
:collapsible="collapsible"
:selectionMode="selectionMode"
:selectionKeys="selectionKeys"
@node-click="onChildNodeClick"
/>
</td>
</tr>
</tbody>
</table>
</template>
<script>
import { DomHandler } from 'primevue/utils';
export default {
name: 'OrganizationChartNode',
emits: ['node-click', 'node-toggle'],
props: {
node: {
type: null,
default: null
},
templates: {
type: null,
default: null
},
collapsible: {
type: Boolean,
default: false
},
collapsedKeys: {
type: null,
default: null
},
selectionKeys: {
type: null,
default: null
},
selectionMode: {
type: String,
default: null
}
},
methods: {
onNodeClick(event) {
if (DomHandler.hasClass(event.target, 'p-node-toggler') || DomHandler.hasClass(event.target, 'p-node-toggler-icon')) {
return;
}
if (this.selectionMode) {
this.$emit('node-click', this.node);
}
},
onChildNodeClick(node) {
this.$emit('node-click', node);
},
toggleNode() {
this.$emit('node-toggle', this.node);
},
onChildNodeToggle(node) {
this.$emit('node-toggle', node);
},
onKeydown(event) {
if (event.code === 'Enter' || event.code === 'Space') {
this.toggleNode();
event.preventDefault();
}
}
},
computed: {
nodeContentClass() {
return ['p-organizationchart-node-content', this.node.styleClass, { 'p-organizationchart-selectable-node': this.selectable, 'p-highlight': this.selected }];
},
leaf() {
return this.node.leaf === false ? false : !(this.node.children && this.node.children.length);
},
colspan() {
return this.node.children && this.node.children.length ? this.node.children.length * 2 : null;
},
childStyle() {
return {
visibility: !this.leaf && this.expanded ? 'inherit' : 'hidden'
};
},
expanded() {
return this.collapsedKeys[this.node.key] === undefined;
},
selectable() {
return this.selectionMode && this.node.selectable !== false;
},
selected() {
return this.selectable && this.selectionKeys && this.selectionKeys[this.node.key] === true;
},
toggleable() {
return this.collapsible && this.node.collapsible !== false && !this.leaf;
}
}
};
</script>

View file

@ -0,0 +1,9 @@
{
"main": "./organizationchart.cjs.js",
"module": "./organizationchart.esm.js",
"unpkg": "./organizationchart.min.js",
"types": "./OrganizationChart.d.ts",
"browser": {
"./sfc": "./OrganizationChart.vue"
}
}