@tmagic/table 1.0.0-beta.1

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/src/Table.vue ADDED
@@ -0,0 +1,224 @@
1
+ <template>
2
+ <el-table
3
+ :data="tableData"
4
+ :show-header="showHeader"
5
+ :max-height="bodyHeight"
6
+ tooltip-effect="dark"
7
+ class="m-table"
8
+ ref="table"
9
+ :default-expand-all="defaultExpandAll"
10
+ :border="hasBorder"
11
+ :row-key="rowkeyName || 'c_id'"
12
+ :tree-props="{ children: 'children' }"
13
+ :empty-text="emptyText || '暂无数据'"
14
+ :span-method="objectSpanMethod"
15
+ @sort-change="sortChange"
16
+ @select="selectHandler"
17
+ @select-all="selectAllHandler"
18
+ @selection-change="selectionChangeHandler"
19
+ >
20
+ <template v-for="(item, columnIndex) in columns">
21
+ <template v-if="item.type === 'expand'">
22
+ <expand-column :config="item" :key="columnIndex"></expand-column>
23
+ </template>
24
+
25
+ <template v-if="item.selection">
26
+ <el-table-column type="selection" :key="columnIndex" width="40" :selectable="item.selectable"></el-table-column>
27
+ </template>
28
+
29
+ <template v-else-if="item.actions">
30
+ <actions-column
31
+ :columns="columns"
32
+ :config="item"
33
+ :rowkey-name="rowkeyName"
34
+ :edit-state="editState"
35
+ :key="columnIndex"
36
+ @afterAction="$emit('afterAction')"
37
+ ></actions-column>
38
+ </template>
39
+
40
+ <template v-else-if="item.type === 'popover'">
41
+ <popover-column :key="columnIndex" :config="item"></popover-column>
42
+ </template>
43
+
44
+ <template v-else>
45
+ <text-column :key="columnIndex" :config="item" :edit-state="editState"></text-column>
46
+ </template>
47
+ </template>
48
+ </el-table>
49
+ </template>
50
+
51
+ <script lang="ts">
52
+ import { defineComponent, PropType } from 'vue';
53
+ import { ElTable } from 'element-plus';
54
+ import { cloneDeep } from 'lodash-es';
55
+
56
+ import ActionsColumn from './ActionsColumn.vue';
57
+ import ExpandColumn from './ExpandColumn.vue';
58
+ import PopoverColumn from './PopoverColumn.vue';
59
+ import TextColumn from './TextColumn.vue';
60
+
61
+ export default defineComponent({
62
+ name: 'm-table',
63
+
64
+ components: { ExpandColumn, ActionsColumn, PopoverColumn, TextColumn },
65
+
66
+ props: {
67
+ data: {
68
+ type: Array,
69
+ require: true,
70
+ },
71
+
72
+ columns: {
73
+ type: Array as PropType<any[]>,
74
+ require: true,
75
+ default: () => [],
76
+ },
77
+
78
+ /** 合并行或列的计算方法 */
79
+ spanMethod: {
80
+ type: Function as PropType<
81
+ (data: { row: any; column: any; rowIndex: number; columnIndex: number }) => [number, number]
82
+ >,
83
+ },
84
+
85
+ fetch: {
86
+ type: Boolean,
87
+ default: false,
88
+ },
89
+
90
+ /** Table 的最大高度。合法的值为数字或者单位为 px 的高度 */
91
+ bodyHeight: {
92
+ type: [String, Number],
93
+ },
94
+
95
+ /** 是否显示表头 */
96
+ showHeader: {
97
+ type: Boolean,
98
+ },
99
+
100
+ /** 空数据时显示的文本内容 */
101
+ emptyText: {
102
+ type: String,
103
+ },
104
+
105
+ /** 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 */
106
+ defaultExpandAll: {
107
+ type: Boolean,
108
+ default: false,
109
+ },
110
+
111
+ rowkeyName: {
112
+ type: String,
113
+ },
114
+
115
+ /** 是否带有纵向边框 */
116
+ border: {
117
+ type: Boolean,
118
+ default: false,
119
+ },
120
+ },
121
+
122
+ emits: ['sort-change', 'afterAction', 'select', 'select-all', 'selection-change'],
123
+
124
+ data(): {
125
+ editState: any[];
126
+ } {
127
+ return {
128
+ editState: [],
129
+ };
130
+ },
131
+
132
+ computed: {
133
+ tableData() {
134
+ if (this.selectionColumn) {
135
+ return this.data || [];
136
+ }
137
+
138
+ return cloneDeep(this.data) || [];
139
+ },
140
+
141
+ selectionColumn() {
142
+ const column = this.columns.filter((item) => item.selection);
143
+ return column.length ? column[0] : null;
144
+ },
145
+
146
+ hasBorder() {
147
+ return typeof this.border !== 'undefined' ? this.border : true;
148
+ },
149
+ },
150
+
151
+ methods: {
152
+ sortChange(data: any) {
153
+ this.$emit('sort-change', data);
154
+ },
155
+
156
+ selectHandler(selection: any, row: any) {
157
+ const column = this.selectionColumn;
158
+ if (!column) {
159
+ return;
160
+ }
161
+
162
+ if (column.selection === 'single') {
163
+ // this.clearSelection()
164
+ // this.toggleRowSelection(row, true)
165
+ }
166
+ this.$emit('select', selection, row);
167
+ },
168
+
169
+ selectAllHandler(selection: any) {
170
+ this.$emit('select-all', selection);
171
+ },
172
+
173
+ selectionChangeHandler(selection: any) {
174
+ this.$emit('selection-change', selection);
175
+ },
176
+
177
+ toggleRowSelection(row: any, selected: boolean) {
178
+ const table = this.$refs.table as InstanceType<typeof ElTable>;
179
+ table.toggleRowSelection.bind(table)(row, selected);
180
+ },
181
+
182
+ toggleRowExpansion(row: any, expanded: boolean) {
183
+ const table = this.$refs.table as InstanceType<typeof ElTable>;
184
+ table.toggleRowExpansion.bind(table)(row, expanded);
185
+ },
186
+
187
+ clearSelection() {
188
+ const table = this.$refs.table as InstanceType<typeof ElTable>;
189
+ table.clearSelection.bind(table)();
190
+ },
191
+
192
+ objectSpanMethod(data: any) {
193
+ if (typeof this.spanMethod === 'function') {
194
+ return this.spanMethod(data);
195
+ }
196
+ return () => ({
197
+ rowspan: 0,
198
+ colspan: 0,
199
+ });
200
+ },
201
+ },
202
+ });
203
+ </script>
204
+
205
+ <style lang="scss">
206
+ .m-table {
207
+ .el-button.action-btn {
208
+ margin-right: 10px;
209
+ }
210
+ .el-button.action-btn + .el-button.action-btn {
211
+ margin-left: 0;
212
+ }
213
+ .keep-all {
214
+ word-break: keep-all;
215
+ }
216
+ .el-table .cell > div {
217
+ display: inline-block;
218
+ vertical-align: middle;
219
+ }
220
+ .el-table__row.el-table__row--level-1 {
221
+ color: #999;
222
+ }
223
+ }
224
+ </style>
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <el-table-column
3
+ show-overflow-tooltip
4
+ :label="config.label"
5
+ :width="config.width"
6
+ :fixed="config.fixed"
7
+ :sortable="config.sortable"
8
+ :prop="config.prop"
9
+ >
10
+ <template v-slot="scope">
11
+ <el-form v-if="config.type && editState[scope.$index]" label-width="0" :model="editState[scope.$index]">
12
+ <m-form-container
13
+ :prop="config.prop"
14
+ :rules="config.rules"
15
+ :config="config"
16
+ :name="config.prop"
17
+ :model="editState[scope.$index]"
18
+ ></m-form-container>
19
+ </el-form>
20
+
21
+ <el-button v-else-if="config.action === 'actionLink'" type="text" @click="config.handler(scope.row)">
22
+ {{ formatter(config, scope.row) }}
23
+ </el-button>
24
+
25
+ <a v-else-if="config.action === 'img'" target="_blank" :href="scope.row[config.prop]"
26
+ ><img :src="scope.row[config.prop]" height="50"
27
+ /></a>
28
+
29
+ <a v-else-if="config.action === 'link'" target="_blank" :href="scope.row[config.prop]" class="keep-all">{{
30
+ scope.row[config.prop]
31
+ }}</a>
32
+
33
+ <el-tooltip v-else-if="config.action === 'tip'" placement="left">
34
+ <template #content>
35
+ <div>{{ formatter(config, scope.row) }}</div>
36
+ </template>
37
+ <el-button type="text">扩展配置</el-button>
38
+ </el-tooltip>
39
+
40
+ <el-tag
41
+ v-else-if="config.action === 'tag'"
42
+ :type="typeof config.type === 'function' ? config.type(scope.row[config.prop], scope.row) : config.type"
43
+ close-transition
44
+ >{{ formatter(config, scope.row) }}</el-tag
45
+ >
46
+ <div v-else v-html="formatter(config, scope.row)"></div>
47
+ </template>
48
+ </el-table-column>
49
+ </template>
50
+
51
+ <script lang="ts">
52
+ import { defineComponent, PropType } from 'vue';
53
+
54
+ import { ColumnConfig } from './schema';
55
+ import { formatter } from './utils';
56
+
57
+ export default defineComponent({
58
+ props: {
59
+ config: {
60
+ type: Object as PropType<ColumnConfig>,
61
+ default: () => ({}),
62
+ required: true,
63
+ },
64
+
65
+ editState: {
66
+ type: Object,
67
+ default: () => {},
68
+ },
69
+ },
70
+
71
+ setup() {
72
+ return {
73
+ formatter,
74
+ };
75
+ },
76
+ });
77
+ </script>
package/src/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making TMagicEditor available.
3
+ *
4
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { App } from 'vue';
20
+
21
+ import Table from './Table.vue';
22
+
23
+ export { default as MagicTable } from './Table.vue';
24
+
25
+ const components = [Table];
26
+
27
+ export default {
28
+ install(app: App) {
29
+ components.forEach((component) => {
30
+ app.component(component.name, component);
31
+ });
32
+ },
33
+ };
package/src/schema.ts ADDED
@@ -0,0 +1,56 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making TMagicEditor available.
3
+ *
4
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { FormConfig, FormValue } from '@tmagic/form';
20
+
21
+ export interface ColumnActionConfig {
22
+ type?: 'delete' | 'copy' | 'edit';
23
+ display?: (vm: any, row: any) => boolean;
24
+ text: string;
25
+ name: string;
26
+ handler?: (row: any) => Promise<any> | any;
27
+ after?: () => void;
28
+ action?: (data: { data: any }) => void;
29
+ }
30
+
31
+ export type ColumnConfig = {
32
+ form?: FormConfig;
33
+ rules?: any;
34
+ values?: FormValue;
35
+ selection?: boolean | 'single';
36
+ selectable?: (row: any, index: number) => boolean;
37
+ label: string;
38
+ fixed?: 'left' | 'right' | boolean;
39
+ width?: number | string;
40
+ actions?: ColumnActionConfig[];
41
+ type: 'popover' | 'expand' | string | ((value: any, row: any) => string);
42
+ text: string;
43
+ prop: string;
44
+ showHeader: boolean;
45
+ table?: ColumnConfig[];
46
+ formatter?: 'datetime' | ((item: any, row: Record<string, any>) => any);
47
+ popover: {
48
+ placement: '';
49
+ width: '';
50
+ trigger: '';
51
+ tableEmbed: '';
52
+ };
53
+ sortable?: boolean | 'custom';
54
+ action?: 'tip' | 'actionLink' | 'img' | 'link' | 'tag';
55
+ handler: (row: any) => void;
56
+ };
@@ -0,0 +1,6 @@
1
+ declare module '*.vue' {
2
+ import { DefineComponent } from 'vue';
3
+
4
+ const component: DefineComponent<{}, {}, any>;
5
+ export default component;
6
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making TMagicEditor available.
3
+ *
4
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { datetimeFormatter } from '@tmagic/utils';
20
+
21
+ import { ColumnConfig } from './schema';
22
+
23
+ export const formatter = (item: ColumnConfig, row: any) => {
24
+ if (item.formatter) {
25
+ if (item.formatter === 'datetime') {
26
+ // eslint-disable-next-line no-param-reassign
27
+ item.formatter = (value: string) => datetimeFormatter(value);
28
+ }
29
+ try {
30
+ return item.formatter(row[item.prop], row);
31
+ } catch (e) {
32
+ return row[item.prop];
33
+ }
34
+ } else {
35
+ return row[item.prop];
36
+ }
37
+ };
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "baseUrl": "../..",
5
+ },
6
+ "exclude": [
7
+ "**/dist/**/*"
8
+ ],
9
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making TMagicEditor available.
3
+ *
4
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { defineConfig } from 'vite';
20
+
21
+ import { getBaseConfig } from '../vite-config';
22
+
23
+ import pkg from './package.json';
24
+
25
+ const deps = Object.keys(pkg.dependencies);
26
+
27
+ export default defineConfig(getBaseConfig(deps, 'TMagicTable'));