@afeefa/vue-app 0.0.61 → 0.0.64

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. package/.afeefa/package/release/version.txt +1 -1
  2. package/README.md +3 -1
  3. package/package.json +1 -1
  4. package/src/api-resources/ApiAction.js +87 -0
  5. package/src/api-resources/ApiActions2.js +13 -0
  6. package/src/api-resources/DeleteAction.js +21 -0
  7. package/src/api-resources/GetAction.js +18 -0
  8. package/src/api-resources/ListAction.js +27 -0
  9. package/src/api-resources/SaveAction.js +15 -0
  10. package/src/components/AModal.vue +21 -3
  11. package/src/components/ASearchSelect.vue +2 -2
  12. package/src/components/ATableRow.vue +4 -0
  13. package/src/components/flying-context/FlyingContextEvent.js +5 -0
  14. package/src/components/form/EditForm.vue +30 -8
  15. package/src/components/form/EditModal.vue +50 -35
  16. package/src/components/form/FormFieldMixin.js +1 -1
  17. package/src/components/form/NestedEditForm.vue +4 -0
  18. package/src/components/list/ListViewMixin.js +2 -2
  19. package/src/events.js +1 -0
  20. package/src-admin/bootstrap.js +1 -0
  21. package/src-admin/components/App.vue +5 -1
  22. package/src-admin/components/FlyingContext.vue +77 -0
  23. package/src-admin/components/FlyingContextContainer.vue +85 -0
  24. package/src-admin/components/app/AppBarButton.vue +10 -2
  25. package/src-admin/components/controls/SearchSelectFormField.vue +1 -1
  26. package/src-admin/components/form/EditFormButtons.vue +40 -0
  27. package/src-admin/components/form/RemoveButton.vue +71 -0
  28. package/src-admin/components/index.js +7 -8
  29. package/src-admin/components/list/ListView.vue +19 -5
  30. package/src-admin/components/pages/EditPage.vue +48 -134
  31. package/src-admin/components/routes/DataRouteMixin.js +84 -0
  32. package/src-admin/config/routing.js +0 -11
  33. package/src-admin/directives/index.js +26 -0
  34. package/src-admin/models/Model.js +3 -3
  35. package/src-admin/components/pages/CreatePage.vue +0 -114
  36. package/src-admin/components/pages/DetailPage.vue +0 -143
  37. package/src-admin/components/pages/EditPageMixin.js +0 -96
  38. package/src-admin/components/pages/ListPage.vue +0 -55
  39. package/src-admin/components/routes/CreateRoute.vue +0 -15
  40. package/src-admin/components/routes/DetailRoute.vue +0 -85
  41. package/src-admin/components/routes/EditRoute.vue +0 -78
  42. package/src-admin/components/routes/ListRoute.vue +0 -110
@@ -1 +1 @@
1
- 0.0.61
1
+ 0.0.64
package/README.md CHANGED
@@ -1 +1,3 @@
1
- # @afeefa/vue-app
1
+ # @afeefa/vue-app
2
+
3
+ Force push :-);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.61",
3
+ "version": "0.0.64",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
@@ -0,0 +1,87 @@
1
+ import { AlertEvent, LoadingEvent } from '@a-vue/events'
2
+ import { eventBus } from '@a-vue/plugins/event-bus/EventBus'
3
+ import { sleep } from '@a-vue/utils/timeout'
4
+ import { ApiAction as ApiResourcesApiAction } from '@afeefa/api-resources-client'
5
+
6
+ import { SaveEvent } from '../events'
7
+
8
+ export class ApiAction extends ApiResourcesApiAction {
9
+ _dispatchGlobalLoadingEvents = false
10
+ _dispatchGlobalSaveEvents = false
11
+ _minDuration = 100
12
+ _startTime = 0
13
+
14
+ id (id) {
15
+ this.param('id', id)
16
+ return this
17
+ }
18
+
19
+ dispatchGlobalLoadingEvents (dispatch = true) {
20
+ this._dispatchGlobalLoadingEvents = dispatch
21
+ return this
22
+ }
23
+
24
+ dispatchGlobalSaveEvents (dispatch = true) {
25
+ this._dispatchGlobalSaveEvents = dispatch
26
+ return this
27
+ }
28
+
29
+ async beforeRequest () {
30
+ this._startTime = Date.now()
31
+
32
+ if (this._dispatchGlobalLoadingEvents) {
33
+ eventBus.dispatch(new LoadingEvent(LoadingEvent.START_LOADING))
34
+ }
35
+
36
+ if (this._dispatchGlobalSaveEvents) {
37
+ eventBus.dispatch(new SaveEvent(SaveEvent.START_SAVING))
38
+ }
39
+ }
40
+
41
+ async beforeBulkRequest () {
42
+ if (this._dispatchGlobalLoadingEvents) {
43
+ eventBus.dispatch(new LoadingEvent(LoadingEvent.START_LOADING))
44
+ }
45
+
46
+ if (this._dispatchGlobalSaveEvents) {
47
+ eventBus.dispatch(new SaveEvent(SaveEvent.START_SAVING))
48
+ }
49
+ }
50
+
51
+ async afterRequest () {
52
+ if (this._minDuration) {
53
+ const diffTime = Date.now() - this._startTime
54
+ const restTime = Math.max(0, this._minDuration - diffTime)
55
+ if (restTime) {
56
+ await sleep(restTime / 1000)
57
+ }
58
+ }
59
+
60
+ if (this._dispatchGlobalLoadingEvents) {
61
+ eventBus.dispatch(new LoadingEvent(LoadingEvent.STOP_LOADING))
62
+ }
63
+
64
+ if (this._dispatchGlobalSaveEvents) {
65
+ eventBus.dispatch(new SaveEvent(SaveEvent.STOP_SAVING))
66
+ }
67
+ }
68
+
69
+ async afterBulkRequest () {
70
+ if (this._dispatchGlobalLoadingEvents) {
71
+ eventBus.dispatch(new LoadingEvent(LoadingEvent.STOP_LOADING))
72
+ }
73
+
74
+ if (this._dispatchGlobalSaveEvents) {
75
+ eventBus.dispatch(new SaveEvent(SaveEvent.STOP_SAVING))
76
+ }
77
+ }
78
+
79
+ alert (message) {
80
+ eventBus.dispatch(new AlertEvent(AlertEvent.MESSAGE, {
81
+ message
82
+ }))
83
+ }
84
+ }
85
+
86
+ export class BulkAction extends ApiAction {
87
+ }
@@ -0,0 +1,13 @@
1
+ import { BulkAction } from './ApiAction'
2
+ import { DeleteAction } from './DeleteAction'
3
+ import { GetAction } from './GetAction'
4
+ import { ListAction } from './ListAction'
5
+ import { SaveAction } from './SaveAction'
6
+
7
+ export {
8
+ BulkAction,
9
+ ListAction,
10
+ GetAction,
11
+ SaveAction,
12
+ DeleteAction
13
+ }
@@ -0,0 +1,21 @@
1
+ import { ApiAction } from './ApiAction'
2
+
3
+ export class DeleteAction extends ApiAction {
4
+ _minDuration = 400
5
+
6
+ delete () {
7
+ this.data(null)
8
+
9
+ return this.execute()
10
+ }
11
+
12
+ async afterRequest () {
13
+ await super.afterRequest()
14
+
15
+ this.alert('Die Daten wurden gelöscht.')
16
+ }
17
+
18
+ processResult () {
19
+ return true
20
+ }
21
+ }
@@ -0,0 +1,18 @@
1
+ import { AlertEvent } from '@a-vue/events'
2
+ import { eventBus } from '@a-vue/plugins/event-bus/EventBus'
3
+
4
+ import { ApiAction } from './ApiAction'
5
+
6
+ export class GetAction extends ApiAction {
7
+ load () {
8
+ return this.execute()
9
+ }
10
+
11
+ processError (result) {
12
+ eventBus.dispatch(new AlertEvent(AlertEvent.ERROR, {
13
+ headline: 'Die Daten konntent nicht geladen werden.',
14
+ message: result.message,
15
+ detail: result.detail
16
+ }))
17
+ }
18
+ }
@@ -0,0 +1,27 @@
1
+ import { NextRouteFilterSource } from '@a-vue/components/list/NextRouteFilterSource'
2
+ import { ListViewModel } from '@afeefa/api-resources-client'
3
+
4
+ import { ApiAction } from './ApiAction'
5
+
6
+ export class ListAction extends ApiAction {
7
+ load () {
8
+ return this.execute()
9
+ }
10
+
11
+ initFiltersForRoute (route) {
12
+ const request = new ListViewModel(this)
13
+ // read from next route query string, but do not push
14
+ // list component will be init with used_filters
15
+ .filterSource(new NextRouteFilterSource(route), false)
16
+ // read from history, but do not push
17
+ // list component will be init with used_filters
18
+ .historyKey(route.path, false)
19
+ .initFilters({
20
+ source: true,
21
+ history: true
22
+ })
23
+ .getApiRequest()
24
+
25
+ return ListAction.fromRequest(request)
26
+ }
27
+ }
@@ -0,0 +1,15 @@
1
+ import { ApiAction } from './ApiAction'
2
+
3
+ export class SaveAction extends ApiAction {
4
+ _minDuration = 400
5
+
6
+ save () {
7
+ return this.execute()
8
+ }
9
+
10
+ async afterRequest () {
11
+ await super.afterRequest()
12
+
13
+ this.alert('Die Daten wurden gespeichert.')
14
+ }
15
+ }
@@ -7,6 +7,8 @@
7
7
  v-bind="$attrs"
8
8
  :contentClass="modalId"
9
9
  transition="v-fade-transition"
10
+ :persistent="true"
11
+ :no-click-animation="true"
10
12
  @click:outside="cancel"
11
13
  @keydown.esc="cancel"
12
14
  >
@@ -41,7 +43,7 @@ import { getZIndex } from 'vuetify/lib/util/helpers'
41
43
  import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
42
44
 
43
45
  @Component({
44
- props: ['show', 'title', 'triggerClass', 'anchorPosition']
46
+ props: ['show', 'title', 'beforeClose', 'triggerClass', 'anchorPosition']
45
47
  })
46
48
  export default class ADialog extends Mixins(UsesPositionServiceMixin, ComponentWidthMixin) {
47
49
  modalId = randomCssClass(10)
@@ -83,7 +85,15 @@ export default class ADialog extends Mixins(UsesPositionServiceMixin, ComponentW
83
85
  * and emit a visibility event
84
86
  */
85
87
  @Watch('show')
86
- showChanged () {
88
+ async showChanged () {
89
+ // check if a modal is allowed to be closed
90
+ if (this.modal && !this.show && this.beforeClose) {
91
+ const result = await this.beforeClose()
92
+ if (!result) {
93
+ return
94
+ }
95
+ }
96
+
87
97
  this.modal = this.show
88
98
  }
89
99
 
@@ -121,7 +131,15 @@ export default class ADialog extends Mixins(UsesPositionServiceMixin, ComponentW
121
131
  this.urp_registerPositionWatcher(this.position)
122
132
  }
123
133
 
124
- cancel () {
134
+ async cancel () {
135
+ // check if a modal is allowed to be closed
136
+ if (this.modal && this.beforeClose) {
137
+ const result = await this.beforeClose()
138
+ if (!result) {
139
+ return
140
+ }
141
+ }
142
+
125
143
  this.modal = false
126
144
  }
127
145
 
@@ -45,7 +45,7 @@
45
45
  <div :class="listCssClass">
46
46
  <search-select-list
47
47
  v-if="isOpen"
48
- :listViewConfig="listViewConfig"
48
+ :listAction="listAction"
49
49
  :q="q"
50
50
  :selectedItems="selectedItems"
51
51
  :events="false"
@@ -96,7 +96,7 @@ import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
96
96
 
97
97
  @Component({
98
98
  props: [
99
- 'listViewConfig',
99
+ 'listAction',
100
100
  'q',
101
101
  'width',
102
102
  'closeOnSelect',
@@ -62,6 +62,10 @@ export default class ATableRow extends Vue {
62
62
  }
63
63
  }
64
64
 
65
+ &.selectable {
66
+ cursor: pointer;
67
+ }
68
+
65
69
  &:hover, &.selected {
66
70
  background: #F4F4F4;
67
71
  }
@@ -0,0 +1,5 @@
1
+ import { BaseEvent } from '@a-vue/plugins/event-bus/BaseEvent'
2
+
3
+ export class FlyingContextEvent extends BaseEvent {
4
+ static HIDE_ALL = 'FlyingContextEvent:hide-all'
5
+ }
@@ -3,12 +3,11 @@
3
3
  v-model="valid"
4
4
  autocomplete="off"
5
5
  >
6
- <slot name="fields" />
7
-
8
6
  <slot
7
+ name="form"
9
8
  :changed="changed"
10
9
  :valid="valid"
11
- :model="model"
10
+ :modelToEdit="modelToEdit"
12
11
  />
13
12
  </v-form>
14
13
  </template>
@@ -18,14 +17,31 @@
18
17
  import { Component, Vue, Watch } from '@a-vue'
19
18
 
20
19
  @Component({
21
- props: ['model']
20
+ props: [
21
+ 'model',
22
+ 'createModelToEdit'
23
+ ]
22
24
  })
23
25
  export default class EditForm extends Vue {
24
26
  EDIT_FORM = true
25
27
 
28
+ modelToEdit = null
26
29
  valid = false
27
30
  lastJson = null
28
31
 
32
+ created () {
33
+ this.reset()
34
+ }
35
+
36
+ reset () {
37
+ if (this.createModelToEdit) {
38
+ this.modelToEdit = this.createModelToEdit(this.model)
39
+ } else if (this.model) {
40
+ this.modelToEdit = this.model.cloneForEdit()
41
+ }
42
+ this.lastJson = this.json
43
+ }
44
+
29
45
  /**
30
46
  * This will be triggered after the this.model has been set
31
47
  * but before sub components may have changed model values
@@ -33,14 +49,20 @@ export default class EditForm extends Vue {
33
49
  * Using the created() method would result in already having set
34
50
  * the default date, hence not detecting a valid "change" anymore.
35
51
  */
36
- @Watch('model', {immediate: true})
52
+ // @Watch('modelToEdit', {immediate: true})
53
+ // @Watch('modelToEdit')
54
+ // modelToEditChanged () {
55
+ // this.lastJson = this.json
56
+ // this.$emit('update:changed', this.changed)
57
+ // }
58
+
59
+ @Watch('model')
37
60
  modelChanged () {
38
- this.lastJson = this.json
39
- this.$emit('update:changed', this.changed)
61
+ this.reset()
40
62
  }
41
63
 
42
64
  get json () {
43
- return JSON.stringify(this.model)
65
+ return JSON.stringify(this.modelToEdit)
44
66
  }
45
67
 
46
68
  get changed () {
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <a-modal
3
3
  :title="title"
4
+ :beforeClose="beforeClose"
4
5
  :show.sync="show_"
5
6
  v-bind="$attrs"
6
7
  >
@@ -10,16 +11,18 @@
10
11
 
11
12
  <edit-form
12
13
  v-if="show_"
14
+ ref="form"
13
15
  :model="model"
16
+ :createModelToEdit="createModelToEdit"
14
17
  >
15
- <template #fields>
18
+ <template #form="{modelToEdit, changed, valid}">
16
19
  <slot
17
- name="fields"
18
- :model="model"
20
+ name="form"
21
+ :modelToEdit="modelToEdit"
22
+ :changed="changed"
23
+ :valid="valid"
19
24
  />
20
- </template>
21
25
 
22
- <template #default="{changed, valid}">
23
26
  <a-row
24
27
  class="mt-8 mb-1 pb-1 gap-4"
25
28
  right
@@ -31,25 +34,14 @@
31
34
  Schließen
32
35
  </v-btn>
33
36
 
34
- <a-row gap="2">
35
- <v-btn
36
- small
37
- :disabled="!changed || !valid"
38
- color="green white--text"
39
- @click="save"
40
- >
41
- Speichern
42
- </v-btn>
43
-
44
- <v-icon
45
- v-if="changed"
46
- small
47
- text
48
- @click="reset"
49
- >
50
- {{ undoIcon }}
51
- </v-icon>
52
- </a-row>
37
+ <edit-form-buttons
38
+ :changed="changed"
39
+ :valid="valid"
40
+ small
41
+ :has="{reset: !!modelToEdit.id}"
42
+ @save="$emit('save', modelToEdit, ignoreChangesOnClose)"
43
+ @reset="$refs.form.reset()"
44
+ />
53
45
  </a-row>
54
46
  </template>
55
47
  </edit-form>
@@ -59,21 +51,26 @@
59
51
 
60
52
  <script>
61
53
  import { Component, Vue, Watch } from '@a-vue'
62
- import { mdiRotateLeft} from '@mdi/js'
54
+ import { DialogEvent } from '@a-vue/events'
63
55
 
64
56
  @Component({
65
- props: ['model', 'title', 'show']
57
+ props: ['model', 'createModelToEdit', 'title', 'show']
66
58
  })
67
59
  export default class EditModal extends Vue {
68
60
  show_ = false
61
+ ignoreChangesOnClose_ = false
69
62
 
70
- undoIcon = mdiRotateLeft
63
+ created () {
64
+ if (this.show) { // open on create with v-show
65
+ this.open()
66
+ }
67
+ }
71
68
 
72
69
  /**
73
70
  * visiblility changes from outside
74
71
  * this will trigger the show_ watcher,
75
72
  * forward the change to the modal and
76
- * later emit a open/close event
73
+ * later emit an open/close event
77
74
  */
78
75
  @Watch('show')
79
76
  showChanged () {
@@ -90,7 +87,6 @@ export default class EditModal extends Vue {
90
87
  @Watch('show_')
91
88
  show_Changed () {
92
89
  if (this.show_) {
93
- this.reset()
94
90
  this.$emit('open')
95
91
  } else {
96
92
  this.$emit('close')
@@ -101,16 +97,35 @@ export default class EditModal extends Vue {
101
97
  this.show_ = true
102
98
  }
103
99
 
104
- close () {
105
- this.show_ = false
100
+ async beforeClose () {
101
+ // run only if show_ is true to prevent double checks with a-modal
102
+ if (this.show_ && this.$refs.form.changed && !this.ignoreChangesOnClose_) {
103
+ const result = await this.$events.dispatch(new DialogEvent(DialogEvent.SHOW, {
104
+ title: 'Änderungen verwerfen?',
105
+ message: 'Im Formular sind nicht gespeicherte Änderungen. Sollen diese verworfen werden?',
106
+ yesButton: 'Verwerfen'
107
+ }))
108
+ if (result !== DialogEvent.RESULT_YES) {
109
+ return false
110
+ }
111
+ }
112
+ return true
106
113
  }
107
114
 
108
- reset () {
109
- this.$emit('reset')
115
+ async close () {
116
+ const result = await this.beforeClose()
117
+ if (!result) {
118
+ return
119
+ }
120
+
121
+ this.show_ = false
110
122
  }
111
123
 
112
- save () {
113
- this.$emit('save')
124
+ /**
125
+ * hook to allow to leave a just created (saved) model
126
+ */
127
+ ignoreChangesOnClose () {
128
+ this.ignoreChangesOnClose_ = true
114
129
  }
115
130
  }
116
131
  </script>
@@ -9,7 +9,7 @@ export class FormFieldMixin extends Vue {
9
9
  let parent = this
10
10
  while (parent) {
11
11
  if (parent.EDIT_FORM) {
12
- return parent.model
12
+ return parent.modelToEdit
13
13
  }
14
14
  parent = parent.$parent
15
15
  }
@@ -21,5 +21,9 @@ export default class NestedEditForm extends Vue {
21
21
  console.warn('Nested edit form does not have a model.')
22
22
  }
23
23
  }
24
+
25
+ get modelToEdit () {
26
+ return this.model
27
+ }
24
28
  }
25
29
  </script>
@@ -8,7 +8,7 @@ import { FilterSourceType } from './FilterSourceType'
8
8
  @Component({
9
9
  props: [
10
10
  'models', 'meta', // given, if already loaded
11
- 'listViewConfig',
11
+ 'listAction',
12
12
  'filterHistoryKey',
13
13
  'loadOnlyIfKeyword',
14
14
  {
@@ -52,7 +52,7 @@ export class ListViewMixin extends Vue {
52
52
  this.meta_ = this.meta
53
53
  }
54
54
 
55
- this.listViewModel = new ListViewModel(this.listViewConfig)
55
+ this.listViewModel = new ListViewModel(this.listAction)
56
56
  .filterSource(filterSource, !!filterSource)
57
57
  .historyKey(historyKey, this.history)
58
58
  .usedFilters(this.meta_.used_filters || null, this.meta_.count_search || 0)
package/src/events.js CHANGED
@@ -2,3 +2,4 @@ export { LoadingEvent } from './components/loading-indicator/LoadingEvent'
2
2
  export { SaveEvent } from './components/save-indicator/SaveEvent'
3
3
  export { AlertEvent } from './components/alert/AlertEvent'
4
4
  export { DialogEvent } from './components/dialog/DialogEvent'
5
+ export { FlyingContextEvent } from './components/flying-context/FlyingContextEvent'
@@ -1,5 +1,6 @@
1
1
  import './config/event-bus'
2
2
  import './config/components'
3
+ import './directives'
3
4
 
4
5
  import { translationPlugin } from '@a-admin/plugins/translation/TranslationPlugin'
5
6
  import { apiResourcesPlugin } from '@a-vue/plugins/api-resources/ApiResourcesPlugin'
@@ -91,6 +91,8 @@
91
91
  </v-list>
92
92
  </v-navigation-drawer>
93
93
 
94
+ <flying-context-container />
95
+
94
96
  <v-app-bar
95
97
  app
96
98
  flat
@@ -142,12 +144,14 @@ import { appConfig } from '@a-admin/config/AppConfig'
142
144
  import { sleep } from '@a-vue/utils/timeout'
143
145
  import AppBarButtons from './app/AppBarButtons'
144
146
  import AppBarTitleContainer from './app/AppBarTitleContainer'
147
+ import FlyingContextContainer from './FlyingContextContainer'
145
148
  import '../styles.scss'
146
149
 
147
150
  @Component({
148
151
  components: {
149
152
  AppBarButtons,
150
- AppBarTitleContainer
153
+ AppBarTitleContainer,
154
+ FlyingContextContainer
151
155
  }
152
156
  })
153
157
  export default class App extends Vue {
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <div class="flyingContext">
3
+ <div :class="contextId">
4
+ <slot v-if="isVisible" />
5
+ </div>
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ import { Component, Watch, Vue } from '@a-vue'
11
+ import { FlyingContextEvent } from '@a-vue/events'
12
+ import { randomCssClass } from '@a-vue/utils/random'
13
+
14
+ @Component({
15
+ props: [{show: false}]
16
+ })
17
+ export default class FlyingContext extends Vue {
18
+ isVisible = false
19
+ contextId = randomCssClass(10)
20
+
21
+ created () {
22
+ this.$events.on(FlyingContextEvent.HIDE_ALL, this.onHide)
23
+ }
24
+
25
+ mounted () {
26
+ if (this.show) {
27
+ this.showChanged()
28
+ }
29
+ }
30
+
31
+ @Watch('show')
32
+ showChanged () {
33
+ if (this.isVisible === this.show) {
34
+ return
35
+ }
36
+
37
+ this.isVisible = this.show
38
+
39
+ if (this.isVisible) {
40
+ const container = this.getSidebarContainer()
41
+ container.appendChild(this.getContent())
42
+ } else {
43
+ this.$el.appendChild(this.getContent())
44
+ }
45
+ }
46
+
47
+ destroyed () {
48
+ const container = this.getSidebarContainer()
49
+ const el = this.getContent()
50
+ if (container.contains(el)) {
51
+ container.removeChild(el)
52
+ }
53
+
54
+ this.$events.off(FlyingContextEvent.HIDE_ALL, this.onHide)
55
+ }
56
+
57
+ onHide () {
58
+ if (this.isVisible) {
59
+ this.$el.appendChild(this.getContent())
60
+ this.isVisible = false
61
+ this.$emit('hide')
62
+ }
63
+ }
64
+
65
+ getContent () {
66
+ return document.querySelector('.' + this.contextId)
67
+ }
68
+
69
+ getSidebarContainer () {
70
+ return document.getElementById('flyingContextContainer__children')
71
+ }
72
+ }
73
+ </script>
74
+
75
+
76
+ <style lang="scss" scoped>
77
+ </style>