fit2cloud-ui-plus 0.0.1-beta.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.
Files changed (89) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +16 -0
  3. package/lib/favicon.bmp +0 -0
  4. package/lib/fit2cloud-ui-plus.es.js +3796 -0
  5. package/lib/fit2cloud-ui-plus.umd.js +1 -0
  6. package/package.json +48 -0
  7. package/src/components/filter-bar/FuFilter.vue +175 -0
  8. package/src/components/filter-bar/FuFilterBar.vue +75 -0
  9. package/src/components/filter-bar/FuFilterConditions.vue +29 -0
  10. package/src/components/filter-bar/FuSearchInput.vue +31 -0
  11. package/src/components/filter-bar/filter-components/FuFilterDate.vue +62 -0
  12. package/src/components/filter-bar/filter-components/FuFilterDateTime.vue +65 -0
  13. package/src/components/filter-bar/filter-components/FuFilterOption.vue +38 -0
  14. package/src/components/filter-bar/filter-components/FuFilterSelect.vue +143 -0
  15. package/src/components/filter-bar/index.ts +19 -0
  16. package/src/components/filter-bar/types.ts +31 -0
  17. package/src/components/read-write-switch/FuInputRwSwitch.vue +44 -0
  18. package/src/components/read-write-switch/FuReadWriteSwitch.vue +91 -0
  19. package/src/components/read-write-switch/FuSelectRwSwitch.vue +53 -0
  20. package/src/components/read-write-switch/index.ts +13 -0
  21. package/src/components/search-bar/FuComplexSearch.vue +108 -0
  22. package/src/components/search-bar/FuQuickSearch.vue +43 -0
  23. package/src/components/search-bar/FuSearchBar.vue +165 -0
  24. package/src/components/search-bar/FuSearchBarButton.vue +14 -0
  25. package/src/components/search-bar/FuSearchContions.vue +24 -0
  26. package/src/components/search-bar/index.ts +13 -0
  27. package/src/components/search-bar/store.ts +25 -0
  28. package/src/components/speed-dial/FuSpeedDial.vue +280 -0
  29. package/src/components/speed-dial/FuSpeedDialActionButton.vue +88 -0
  30. package/src/components/speed-dial/FuSpeedDialButton.vue +42 -0
  31. package/src/components/speed-dial/FuSpeedDialItem.vue +88 -0
  32. package/src/components/speed-dial/index.ts +11 -0
  33. package/src/components/split-pane/FuSplitPane.vue +228 -0
  34. package/src/components/split-pane/index.ts +8 -0
  35. package/src/components/steps/FuHorizontalNavigation.vue +18 -0
  36. package/src/components/steps/FuHorizontalSteps.vue +94 -0
  37. package/src/components/steps/FuStep.vue +13 -0
  38. package/src/components/steps/FuSteps.vue +22 -0
  39. package/src/components/steps/FuStepsFooter.ts +79 -0
  40. package/src/components/steps/FuVerticalNavigation.vue +35 -0
  41. package/src/components/steps/FuVerticalSteps.vue +79 -0
  42. package/src/components/steps/Stepper.ts +188 -0
  43. package/src/components/steps/index.ts +11 -0
  44. package/src/components/table/FuTable.vue +145 -0
  45. package/src/components/table/FuTableBody.ts +40 -0
  46. package/src/components/table/FuTablePagination.vue +42 -0
  47. package/src/components/table/index.ts +15 -0
  48. package/src/components/table/table-column-dropdown/FuTableColumnDropdown.vue +102 -0
  49. package/src/components/table/table-column-dropdown/index.ts +7 -0
  50. package/src/components/table/table-column-select/FuTableColumnSelect.vue +22 -0
  51. package/src/components/table/table-column-select/FuTableColumnSelectDialog.vue +99 -0
  52. package/src/components/table/table-column-select/FuTableColumnSelectPopover.vue +80 -0
  53. package/src/components/table/table-column-select/index.ts +8 -0
  54. package/src/components/table/table-column-select/utils.ts +59 -0
  55. package/src/components/table/table-operations/FuTableButton.vue +19 -0
  56. package/src/components/table/table-operations/FuTableMoreButton.vue +52 -0
  57. package/src/components/table/table-operations/FuTableOperations.vue +88 -0
  58. package/src/components/table/table-operations/index.ts +12 -0
  59. package/src/components/tabs/FuTabs.vue +84 -0
  60. package/src/components/tabs/index.ts +8 -0
  61. package/src/components/virtual-scroller/FuVirtualHorizontalScroll.js +96 -0
  62. package/src/components/virtual-scroller/FuVirtualScroll.js +15 -0
  63. package/src/components/virtual-scroller/FuVirtualVerticalScroll.js +95 -0
  64. package/src/components/virtual-scroller/index.js +10 -0
  65. package/src/hooks/index.ts +3 -0
  66. package/src/hooks/use-global-config/index.ts +32 -0
  67. package/src/hooks/use-locale/index.ts +47 -0
  68. package/src/index.ts +19 -0
  69. package/src/locale/index.ts +12 -0
  70. package/src/locale/lang/en.ts +58 -0
  71. package/src/locale/lang/zh-cn.ts +58 -0
  72. package/src/locale/lang/zh-tw.ts +58 -0
  73. package/src/styles/common/config.scss +5 -0
  74. package/src/styles/common/function.scss +81 -0
  75. package/src/styles/common/mixins.scss +85 -0
  76. package/src/styles/common/variables.scss +28 -0
  77. package/src/styles/components/filter-bar.scss +227 -0
  78. package/src/styles/components/read-write-switch.scss +6 -0
  79. package/src/styles/components/search-bar.scss +285 -0
  80. package/src/styles/components/speed-dial.scss +107 -0
  81. package/src/styles/components/split-pane.scss +111 -0
  82. package/src/styles/components/steps.scss +110 -0
  83. package/src/styles/components/table.scss +105 -0
  84. package/src/styles/components/tabs.scss +10 -0
  85. package/src/styles/components/virtual-scroller.scss +24 -0
  86. package/src/styles/index.scss +11 -0
  87. package/src/tools/theme.ts +23 -0
  88. package/src/tools/time.ts +30 -0
  89. package/src/tools/utils.ts +60 -0
@@ -0,0 +1,188 @@
1
+ import { useLocale } from "@/hooks"
2
+ const { t } = useLocale()
3
+
4
+ interface StepperOptions {
5
+ steps: string
6
+ index: number
7
+ activeSet: any
8
+ isLoading?: string
9
+ cancelButtonText: string
10
+ finishButtonText: string
11
+ prevButtonText: string
12
+ nextButtonText: string
13
+ buttonSize: string
14
+ footerAlign: string
15
+ showCancel: any
16
+ beforeActive: Function
17
+ beforeLeave: Function
18
+ height: string
19
+ }
20
+
21
+ export class Stepper {
22
+ steps: string
23
+ index: number
24
+ activeSet: any
25
+ isLoading: string
26
+ cancelButtonText: string
27
+ finishButtonText: string
28
+ prevButtonText: string
29
+ nextButtonText: string
30
+ buttonSize: string
31
+ footerAlign: string
32
+ showCancel: any
33
+ beforeActive: Function
34
+ beforeLeave: Function
35
+ height: string
36
+ constructor(options?: StepperOptions) {
37
+ options = options || ({} as StepperOptions)
38
+ // 所有步骤节点(Step对象数组)
39
+ this.steps = options.steps
40
+ // 正在执行的节点的索引
41
+ this.index = options.index === undefined ? 0 : options.index
42
+ // 激活过的节点的索引
43
+ this.activeSet = new Set()
44
+ // loading状态
45
+ this.isLoading = options.isLoading
46
+ // footer 属性
47
+ this.cancelButtonText = options.cancelButtonText || t("fu.steps.cancel")
48
+ this.finishButtonText = options.finishButtonText || t("fu.steps.finish")
49
+ this.prevButtonText = options.prevButtonText || t("fu.steps.prev")
50
+ this.nextButtonText = options.nextButtonText || t("fu.steps.next")
51
+ this.buttonSize = options.buttonSize
52
+ this.footerAlign = options.footerAlign || 'flex'
53
+ // 是否显示取消按钮
54
+ this.showCancel = options.showCancel === undefined ? false : options.showCancel
55
+ // 激活前钩子
56
+ this.beforeActive = options.beforeActive
57
+ // 离开前钩子
58
+ this.beforeLeave = options.beforeLeave
59
+ // 高度
60
+ this.height = options.height
61
+ }
62
+
63
+ // index是否为第一个节点
64
+ isFirst(index: number) {
65
+ return index === 0;
66
+ }
67
+
68
+ // index是否为最后一个节点
69
+ isLast(index: number) {
70
+ return index === this.steps.length - 1;
71
+ }
72
+
73
+ // index的节点是否激活过
74
+ isActive(index: number) {
75
+ return this.activeSet.has(index);
76
+ }
77
+
78
+ // index的节点是否为正在激活的节点
79
+ isCurrent(index: number) {
80
+ return this.index === index
81
+ }
82
+
83
+ // 激活
84
+ active(index: number) {
85
+ // 在节点范围内,并且不等于当前节点
86
+ const isValid = index >= 0 && index < this.steps.length && this.index !== index
87
+ const forward = index > this.index
88
+ if (isValid) {
89
+ // 离开前钩子返回false,则不执行激活
90
+ if (this.executeHook("beforeLeave", this.index, forward) !== false) {
91
+ // 激活前钩子返回false,则不执行激活
92
+ if (this.executeHook("beforeActive", index, forward) !== false) {
93
+ // 激活
94
+ this.index = index
95
+ this.activeSet.add(index)
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ // 反激活
102
+ inactive(index: number) {
103
+ this.activeSet.delete(index)
104
+ }
105
+
106
+ // 下一步
107
+ next() {
108
+ if (!this.isLast(this.index)) {
109
+ this.active(this.index + 1)
110
+ }
111
+ }
112
+
113
+ // 上一步
114
+ prev() {
115
+ if (!this.isFirst(this.index)) {
116
+ this.active(this.index - 1)
117
+ }
118
+ }
119
+
120
+ // 使用索引获取Step对象
121
+ getStep(index: number) {
122
+ if (this.steps && this.steps.length > index) {
123
+ return this.steps[index]
124
+ }
125
+ }
126
+
127
+ // 使用ID获取节点索引
128
+ getIndex(id: string) {
129
+ if (this.steps) {
130
+ for (let i = 0; i < this.steps.length; i++) {
131
+ let step = this.steps[i];
132
+ if (id === step.id) {
133
+ return i;
134
+ }
135
+ }
136
+ }
137
+ return -1;
138
+ }
139
+
140
+ executeHook(functionName: string, index: number, forward: boolean) {
141
+ const step: any = this.getStep(index)
142
+ // 如果节点定义了钩子方法,执行节点的
143
+ if (step[functionName]) {
144
+ return step[functionName](step, forward)
145
+ }
146
+
147
+ // 节点没定义,则执行Steps的钩子方法
148
+ if (this[functionName]) {
149
+ return this[functionName](step, forward)
150
+ }
151
+ }
152
+ }
153
+
154
+ interface StepOptions {
155
+ id: string
156
+ index: number
157
+ beforeActive: Function
158
+ beforeLeave: Function
159
+ title: string
160
+ description: string
161
+ icon: string
162
+ status: string
163
+ }
164
+
165
+ export class Step {
166
+ id: string
167
+ index: number
168
+ beforeActive: Function
169
+ beforeLeave: Function
170
+ title: string
171
+ description: string
172
+ icon: string
173
+ status: string
174
+ constructor(options?: StepOptions) {
175
+ options = options || ({} as StepOptions)
176
+ this.id = options.id
177
+ this.index = options.index
178
+ // 激活前钩子
179
+ this.beforeActive = options.beforeActive
180
+ // 离开前钩子
181
+ this.beforeLeave = options.beforeLeave
182
+ // el-step 属性
183
+ this.title = options.title
184
+ this.description = options.description
185
+ this.icon = options.icon
186
+ this.status = options.status
187
+ }
188
+ }
@@ -0,0 +1,11 @@
1
+ import FuSteps from './FuSteps.vue';
2
+ import FuStep from './FuStep.vue';
3
+
4
+ import type {App} from 'vue'
5
+
6
+ export default {
7
+ install: (app: App): void => {
8
+ // app.component(FuStep.name, FuStep);
9
+ // app.component(FuSteps.name, FuSteps);
10
+ }
11
+ };
@@ -0,0 +1,145 @@
1
+ <template>
2
+ <el-table class="fu-table" v-bind="$attrs" :key="key" header-row-class-name="fu-table-header">
3
+ <fu-table-body name="table-body" :columns="columns">
4
+ <slot />
5
+ </fu-table-body>
6
+ </el-table>
7
+ </template>
8
+
9
+ <script lang="ts" setup>
10
+ import { onMounted, useSlots, ref, watch, computed, onUpdated, provide } from "vue";
11
+ import FuTableBody from "@/components/table/FuTableBody";
12
+ defineOptions({ name: "FuTable" });
13
+ const props = defineProps({
14
+ columns: Array,
15
+ refresh: {
16
+ type: Boolean,
17
+ default: true,
18
+ },
19
+ localKey: String, // 如果需要记住选择的列,则这里添加一个唯一的Key
20
+
21
+ });
22
+
23
+ const slots = useSlots()
24
+
25
+ const key = ref(0);
26
+
27
+
28
+ const prefix = "FU-T-"
29
+
30
+ const isFix = (node: any) => {
31
+ const includeTag = node.type.name.indexOf("FuTableColumnDropdown") >= 0
32
+ const { fix } = node.props
33
+ let { type } = node.props
34
+ return (fix !== undefined && fix !== false) || ["selection", "index", "expand"].includes(type) || includeTag
35
+ }
36
+
37
+ const getLabel = (node: any) => {
38
+ if (node.props.label) return node.props.label
39
+ const includeTag = node.type.name.indexOf("FuTableColumnDropdown") >= 0
40
+ let { label, type } = node.props
41
+ if (includeTag) label = prefix + "dropdown"
42
+ label ??= node.props.label
43
+ label ??= prefix + type
44
+ return label;
45
+ }
46
+
47
+ const cleanColumns = (columns: any) => {
48
+ columns.splice(0, columns.length)
49
+ }
50
+
51
+ const updateNodes = (nodes: any) => {
52
+ nodes.forEach((node: any) => {
53
+ if (!node.type.key) {
54
+ node.type.key = getLabel(node)
55
+ }
56
+ })
57
+ }
58
+
59
+ const initColumns = (nodes: any, columns: any) => {
60
+ nodes.forEach((node: any) => {
61
+ const label = getLabel(node)
62
+ const fix = isFix(node);
63
+ const { show } = node.props
64
+ if (!label && !fix) {
65
+ throw new Error("unfixed column's label is required.")
66
+ }
67
+ columns.push({ label, show, fix })
68
+ })
69
+ }
70
+
71
+ const copyColumns = (source: any, target: any) => {
72
+ source.forEach((col: any) => {
73
+ target.push(col)
74
+ })
75
+ }
76
+
77
+ const updateColumns = (nodes: any, columns: any) => {
78
+ if (columns === undefined) return
79
+ // 如果保存的列跟实际的列冲突则以实际的为准
80
+ if (nodes.length !== columns.length) {
81
+ cleanColumns(columns)
82
+ initColumns(nodes, columns)
83
+ }
84
+ if (columns.some((col: any) => col.label === undefined)) {
85
+ columns.forEach((col: any, i: any) => {
86
+ col.label ??= getLabel(nodes[i])
87
+ })
88
+ }
89
+ }
90
+
91
+
92
+ const columnsKey = computed(() => {
93
+ return prefix + props.localKey
94
+ })
95
+ // 去掉v-if=false的node
96
+ const children = slots.default?.().filter((c: any) => c.type.name !== undefined)
97
+ watch(() => props.columns,
98
+ () => {
99
+ // 设置refresh,可以避免抖动或闪烁,但是table会更新一次
100
+ if (props.refresh) {
101
+ key.value++;
102
+ }
103
+ if (props.localKey) {
104
+ localStorage.setItem(columnsKey.value, JSON.stringify(props.columns));
105
+ }
106
+
107
+ },
108
+ { deep: true }
109
+ )
110
+ // 之前的created
111
+ onMounted(() => {
112
+ updateNodes(children)
113
+ // 表格没有内容或者不需要选列
114
+ if (!children || !props.columns) return
115
+
116
+ // 需要读取localStorage
117
+ if (props.localKey) {
118
+ let str = localStorage.getItem(columnsKey.value)
119
+ if (str) {
120
+ try {
121
+ const columns = JSON.parse(str)
122
+ cleanColumns(props.columns)
123
+ copyColumns(columns, props.columns)
124
+ updateColumns(children, props.columns)
125
+ return
126
+ } catch (e) {
127
+ console.error("get columns error", e)
128
+ }
129
+ }
130
+ }
131
+
132
+ if (props.columns.length === 0) {
133
+ initColumns(children, props.columns)
134
+ }
135
+ })
136
+
137
+
138
+ provide("localKey", props.localKey)
139
+
140
+ onUpdated(() => {
141
+ updateNodes(children)
142
+ updateColumns(children, props.columns)
143
+ })
144
+
145
+ </script>
@@ -0,0 +1,40 @@
1
+ import { h } from 'vue'
2
+
3
+ const isFix = (node: any) => {
4
+ const includeTag = node.type.name.indexOf("FuTableColumnDropdown") >= 0
5
+ const { fix } = node.props
6
+ let { type } = node.props
7
+ return (fix !== undefined && fix !== false) || ["selection", "index", "expand"].includes(type) || includeTag
8
+ }
9
+
10
+ const getLabel = (node: any) => {
11
+ if (node.props.label) return node.props.label
12
+ const prefix = "FU-T-"
13
+ const includeTag = node.type.name.indexOf("FuTableColumnDropdown") >= 0
14
+ let { label, type } = node.props
15
+ if (includeTag) label = prefix + "dropdown"
16
+ label ??= node.props.label
17
+ label ??= prefix + type
18
+ return label;
19
+ }
20
+ const FuTableBody = (props: any, context: any) => {
21
+ const slots = context.slots.default()
22
+ const nodes: any = [];
23
+ let { columns } = props
24
+ const children = slots[0].children.filter((c: any) => c.type.name !== undefined)
25
+ if (!children) return nodes
26
+ if (!columns || columns?.length === 0) return children
27
+ columns.forEach((col: any) => {
28
+ let node = children.find((child: any) => {
29
+ return col.label === getLabel(child)
30
+ })
31
+ if (node && (isFix(node) || col.show !== false)) {
32
+ nodes.push(node);
33
+ }
34
+ })
35
+ return nodes
36
+ }
37
+
38
+ export default FuTableBody;
39
+
40
+
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage"
3
+ :page-sizes="pageSizes" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total">
4
+ </el-pagination>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ defineOptions({ name: "FuTablePagination" });
9
+ const props = defineProps({
10
+ currentPage: {
11
+ type: Number,
12
+ default: 1
13
+ },
14
+ pageSize: {
15
+ type: Number,
16
+ default: 5
17
+ },
18
+ pageSizes: {
19
+ type: Array,
20
+ default: function () {
21
+ return [5, 10, 20, 50, 100]
22
+ }
23
+ },
24
+ total: {
25
+ type: Number,
26
+ default: 0
27
+ },
28
+
29
+ });
30
+ const emit = defineEmits(["size-change", "current-change", "change", "update:pageSize", "update:currentPage"])
31
+
32
+ function handleSizeChange(size: number) {
33
+ emit('update:pageSize', size)
34
+ emit("size-change");
35
+ emit("change"); // 兼容历史版本
36
+ }
37
+ function handleCurrentChange(current: number) {
38
+ emit('update:currentPage', current)
39
+ emit("current-change");
40
+ emit("change"); // 兼容历史版本
41
+ }
42
+ </script>
@@ -0,0 +1,15 @@
1
+ import FuTable from "./FuTable.vue"
2
+ import FuTableColumnSelect from "./table-column-select"
3
+ import FuTablePagination from "./FuTablePagination.vue"
4
+ import FuTableOperations from "./table-operations"
5
+ import FuTableColumnDropdown from "./table-column-dropdown"
6
+
7
+ import type { App } from 'vue'
8
+ FuTable.install = (app: App): void => {
9
+ app.component(FuTable.name, FuTable);
10
+ app.component(FuTablePagination.name, FuTablePagination)
11
+ app.use(FuTableOperations.install)
12
+ app.use(FuTableColumnSelect.install)
13
+ app.use(FuTableColumnDropdown.install)
14
+ };
15
+ export default FuTable;
@@ -0,0 +1,102 @@
1
+ <template>
2
+ <el-table-column class-name="fu-table-column-dropdown" :width="width" :resizable="false" align="center"
3
+ v-bind="$attrs">
4
+ <template #default="scope">
5
+ <el-dropdown @command="handleCommand" :trigger="trigger" :class="showType === 'hover' ? 'fu-show-icon' : ''"
6
+ v-if="isShow(scope.row)" placement="bottom" :ref="`dropdown${scope.$index}`">
7
+ <span class="fu-dropdown-link">
8
+ <slot name="icon">
9
+ <el-icon class="fu-icon-more">
10
+ <MoreFilled />
11
+ </el-icon>
12
+ </slot>
13
+ </span>
14
+ <template #dropdown>
15
+ <el-dropdown-menu>
16
+ <slot name="title">
17
+ <div class="fu-table-column-dropdown__title" v-if="title">
18
+ {{ title }}
19
+ </div>
20
+ </slot>
21
+ <slot v-bind="scope">
22
+ <el-dropdown-item v-for="(item, i) in menus" :key="i" :icon="item.icon"
23
+ :disabled="disabled(item, scope.row)" :divided="item.divided" :command="composeValue(item, scope.row)">
24
+ {{ item.label }}
25
+ </el-dropdown-item>
26
+ </slot>
27
+ </el-dropdown-menu>
28
+ </template>
29
+ </el-dropdown>
30
+ </template>
31
+
32
+ </el-table-column>
33
+ </template>
34
+ <script lang="ts" setup>
35
+ import { computed, getCurrentInstance } from "vue";
36
+ defineOptions({ name: "FuTableColumnDropdown" });
37
+ const props = defineProps({
38
+ showType: {
39
+ type: String,
40
+ default: "always",
41
+ validator: (value: string) => ["always", "hover", "selected"].includes(value),
42
+ },
43
+ menus: {
44
+ type: Array,
45
+ default: () => [],
46
+ },
47
+ title: String,
48
+ trigger: {
49
+ type: String,
50
+ default: "click",
51
+ },
52
+ width: {
53
+ type: String,
54
+ default: "40",
55
+ },
56
+
57
+ });
58
+
59
+ const instance = getCurrentInstance()
60
+
61
+
62
+ const isShow = computed(() => {
63
+ return function (row: any) {
64
+ if (props.showType === "selected") {
65
+ const selection = instance?.parent?.parent?.store?.getSelectionRows()
66
+ return selection.includes(row) && true;
67
+ } else {
68
+ return true;
69
+ }
70
+ };
71
+ });
72
+
73
+ const disabled = computed(() => {
74
+ return function (item: any, row: any) {
75
+ return typeof item.disabled === "function"
76
+ ? item.disabled(row)
77
+ : item.disabled;
78
+ };
79
+ });
80
+
81
+
82
+ function handleCommand({ item, row }: any) {
83
+ item.click(row);
84
+ }
85
+ function composeValue(item: any, row: any) {
86
+ return {
87
+ item,
88
+ row,
89
+ };
90
+ }
91
+
92
+ function show(index: number) {
93
+ instance.refs[`dropdown${index}`].handleOpen();
94
+ }
95
+ function hide(index: number) {
96
+ instance.refs[`dropdown${index}`].handleClose();
97
+ }
98
+ defineExpose({
99
+ show,
100
+ hide
101
+ })
102
+ </script>
@@ -0,0 +1,7 @@
1
+ import FuTableColumnDropdown from "./FuTableColumnDropdown.vue";
2
+ import type { App } from 'vue'
3
+ FuTableColumnDropdown.install = (app: App): void =>{
4
+ app.component(FuTableColumnDropdown.name, FuTableColumnDropdown);
5
+ };
6
+
7
+ export default FuTableColumnDropdown;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import { defineComponent, h } from 'vue'
3
+ import FuTableColumnSelectPopover from "./FuTableColumnSelectPopover.vue";
4
+ import FuTableColumnSelectDialog from "./FuTableColumnSelectDialog.vue";
5
+
6
+ export default defineComponent({
7
+ name: 'FuTableColumnSelect',
8
+ props: ["type"],
9
+ setup(props, context) {
10
+ const { type } = props
11
+ return () => {
12
+ if (type === "dialog") {
13
+ return h(FuTableColumnSelectDialog, context.attrs, context.slots)
14
+ } else {
15
+ return h(FuTableColumnSelectPopover, context.attrs, context.slots)
16
+ }
17
+ }
18
+ }
19
+
20
+ })
21
+ </script>
22
+
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <div style="display: inline-block">
3
+ <!-- :size="configSize" -->
4
+ <el-button class="fu-search-bar-button" :icon="icon" @click="visible = true">{{t('fu.table.custom_table_rows')}}</el-button>
5
+ <el-dialog custom-class="fu-table-column-select-dialog" v-model="visible" @open="open" append-to-body>
6
+ <template #title>
7
+ <h3>
8
+ {{ t('fu.table.custom_table_fields') }}
9
+ </h3>
10
+ <el-alert :title="t('fu.table.custom_table_fields_desc')" type="info" :closable="false"/>
11
+ </template>
12
+
13
+ <el-checkbox v-for="(c, i) in cloneColumns" :key="i" v-model="c.show" :checked="c.show !== false" draggable="true"
14
+ @dragstart="dragstart($event, i)" @dragenter="dragenter" @dragleave="dragleave"
15
+ @dragover.prevent @dragend="dragend" @drop="drop($event, cloneColumns, i)" v-show="!c.fix">
16
+ {{ c.label }}
17
+ </el-checkbox>
18
+
19
+ <template #footer>
20
+ <el-button @click="reset" v-if="columnsKey">
21
+ {{ t('fu.table.reset') }}
22
+ </el-button>
23
+ <el-button type="primary" @click="ok">
24
+ {{ t('fu.table.ok') }}
25
+ </el-button>
26
+ </template>
27
+ </el-dialog>
28
+ </div>
29
+
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import {ref, inject} from "vue";
34
+ import {tableColumnSelect} from "./utils"
35
+ import {useLocale} from "@/hooks"
36
+
37
+ const props = defineProps({
38
+ icon: {
39
+ type: String,
40
+ default: "Setting"
41
+ },
42
+ trigger: {
43
+ type: String,
44
+ default: "hover",
45
+ validator: (value: string) => ['click', 'hover'].includes(value)
46
+ },
47
+ columns: {
48
+ type: Array,
49
+ default: () => []
50
+ },
51
+
52
+ })
53
+
54
+ const localKey = inject("localKey")
55
+
56
+ const {t} = useLocale()
57
+
58
+ const cloneColumn = (source: any, target: any) => {
59
+ source.forEach((col: any) => {
60
+ target.push(Object.assign({}, col))
61
+ })
62
+ return target
63
+ }
64
+
65
+
66
+ const {
67
+ columnsKey,
68
+ dragstart,
69
+ dragenter,
70
+ dragleave,
71
+ dragend,
72
+ drop
73
+ } = tableColumnSelect(localKey)
74
+
75
+ const cloneColumns = ref([])
76
+ const visible = ref(false)
77
+
78
+ function open() {
79
+ cloneColumns.value = []
80
+ cloneColumn(props.columns, cloneColumns.value)
81
+ }
82
+
83
+ function ok() {
84
+ props.columns.splice(0, props.columns.length)
85
+ cloneColumns.value.forEach(c => {
86
+ props.columns.push(c)
87
+ })
88
+ visible.value = false
89
+ }
90
+
91
+ function reset() {
92
+ if (columnsKey) {
93
+ localStorage.removeItem(columnsKey.value)
94
+ }
95
+ props.columns.splice(0, props.columns.length)
96
+ visible.value = false
97
+ }
98
+
99
+ </script>