@afeefa/vue-app 0.0.220 → 0.0.221

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.221
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.221",
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,11 @@ 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
+ yStart = null
133
+ scrollTopStart = null
134
+
125
135
  @Watch('isLoading')
126
136
  isLoadingChanged () {
127
137
  if (this.events) {
@@ -191,6 +201,81 @@ export default class ListView extends Mixins(ListViewMixin) {
191
201
  }
192
202
  this.$emit('flyingContext', model)
193
203
  }
204
+
205
+ startShifting (event) {
206
+ if (this.scrollContainerX || this.scrollContainerY) {
207
+ window.addEventListener('mouseup', this.stopShifting)
208
+ window.addEventListener('mousemove', this.shift)
209
+
210
+ this.$el.style.userSelect = 'none'
211
+
212
+ if (this.scrollContainerX) {
213
+ this.xStart = event.clientX
214
+ this.scrollLeftStart = this.scrollContainerX.scrollLeft
215
+ }
216
+
217
+ if (this.scrollContainerY) {
218
+ this.yStart = event.clientY
219
+ this.scrollTopStart = this.scrollContainerY.scrollTop
220
+ }
221
+ }
222
+ }
223
+
224
+ stopShifting (event) {
225
+ window.removeEventListener('mouseup', this.stopShifting)
226
+ window.removeEventListener('mousemove', this.shift)
227
+
228
+ this.$el.style.userSelect = 'auto'
229
+ }
230
+
231
+ shift (event) {
232
+ if (this.scrollContainerX || this.scrollContainerY) {
233
+ if (this.scrollContainerX) {
234
+ const diffX = this.xStart - event.clientX
235
+ this.scrollContainerX.scrollLeft = this.scrollLeftStart + diffX
236
+ }
237
+
238
+ if (this.scrollContainerY) {
239
+ const diffY = this.yStart - event.clientY
240
+ this.scrollContainerY.scrollTop = this.scrollTopStart + diffY
241
+ }
242
+ }
243
+ }
244
+
245
+ @Watch('$route.name')
246
+ routeChanged () {
247
+ if (this.scrollContainerX) {
248
+ this.scrollContainerX.scrollLeft = 0
249
+ }
250
+
251
+ if (this.scrollContainerY) {
252
+ this.scrollContainerY.scrollTop = 0
253
+ }
254
+ }
255
+
256
+ get scrollContainerX () {
257
+ return this.getScrollParent(this.$el.querySelector('.a-table-wrapper'), 'h')
258
+ }
259
+
260
+ get scrollContainerY () {
261
+ return this.getScrollParent(this.$el.querySelector('.a-table-wrapper'), 'v')
262
+ }
263
+
264
+ getScrollParent (node, direction) {
265
+ if (node == null) {
266
+ return null
267
+ }
268
+
269
+ if (direction === 'h' && (node.scrollWidth > node.clientWidth)) {
270
+ return node
271
+ }
272
+
273
+ if (direction === 'v' && (node.scrollHeight > node.clientHeight)) {
274
+ return node
275
+ }
276
+
277
+ return this.getScrollParent(node.parentNode, direction)
278
+ }
194
279
  }
195
280
  </script>
196
281
 
@@ -199,15 +284,26 @@ export default class ListView extends Mixins(ListViewMixin) {
199
284
  .listView {
200
285
  max-width: 100%;
201
286
  padding-top: .2rem; // unless, floating input labels might be cut
287
+ }
288
+
289
+ .a-table-wrapper {
290
+ max-width: 100%;
202
291
  overflow-x: auto;
203
292
  overflow-y: hidden;
293
+ padding-bottom: 1rem;
294
+ cursor: grab;
204
295
  }
205
296
 
206
- .filters {
297
+ .filters:not(:empty) {
207
298
  margin-left: 4px;
208
299
  margin-bottom: 2rem;
209
300
  }
210
301
 
302
+ filters-below:not(:empty) {
303
+ margin-left: 4px;
304
+ margin-top: 2rem;
305
+ }
306
+
211
307
  :deep(.a-table-row > :last-child) {
212
308
  width: 100%;
213
309
  }