@afeefa/vue-app 0.0.220 → 0.0.222

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.
@@ -1 +1 @@
1
- 0.0.220
1
+ 0.0.222
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.220",
3
+ "version": "0.0.222",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
@@ -17,6 +17,7 @@ import RemoveDialog from './form/RemoveDialog'
17
17
  import HSeparator from './HSeparator'
18
18
  import ListCard from './list/ListCard'
19
19
  import ListColumnHeader from './list/ListColumnHeader'
20
+ import ListColumnSelector from './list/ListColumnSelector'
20
21
  import ListContent from './list/ListContent'
21
22
  import ListMeta from './list/ListMeta'
22
23
  import ListTitle from './list/ListTitle'
@@ -35,6 +36,7 @@ Vue.component('ListContent', ListContent)
35
36
  Vue.component('ListMeta', ListMeta)
36
37
  Vue.component('ListTitle', ListTitle)
37
38
  Vue.component('ListView', ListView)
39
+ Vue.component('ListColumnSelector', ListColumnSelector)
38
40
 
39
41
  Vue.component('EditPage', EditPage)
40
42
  Vue.component('EditFormButtons', EditFormButtons)
@@ -0,0 +1,58 @@
1
+ <template>
2
+ <div>
3
+ <a-context-menu>
4
+ <template #activator>
5
+ <div class="contextButton">
6
+ {{ selectedColumns.length }}/{{ Object.keys(columns).length }}
7
+ </div>
8
+ </template>
9
+
10
+ <a-checkbox-group
11
+ v-model="selectedColumns"
12
+ :options="options"
13
+ vertical
14
+ v-on="$listeners"
15
+ @input="columnSelected"
16
+ />
17
+ </a-context-menu>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ import { Component, Vue } from '@a-vue'
23
+
24
+ @Component({
25
+ props: ['columns']
26
+ })
27
+ export default class ListColumnSelector extends Vue {
28
+ selectedColumns = []
29
+
30
+ created () {
31
+ this.selectedColumns = Object.keys(this.columns)
32
+ .filter(k => this.columns[k].visible)
33
+ }
34
+
35
+ get options () {
36
+ return Object.keys(this.columns).map(k => {
37
+ return {
38
+ itemText: this.columns[k].title,
39
+ itemValue: k
40
+ }
41
+ })
42
+ }
43
+
44
+ columnSelected () {
45
+ for (const key in this.columns) {
46
+ this.columns[key].visible = this.selectedColumns.includes(key)
47
+ }
48
+ }
49
+ }
50
+ </script>
51
+
52
+
53
+ <style lang="scss" scoped>
54
+ .contextButton {
55
+ font-size: .7rem;
56
+ cursor: pointer;
57
+ }
58
+ </style>
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <div class="listView">
2
+ <div
3
+ class="listView"
4
+ @mousedown="startShifting"
5
+ >
3
6
  <div
4
7
  v-if="$has.filters"
5
8
  class="filters"
@@ -29,7 +32,9 @@
29
32
  <div class="a-table-wrapper">
30
33
  <a-table>
31
34
  <a-table-header>
32
- <div v-if="$has.icon" />
35
+ <div v-if="$has.icon">
36
+ <slot name="header-icon" />
37
+ </div>
33
38
 
34
39
  <slot name="header-table" />
35
40
  </a-table-header>
@@ -99,7 +104,7 @@
99
104
 
100
105
  <div
101
106
  v-if="$has.filters"
102
- class="filters"
107
+ class="filters filters-below"
103
108
  >
104
109
  <slot
105
110
  name="filters-below"
@@ -122,6 +127,13 @@ import { LoadingEvent } from '@a-vue/events'
122
127
  export default class ListView extends Mixins(ListViewMixin) {
123
128
  $hasOptions = ['icon', 'filters']
124
129
 
130
+ xStart = null
131
+ scrollLeftStart = null
132
+ scrollContainerX = null
133
+ yStart = null
134
+ scrollTopStart = null
135
+ scrollContainerY = null
136
+
125
137
  @Watch('isLoading')
126
138
  isLoadingChanged () {
127
139
  if (this.events) {
@@ -191,6 +203,76 @@ export default class ListView extends Mixins(ListViewMixin) {
191
203
  }
192
204
  this.$emit('flyingContext', model)
193
205
  }
206
+
207
+ startShifting (event) {
208
+ this.scrollContainerX = this.getScrollParent(this.$el.querySelector('.a-table-wrapper'), 'h')
209
+ this.scrollContainerY = this.getScrollParent(this.$el.querySelector('.a-table-wrapper'), 'v')
210
+
211
+ if (this.scrollContainerX || this.scrollContainerY) {
212
+ window.addEventListener('mouseup', this.stopShifting)
213
+ window.addEventListener('mousemove', this.shift)
214
+
215
+ this.$el.style.userSelect = 'none'
216
+
217
+ if (this.scrollContainerX) {
218
+ this.xStart = event.clientX
219
+ this.scrollLeftStart = this.scrollContainerX.scrollLeft
220
+ }
221
+
222
+ if (this.scrollContainerY) {
223
+ this.yStart = event.clientY
224
+ this.scrollTopStart = this.scrollContainerY.scrollTop
225
+ }
226
+ }
227
+ }
228
+
229
+ stopShifting (event) {
230
+ window.removeEventListener('mouseup', this.stopShifting)
231
+ window.removeEventListener('mousemove', this.shift)
232
+
233
+ this.$el.style.userSelect = 'auto'
234
+ }
235
+
236
+ shift (event) {
237
+ if (this.scrollContainerX || this.scrollContainerY) {
238
+ if (this.scrollContainerX) {
239
+ const diffX = this.xStart - event.clientX
240
+ this.scrollContainerX.scrollLeft = this.scrollLeftStart + diffX
241
+ }
242
+
243
+ if (this.scrollContainerY) {
244
+ const diffY = this.yStart - event.clientY
245
+ this.scrollContainerY.scrollTop = this.scrollTopStart + diffY
246
+ }
247
+ }
248
+ }
249
+
250
+ @Watch('$route.name')
251
+ routeChanged () {
252
+ if (this.scrollContainerX) {
253
+ this.scrollContainerX.scrollLeft = 0
254
+ }
255
+
256
+ if (this.scrollContainerY) {
257
+ this.scrollContainerY.scrollTop = 0
258
+ }
259
+ }
260
+
261
+ getScrollParent (node, direction) {
262
+ if (node == null) {
263
+ return null
264
+ }
265
+
266
+ if (direction === 'h' && (node.scrollWidth > node.clientWidth)) {
267
+ return node
268
+ }
269
+
270
+ if (direction === 'v' && (node.scrollHeight > node.clientHeight)) {
271
+ return node
272
+ }
273
+
274
+ return this.getScrollParent(node.parentNode, direction)
275
+ }
194
276
  }
195
277
  </script>
196
278
 
@@ -199,15 +281,26 @@ export default class ListView extends Mixins(ListViewMixin) {
199
281
  .listView {
200
282
  max-width: 100%;
201
283
  padding-top: .2rem; // unless, floating input labels might be cut
284
+ }
285
+
286
+ .a-table-wrapper {
287
+ max-width: 100%;
202
288
  overflow-x: auto;
203
289
  overflow-y: hidden;
290
+ padding-bottom: 1rem;
291
+ cursor: grab;
204
292
  }
205
293
 
206
- .filters {
294
+ .filters:not(:empty) {
207
295
  margin-left: 4px;
208
296
  margin-bottom: 2rem;
209
297
  }
210
298
 
299
+ filters-below:not(:empty) {
300
+ margin-left: 4px;
301
+ margin-top: 2rem;
302
+ }
303
+
211
304
  :deep(.a-table-row > :last-child) {
212
305
  width: 100%;
213
306
  }