@tripup-company/element-ui-extended 0.0.9 → 0.0.10
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/dist/element-ui-extended.common.js +105 -254
- package/dist/element-ui-extended.common.js.map +1 -1
- package/dist/element-ui-extended.umd.js +105 -254
- package/dist/element-ui-extended.umd.js.map +1 -1
- package/dist/element-ui-extended.umd.min.js +1 -1
- package/dist/element-ui-extended.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/App.vue +31 -21
- package/src/components/CompositeTable/index.vue +62 -40
- package/src/components/GenericFilters/QuickSearchFilter.vue +41 -0
- package/src/components/GenericPaginator/index.vue +0 -1
- package/src/components/GenericTable/index.vue +29 -8
- package/src/components/GenericFilters/FilterTopRow.vue +0 -83
- package/src/components/GenericFilters/GenericTopFilter.vue +0 -54
- package/src/filters-top.js +0 -8
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div id="app">
|
|
3
|
-
<composite-table
|
|
3
|
+
<composite-table
|
|
4
|
+
:storageKey="'Project_name'"
|
|
5
|
+
:fields="fields"
|
|
6
|
+
:filters="filters"
|
|
7
|
+
:top-filter="topFilter"
|
|
8
|
+
:repository="repository"
|
|
9
|
+
></composite-table>
|
|
4
10
|
<img alt="Vue logo" src="./assets/logo.png" />
|
|
5
11
|
</div>
|
|
6
12
|
</template>
|
|
@@ -9,35 +15,39 @@
|
|
|
9
15
|
import { Component, Vue } from "vue-property-decorator";
|
|
10
16
|
import CompositeTable from "@/components/CompositeTable/index.vue";
|
|
11
17
|
import filters from "./filters";
|
|
12
|
-
import
|
|
18
|
+
import topFilter from "./topFilter";
|
|
13
19
|
import repository from "./repositories/contacts-repository";
|
|
14
20
|
@Component({
|
|
15
21
|
components: { CompositeTable },
|
|
16
22
|
data: function () {
|
|
17
|
-
let repo = new repository(
|
|
23
|
+
let repo = new repository("", "/test", null);
|
|
18
24
|
return {
|
|
19
25
|
filters: filters,
|
|
20
|
-
|
|
26
|
+
topFilter: topFilter,
|
|
21
27
|
repository: repo,
|
|
22
28
|
fields: [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
{
|
|
30
|
+
prop: "full_name",
|
|
31
|
+
label: "Full Name",
|
|
32
|
+
formatter: (row) => {
|
|
33
|
+
return row.first_name + " " + row.last_name;
|
|
34
|
+
},
|
|
27
35
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
{
|
|
37
|
+
prop: "email",
|
|
38
|
+
label: "Email",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
prop: "phone",
|
|
42
|
+
label: "Phone",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
prop: "created_at",
|
|
46
|
+
label: "Created at",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
},
|
|
41
51
|
})
|
|
42
52
|
export default class App extends Vue {}
|
|
43
53
|
</script>
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div v-loading="loading" class="composite-table">
|
|
3
3
|
<slot>
|
|
4
|
-
<slot name="top-filter" v-bind="{ filtersTop, search }">
|
|
5
|
-
<generic-top-filter
|
|
6
|
-
v-if="filtersTop.length"
|
|
7
|
-
:filters="filtersTop"
|
|
8
|
-
:search="search"
|
|
9
|
-
@apply:filter="handleApplyFilter"
|
|
10
|
-
@reset:filter="handleResetFilter"
|
|
11
|
-
/>
|
|
12
|
-
</slot>
|
|
13
|
-
|
|
14
4
|
<el-row :gutter="20">
|
|
15
5
|
<el-col :span="18">
|
|
6
|
+
<slot name="quick-search-filter" v-bind="{ topFilter, search }">
|
|
7
|
+
<quick-search-filter
|
|
8
|
+
v-if="topFilter"
|
|
9
|
+
:filter="topFilter"
|
|
10
|
+
:search="topSearch"
|
|
11
|
+
@apply:filter="handleApplyTopFilter"
|
|
12
|
+
@reset:filter="handleResetTopFilter"
|
|
13
|
+
/>
|
|
14
|
+
</slot>
|
|
16
15
|
<slot name="table" v-bind="{ fields, data }">
|
|
17
16
|
<generic-table
|
|
18
17
|
:fields="fields"
|
|
@@ -58,10 +57,11 @@ import GenericTable from "@/components/GenericTable";
|
|
|
58
57
|
import ListQueryService from "@/services/list-query-service";
|
|
59
58
|
import { LocalStorageService } from "@/services/local-storage-service";
|
|
60
59
|
import MetaModel from "@/models/meta-model";
|
|
61
|
-
import
|
|
60
|
+
import QuickSearchFilter from "@/components/GenericFilters/QuickSearchFilter";
|
|
61
|
+
import FilterConverter from "../GenericFilters/filter-convertor";
|
|
62
62
|
export default {
|
|
63
63
|
components: {
|
|
64
|
-
|
|
64
|
+
QuickSearchFilter,
|
|
65
65
|
GenericFilter,
|
|
66
66
|
GenericTable,
|
|
67
67
|
GenericPaginator,
|
|
@@ -82,16 +82,18 @@ export default {
|
|
|
82
82
|
default: () => [],
|
|
83
83
|
type: Array,
|
|
84
84
|
},
|
|
85
|
-
|
|
86
|
-
default
|
|
87
|
-
|
|
85
|
+
topFilter: {
|
|
86
|
+
default() {
|
|
87
|
+
return {};
|
|
88
|
+
},
|
|
89
|
+
type: Object,
|
|
88
90
|
},
|
|
89
91
|
filters: {
|
|
90
92
|
default: () => [],
|
|
91
93
|
type: Array,
|
|
92
94
|
},
|
|
93
95
|
includes: {
|
|
94
|
-
default:
|
|
96
|
+
default: "--",
|
|
95
97
|
type: String,
|
|
96
98
|
},
|
|
97
99
|
storageKey: {
|
|
@@ -105,25 +107,31 @@ export default {
|
|
|
105
107
|
this.$route ? this.$route.name : "storage.key",
|
|
106
108
|
localStorage
|
|
107
109
|
);
|
|
110
|
+
const filterConvertor = new FilterConverter();
|
|
108
111
|
let search = {};
|
|
112
|
+
let topSearch = {};
|
|
109
113
|
for (const column of this.filters) {
|
|
110
114
|
search[column.name] = {
|
|
111
115
|
operator: "",
|
|
112
116
|
value: "",
|
|
113
117
|
};
|
|
114
118
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
position: "top",
|
|
119
|
+
if (this.topFilter) {
|
|
120
|
+
topSearch[this.topFilter.name] = {
|
|
118
121
|
value: "",
|
|
122
|
+
operator: this.topFilter.operator,
|
|
119
123
|
};
|
|
120
124
|
}
|
|
125
|
+
|
|
121
126
|
search = Object.assign(search, listQueryService.getListQuery().search);
|
|
127
|
+
topSearch = Object.assign(topSearch, listQueryService.getListQuery().topSearch);
|
|
122
128
|
return {
|
|
123
129
|
loading: false,
|
|
124
130
|
filter: {},
|
|
125
131
|
data: [],
|
|
126
132
|
search: search,
|
|
133
|
+
topSearch: topSearch,
|
|
134
|
+
filterConvertor: filterConvertor,
|
|
127
135
|
meta: Object.assign(
|
|
128
136
|
new MetaModel(),
|
|
129
137
|
listQueryService.getListQuery().meta
|
|
@@ -135,10 +143,15 @@ export default {
|
|
|
135
143
|
queryFilter() {
|
|
136
144
|
const meta = this.listQueryService.getListQuery().meta;
|
|
137
145
|
const query = {
|
|
138
|
-
page: this.meta?.pagination?.current_page
|
|
139
|
-
|
|
146
|
+
page: this.meta?.pagination?.current_page
|
|
147
|
+
? this.meta.pagination.current_page
|
|
148
|
+
: meta.page,
|
|
149
|
+
limit: this.meta?.pagination?.per_page
|
|
150
|
+
? this.meta.pagination.per_page
|
|
151
|
+
: meta.limit,
|
|
140
152
|
};
|
|
141
|
-
|
|
153
|
+
const filter = this.filterConvertor.applyFilter({ ...this.search, ...this.topSearch });
|
|
154
|
+
return { ...query, ...filter };
|
|
142
155
|
},
|
|
143
156
|
currentPage() {
|
|
144
157
|
if (this.data.meta?.pagination) {
|
|
@@ -169,7 +182,10 @@ export default {
|
|
|
169
182
|
async fetch() {
|
|
170
183
|
this.loading = true;
|
|
171
184
|
try {
|
|
172
|
-
const response = await this.repository.all(
|
|
185
|
+
const response = await this.repository.all(
|
|
186
|
+
this.queryFilter,
|
|
187
|
+
this.includes
|
|
188
|
+
);
|
|
173
189
|
this.data = response.data;
|
|
174
190
|
Vue.set(this.data, "meta", response.meta);
|
|
175
191
|
} catch (e) {
|
|
@@ -188,7 +204,7 @@ export default {
|
|
|
188
204
|
page: this.listQueryService.getListQuery().meta.page,
|
|
189
205
|
},
|
|
190
206
|
});
|
|
191
|
-
this.meta.
|
|
207
|
+
Vue.set(this.data, "meta.per_page.current_page", val);
|
|
192
208
|
this.fetch();
|
|
193
209
|
},
|
|
194
210
|
handleCurrentChange(val) {
|
|
@@ -198,34 +214,40 @@ export default {
|
|
|
198
214
|
limit: this.listQueryService.getListQuery().meta.limit,
|
|
199
215
|
},
|
|
200
216
|
});
|
|
201
|
-
this.data
|
|
217
|
+
Vue.set(this.data, "meta.pagination.current_page", val);
|
|
202
218
|
this.fetch();
|
|
203
219
|
},
|
|
204
|
-
handleFilterChange(
|
|
205
|
-
this.
|
|
206
|
-
this.data.meta.pagination.current_page = 1;
|
|
220
|
+
handleFilterChange() {
|
|
221
|
+
Vue.set(this.data, "meta.pagination.current_page", 1);
|
|
207
222
|
this.fetch();
|
|
208
223
|
},
|
|
209
|
-
handleApplyFilter(
|
|
224
|
+
handleApplyFilter() {
|
|
210
225
|
this.listQueryService.updateListQuery({ search: this.search });
|
|
211
|
-
this.handleFilterChange(
|
|
226
|
+
this.handleFilterChange();
|
|
212
227
|
},
|
|
213
228
|
handleResetFilter() {
|
|
214
229
|
for (const column in this.search) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
} else {
|
|
220
|
-
this.search[column] = Object.assign(this.search[column], {
|
|
221
|
-
operator: "",
|
|
222
|
-
value: "",
|
|
223
|
-
});
|
|
224
|
-
}
|
|
230
|
+
this.search[column] = Object.assign(this.search[column], {
|
|
231
|
+
operator: "",
|
|
232
|
+
value: "",
|
|
233
|
+
});
|
|
225
234
|
}
|
|
226
235
|
this.listQueryService.updateListQuery({ search: {} });
|
|
227
236
|
this.handleFilterChange({});
|
|
228
237
|
},
|
|
238
|
+
handleApplyTopFilter() {
|
|
239
|
+
this.listQueryService.updateListQuery({ topSearch: this.topSearch });
|
|
240
|
+
this.handleFilterChange();
|
|
241
|
+
},
|
|
242
|
+
handleResetTopFilter() {
|
|
243
|
+
for (const column in this.topSearch) {
|
|
244
|
+
this.topSearch[column] = Object.assign(this.topSearch[column], {
|
|
245
|
+
value: "",
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
this.listQueryService.updateListQuery({ topSearch: {} });
|
|
249
|
+
this.handleFilterChange({});
|
|
250
|
+
},
|
|
229
251
|
},
|
|
230
252
|
};
|
|
231
253
|
</script>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-row class="m-b-20">
|
|
3
|
+
<el-col v-if="filter">
|
|
4
|
+
<el-input
|
|
5
|
+
v-if="filter.type === 'string'"
|
|
6
|
+
v-model="search[filter.name].value"
|
|
7
|
+
clearable
|
|
8
|
+
@clear="resetFilter"
|
|
9
|
+
@keyup.enter.native="applyFilter"
|
|
10
|
+
/>
|
|
11
|
+
</el-col>
|
|
12
|
+
</el-row>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
export default {
|
|
17
|
+
name: "QuickSearchFilter",
|
|
18
|
+
props: {
|
|
19
|
+
filter: {
|
|
20
|
+
type: Object,
|
|
21
|
+
default: () => {
|
|
22
|
+
return {};
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
search: {
|
|
26
|
+
type: Object,
|
|
27
|
+
default: () => {
|
|
28
|
+
return {};
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
methods: {
|
|
33
|
+
applyFilter() {
|
|
34
|
+
this.$emit("apply:filter");
|
|
35
|
+
},
|
|
36
|
+
resetFilter() {
|
|
37
|
+
this.$emit("reset:filter");
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
</script>
|
|
@@ -3,14 +3,36 @@
|
|
|
3
3
|
<el-table :data="data" border @sort-change="sortChange">
|
|
4
4
|
<template v-for="field in fields">
|
|
5
5
|
<template v-if="field.callback">
|
|
6
|
-
<el-table-column
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
<el-table-column
|
|
7
|
+
:key="field.prop"
|
|
8
|
+
v-slot="context"
|
|
9
|
+
:prop="field.prop"
|
|
10
|
+
:label="field.label"
|
|
11
|
+
:width="field.width ? field.width : null"
|
|
12
|
+
:sortable="field.sortable ? field.sortable : null"
|
|
13
|
+
>
|
|
14
|
+
<el-link
|
|
15
|
+
@click="field.callback(field.prop, context.$index, context.row)"
|
|
16
|
+
>
|
|
17
|
+
{{
|
|
18
|
+
typeof field.formatter === "function"
|
|
19
|
+
? field.formatter(context.row)
|
|
20
|
+
: context.row[field.prop]
|
|
21
|
+
}}
|
|
9
22
|
</el-link>
|
|
10
23
|
</el-table-column>
|
|
11
24
|
</template>
|
|
12
25
|
<template v-else>
|
|
13
|
-
<el-table-column
|
|
26
|
+
<el-table-column
|
|
27
|
+
:formatter="
|
|
28
|
+
typeof field.formatter === 'function' ? field.formatter : null
|
|
29
|
+
"
|
|
30
|
+
:key="field.prop"
|
|
31
|
+
:prop="field.prop"
|
|
32
|
+
:label="field.label"
|
|
33
|
+
:width="field.width ? field.width : null"
|
|
34
|
+
:sortable="field.sortable ? field.sortable : null"
|
|
35
|
+
/>
|
|
14
36
|
</template>
|
|
15
37
|
</template>
|
|
16
38
|
</el-table>
|
|
@@ -18,7 +40,6 @@
|
|
|
18
40
|
</template>
|
|
19
41
|
|
|
20
42
|
<script>
|
|
21
|
-
|
|
22
43
|
export default {
|
|
23
44
|
name: "GenericTable",
|
|
24
45
|
props: {
|
|
@@ -44,8 +65,8 @@ export default {
|
|
|
44
65
|
},
|
|
45
66
|
methods: {
|
|
46
67
|
sortChange(data) {
|
|
47
|
-
this.$emit(
|
|
48
|
-
}
|
|
49
|
-
}
|
|
68
|
+
this.$emit("sort:change", data);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
50
71
|
};
|
|
51
72
|
</script>
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<el-col v-if="column" :span="18" class="m-b-20">
|
|
3
|
-
<el-col v-if="column.type !== 'checkbox'" class="m-b-5 p-l-0">
|
|
4
|
-
<label>{{ column.label }}</label>
|
|
5
|
-
</el-col>
|
|
6
|
-
<el-input v-if="column.type==='string'" v-model="search.value" />
|
|
7
|
-
</el-col>
|
|
8
|
-
</template>
|
|
9
|
-
<script>
|
|
10
|
-
export default {
|
|
11
|
-
props: {
|
|
12
|
-
column: {
|
|
13
|
-
type: Object,
|
|
14
|
-
default() {
|
|
15
|
-
return {};
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
search: {
|
|
19
|
-
type: Object,
|
|
20
|
-
default() {
|
|
21
|
-
return {};
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
data() {
|
|
26
|
-
return {
|
|
27
|
-
loading: false,
|
|
28
|
-
selectKey: this.column.selectKey ?? 'key',
|
|
29
|
-
selectLabel: this.column.selectLabel ?? 'label',
|
|
30
|
-
selectValue: this.column.selectValue ?? 'key',
|
|
31
|
-
filterable: this.column.filterable ?? false,
|
|
32
|
-
remote: this.column.remote ?? false,
|
|
33
|
-
remoteMethod: this.column.remoteMethod ?? null,
|
|
34
|
-
selectListLocal: this.search.selectList ? this.search.selectList : (this.column.type === 'enum' ? this.column.values : this.boolValues),
|
|
35
|
-
};
|
|
36
|
-
},
|
|
37
|
-
computed: {
|
|
38
|
-
isMultiple() {
|
|
39
|
-
return this.column.is_multiple ? this.column.is_multiple : false;
|
|
40
|
-
},
|
|
41
|
-
remoteMethodHandler: {
|
|
42
|
-
get() {
|
|
43
|
-
if (this.remoteMethod !== null) {
|
|
44
|
-
return this.remoteCall;
|
|
45
|
-
}
|
|
46
|
-
return null;
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
watch: {
|
|
51
|
-
search() {
|
|
52
|
-
if (this.search.operator === '') {
|
|
53
|
-
this.showFilter = false;
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
mounted() {
|
|
58
|
-
if (this.column.operator) {
|
|
59
|
-
this.search.operator = this.column.operator;
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
methods: {
|
|
63
|
-
async remoteCall(query) {
|
|
64
|
-
this.loading = true;
|
|
65
|
-
const response = await this.remoteMethod.all({ search: this.selectLabel + ':' + query, searchFields: this.selectLabel + ':like' });
|
|
66
|
-
this.selectListLocal = response.data;
|
|
67
|
-
this.search['selectList'] = response.data;
|
|
68
|
-
this.loading = false;
|
|
69
|
-
},
|
|
70
|
-
updateSearch(key) {
|
|
71
|
-
if (key && this.remote) {
|
|
72
|
-
const obj = { [this.selectKey]: key };
|
|
73
|
-
for (const item of this.selectListLocal) {
|
|
74
|
-
if (item[this.selectKey] === key) {
|
|
75
|
-
obj[this.selectLabel] = item[this.selectLabel];
|
|
76
|
-
this.search.selectList = [obj];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
</script>
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<el-row>
|
|
3
|
-
<filter-top-row
|
|
4
|
-
v-for="column in filters"
|
|
5
|
-
:key="column.name"
|
|
6
|
-
:column="column"
|
|
7
|
-
:search="search[column.name]"
|
|
8
|
-
/>
|
|
9
|
-
<el-col :span="6" class="m-t-20">
|
|
10
|
-
<el-button @click="applyFilter">Filter</el-button>
|
|
11
|
-
<el-button @click="resetFilter">Reset filter</el-button>
|
|
12
|
-
</el-col>
|
|
13
|
-
</el-row>
|
|
14
|
-
</template>
|
|
15
|
-
|
|
16
|
-
<script>
|
|
17
|
-
import FilterConverter from "./filter-convertor.ts";
|
|
18
|
-
import FilterTopRow from "./FilterTopRow";
|
|
19
|
-
export default {
|
|
20
|
-
name: "GenericTopFilter",
|
|
21
|
-
props: {
|
|
22
|
-
filters: {
|
|
23
|
-
type: Array,
|
|
24
|
-
default: () => {
|
|
25
|
-
return {};
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
search: {
|
|
29
|
-
type: Object,
|
|
30
|
-
default: () => {
|
|
31
|
-
return {};
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
components: { FilterTopRow },
|
|
36
|
-
data() {
|
|
37
|
-
const filterConvertor = new FilterConverter();
|
|
38
|
-
return {
|
|
39
|
-
filterConvertor: filterConvertor,
|
|
40
|
-
};
|
|
41
|
-
},
|
|
42
|
-
methods: {
|
|
43
|
-
getFilter() {
|
|
44
|
-
return this.filterConvertor.applyFilter(this.search);
|
|
45
|
-
},
|
|
46
|
-
applyFilter() {
|
|
47
|
-
this.$emit("apply:filter", this.filterConvertor.applyFilter(this.search));
|
|
48
|
-
},
|
|
49
|
-
resetFilter() {
|
|
50
|
-
this.$emit("reset:filter", {});
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
</script>
|