@@ -18,27 +18,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
<template >
19
19
<div >
20
20
<!-- dropdown menu -->
21
- <component :is =" menuTransition" :target =" target" >
22
- <v-card
23
- ref =" menuContent"
24
- v-if =" node"
25
- v-show =" showMenu"
26
- @show-mutations-menu =" showMutationsMenu"
27
- :key =" node.id"
28
- v-click-outside =" { handler: onClickOutside, closeConditional: () => !dialog }"
29
- class =" c-mutation-menu elevation-10 overflow-y-auto"
30
- max-height =" 90vh"
31
- width =" max-content"
32
- max-width =" min(600px, 100%)"
33
- theme =" dark"
34
- position =" absolute"
35
- :style =" {
36
- left: `${x}px`,
37
- top: `${y}px`,
38
- // Set transition origin relative to clicked target:
39
- '--v-overlay-anchor-origin': 'bottom right',
40
- }"
41
- >
21
+ <v-menu
22
+ v-if =" node"
23
+ :key =" target.dataset.cInteractive"
24
+ v-model =" showMenu"
25
+ :target =" target"
26
+ :close-on-content-click =" false"
27
+ content-class =" c-mutation-menu"
28
+ max-width =" 600px"
29
+ theme =" dark"
30
+ >
31
+ <v-card >
42
32
<v-card-title class =" pb-1 pt-3" >
43
33
{{ node.id }}
44
34
</v-card-title >
@@ -89,7 +79,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
89
79
<v-list-item v-if =" canExpand" >
90
80
<v-btn
91
81
id =" less-more-button"
92
- @click =" expandCollapse "
82
+ @click =" () => expanded = !expanded "
93
83
block
94
84
variant =" tonal"
95
85
>
@@ -98,7 +88,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
98
88
</v-list-item >
99
89
</v-list >
100
90
</v-card >
101
- </component >
91
+ </v-menu >
102
92
<v-dialog
103
93
v-if =" dialogMutation"
104
94
v-model =" dialog"
@@ -111,7 +101,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
111
101
:cylcObject =" node"
112
102
:initialData =" initialData(dialogMutation, node.tokens)"
113
103
@close =" () => dialog = false"
114
- @success =" closeMenu "
104
+ @success =" () => showMenu = false "
115
105
:types =" types"
116
106
:key =" dialogKey /* Enables re-render of component each time dialog opened */"
117
107
ref =" mutationComponent"
@@ -121,24 +111,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
121
111
</template >
122
112
123
113
<script >
124
- import { computed , nextTick } from ' vue'
114
+ import { nextTick } from ' vue'
125
115
import {
126
116
filterAssociations ,
127
117
getMutationArgsFromTokens ,
128
118
mutate
129
119
} from ' @/utils/aotf'
130
- import { useReducedAnimation } from ' @/composables/localStorage'
131
120
import Mutation from ' @/components/cylc/Mutation.vue'
132
121
import {
133
122
mdiPencil
134
123
} from ' @mdi/js'
135
124
import { mapGetters , mapState } from ' vuex'
136
125
import WorkflowState from ' @/model/WorkflowState.model'
137
- import { VDialogTransition } from ' vuetify/components/transitions'
138
126
import { eventBus } from ' @/services/eventBus'
139
127
140
128
export default {
141
- name: ' CylcObjectMenu ' ,
129
+ name: ' CommandMenu ' ,
142
130
143
131
components: {
144
132
Mutation
@@ -152,15 +140,6 @@ export default {
152
140
}
153
141
},
154
142
155
- setup () {
156
- const reducedAnimation = useReducedAnimation ()
157
- return {
158
- menuTransition: computed (
159
- () => reducedAnimation .value ? ' slot' : VDialogTransition
160
- ),
161
- }
162
- },
163
-
164
143
data () {
165
144
return {
166
145
dialog: false ,
@@ -172,20 +151,16 @@ export default {
172
151
isLoadingMutations: true ,
173
152
showMenu: false ,
174
153
types: [],
175
- x: 0 ,
176
- y: 0 ,
177
154
target: null ,
178
155
}
179
156
},
180
157
181
158
mounted () {
182
159
eventBus .on (' show-mutations-menu' , this .showMutationsMenu )
183
- document .addEventListener (' keydown' , this .onKeydown )
184
160
},
185
161
186
162
beforeUnmount () {
187
163
eventBus .off (' show-mutations-menu' , this .showMutationsMenu )
188
- document .removeEventListener (' keydown' , this .onKeydown )
189
164
},
190
165
191
166
computed: {
@@ -269,66 +244,6 @@ export default {
269
244
this .dialogKey = ! this .dialogKey
270
245
},
271
246
272
- closeMenu () {
273
- this .showMenu = false
274
- this .expanded = false
275
- },
276
-
277
- /**
278
- * Handler for clicking outside menu (close it).
279
- *
280
- * We override vuetify default handling because we don't want to
281
- * close when clicking on another cylc object.
282
- *
283
- * @param {Event} e - the click event
284
- */
285
- onClickOutside (e ) {
286
- this .closeMenu ()
287
-
288
- // check if the thing being clicked on is a child of the thing that the
289
- // menu is open for
290
- let target = e .target
291
- while (target) {
292
- if (target? .getAttribute (' data-c-interactive' )) {
293
- // keep the menu open
294
- this .showMenu = true
295
- break
296
- }
297
- target = target .parentElement
298
- }
299
- },
300
-
301
- onKeydown (e ) {
302
- if (! this .dialog && e .key === ' Escape' ) {
303
- this .closeMenu ()
304
- }
305
- },
306
-
307
- expandCollapse () {
308
- this .expanded = ! this .expanded
309
- this .reposition ()
310
- },
311
-
312
- /**
313
- * Place the menu in a way that prevents it overflowing off screen and
314
- * so it takes up the full width as needed on narrow viewports.
315
- *
316
- * @param {number} x - preferred x coordinate
317
- * @param {number} y - preferred y coordinate
318
- */
319
- reposition (x = null , y = null ) {
320
- x ?? = this .x
321
- y ?? = this .y
322
- nextTick (() => {
323
- this .x = x + this .$refs .menuContent .$el .clientWidth > document .body .clientWidth
324
- ? document .body .clientWidth - this .$refs .menuContent .$el .clientWidth
325
- : x
326
- this .y = y + this .$refs .menuContent .$el .clientHeight > document .body .clientHeight
327
- ? document .body .clientHeight - this .$refs .menuContent .$el .clientHeight - 5
328
- : y
329
- })
330
- },
331
-
332
247
/* Call a mutation using only the tokens for args. */
333
248
callMutationFromContext (mutation ) {
334
249
this .showMenu = false
@@ -363,32 +278,32 @@ export default {
363
278
}
364
279
},
365
280
366
- showMutationsMenu ({ node, event }) {
367
- this .target = event . target
281
+ async showMutationsMenu ({ node, target }) {
282
+ this .target = target
368
283
this .node = node
284
+ this .expanded = false
285
+ // show the menu after it's rendered to ensure animation works properly
286
+ await nextTick ()
369
287
this .showMenu = true
370
- this .reposition (event .clientX , event .clientY )
371
- // await graphql query to get mutations
372
- this .$workflowService .introspection .then (({ mutations, types }) => {
373
- // if mutations are slow to load then there will be a delay before they are reactively
374
- // displayed in the menu (this is what the skeleton-loader is for)
375
- this .isLoadingMutations = false
376
- this .types = types
377
- let type = this .node .type
378
- if (type === ' family' ) {
379
- // show the same mutation list for families as for tasks
380
- type = ' task'
381
- }
382
- this .mutations = filterAssociations (
383
- type,
384
- this .node .tokens ,
385
- mutations,
386
- this .user .permissions
387
- ).sort (
388
- (a , b ) => a .mutation .name .localeCompare (b .mutation .name )
389
- )
390
- this .reposition (event .clientX , event .clientY )
391
- })
288
+ // ensure graphql query to get mutations has completed
289
+ const { mutations , types } = await this .$workflowService .introspection
290
+ // if mutations are slow to load then there will be a delay before they are reactively
291
+ // displayed in the menu (this is what the skeleton-loader is for)
292
+ this .isLoadingMutations = false
293
+ this .types = types
294
+ let type = this .node .type
295
+ if (type === ' family' ) {
296
+ // show the same mutation list for families as for tasks
297
+ type = ' task'
298
+ }
299
+ this .mutations = filterAssociations (
300
+ type,
301
+ this .node .tokens ,
302
+ mutations,
303
+ this .user .permissions
304
+ ).sort (
305
+ (a , b ) => a .mutation .name .localeCompare (b .mutation .name )
306
+ )
392
307
},
393
308
394
309
initialData (mutation , tokens ) {
0 commit comments