@ctzy-web-client/plugin-component-vue 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +43 -0
- package/src/advance-select/advance-operation.vue +44 -0
- package/src/advance-select/advance-option.vue +115 -0
- package/src/advance-select/advance-select.vue +343 -0
- package/src/advance-select/events-helpers.js +40 -0
- package/src/advance-select/index.js +13 -0
- package/src/advance-select/use-advance-option.js +58 -0
- package/src/advance-select/use-advance-select.js +142 -0
- package/src/application-slot/application-slot.js +70 -0
- package/src/application-slot/breadcrumb-item.vue +12 -0
- package/src/application-slot/header-tools-item.vue +12 -0
- package/src/application-slot/index.js +17 -0
- package/src/breadcrumb-select/breadcrumb-select.vue +97 -0
- package/src/breadcrumb-select/index.js +6 -0
- package/src/components.js +39 -0
- package/src/contextmenu/contextmenu-item.vue +13 -0
- package/src/contextmenu/contextmenu.vue +56 -0
- package/src/contextmenu/index.js +11 -0
- package/src/contextmenu/use-contextmenu.js +117 -0
- package/src/data-form/data-form-item.vue +49 -0
- package/src/data-form/data-form.vue +212 -0
- package/src/data-form/dynamic-component.js +24 -0
- package/src/data-form/form-components/Blots/AtBlot.js +32 -0
- package/src/data-form/form-components/bwa-date-picker.vue +43 -0
- package/src/data-form/form-components/bwa-date-time-picker.vue +49 -0
- package/src/data-form/form-components/bwa-input-float.vue +41 -0
- package/src/data-form/form-components/bwa-input-integer.vue +58 -0
- package/src/data-form/form-components/bwa-input.vue +32 -0
- package/src/data-form/form-components/bwa-multi-select.vue +27 -0
- package/src/data-form/form-components/bwa-rich-text-tinymce.vue +561 -0
- package/src/data-form/form-components/bwa-rich-text.vue +395 -0
- package/src/data-form/form-components/bwa-select.vue +67 -0
- package/src/data-form/form-components/bwa-textarea.vue +28 -0
- package/src/data-form/form-components/bwa-upload.vue +145 -0
- package/src/data-form/form-components/bwa-user-multi-select.vue +25 -0
- package/src/data-form/form-components/bwa-user-select.vue +81 -0
- package/src/data-form/index.js +35 -0
- package/src/data-table/data-column-view.vue +131 -0
- package/src/data-table/data-table-card.vue +81 -0
- package/src/data-table/data-table-column.vue +52 -0
- package/src/data-table/data-table.vue +426 -0
- package/src/data-table/dynamic-component.js +58 -0
- package/src/data-table/index.js +13 -0
- package/src/data-table/use-datatable-drag.js +156 -0
- package/src/datatable-settings/datatable-settings.vue +323 -0
- package/src/datatable-settings/index.js +6 -0
- package/src/date-range/date-picker.vue +115 -0
- package/src/date-range/date-range.vue +202 -0
- package/src/date-range/index.js +6 -0
- package/src/drag-list/constants.js +1 -0
- package/src/drag-list/drag-item.vue +46 -0
- package/src/drag-list/drag-list.vue +50 -0
- package/src/drag-list/index.js +6 -0
- package/src/drag-list/use-drag-list.js +209 -0
- package/src/dragable/constants.js +3 -0
- package/src/dragable/dragable-item.vue +19 -0
- package/src/dragable/dragable-operation.vue +28 -0
- package/src/dragable/dragable.vue +26 -0
- package/src/dragable/index.js +14 -0
- package/src/dragable/use-dragable.js +227 -0
- package/src/filter-panel/conditions/condition.js +35 -0
- package/src/filter-panel/conditions/date-range-condition.vue +35 -0
- package/src/filter-panel/conditions/department-condition/data.json +29537 -0
- package/src/filter-panel/conditions/department-condition/department-condition.vue +92 -0
- package/src/filter-panel/conditions/department-condition/department-node.vue +52 -0
- package/src/filter-panel/conditions/index.js +22 -0
- package/src/filter-panel/conditions/input-condition.vue +63 -0
- package/src/filter-panel/conditions/multi-user-condition.vue +56 -0
- package/src/filter-panel/conditions/multiple-menu-condition.vue +45 -0
- package/src/filter-panel/conditions/single-menu-condition.vue +58 -0
- package/src/filter-panel/conditions/single-user-condition.vue +56 -0
- package/src/filter-panel/filter-panel-item.vue +46 -0
- package/src/filter-panel/filter-panel.vue +149 -0
- package/src/filter-panel/index.js +17 -0
- package/src/filter-panel/use-filter-panel-item.js +59 -0
- package/src/filter-panel/use-filter-panel.js +203 -0
- package/src/hooks/use-data/index.js +234 -0
- package/src/index.js +48 -0
- package/src/layout/index.js +6 -0
- package/src/layout/layout.vue +74 -0
- package/src/make-installer.js +36 -0
- package/src/math/Rectangle.js +28 -0
- package/src/menu/index.js +6 -0
- package/src/menu/menu-item.vue +41 -0
- package/src/menu/menu.vue +53 -0
- package/src/panel/index.js +6 -0
- package/src/panel/panel.vue +42 -0
- package/src/panel-tabs/index.js +6 -0
- package/src/panel-tabs/panel-tabs.js +92 -0
- package/src/pct-filter-panel/index.js +10 -0
- package/src/pct-filter-panel/pct-compents/index.js +10 -0
- package/src/pct-filter-panel/pct-compents/pct-Input-condition.vue +63 -0
- package/src/pct-filter-panel/pct-compents/pct-date-range-condition.vue +60 -0
- package/src/pct-filter-panel/pct-compents/pct-multiple-menu-condition.vue +177 -0
- package/src/pct-filter-panel/pct-compents/pct-multiple-menu-condition2.vue +142 -0
- package/src/pct-filter-panel/pct-filter-panel-item.vue +46 -0
- package/src/pct-filter-panel/pct-filter-panel.vue +201 -0
- package/src/pct-filter-panel/use-filter-panel-item.js +61 -0
- package/src/pct-filter-panel/use-filter-panel.js +206 -0
- package/src/plugins.js +3 -0
- package/src/progress/index.js +8 -0
- package/src/progress/progress-item.vue +81 -0
- package/src/progress/progress.vue +58 -0
- package/src/progress/use-progress.js +66 -0
- package/src/utils/db.js +8 -0
- package/src/utils.js +263 -0
- package/src/where-filter-panel/index.js +0 -0
- package/src/where-filter-panel/use-where-filter-panel.js +28 -0
- package/src/where-filter-panel/where-filter-panel.vue +9 -0
- package/style/advance-select.scss +316 -0
- package/style/breadcrumb-select.scss +80 -0
- package/style/common/var.scss +240 -0
- package/style/common.scss +48 -0
- package/style/contextmenu.scss +58 -0
- package/style/data-form.scss +35 -0
- package/style/data-table.scss +81 -0
- package/style/datatable-settings.scss +125 -0
- package/style/date-range.scss +136 -0
- package/style/department-condition.scss +39 -0
- package/style/drag-list.scss +68 -0
- package/style/dragable.scss +8 -0
- package/style/filter-panel.scss +199 -0
- package/style/index.scss +22 -0
- package/style/input-condition.scss +30 -0
- package/style/layout.scss +70 -0
- package/style/menu.scss +184 -0
- package/style/mixins/_var.scss +21 -0
- package/style/mixins/config.scss +4 -0
- package/style/mixins/function.scss +62 -0
- package/style/mixins/mixins.scss +88 -0
- package/style/panel-tabs.scss +60 -0
- package/style/panel.scss +110 -0
- package/style/pct-filter-panel.scss +306 -0
- package/style/progress.scss +122 -0
- package/style/rich-text.scss +30 -0
- package/style/theme/theme.scss +161 -0
- package/style/theme/var.scss +34 -0
- package/style/var.scss +21 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { computed, reactive, unref, watch } from 'vue';
|
|
2
|
+
import { debounce } from 'lodash';
|
|
3
|
+
|
|
4
|
+
export const useAdvanceSelectStates = (props) => {
|
|
5
|
+
return reactive({
|
|
6
|
+
options: new Map(),
|
|
7
|
+
cachedOptions: new Map(),
|
|
8
|
+
optionsCount: 0,
|
|
9
|
+
selected: props.multiple ? [] : {},
|
|
10
|
+
search: '',
|
|
11
|
+
isShowPopper: false,
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const useAdvanceSelect = (props, states, ctx) => {
|
|
16
|
+
const cachedOptions = computed(() =>
|
|
17
|
+
Array.from(states.cachedOptions.values())
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
watch(
|
|
21
|
+
computed(() => states.isShowPopper),
|
|
22
|
+
(isShowPopper) => {
|
|
23
|
+
if (!isShowPopper) {
|
|
24
|
+
states.search = '';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
watch(
|
|
30
|
+
() => props.modelValue,
|
|
31
|
+
() => {
|
|
32
|
+
setSelected();
|
|
33
|
+
},
|
|
34
|
+
{ flush: 'post', deep: true }
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const selectedLabel = computed(() => {
|
|
38
|
+
return props.multiple
|
|
39
|
+
? states.selected.map((selected) => selected.label)
|
|
40
|
+
: states.selected.label || props.modelValue;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const getOption = (value) => {
|
|
44
|
+
let option = null;
|
|
45
|
+
for (const item of cachedOptions.value) {
|
|
46
|
+
if (item.value === value) {
|
|
47
|
+
option = {
|
|
48
|
+
value,
|
|
49
|
+
label: item.currentLabel,
|
|
50
|
+
};
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (option) {
|
|
56
|
+
return option;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { value, label: value };
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const setSelected = () => {
|
|
63
|
+
if (!props.multiple) {
|
|
64
|
+
const option = getOption(props.modelValue);
|
|
65
|
+
states.selected = option;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const result = [];
|
|
69
|
+
if (Array.isArray(props.modelValue)) {
|
|
70
|
+
props.modelValue.forEach((value) => {
|
|
71
|
+
result.push(getOption(value));
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
states.selected = result;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const onOptionCreate = (option) => {
|
|
78
|
+
states.optionsCount++;
|
|
79
|
+
states.options.set(option.value, option);
|
|
80
|
+
states.cachedOptions.set(option.value, option);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const onOptionDestroy = (key, option) => {
|
|
84
|
+
if (states.options.get(key) === option) {
|
|
85
|
+
states.optionsCount--;
|
|
86
|
+
states.options.delete(key);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const handleClearClick = () => {
|
|
91
|
+
ctx.emit('update:modelValue', props.multiple ? [] : '');
|
|
92
|
+
if (props.closeAfterSelection) {
|
|
93
|
+
states.isShowPopper = false;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleOptionSelect = (option) => {
|
|
98
|
+
if (props.multiple) {
|
|
99
|
+
const value = (props.modelValue || []).slice();
|
|
100
|
+
const optionIndex = value.indexOf(option.value);
|
|
101
|
+
if (optionIndex > -1) {
|
|
102
|
+
if (props.required && value.length === 1) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
value.splice(optionIndex, 1);
|
|
107
|
+
} else if (
|
|
108
|
+
props.multipleLimit <= 0 ||
|
|
109
|
+
value.length < props.multipleLimit
|
|
110
|
+
) {
|
|
111
|
+
value.push(option.value);
|
|
112
|
+
}
|
|
113
|
+
ctx.emit('update:modelValue', value);
|
|
114
|
+
if (props.closeAfterSelection) {
|
|
115
|
+
states.isShowPopper = false;
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
ctx.emit('update:modelValue', option.value);
|
|
119
|
+
states.isShowPopper = false;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const hidePoppper = () => {
|
|
124
|
+
states.isShowPopper = false;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
watch(
|
|
128
|
+
computed(() => states.options.entries()),
|
|
129
|
+
() => {
|
|
130
|
+
setSelected();
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
selectedLabel,
|
|
136
|
+
onOptionCreate,
|
|
137
|
+
onOptionDestroy,
|
|
138
|
+
handleClearClick,
|
|
139
|
+
handleOptionSelect,
|
|
140
|
+
hidePoppper,
|
|
141
|
+
};
|
|
142
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Fragment,
|
|
3
|
+
h,
|
|
4
|
+
onBeforeUnmount,
|
|
5
|
+
onMounted,
|
|
6
|
+
render,
|
|
7
|
+
useSlots,
|
|
8
|
+
effectScope,
|
|
9
|
+
effect,
|
|
10
|
+
} from 'vue';
|
|
11
|
+
import { useGlobalConfig, applicationKey } from 'web-base-client-vue';
|
|
12
|
+
|
|
13
|
+
let uuid = 1;
|
|
14
|
+
|
|
15
|
+
const ApplicationSlot = {
|
|
16
|
+
name: 'BwaApplicationSlot',
|
|
17
|
+
props: {
|
|
18
|
+
type: String,
|
|
19
|
+
},
|
|
20
|
+
setup(props) {
|
|
21
|
+
let currentUuid = uuid++;
|
|
22
|
+
|
|
23
|
+
const slots = useSlots();
|
|
24
|
+
|
|
25
|
+
const application = useGlobalConfig(applicationKey);
|
|
26
|
+
|
|
27
|
+
const scope = effectScope();
|
|
28
|
+
|
|
29
|
+
let container = null;
|
|
30
|
+
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
container = document.createElement('div');
|
|
33
|
+
|
|
34
|
+
scope.run(() => {
|
|
35
|
+
effect(() => {
|
|
36
|
+
const vnodes = slots.default?.();
|
|
37
|
+
let _vnodes = [...vnodes];
|
|
38
|
+
|
|
39
|
+
for (let i = 0; i < _vnodes.length; i++) {
|
|
40
|
+
const vnode = _vnodes[i];
|
|
41
|
+
|
|
42
|
+
vnode.appContext = ApplicationSlot._context;
|
|
43
|
+
|
|
44
|
+
if (Array.isArray(vnode.children)) {
|
|
45
|
+
_vnodes = _vnodes.concat(vnode.children);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const vnode = h(Fragment, vnodes);
|
|
50
|
+
vnode.appContext = ApplicationSlot._context;
|
|
51
|
+
|
|
52
|
+
render(vnode, container);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
application.value.addApplicationSlot(props.type, currentUuid, container);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
onBeforeUnmount(() => {
|
|
60
|
+
application.value.removeApplicationSlot(props.type, currentUuid);
|
|
61
|
+
render(null, container);
|
|
62
|
+
container = null;
|
|
63
|
+
scope.stop();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return () => h('i', { style: { display: 'none' } });
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default ApplicationSlot;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { withInstall } from 'element-plus/es/utils/vue/install';
|
|
2
|
+
import ApplicationSlot from './application-slot.js';
|
|
3
|
+
import BreadcrumbItem from './breadcrumb-item.vue';
|
|
4
|
+
import HeaderToolsItem from './header-tools-item.vue';
|
|
5
|
+
|
|
6
|
+
ApplicationSlot.install = (app) => {
|
|
7
|
+
ApplicationSlot._context = app._context;
|
|
8
|
+
app.component(ApplicationSlot.name, ApplicationSlot);
|
|
9
|
+
app.component(BreadcrumbItem.name, BreadcrumbItem);
|
|
10
|
+
app.component(HeaderToolsItem.name, HeaderToolsItem);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const BwaApplicationSlot = ApplicationSlot;
|
|
14
|
+
export const BwaBreadcrumbItem = withInstall(BreadcrumbItem);
|
|
15
|
+
export const BwaHeaderToolsItem = withInstall(HeaderToolsItem);
|
|
16
|
+
|
|
17
|
+
export default BwaApplicationSlot;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<BwaAdvanceSelect
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:showSelection="false"
|
|
5
|
+
:search-placeholder="searchPlaceholder"
|
|
6
|
+
:multiple="false"
|
|
7
|
+
>
|
|
8
|
+
<template #contentTop v-if="recentEmptyDesc">
|
|
9
|
+
<div :class="ns.be('item', 'top')">
|
|
10
|
+
<slot name="recent">
|
|
11
|
+
<div :class="ns.be('item', 'top-empty')">{{ recentEmptyDesc }}</div>
|
|
12
|
+
</slot>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<template #contentBottom>
|
|
17
|
+
<AdvanceOperation v-if="showAll" :class="ns.be('item', 'opt')" @click="emit('all')">
|
|
18
|
+
<i class="ptp-caozuo-chakan ptp-icon"></i>
|
|
19
|
+
<span :class="ns.be('item', 'opt-label')">{{ allDesc }}</span>
|
|
20
|
+
</AdvanceOperation>
|
|
21
|
+
<AdvanceOperation v-if="showMine" :class="ns.be('item', 'opt')" @click="emit('mine')">
|
|
22
|
+
<i class="ptp-caozuo-chakan ptp-icon"></i>
|
|
23
|
+
<span :class="ns.be('item', 'opt-label')">{{ allMine }}</span>
|
|
24
|
+
</AdvanceOperation>
|
|
25
|
+
<AdvanceOperation v-if="showSave" :class="ns.be('item', 'opt')" @click="emit('save')">
|
|
26
|
+
<ElIcon><CirclePlus /></ElIcon>
|
|
27
|
+
<span :class="ns.be('item', 'opt-label')">{{ saveDesc }}</span>
|
|
28
|
+
</AdvanceOperation>
|
|
29
|
+
</template>
|
|
30
|
+
<slot></slot>
|
|
31
|
+
|
|
32
|
+
<template #reference="{ label }">
|
|
33
|
+
<ElButton :class="ns.be('item', 'dropdown')">
|
|
34
|
+
<i class="ptp-qiehuan ptp-icon"></i>
|
|
35
|
+
<span :class="ns.be('item', 'content')">
|
|
36
|
+
{{ label || defaultLabel }}
|
|
37
|
+
</span>
|
|
38
|
+
<ElIcon><ArrowDown /></ElIcon>
|
|
39
|
+
</ElButton>
|
|
40
|
+
</template>
|
|
41
|
+
</BwaAdvanceSelect>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script setup>
|
|
45
|
+
import { ElButton, ElIcon } from 'element-plus';
|
|
46
|
+
import { useAttrs } from 'vue';
|
|
47
|
+
import { useNamespace } from 'web-base-client-vue';
|
|
48
|
+
import BwaAdvanceSelect from '../advance-select';
|
|
49
|
+
import AdvanceOperation from '../advance-select/advance-operation.vue';
|
|
50
|
+
|
|
51
|
+
defineOptions({ name: 'BwaBreadcrumbSelect' });
|
|
52
|
+
|
|
53
|
+
const props = defineProps({
|
|
54
|
+
defaultLabel: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: '请选择',
|
|
57
|
+
},
|
|
58
|
+
recentEmptyDesc: {
|
|
59
|
+
type: String,
|
|
60
|
+
default: '最近访问项目',
|
|
61
|
+
},
|
|
62
|
+
searchPlaceholder: {
|
|
63
|
+
type: String,
|
|
64
|
+
default: '项目名称',
|
|
65
|
+
},
|
|
66
|
+
allDesc: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: '全部项目',
|
|
69
|
+
},
|
|
70
|
+
allMine: {
|
|
71
|
+
type: String,
|
|
72
|
+
default: '我的项目',
|
|
73
|
+
},
|
|
74
|
+
saveDesc: {
|
|
75
|
+
type: String,
|
|
76
|
+
default: '新增项目',
|
|
77
|
+
},
|
|
78
|
+
showSave: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
default: true,
|
|
81
|
+
},
|
|
82
|
+
showMine: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: false,
|
|
85
|
+
},
|
|
86
|
+
showAll: {
|
|
87
|
+
type: Boolean,
|
|
88
|
+
default: true
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const emit = defineEmits(['all','mine', 'save']);
|
|
93
|
+
|
|
94
|
+
const attrs = useAttrs();
|
|
95
|
+
|
|
96
|
+
const ns = useNamespace('breadcrumb');
|
|
97
|
+
</script>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BwaDataForm } from './data-form';
|
|
2
|
+
import { BwaDataTable } from './data-table';
|
|
3
|
+
import { BwaFilterPanel, BwaCondition } from './filter-panel';
|
|
4
|
+
import { BwaAdvanceSelect } from './advance-select';
|
|
5
|
+
import { BwaDateRange } from './date-range';
|
|
6
|
+
import { BwaApplicationSlot } from './application-slot';
|
|
7
|
+
import { BwaLayout } from './layout';
|
|
8
|
+
import { BwaMenu } from './menu';
|
|
9
|
+
import { BwaPanel } from './panel';
|
|
10
|
+
import { BwaPanelTab } from './panel-tabs';
|
|
11
|
+
import { BwaBreadcrumbSelect } from './breadcrumb-select';
|
|
12
|
+
import { BwaDataTableSetting } from './datatable-settings';
|
|
13
|
+
import { BwaDraglist } from './drag-list';
|
|
14
|
+
import { BwaProgress } from './progress';
|
|
15
|
+
import { BwaDragable } from './dragable';
|
|
16
|
+
import { BwaPctFilterPanel } from './pct-filter-panel';
|
|
17
|
+
import { BwaPctMultipleMenuCondition, BwaPctInputCondition, BwaPctDateRangeCondition } from './pct-filter-panel/pct-compents'
|
|
18
|
+
export default [
|
|
19
|
+
BwaDataForm,
|
|
20
|
+
BwaDataTable,
|
|
21
|
+
BwaFilterPanel,
|
|
22
|
+
BwaAdvanceSelect,
|
|
23
|
+
BwaDateRange,
|
|
24
|
+
BwaCondition,
|
|
25
|
+
BwaApplicationSlot,
|
|
26
|
+
BwaLayout,
|
|
27
|
+
BwaMenu,
|
|
28
|
+
BwaPanel,
|
|
29
|
+
BwaPanelTab,
|
|
30
|
+
BwaBreadcrumbSelect,
|
|
31
|
+
BwaDataTableSetting,
|
|
32
|
+
BwaDraglist,
|
|
33
|
+
BwaProgress,
|
|
34
|
+
BwaDragable,
|
|
35
|
+
BwaPctFilterPanel,
|
|
36
|
+
BwaPctMultipleMenuCondition,
|
|
37
|
+
BwaPctInputCondition,
|
|
38
|
+
BwaPctDateRangeCondition
|
|
39
|
+
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="ns.b()">
|
|
3
|
+
<slot></slot>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup>
|
|
8
|
+
import { useNamespace } from 'web-base-client-vue';
|
|
9
|
+
|
|
10
|
+
defineOptions({ name: 'BwaContextmenuItem' });
|
|
11
|
+
|
|
12
|
+
const ns = useNamespace('contextmenu-item');
|
|
13
|
+
</script>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="ns.b()">
|
|
3
|
+
<ElScrollbar max-height="400px" ref="scrollbarRef">
|
|
4
|
+
<div
|
|
5
|
+
v-for="menu in menus"
|
|
6
|
+
@click="clickHandle(menu)"
|
|
7
|
+
:key="menu.id"
|
|
8
|
+
:class="ns.b('item')"
|
|
9
|
+
>
|
|
10
|
+
{{ menu.label }}
|
|
11
|
+
</div>
|
|
12
|
+
</ElScrollbar>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script setup>
|
|
17
|
+
import { ElScrollbar } from 'element-plus';
|
|
18
|
+
import { computed, onMounted, ref, unref, watch } from 'vue';
|
|
19
|
+
import { useNamespace } from 'web-base-client-vue';
|
|
20
|
+
|
|
21
|
+
defineOptions({ name: 'BwaContextmenu' });
|
|
22
|
+
|
|
23
|
+
const props = defineProps({
|
|
24
|
+
visible: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: false,
|
|
27
|
+
},
|
|
28
|
+
menus: {
|
|
29
|
+
type: Array,
|
|
30
|
+
default: () => [],
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const emit = defineEmits(['select']);
|
|
35
|
+
|
|
36
|
+
const ns = useNamespace('contextmenu');
|
|
37
|
+
|
|
38
|
+
const scrollbarRef = ref(null);
|
|
39
|
+
|
|
40
|
+
const clickHandle = (item) => {
|
|
41
|
+
emit('select', item);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
watch(
|
|
46
|
+
computed(() => props.visible),
|
|
47
|
+
(visible) => {
|
|
48
|
+
if (!visible) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
unref(scrollbarRef).scrollTo(0, 0);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Contextmenu from './contextmenu.vue';
|
|
2
|
+
|
|
3
|
+
Contextmenu.install = (app) => {
|
|
4
|
+
Contextmenu._context = app._context;
|
|
5
|
+
app.component(Contextmenu.name, Contextmenu);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const BwaContextmenu = Contextmenu;
|
|
9
|
+
export { useContextmenu } from './use-contextmenu';
|
|
10
|
+
|
|
11
|
+
export default BwaContextmenu;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createApp,
|
|
3
|
+
h,
|
|
4
|
+
nextTick,
|
|
5
|
+
onBeforeUnmount,
|
|
6
|
+
onMounted,
|
|
7
|
+
reactive,
|
|
8
|
+
ref,
|
|
9
|
+
unref,
|
|
10
|
+
vShow,
|
|
11
|
+
withDirectives,
|
|
12
|
+
} from 'vue';
|
|
13
|
+
import { useWindowSize, useElementBounding } from '@vueuse/core';
|
|
14
|
+
import { useNamespace } from 'web-base-client-vue';
|
|
15
|
+
import Contextmenu from './contextmenu.vue';
|
|
16
|
+
|
|
17
|
+
export function useContextmenu({ menus = [] } = {}) {
|
|
18
|
+
const ns = useNamespace('contextmenu');
|
|
19
|
+
|
|
20
|
+
menus = ref([...menus]);
|
|
21
|
+
|
|
22
|
+
let el = document.createElement('div');
|
|
23
|
+
|
|
24
|
+
const contextmenuWrapper = ref(null);
|
|
25
|
+
|
|
26
|
+
const visible = ref(false);
|
|
27
|
+
|
|
28
|
+
const bounding = ref(null);
|
|
29
|
+
const position = reactive({ x: 0, y: 0 });
|
|
30
|
+
|
|
31
|
+
const windowSize = useWindowSize();
|
|
32
|
+
|
|
33
|
+
let resolve = null;
|
|
34
|
+
|
|
35
|
+
const contextmenuInstance = createApp({
|
|
36
|
+
setup() {
|
|
37
|
+
onMounted(() => {
|
|
38
|
+
bounding.value = useElementBounding(contextmenuWrapper);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return () =>
|
|
42
|
+
withDirectives(
|
|
43
|
+
h(
|
|
44
|
+
'div',
|
|
45
|
+
{
|
|
46
|
+
class: ns.e('wrapper'),
|
|
47
|
+
ref: contextmenuWrapper,
|
|
48
|
+
tabIndex: -1,
|
|
49
|
+
style: {
|
|
50
|
+
left: position.x + 'px',
|
|
51
|
+
top: position.y + 'px',
|
|
52
|
+
},
|
|
53
|
+
onContextmenu(e) {
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
e.stopPropagation();
|
|
56
|
+
},
|
|
57
|
+
onBlur() {
|
|
58
|
+
resolve?.(null);
|
|
59
|
+
visible.value = false;
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
[
|
|
63
|
+
h(Contextmenu, {
|
|
64
|
+
menus: unref(menus),
|
|
65
|
+
visible: unref(visible),
|
|
66
|
+
onSelect(item) {
|
|
67
|
+
resolve?.(item);
|
|
68
|
+
visible.value = false;
|
|
69
|
+
},
|
|
70
|
+
}),
|
|
71
|
+
]
|
|
72
|
+
),
|
|
73
|
+
[[vShow, unref(visible)]]
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const showContextmenu = async (x, y) => {
|
|
79
|
+
if (!Array.isArray(unref(menus)) || !unref(menus).length) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
visible.value = true;
|
|
84
|
+
|
|
85
|
+
let promise = new Promise((_resolve) => {
|
|
86
|
+
resolve = _resolve;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
await nextTick();
|
|
90
|
+
|
|
91
|
+
position.x = x;
|
|
92
|
+
position.y = y;
|
|
93
|
+
|
|
94
|
+
if (windowSize.height.value - position.y < bounding.value.height) {
|
|
95
|
+
position.y = windowSize.height.value - bounding.value.height;
|
|
96
|
+
}
|
|
97
|
+
if (windowSize.width.value - position.x < bounding.value.width) {
|
|
98
|
+
position.x = windowSize.width.value - bounding.value.width;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
contextmenuWrapper.value.focus();
|
|
102
|
+
|
|
103
|
+
return promise;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
onMounted(() => {
|
|
107
|
+
contextmenuInstance.mount(el);
|
|
108
|
+
document.body.appendChild(el);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
onBeforeUnmount(() => {
|
|
112
|
+
document.body.removeChild(el);
|
|
113
|
+
contextmenuInstance.unmount();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return { showContextmenu };
|
|
117
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ElFormItem
|
|
3
|
+
v-if="formColumn && formColumn.visible"
|
|
4
|
+
v-bind="attrs"
|
|
5
|
+
:label="label"
|
|
6
|
+
:class="{ custom: !$slots.default }"
|
|
7
|
+
:prop="formColumn.fullAttrName"
|
|
8
|
+
>
|
|
9
|
+
<slot :column="formColumn" :record="dataForm.data" :dataForm="dataForm">
|
|
10
|
+
<DynamicComponent :column="formColumn" :record="dataForm.data" />
|
|
11
|
+
</slot>
|
|
12
|
+
</ElFormItem>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup>
|
|
16
|
+
import { ElFormItem, formContextKey } from 'element-plus';
|
|
17
|
+
import { inject, computed, useAttrs, provide, reactive } from 'vue';
|
|
18
|
+
import { dataFormKey } from 'web-base-client-vue';
|
|
19
|
+
import DynamicComponent from './dynamic-component.js';
|
|
20
|
+
|
|
21
|
+
defineOptions({ name: 'BwaDataFormItem' });
|
|
22
|
+
|
|
23
|
+
const props = defineProps({
|
|
24
|
+
name: { type: String },
|
|
25
|
+
isShowLabelColon: { type: Boolean }
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const attrs = useAttrs();
|
|
29
|
+
|
|
30
|
+
const dataForm = inject(dataFormKey);
|
|
31
|
+
|
|
32
|
+
const formContext = inject(formContextKey, {});
|
|
33
|
+
|
|
34
|
+
const formColumn = dataForm
|
|
35
|
+
.getDisplayColumns()
|
|
36
|
+
.find((col) => col.fullAttrName == props.name);
|
|
37
|
+
|
|
38
|
+
const label = computed(() => {
|
|
39
|
+
return attrs.label || (formColumn ? formColumn.title + (props.isShowLabelColon ? ' :' : '') : '');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const _formContext = {};
|
|
43
|
+
_formContext.disabled = computed(
|
|
44
|
+
() => formContext.disabled || formColumn?.disabled
|
|
45
|
+
);
|
|
46
|
+
Reflect.setPrototypeOf(_formContext, formContext);
|
|
47
|
+
|
|
48
|
+
provide(formContextKey, reactive(_formContext));
|
|
49
|
+
</script>
|