@afeefa/vue-app 0.0.220 → 0.0.222

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }