@tripup-company/element-ui-extended 0.0.2 → 0.0.7

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 (39) hide show
  1. package/README.md +150 -0
  2. package/dist/element-ui-extended.common.js +859 -681
  3. package/dist/element-ui-extended.common.js.map +1 -1
  4. package/dist/element-ui-extended.umd.js +859 -681
  5. package/dist/element-ui-extended.umd.js.map +1 -1
  6. package/dist/element-ui-extended.umd.min.js +1 -1
  7. package/dist/element-ui-extended.umd.min.js.map +1 -1
  8. package/package.json +23 -4
  9. package/src/App.vue +31 -2
  10. package/src/components/CompositeTable/index.vue +219 -0
  11. package/src/components/{GenericTable → GenericFilters}/FilterRow.vue +9 -2
  12. package/src/components/{GenericTable → GenericFilters}/FilterTopRow.vue +1 -1
  13. package/src/components/{GenericTable → GenericFilters}/GenericTopFilter.vue +22 -9
  14. package/src/components/{GenericTable/GenericFilter.vue → GenericFilters/index.vue} +23 -9
  15. package/src/components/GenericPaginator/index.vue +53 -0
  16. package/src/components/GenericTable/index.vue +23 -153
  17. package/src/filters-top.js +8 -0
  18. package/src/filters.js +64 -0
  19. package/src/lang/en.js +167 -0
  20. package/src/lang/index.js +35 -0
  21. package/src/lang/vi.js +166 -0
  22. package/src/lang/zh.js +164 -0
  23. package/src/models/base-model.ts +10 -0
  24. package/src/models/contact-model.ts +23 -0
  25. package/src/models/meta-model.ts +13 -0
  26. package/src/services/list-query-service.ts +39 -0
  27. package/src/services/local-storage-service.ts +27 -0
  28. package/src/services/resolutions.js +21 -0
  29. package/src/test/unit/components/TestComponent.vue +15 -0
  30. package/src/types/article.js +6 -0
  31. package/src/types/article.js.map +1 -0
  32. package/src/types/axiosInterface.ts +54 -0
  33. package/src/types/collection.ts +6 -0
  34. package/src/types/error.ts +3 -0
  35. package/src/types/icontact.ts +17 -0
  36. package/src/types/meta.ts +7 -0
  37. package/src/types/pagination.ts +8 -0
  38. package/src/components/GenericTable/GenericPaginator.vue +0 -37
  39. package/src/components/GenericTable/GenericRows.vue +0 -27
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "@tripup-company/element-ui-extended",
3
- "version": "0.0.2",
3
+ "version": "0.0.7",
4
4
  "main": "./dist/element-ui-extended.umd.js",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
7
7
  "build": "vue-cli-service build",
8
8
  "lint": "vue-cli-service lint",
9
- "build-lib": "vue-cli-service build --target lib src/index.ts"
9
+ "build-lib": "vue-cli-service build --target lib src/index.ts",
10
+ "test": "mochapack --webpack-config webpack.test.config.js --require mock-local-storage --require ./src/test/setup.js ./src/test/unit/**/*.js"
10
11
  },
11
12
  "dependencies": {
13
+ "axios": "^0.24.0",
12
14
  "core-js": "^3.6.5",
15
+ "element-ui": "^2.15.6",
16
+ "mocha": "^9.1.4",
13
17
  "npe": "^1.2.0",
14
18
  "vue": "^2.6.11",
15
19
  "vue-class-component": "^7.2.3",
16
- "vue-property-decorator": "^9.1.2"
20
+ "vue-i18n": "^8.26.8",
21
+ "vue-property-decorator": "^9.1.2",
22
+ "vue-router": "^3.5.3"
17
23
  },
18
24
  "devDependencies": {
19
25
  "@typescript-eslint/eslint-plugin": "^4.18.0",
@@ -24,18 +30,31 @@
24
30
  "@vue/cli-service": "~4.5.0",
25
31
  "@vue/eslint-config-prettier": "^6.0.0",
26
32
  "@vue/eslint-config-typescript": "^7.0.0",
33
+ "@vue/test-utils": "^1.2.1",
27
34
  "eslint": "^6.7.2",
28
35
  "eslint-plugin-prettier": "^3.3.1",
29
36
  "eslint-plugin-vue": "^6.2.2",
37
+ "expect": "^27.0.6",
38
+ "jsdom": "^16.6.0",
39
+ "jsdom-global": "^3.0.2",
40
+ "mochapack": "^2.1.2",
41
+ "mock-local-storage": "^1.1.19",
30
42
  "prettier": "^2.2.1",
31
43
  "sass": "^1.26.5",
32
44
  "sass-loader": "^8.0.2",
33
45
  "typescript": "~4.1.5",
46
+ "vue-loader": "^15.9.5",
34
47
  "vue-template-compiler": "^2.6.11"
35
48
  },
36
49
  "files": [
37
50
  "dist/*",
38
- "src/**/*.vue"
51
+ "src/**/*.vue",
52
+ "src/services/*",
53
+ "src/models/*",
54
+ "src/lang/*",
55
+ "src/types/*",
56
+ "src/filters.js",
57
+ "src/filters-top.js"
39
58
  ],
40
59
  "description": "## Project setup ``` npm install ```",
41
60
  "repository": {
package/src/App.vue CHANGED
@@ -1,14 +1,43 @@
1
1
  <template>
2
2
  <div id="app">
3
+ <composite-table :fields="fields" :filters="filters" :filters-top="filtersTop" :repository="repository"></composite-table>
3
4
  <img alt="Vue logo" src="./assets/logo.png" />
4
-
5
5
  </div>
6
6
  </template>
7
7
 
8
8
  <script lang="ts">
9
9
  import { Component, Vue } from "vue-property-decorator";
10
+ import CompositeTable from "@/components/CompositeTable/index.vue";
11
+ import filters from "./filters";
12
+ import filtersTop from "./filters-top";
13
+ import repository from "./repositories/contacts-repository";
10
14
  @Component({
11
- components: {},
15
+ components: { CompositeTable },
16
+ data: function () {
17
+ let repo = new repository('', '/test', null);
18
+ return {
19
+ filters: filters,
20
+ filtersTop: filtersTop,
21
+ repository: repo,
22
+ fields: [
23
+ {
24
+ prop: 'full_name', label: 'Full Name',
25
+ formatter: row => {
26
+ return row.first_name + ' ' + row.last_name;
27
+ },
28
+ },
29
+ {
30
+ prop: 'email', label: 'Email',
31
+ },
32
+ {
33
+ prop: 'phone', label: 'Phone',
34
+ },
35
+ {
36
+ prop: 'created_at', label: 'Created at',
37
+ },
38
+ ],
39
+ }
40
+ }
12
41
  })
13
42
  export default class App extends Vue {}
14
43
  </script>
@@ -0,0 +1,219 @@
1
+ <template>
2
+ <div v-loading="loading" class="composite-table">
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
+ <el-row :gutter="20">
15
+ <el-col :span="18">
16
+ <slot name="table" v-bind="{ fields, data }">
17
+ <generic-table
18
+ :fields="fields"
19
+ :data="data"
20
+ @sort:change="handleChangeSort"
21
+ />
22
+ </slot>
23
+ <el-row>
24
+ <el-col>
25
+ <slot name="paginator" v-bind="{ total, limit, currentPage }">
26
+ <generic-paginator
27
+ :total="total"
28
+ :limit="limit"
29
+ :current-page="currentPage"
30
+ @size:change="handleSizeChange"
31
+ @page:change="handleCurrentChange"
32
+ />
33
+ </slot>
34
+ </el-col>
35
+ </el-row>
36
+ </el-col>
37
+ <el-col :span="6">
38
+ <slot name="filter" v-bind="{ filters, search }">
39
+ <generic-filter
40
+ v-if="filters.length"
41
+ :filters="filters"
42
+ :search="search"
43
+ @apply:filter="handleApplyFilter"
44
+ @reset:filter="handleResetFilter"
45
+ />
46
+ </slot>
47
+ </el-col>
48
+ </el-row>
49
+ </slot>
50
+ </div>
51
+ </template>
52
+
53
+ <script>
54
+ import Vue from "vue";
55
+ import GenericFilter from "../GenericFilters/index";
56
+ import GenericPaginator from "../GenericPaginator";
57
+ import GenericTable from "@/components/GenericTable";
58
+ import ListQueryService from "@/services/list-query-service";
59
+ import { LocalStorageService } from "@/services/local-storage-service";
60
+ import MetaModel from "@/models/meta-model";
61
+ import GenericTopFilter from "@/components/GenericFilters/GenericTopFilter";
62
+ export default {
63
+ components: {
64
+ GenericTopFilter,
65
+ GenericFilter,
66
+ GenericTable,
67
+ GenericPaginator,
68
+ },
69
+ name: "CompositeTable",
70
+ props: {
71
+ repository: {
72
+ default() {
73
+ return {};
74
+ },
75
+ type: Object,
76
+ },
77
+ title: {
78
+ default: "",
79
+ type: String,
80
+ },
81
+ fields: {
82
+ default: () => [],
83
+ type: Array,
84
+ },
85
+ filtersTop: {
86
+ default: () => [],
87
+ type: Array,
88
+ },
89
+ filters: {
90
+ default: () => [],
91
+ type: Array,
92
+ },
93
+ },
94
+ data: function () {
95
+ const localStorage = new LocalStorageService();
96
+ const listQueryService = new ListQueryService(
97
+ this.$route ? this.$route.name : "storage.key",
98
+ localStorage
99
+ );
100
+ let search = {};
101
+ for (const column of this.filters) {
102
+ search[column.name] = {
103
+ operator: "",
104
+ value: "",
105
+ };
106
+ }
107
+ for (const column of this.filtersTop) {
108
+ search[column.name] = {
109
+ position: "top",
110
+ value: "",
111
+ };
112
+ }
113
+ search = Object.assign(search, listQueryService.getListQuery().search);
114
+ return {
115
+ loading: false,
116
+ filter: {},
117
+ data: [],
118
+ search: search,
119
+ meta: Object.assign(
120
+ new MetaModel(),
121
+ listQueryService.getListQuery().meta
122
+ ),
123
+ listQueryService: listQueryService,
124
+ };
125
+ },
126
+ computed: {
127
+ currentPage() {
128
+ if (this.data.meta?.pagination) {
129
+ return this.data.meta.pagination.current_page;
130
+ }
131
+ return 0;
132
+ },
133
+ total() {
134
+ if (this.data.meta?.pagination) {
135
+ return this.data.meta.pagination.total;
136
+ }
137
+ return 0;
138
+ },
139
+ limit() {
140
+ if (this.data.meta?.pagination) {
141
+ return this.data.meta.pagination.per_page;
142
+ }
143
+ if (this.listQueryService.getListQuery().meta?.limit) {
144
+ return this.listQueryService.getListQuery().meta?.limit;
145
+ }
146
+ return 10;
147
+ },
148
+ },
149
+ mounted() {
150
+ this.fetch();
151
+ },
152
+ methods: {
153
+ async fetch() {
154
+ this.loading = true;
155
+ try {
156
+ const response = await this.repository.all(
157
+ this.listQueryService.getListQuery()
158
+ );
159
+ this.data = response.data;
160
+ Vue.set(this.data, "meta", response.meta);
161
+ } catch (e) {
162
+ this.$message.error(e.message);
163
+ }
164
+ this.loading = false;
165
+ },
166
+ handleChangeSort(val) {
167
+ this.listQueryService.updateSort(val);
168
+ this.fetch();
169
+ },
170
+ handleSizeChange(val) {
171
+ this.listQueryService.updateListQuery({
172
+ meta: {
173
+ limit: val,
174
+ page: this.listQueryService.getListQuery().meta.page,
175
+ },
176
+ });
177
+ this.meta.pagination.per_page = val;
178
+ this.fetch();
179
+ },
180
+ handleCurrentChange(val) {
181
+ this.listQueryService.updateListQuery({
182
+ meta: {
183
+ page: val,
184
+ limit: this.listQueryService.getListQuery().meta.limit,
185
+ },
186
+ });
187
+ this.meta.pagination.current_page = val;
188
+ this.fetch();
189
+ },
190
+ handleFilterChange(val) {
191
+ this.filter = val;
192
+ this.meta.pagination.current_page = 1;
193
+ this.fetch();
194
+ },
195
+ handleApplyFilter(filters) {
196
+ this.listQueryService.updateListQuery({ search: this.search });
197
+ this.handleFilterChange(filters);
198
+ },
199
+ handleResetFilter() {
200
+ for (const column in this.search) {
201
+ if (this.search[column].position === "top") {
202
+ this.search[column] = Object.assign(this.search[column], {
203
+ value: "",
204
+ });
205
+ } else {
206
+ this.search[column] = Object.assign(this.search[column], {
207
+ operator: "",
208
+ value: "",
209
+ });
210
+ }
211
+ }
212
+ this.listQueryService.updateListQuery({ search: {} });
213
+ this.handleFilterChange({});
214
+ },
215
+ },
216
+ };
217
+ </script>
218
+
219
+ <style scoped></style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-row v-if="column.position !== 'top'" class="m-b-10">
2
+ <el-row class="m-b-10">
3
3
  <el-row>
4
4
  <el-col :lg="4" :md="4" :sm="4" :xs="4">
5
5
  <el-checkbox v-model="showFilter"><span>{{ column.label }}</span></el-checkbox>
@@ -20,8 +20,10 @@
20
20
  </el-row>
21
21
  </el-row>
22
22
  </template>
23
+
23
24
  <script>
24
25
  export default {
26
+ name: "FilterRow",
25
27
  props: {
26
28
  column: {
27
29
  type: Object,
@@ -60,6 +62,7 @@ export default {
60
62
  ],
61
63
  enumOperators: [
62
64
  { 'value': 'equal', 'label': 'is' },
65
+ { 'value': 'in', 'label': 'in' },
63
66
  ],
64
67
  boolValues: {
65
68
  null: 'empty',
@@ -93,5 +96,9 @@ export default {
93
96
  return disable;
94
97
  },
95
98
  },
96
- };
99
+ }
97
100
  </script>
101
+
102
+ <style scoped>
103
+
104
+ </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-col v-if="column.position === 'top'" :span="18" class="m-b-20">
2
+ <el-col v-if="column" :span="18" class="m-b-20">
3
3
  <el-col v-if="column.type !== 'checkbox'" class="m-b-5 p-l-0">
4
4
  <label>{{ column.label }}</label>
5
5
  </el-col>
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <div>
2
+ <el-row>
3
3
  <filter-top-row
4
- v-for="(column) in data.filters"
4
+ v-for="column in filters"
5
5
  :key="column.name"
6
6
  :column="column"
7
7
  :search="search[column.name]"
@@ -10,16 +10,29 @@
10
10
  <el-button @click="applyFilter">Filter</el-button>
11
11
  <el-button @click="resetFilter">Reset filter</el-button>
12
12
  </el-col>
13
- </div>
13
+ </el-row>
14
14
  </template>
15
15
 
16
16
  <script>
17
- import FilterTopRow from './FilterTopRow';
18
- import FilterConverter from './filter-convertor.ts';
17
+ import FilterConverter from "./filter-convertor.ts";
18
+ import FilterTopRow from "./FilterTopRow";
19
19
  export default {
20
- name: 'GenericTopFilter',
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
+ },
21
35
  components: { FilterTopRow },
22
- inject: ['data', 'actions', 'search'],
23
36
  data() {
24
37
  const filterConvertor = new FilterConverter();
25
38
  return {
@@ -31,10 +44,10 @@ export default {
31
44
  return this.filterConvertor.applyFilter(this.search);
32
45
  },
33
46
  applyFilter() {
34
- this.actions.handleApplyFilter();
47
+ this.$emit("apply:filter", this.filterConvertor.applyFilter(this.search));
35
48
  },
36
49
  resetFilter() {
37
- this.actions.handleResetFilter();
50
+ this.$emit("reset:filter", {});
38
51
  },
39
52
  },
40
53
  };
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <el-card>
3
3
  <filter-row
4
- v-for="(column) in data.filters"
4
+ v-for="(column) in filters"
5
5
  :key="column.name"
6
6
  :column="column"
7
7
  :search="search[column.name]"
@@ -12,12 +12,22 @@
12
12
  </template>
13
13
 
14
14
  <script>
15
- import FilterRow from './FilterRow';
16
- import FilterConverter from './filter-convertor.ts';
15
+ import FilterRow from "./FilterRow";
16
+ import FilterConverter from "./filter-convertor";
17
+
17
18
  export default {
18
- name: 'GenericFilter',
19
+ name: "GenericFilter",
20
+ props: {
21
+ filters: {
22
+ type: Array,
23
+ default: () => { return {}}
24
+ },
25
+ search: {
26
+ type: Object,
27
+ default: () => { return {}}
28
+ },
29
+ },
19
30
  components: { FilterRow },
20
- inject: ['data', 'actions', 'search'],
21
31
  data() {
22
32
  const filterConvertor = new FilterConverter();
23
33
  return {
@@ -29,11 +39,15 @@ export default {
29
39
  return this.filterConvertor.applyFilter(this.search);
30
40
  },
31
41
  applyFilter() {
32
- this.actions.handleApplyFilter();
42
+ this.$emit('apply:filter', this.filterConvertor.applyFilter(this.search) );
33
43
  },
34
44
  resetFilter() {
35
- this.actions.handleResetFilter();
45
+ this.$emit('reset:filter', {});
36
46
  },
37
- },
38
- };
47
+ }
48
+ }
39
49
  </script>
50
+
51
+ <style scoped>
52
+
53
+ </style>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <div class="m-t-15">
3
+ <el-pagination
4
+ :total="total"
5
+ :current-page="currentPage"
6
+ :page-size="limit"
7
+ :layout="'total, sizes, prev, pager, next, jumper'"
8
+ @size-change="sizeChange"
9
+ @current-change="pageChange"
10
+ />
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ export default {
16
+ name: "GeneticPaginator",
17
+ props: {
18
+ limit: {
19
+ type: Number,
20
+ default () {
21
+ return 0;
22
+ },
23
+ },
24
+ currentPage: {
25
+ type: Number,
26
+ default () {
27
+ return 0;
28
+ },
29
+ },
30
+ total: {
31
+ type: Number,
32
+ default () {
33
+ return 0;
34
+ },
35
+ },
36
+ pageSizes: {
37
+ type: Array,
38
+ default() {
39
+ return [10, 15, 20, 30, 50];
40
+ },
41
+ },
42
+ },
43
+ methods: {
44
+ pageChange (val) {
45
+ debugger;
46
+ this.$emit('page:change', val);
47
+ },
48
+ sizeChange(val) {
49
+ this.$emit('size:change', val);
50
+ },
51
+ }
52
+ }
53
+ </script>