spark-grid-vue3 0.0.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.
Files changed (45) hide show
  1. package/README.md +30 -0
  2. package/index.html +11 -0
  3. package/jsconfig.json +8 -0
  4. package/package.json +32 -0
  5. package/playground/App.vue +35 -0
  6. package/playground/index.html +13 -0
  7. package/playground/main.ts +17 -0
  8. package/playground/vite.config.ts +23 -0
  9. package/public/favicon.ico +0 -0
  10. package/src/SparkGrid.vue +3 -0
  11. package/src/assets/DataTable.html +9 -0
  12. package/src/assets/DataTable.scss +255 -0
  13. package/src/assets/DataTable.ts +78 -0
  14. package/src/components/GridAction.vue +63 -0
  15. package/src/components/GridBody.vue +31 -0
  16. package/src/components/GridCheckbox.vue +29 -0
  17. package/src/components/GridContentWrapper.vue +44 -0
  18. package/src/components/GridFooter.vue +96 -0
  19. package/src/components/GridHeader.vue +71 -0
  20. package/src/components/GridHeaderCheckbox.vue +41 -0
  21. package/src/components/GridRadioButton.vue +31 -0
  22. package/src/components/GridRow.vue +176 -0
  23. package/src/components/GridSearchField.vue +153 -0
  24. package/src/components/GridSearchRow.vue +45 -0
  25. package/src/components/GridSummarizer.vue +27 -0
  26. package/src/components/RuntimeRenderer.vue +26 -0
  27. package/src/definition/enums.ts +16 -0
  28. package/src/definition/install.d.ts +11 -0
  29. package/src/definition/types.d.ts +160 -0
  30. package/src/index.ts +11 -0
  31. package/src/main.ts +10 -0
  32. package/src/types.d.ts +5 -0
  33. package/src/utils/CellValueGetter.ts +21 -0
  34. package/src/utils/CheckboxSelectedMapper.ts +11 -0
  35. package/src/utils/Conditionals.ts +9 -0
  36. package/src/utils/DataFetcher.ts +39 -0
  37. package/src/utils/EventEmitter.ts +31 -0
  38. package/src/utils/EventHandler.ts +140 -0
  39. package/src/utils/GridStyler.ts +90 -0
  40. package/src/utils/RadioButtonSelectedMapper.ts +17 -0
  41. package/src/utils/UrlBuilder.ts +38 -0
  42. package/src/utils/UuidMapper.ts +13 -0
  43. package/tsconfig.json +19 -0
  44. package/vite.config.js +16 -0
  45. package/vite.config.ts +29 -0
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # fetch-data-table
2
+
3
+ This template should help get you started developing with Vue 3 in Vite.
4
+
5
+ ## Recommended IDE Setup
6
+
7
+ [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
8
+
9
+ ## Customize configuration
10
+
11
+ See [Vite Configuration Reference](https://vitejs.dev/config/).
12
+
13
+ ## Project Setup
14
+
15
+ ```sh
16
+ npm install
17
+ ```
18
+
19
+ ### Compile and Hot-Reload for Development
20
+
21
+ ```sh
22
+ npm run dev
23
+ ```
24
+
25
+ ### Compile and Minify for Production
26
+
27
+ ```sh
28
+ npm run build
29
+ ```
30
+ # spark-grid-vue
package/index.html ADDED
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8"/>
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
7
+ <title>Spark Grid - Vue3</title>
8
+ </head>
9
+ <body>
10
+ </body>
11
+ </html>
package/jsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "compilerOptions": {
3
+ "paths": {
4
+ "@/*": ["./src/*"]
5
+ }
6
+ },
7
+ "exclude": ["node_modules", "dist"]
8
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "spark-grid-vue3",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "author": "",
7
+ "license": "ISC",
8
+ "dependencies": {
9
+ "vue": "^3.4.37"
10
+ },
11
+ "scripts": {
12
+ "build": "vite build",
13
+ "playground": "vite --config playground/vite.config.ts"
14
+ },
15
+ "devDependencies": {
16
+ "@vitejs/plugin-vue": "^5.1.4",
17
+ "@vue/compiler-sfc": "^3.5.10",
18
+ "mitt": "^3.0.1",
19
+ "rollup-plugin-typescript2": "^0.36.0",
20
+ "sass": "^1.79.4",
21
+ "sass-embedded": "^1.79.4",
22
+ "typescript": "^5.6.2",
23
+ "vite": "^5.4.8"
24
+ },
25
+ "peerDependencies": {
26
+ "@imengyu/vue3-context-menu": "^1.4.2",
27
+ "axios": "^1.7.7",
28
+ "get-value": "^3.0.1",
29
+ "lodash": "^4.17.21",
30
+ "uuid": "^10.0.0"
31
+ }
32
+ }
@@ -0,0 +1,35 @@
1
+ <template>
2
+ <DynaGrid
3
+ :config="grid"
4
+ />
5
+ </template>
6
+
7
+ <style scoped>
8
+ #app {
9
+ padding: 20px;
10
+ }
11
+ </style>
12
+
13
+ <script lang="ts">
14
+ import {Component} from "@vue/runtime-core";
15
+ import type {SparkGridConfig} from "../src/definition/types";
16
+
17
+ export default {
18
+ computed: {
19
+ grid(): SparkGridConfig {
20
+ return {
21
+ datasource: (params: any) => {
22
+ return [
23
+ {id: 1, name: "John Doe"},
24
+ ]
25
+ },
26
+
27
+ columns: [
28
+ {name: "id", label: "ID"}
29
+ ]
30
+ }
31
+ }
32
+ }
33
+ } as Component
34
+ </script>
35
+
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8"/>
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
7
+ <title>Dyna Grid Playground</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="./main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,17 @@
1
+ import {createApp} from 'vue';
2
+ import App from './App.vue';
3
+ import {DataTable} from '../src/index';
4
+ import mitt from "mitt";
5
+
6
+ const app = createApp(App);
7
+ const emitter = mitt()
8
+
9
+ app.use(DataTable, {
10
+ eventProxy: {
11
+ emit: emitter.emit,
12
+ on: emitter.on,
13
+ off: emitter.off,
14
+ }
15
+ })
16
+
17
+ app.mount('#app');
@@ -0,0 +1,23 @@
1
+ import {defineConfig} from 'vite';
2
+ import vue from '@vitejs/plugin-vue';
3
+ import path from 'path';
4
+
5
+ export default defineConfig({
6
+ root: path.resolve(__dirname), // Set the playground folder as the root
7
+ plugins: [vue()],
8
+ resolve: {
9
+ alias: {
10
+ // Alias to your plugin's src directory
11
+ '@': path.resolve(__dirname, '../src')
12
+ }
13
+ },
14
+ server: {
15
+ open: true, // Automatically open the browser
16
+ port: 3000 // Port for the playground server
17
+ },
18
+ build: {
19
+ rollupOptions: {
20
+ input: path.resolve(__dirname, 'index.html') // Specify the HTML entry
21
+ }
22
+ }
23
+ });
Binary file
@@ -0,0 +1,3 @@
1
+ <template src="./assets/DataTable.html"/>
2
+ <script lang="ts" src="./assets/DataTable.ts"/>
3
+ <style src="./assets/DataTable.scss" lang="scss"/>
@@ -0,0 +1,9 @@
1
+ <GridContentWrapper :grid="grid">
2
+ <div v-loading="grid.loading">
3
+ <GridHeader :grid="grid"/>
4
+ <GridSearchRow :grid="grid" v-if="config.searchEnabled !== false"/>
5
+ <GridBody :grid="grid"/>
6
+ <GridSummarizer v-if="config.footerSummarizerEnabled" :grid="grid"/>
7
+ <GridFooter v-if="config.footerVisible ?? true" :grid="grid"/>
8
+ </div>
9
+ </GridContentWrapper>
@@ -0,0 +1,255 @@
1
+ .context-menu-open {
2
+ background-color: #e4ebff !important;
3
+ }
4
+
5
+ .grid-wrapper {
6
+ border-right: 1px solid #ddd;
7
+ border-left: 1px solid #ddd;
8
+ }
9
+
10
+ .grid-body > .grid-row:nth-of-type(odd) {
11
+ background-color: rgb(240 240 240);
12
+ }
13
+
14
+ .grid-body {
15
+ z-index: 0;
16
+ position: relative;
17
+
18
+ .grid-row:last-child .grid-cell {
19
+ border-bottom: 1px solid #ddd;
20
+ }
21
+ }
22
+
23
+ .grid-row-focused .grid-cell {
24
+ background: rgb(232, 245, 233) !important;
25
+ }
26
+
27
+ .grid-row-checked .grid-cell {
28
+ background: rgb(232, 238, 245) !important;
29
+ }
30
+
31
+ .grid-cell-focused {
32
+ border: 1px solid black !important;
33
+ }
34
+
35
+ .grid-cell {
36
+ border: 1px solid transparent;
37
+ border-top: 1px solid #ddd;
38
+ border-left: 1px solid #ddd;
39
+ border-collapse: collapse;
40
+ position: relative;
41
+ display: flex;
42
+ align-items: center;
43
+ overflow-wrap: break-word;
44
+ word-break: break-word;
45
+ font-size: 12px;
46
+
47
+ &.grid-cell-center-alignment {
48
+ justify-content: center;
49
+ }
50
+
51
+ &.grid-cell-left-alignment {
52
+ justify-content: start;
53
+ }
54
+
55
+ &.grid-cell-right-alignment {
56
+ justify-content: end;
57
+ }
58
+
59
+ &:first-child {
60
+ border-left: 1px solid transparent;
61
+ }
62
+
63
+ &:last-child {
64
+ border-right: 1px solid #ddd;
65
+ }
66
+ }
67
+
68
+ .grid-cell .cell-has-comment {
69
+ width: 0;
70
+ height: 0;
71
+ border-left: 10px solid transparent;
72
+ border-right: 10px solid transparent;
73
+ border-top: 10px solid #36585e;
74
+ top: -1px;
75
+ position: absolute;
76
+ right: -7px;
77
+ transform: rotate(225deg);
78
+ }
79
+
80
+ .grid-footer {
81
+ display: flex;
82
+ flex-direction: row;
83
+ align-items: center;
84
+ padding: 5px 10px;
85
+ border-bottom: 1px solid #ddd;
86
+ border-top: 1px solid #ddd;
87
+ background: #f2f2f2;
88
+ font-size: 12px;
89
+
90
+ & > * {
91
+ flex: 1;
92
+ }
93
+
94
+ ul {
95
+ display: inline-block;
96
+ padding: 0px;
97
+ margin: 0px;
98
+ list-style: none;
99
+
100
+ li {
101
+ display: inline-block;
102
+
103
+ & > button {
104
+ padding: 5px;
105
+ min-width: 30px;
106
+ margin-left: 2px;
107
+ text-align: center;
108
+ text-decoration: none;
109
+ background: transparent;
110
+ cursor: pointer;
111
+ color: #333;
112
+ border: 1px solid transparent;
113
+ border-radius: 3px;
114
+ }
115
+
116
+ & > button[disabled] {
117
+ color: #ccc;
118
+ cursor: default;
119
+ }
120
+
121
+ &.current > button {
122
+ color: #fff;
123
+ background-color: #455a64;
124
+ cursor: default;
125
+ }
126
+ }
127
+
128
+ li:not(.current):hover > button:not([disabled]) {
129
+ background-color: #f5f5f5;
130
+ }
131
+ }
132
+ }
133
+
134
+ .grid-search-row {
135
+ z-index: 0;
136
+ }
137
+
138
+ .grid-search-row .grid-search-row-cell {
139
+ background: white;
140
+ border: 1px solid transparent;
141
+ border-top: 1px solid #ddd;
142
+ border-left: 1px solid #ddd;
143
+ border-collapse: collapse;
144
+ padding: 10px;
145
+
146
+ input, select {
147
+ z-index: 0 !important;
148
+ }
149
+
150
+ &:first-child {
151
+ border-left: 1px solid transparent;
152
+ }
153
+
154
+ &:last-child {
155
+ border-right: 1px solid #ddd;
156
+ }
157
+ }
158
+
159
+ .grid-search-row .has-feedback.has-feedback-left > .el-input input {
160
+ padding-left: 33px;
161
+ padding-right: 0 !important;
162
+ }
163
+
164
+ .input-wrapper {
165
+ position: relative;
166
+ }
167
+
168
+ .clear-input {
169
+ cursor: pointer;
170
+ }
171
+
172
+ .grid-header-cell {
173
+ border-top: 1px solid #ddd;
174
+ border-left: 1px solid #ddd;
175
+ border-collapse: collapse;
176
+ position: relative;
177
+ display: flex;
178
+ align-items: center;
179
+ background: #eeeeee;
180
+ font-weight: 600;
181
+ border-bottom: 1px solid #bbb;
182
+ font-size: 12px;
183
+ padding: 8px 10px;
184
+
185
+ &.grid-header-order {
186
+ cursor: pointer;
187
+
188
+ &:hover {
189
+ background: #e3e3e3;
190
+ }
191
+ }
192
+
193
+ &.grid-cell-center-alignment {
194
+ justify-content: center;
195
+ }
196
+
197
+ &.grid-cell-left-alignment {
198
+ justify-content: start;
199
+ }
200
+
201
+ &.grid-cell-right-alignment {
202
+ justify-content: end;
203
+ }
204
+
205
+ &:first-child {
206
+ border-left: none;
207
+ }
208
+
209
+ &:last-child {
210
+ border-right: 1px solid #ddd;
211
+ }
212
+ }
213
+
214
+ .grid-summarizer-cell {
215
+ border-top: 1px solid #ddd;
216
+ border-left: 1px solid #ddd;
217
+ border-collapse: collapse;
218
+ display: flex;
219
+ align-items: center;
220
+ background: #ededed;
221
+ font-weight: 600;
222
+ border-bottom: 1px solid #bbb;
223
+
224
+ &.grid-cell-center-alignment {
225
+ justify-content: center;
226
+ }
227
+
228
+ &.grid-cell-left-alignment {
229
+ justify-content: start;
230
+ }
231
+
232
+ &.grid-cell-right-alignment {
233
+ justify-content: end;
234
+ }
235
+
236
+ &:first-child {
237
+ border-left: none;
238
+ }
239
+
240
+ &:last-child {
241
+ border-right: 1px solid #ddd;
242
+ }
243
+ }
244
+
245
+ .grid-header-sticky {
246
+ position: sticky;
247
+ top: 0;
248
+ z-index: 200;
249
+ }
250
+
251
+ .grid-summarizer-sticky {
252
+ position: sticky;
253
+ bottom: 0;
254
+ z-index: 200;
255
+ }
@@ -0,0 +1,78 @@
1
+ import GridSearchRow from "../components/GridSearchRow.vue"
2
+ import GridFooter from "../components/GridFooter.vue"
3
+ import GridHeader from "../components/GridHeader.vue"
4
+ import GridBody from "../components/GridBody.vue"
5
+ import GridContentWrapper from "../components/GridContentWrapper.vue"
6
+ import GridSummarizer from "../components/GridSummarizer.vue"
7
+ import type {Component} from "@vue/runtime-core"
8
+ import type {SparkGridConfig, Props} from "../definition/types"
9
+ import {DataFetcher} from "../utils/DataFetcher"
10
+ import {EventHandler} from "../utils/EventHandler"
11
+ // @ts-ignore
12
+ import {v4 as uuidV4} from "uuid"
13
+
14
+ export default {
15
+ emits: ['mounted'],
16
+ props: ['config'],
17
+ name: "SparkGrid",
18
+
19
+ components: {
20
+ GridFooter,
21
+ GridSearchRow,
22
+ GridSummarizer,
23
+ GridContentWrapper,
24
+ GridHeader,
25
+ GridBody,
26
+ },
27
+
28
+ data(): object {
29
+ return {
30
+ uuid: uuidV4(),
31
+ orderBy: null,
32
+ filters: {},
33
+ loading: false,
34
+ currentPage: 1,
35
+ totalRows: 0,
36
+ rows: [],
37
+ focusedCell: null,
38
+ rowsPerPage: 10,
39
+ }
40
+ },
41
+
42
+ methods: {
43
+ fetch: DataFetcher.fetch,
44
+ refresh: EventHandler.refresh,
45
+ setRows: EventHandler.setRows,
46
+ getRows: EventHandler.getRows,
47
+ getCheckedRows: EventHandler.getCheckedRows,
48
+ clearCheckedRows: EventHandler.clearCheckedRows,
49
+ getColumns: EventHandler.getColumns,
50
+ setFilter: EventHandler.setFilter,
51
+ setFilters: EventHandler.setFilters,
52
+ applyFilter: EventHandler.applyFilter,
53
+ applyOrderBy: EventHandler.applyOrderBy,
54
+ paginate: EventHandler.paginate,
55
+ getSummarizedValue: EventHandler.getSummarizedValue,
56
+ getSelectedRadioRow: EventHandler.getSelectedRadioRow,
57
+ setSelectedRadioRow: EventHandler.setSelectedRadioRow,
58
+ clearRadioRowSelection: EventHandler.clearRadioRowSelection,
59
+ },
60
+
61
+ computed: {
62
+ grid(): Component<Props> {
63
+ return this
64
+ }
65
+ },
66
+
67
+ mounted() {
68
+ this.$emit('mounted', this)
69
+
70
+ const config: SparkGridConfig = this.config
71
+
72
+ if (config.sendRequestOnMounted !== false) {
73
+ this.refresh()
74
+ }
75
+
76
+ this.rowsPerPage = config.rowsPerPage ?? this.rowsPerPage
77
+ }
78
+ } as Component<Props>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <td :style='width' class="text-center">
3
+ <span v-for="(action, i) in actions">
4
+ <button
5
+ :disabled="disabled"
6
+ type="button"
7
+ :key="i"
8
+ :title="action.title || ''"
9
+ v-show="shouldShow(action, row)"
10
+ @click="action.action(Object.assign({}, row))"
11
+ :class="getButtonClasses(action)">
12
+ <b v-if="action.buttonType === 'labeled'"><i :class="action.icon"></i></b>
13
+ <i :class="action.icon" v-else></i>
14
+
15
+ {{ action.buttonLabel || "" }}
16
+ </button>
17
+ </span>
18
+ </td>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ name: "grid-action",
24
+
25
+ props: {
26
+ actions: {
27
+ type : Array,
28
+ required: true
29
+ },
30
+
31
+ row: {
32
+ type : Object,
33
+ required: true
34
+ },
35
+
36
+ width: {
37
+ type : String,
38
+ required: true
39
+ },
40
+
41
+ disabled: {
42
+ type : Boolean,
43
+ required: false,
44
+ default : false
45
+ }
46
+ },
47
+
48
+ methods: {
49
+ shouldShow(action, row) {
50
+ if (typeof action.showWhen === "function") {
51
+ return action.showWhen(row);
52
+ }
53
+
54
+ return true;
55
+ },
56
+
57
+ getButtonClasses(action) {
58
+ const btnClasses = action.buttonType === "labeled" ? "btn-labeled" : "btn-xs btn-icon btn-flat action-icon";
59
+ return `btn btn-sm ${action.class} ${btnClasses}`;
60
+ }
61
+ }
62
+ };
63
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div class="grid-body">
3
+ <div class="empty-grid-placeholder" v-show="rows.length == 0">
4
+ Nenhum registro encontrado.
5
+ </div>
6
+
7
+ <GridRow v-for="row in rows" :row="row" :grid="grid" :key="row._uuid"/>
8
+ </div>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import GridRow from "./GridRow.vue"
13
+ import type {GridComponent} from "../definition/types"
14
+ import {computed} from "vue"
15
+
16
+ const props = defineProps<{
17
+ grid: GridComponent
18
+ }>()
19
+
20
+ const rows = computed(() => props.grid.getRows())
21
+ </script>
22
+
23
+ <style scoped lang="scss">
24
+ .empty-grid-placeholder {
25
+ width: 100%;
26
+ padding: 50px 0;
27
+ text-align: center;
28
+ border-top: 1px solid #ddd;
29
+ background: #fdfdfd;
30
+ }
31
+ </style>
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <div class="grid-cell" :style="GridStyler.getCheckboxColumnStyles()">
3
+ <div class="checker">
4
+ <span :class="{'checked': row._isChecked}">
5
+ <input
6
+ type="checkbox"
7
+ :name="row._uuid"
8
+ :disabled="disabled"
9
+ @input="emits('change', $event.target.value)"
10
+ class="styled"
11
+ :value="row._isChecked"
12
+ :checked="row._isChecked"
13
+ />
14
+ </span>
15
+ </div>
16
+ </div>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import {GridStyler} from "../utils/GridStyler"
21
+ import type {Row} from "../definition/types"
22
+
23
+ const props = defineProps<{
24
+ row: Row,
25
+ disabled?: boolean
26
+ }>()
27
+
28
+ const emits = defineEmits(['change'])
29
+ </script>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div class="grid-wrapper" :style="styles" :class="classes">
3
+ <slot></slot>
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import type {GridComponent} from "../definition/types"
9
+ import {computed} from "vue"
10
+
11
+ const props = defineProps<{ grid: GridComponent }>()
12
+
13
+ const classes = computed(() => {
14
+ let classes = []
15
+
16
+ if (props.grid.config.stickyHeaderEnabled) {
17
+ classes.push("grid-sticky-header")
18
+ }
19
+
20
+ return classes.join(" ")
21
+ })
22
+
23
+ const styles = computed(() => {
24
+ let styles: any = {
25
+ background: '#fafafa'
26
+ }
27
+
28
+ if (props.grid.config.overflowEnabled) {
29
+ styles['overflow-x'] = 'auto'
30
+ styles['max-height'] = `${props.grid.config.height ?? window.innerHeight}px`
31
+ styles['min-height'] = `${props.grid.config.height ?? window.innerHeight}px`
32
+
33
+ if (props.grid.config.stickyHeaderEnabled) {
34
+ styles['position'] = 'relative'
35
+ }
36
+ }
37
+
38
+ return styles
39
+ })
40
+ </script>
41
+
42
+ <style>
43
+
44
+ </style>