@@ -50,9 +50,9 @@ import {
5050
5151import { Alert } from '@/model/Alert.model'
5252import { store } from '@/store/index'
53- import { Tokens } from '@/utils/uid'
53+ import { detokenise , Tokens } from '@/utils/uid'
5454import { WorkflowState , WorkflowStateNames } from '@/model/WorkflowState.model'
55- import { isBoolean } from 'lodash-es'
55+ import { isBoolean , startCase } from 'lodash-es'
5656
5757/** @typedef {import('@apollo/client').ApolloClient } ApolloClient */
5858/** @typedef {import('graphql').IntrospectionInputType } IntrospectionInputType */
@@ -71,7 +71,7 @@ import { isBoolean } from 'lodash-es'
7171 * @property {GQLType } type
7272 * @property {?string } defaultValue
7373 * @property {string= } _title
74- * @property {string= } _cylcObject
74+ * @property {string= } _cylcObjects
7575 * @property {string= } _cylcType
7676 * @property {boolean= } _required
7777 * @property {boolean= } _multiple
@@ -165,8 +165,8 @@ export const cylcObjects = Object.freeze({
165165 User : 'user' ,
166166 Workflow : 'workflow' ,
167167 CyclePoint : 'cycle' ,
168- Namespace : 'task ' ,
169- // Task: 'task',
168+ Family : 'family ' ,
169+ Task : 'task' ,
170170 Job : 'job'
171171} )
172172
@@ -187,36 +187,27 @@ export const primaryMutations = {
187187 'hold' ,
188188 'release' ,
189189 'trigger' ,
190- 'kill'
190+ 'kill' ,
191+ 'set' ,
192+ ] ,
193+ [ cylcObjects . Family ] : [
194+ 'hold' ,
195+ 'release' ,
196+ 'trigger' ,
197+ 'kill' ,
198+ 'set' ,
191199 ] ,
192- [ cylcObjects . Namespace ] : [
200+ [ cylcObjects . Task ] : [
193201 'hold' ,
194202 'release' ,
195203 'trigger' ,
196204 'kill' ,
205+ 'set' ,
197206 'log' ,
198207 'info' ,
199- 'set'
200- ]
208+ ] ,
201209}
202210
203- // handle families the same as tasks
204- primaryMutations . family = primaryMutations [ cylcObjects . Namespace ]
205-
206- /**
207- * Cylc "objects" in hierarchy order.
208- *
209- * Note, this is the order they would appear in a tree representation.
210- */
211- const identifierOrder = [
212- cylcObjects . User ,
213- cylcObjects . Workflow ,
214- cylcObjects . CyclePoint ,
215- cylcObjects . Namespace ,
216- // cylcObjects.Task,
217- cylcObjects . Job
218- ]
219-
220211/**
221212 * Mapping of mutation argument types to Cylc "objects" (workflow, cycle,
222213 * task etc.).
@@ -225,52 +216,39 @@ const identifierOrder = [
225216 * auto-populate the input element in the mutation form based on the object
226217 * that was clicked on.
227218 *
228- * object: [[typeName: String, impliesMultiple: Boolean]]
229219 */
230- export const mutationMapping = {
231- [ cylcObjects . User ] : [ ] ,
232- [ cylcObjects . Workflow ] : [
233- [ 'WorkflowID' , false ]
234- ] ,
235- [ cylcObjects . CyclePoint ] : [
236- [ 'CyclePoint' , false ] ,
237- [ 'CyclePointGlob' , true ]
238- ] ,
239- [ cylcObjects . Namespace ] : [
240- [ 'NamespaceName' , false ] ,
241- [ 'NamespaceIDGlob' , true ]
242- ] ,
243- // [cylcObjects.Task]: [
244- // ['TaskID', false]
245- // ],
246- [ cylcObjects . Job ] : [
247- [ 'JobID' , false ]
248- ]
220+ const mutationMapping = {
221+ WorkflowID : [ cylcObjects . Workflow ] ,
222+ CyclePoint : [ cylcObjects . CyclePoint ] ,
223+ CyclePointGlob : [ cylcObjects . CyclePoint ] ,
224+ NamespaceName : [ cylcObjects . Task , cylcObjects . Family ] ,
225+ NamespaceIDGlob : [ cylcObjects . Task , cylcObjects . Family ] ,
226+ // TaskID: [cylcObjects.Task],
227+ JobID : [ cylcObjects . Job ] ,
249228}
250229
230+ /** Argument types that imply multiple values. */
231+ const impliesMultiple = Object . freeze ( [
232+ 'CyclePointGlob' ,
233+ 'NamespaceIDGlob' ,
234+ ] )
235+
251236/**
252237 * Mutation argument types which are derived from more than one token.
253238 */
254239export const compoundFields = {
255- WorkflowID : ( tokens ) => {
256- if ( tokens [ cylcObjects . User ] ) {
257- return `~${ tokens [ cylcObjects . User ] } /${ tokens [ cylcObjects . Workflow ] } `
258- }
259- // don't provide user if not specified
260- // (will fallback to the UIs user)
261- return tokens [ cylcObjects . Workflow ]
262- } ,
240+ WorkflowID : ( tokens ) => detokenise ( tokens , { workflow : true } ) ,
263241 NamespaceIDGlob : ( tokens ) => (
264242 // expand unspecified fields to '*'
265243 ( tokens [ cylcObjects . CyclePoint ] || '*' ) +
266244 '/' +
267- ( tokens [ cylcObjects . Namespace ] || '*' )
245+ ( tokens [ cylcObjects . Task ] || '*' )
268246 ) ,
269247 TaskID : ( tokens ) => (
270248 // expand unspecified fields to '*'
271249 ( tokens [ cylcObjects . CyclePoint ] || '*' ) +
272250 '/' +
273- tokens [ cylcObjects . Namespace ]
251+ tokens [ cylcObjects . Task ]
274252 )
275253}
276254
@@ -309,7 +287,7 @@ export const dummyMutations = [
309287
310288 This only applies for the cycle point of the chosen task/family instance.` ,
311289 args : [ ] ,
312- _appliesTo : [ cylcObjects . Namespace , cylcObjects . CyclePoint ] ,
290+ _appliesTo : [ cylcObjects . Task , cylcObjects . Family , cylcObjects . CyclePoint ] ,
313291 _requiresInfo : true ,
314292 _validStates : [ WorkflowState . RUNNING . name , WorkflowState . PAUSED . name ] ,
315293 _dialogWidth : '1200px' ,
@@ -318,15 +296,15 @@ export const dummyMutations = [
318296 name : 'log' ,
319297 description : 'View the logs.' ,
320298 args : [ ] ,
321- _appliesTo : [ cylcObjects . Workflow , cylcObjects . Namespace , cylcObjects . Job ] ,
299+ _appliesTo : [ cylcObjects . Workflow , cylcObjects . Task , cylcObjects . Job ] ,
322300 _requiresInfo : false ,
323301 _validStates : WorkflowStateNames ,
324302 } ,
325303 {
326304 name : 'info' ,
327305 description : 'View task information.' ,
328306 args : [ ] ,
329- _appliesTo : [ cylcObjects . Namespace ] ,
307+ _appliesTo : [ cylcObjects . Task ] ,
330308 _requiresInfo : false
331309 } ,
332310]
@@ -362,33 +340,6 @@ export function tokenise (id) {
362340 return ret
363341}
364342
365- /**
366- * Return the lowest token in the hierarchy.
367- *
368- * @param {Object } tokens
369- * @returns {String }
370- * */
371- export function getType ( tokens ) {
372- let last = null
373- let item = null
374- for ( const key of identifierOrder ) {
375- item = tokens [ key ]
376- if ( ! item ) {
377- break
378- }
379- last = key
380- }
381- return last
382- }
383-
384- /**
385- * Convert camel case to words.
386- */
387- export function camelToWords ( camel ) {
388- const result = ( camel || '' ) . replace ( / ( [ A - Z ] ) / g, ' $1' )
389- return result . charAt ( 0 ) . toUpperCase ( ) + result . slice ( 1 )
390- }
391-
392343/**
393344 * Find the GraphQL object with the given name.
394345 *
@@ -450,7 +401,7 @@ export function extractFields (type, fields, types) {
450401 */
451402export function processMutations ( mutations , types ) {
452403 for ( const mutation of mutations ) {
453- mutation . _title = camelToWords ( mutation . name )
404+ mutation . _title = startCase ( mutation . name )
454405 mutation . _icon = getMutationIcon ( mutation . name )
455406 mutation . _shortDescription = getMutationShortDesc ( mutation . description )
456407 mutation . _help = getMutationExtendedDesc ( mutation . description )
@@ -505,8 +456,8 @@ export function getMutationExtendedDesc (text) {
505456 * This adds some computed fields prefixed with an underscore for later use:
506457 * _title:
507458 * Human-readable name for the mutation.
508- * _cylcObject :
509- * The Cylc Object this field relates to if any (e.g. Cycle, Task etc.).
459+ * _cylcObjects :
460+ * The Cylc objects this field relates to if any (e.g. Cycle, Task etc.).
510461 * _cylcType:
511462 * The underlying GraphQL type that provides this relationship
512463 * (e.g. taskID).
@@ -524,37 +475,25 @@ export function processArguments (mutation, types) {
524475 for ( const arg of mutation . args ) {
525476 let pointer = arg . type
526477 let multiple = false
527- let cylcObject = null
528- let cylcType = null
478+ let cylcObjects
479+ let cylcType
529480 const required = arg . type ?. kind === NON_NULL
530481 while ( pointer ) {
531482 // walk down the nested type tree
532483 if ( pointer . kind === LIST ) {
533484 multiple = true
534485 } else if ( pointer . kind !== NON_NULL && pointer . name ) {
535486 cylcType = pointer . name
536- for ( const objectName in mutationMapping ) {
537- for ( const [ type , impliesMultiple ] of mutationMapping [ objectName ] ) {
538- if ( pointer . name === type ) {
539- cylcObject = objectName
540- if ( impliesMultiple ) {
541- multiple = true
542- }
543- break
544- }
545- }
546- if ( cylcObject ) {
547- break
548- }
549- }
550- if ( cylcObject ) {
487+ cylcObjects = mutationMapping [ cylcType ]
488+ multiple ||= impliesMultiple . includes ( cylcType )
489+ if ( cylcObjects ) {
551490 break
552491 }
553492 }
554493 pointer = pointer . ofType
555494 }
556- arg . _title = camelToWords ( arg . name )
557- arg . _cylcObject = cylcObject
495+ arg . _title = startCase ( arg . name )
496+ arg . _cylcObjects = cylcObjects
558497 arg . _cylcType = cylcType
559498 arg . _multiple = multiple
560499 arg . _required = required
@@ -633,16 +572,20 @@ export function filterAssociations (cylcObject, tokens, mutations, permissions)
633572 ) ,
634573 ]
635574 for ( const mutation of mutations ) {
575+ if ( cylcObject === 'cycle' && mutation . name === 'play' ) {
576+ // Don't show 'play' on cycle points as the cycle point options that get auto-filled don't apply for restarting a workflow.
577+ continue
578+ }
636579 const authorised = permissions . includes ( mutation . name . toLowerCase ( ) )
637580 let requiresInfo = mutation . _requiresInfo ?? false
638581 let applies = mutation . _appliesTo ?. includes ( cylcObject )
639582 for ( const arg of mutation . args ) {
640- if ( arg . _cylcObject ) {
641- if ( arg . _cylcObject === cylcObject ) {
583+ if ( arg . _cylcObjects ) {
584+ if ( arg . _cylcObjects . includes ( cylcObject ) ) {
642585 // this is the object type we are filtering for
643586 applies = true
644587 }
645- if ( arg . _required && ! tokens [ arg . _cylcObject ] ) {
588+ if ( arg . _required && ! arg . _cylcObjects . some ( ( t ) => tokens [ t ] ) ) {
646589 // this cannot be satisfied by the context
647590 requiresInfo = true
648591 }
@@ -859,39 +802,31 @@ export function constructQueryStr (query) {
859802 * */
860803export function getMutationArgsFromTokens ( mutation , tokens ) {
861804 const argspec = { }
862- let value
863805 for ( const arg of mutation . args ) {
864- if ( arg . _cylcObject ) {
865- const alternate = alternateFields [ arg . _cylcType ]
866- for ( let token in tokens ) {
867- if ( [ token , alternate ] . includes ( arg . _cylcObject ) ) {
868- if ( arg . name === 'cutoff' ) {
869- // Work around for a field we don't want filled in, see:
870- // * https://github.com/cylc/cylc-ui/issues/1222
871- // * https://github.com/cylc/cylc-ui/issues/1225
872- // TODO: Once #1225 is done the field type can be safely changed in
873- // the schema without creating a compatibility issue with the UIS.
874- continue
875- }
876- if ( arg . _cylcObject === alternate ) {
877- token = alternate
878- }
879- if ( arg . _cylcType in compoundFields ) {
880- value = compoundFields [ arg . _cylcType ] ( tokens )
881- } else {
882- value = tokens [ token ]
883- }
884- if ( arg . _multiple ) {
885- value = [ value ]
886- }
887- argspec [ arg . name ] = value
888- break
889- }
806+ if (
807+ arg . _cylcObjects &&
808+ // Work around for a field we don't want filled in, see:
809+ // * https://github.com/cylc/cylc-ui/issues/1222
810+ // * https://github.com/cylc/cylc-ui/issues/1225
811+ // TODO: Once #1225 is done the field type can be safely changed in
812+ // the schema without creating a compatibility issue with the UIS.
813+ arg . name !== 'cutoff'
814+ ) {
815+ let value
816+ if ( arg . _cylcType in compoundFields ) {
817+ value = compoundFields [ arg . _cylcType ] ( tokens )
818+ } else {
819+ const alternate = alternateFields [ arg . _cylcType ]
820+ const token = arg . _cylcObjects . includes ( alternate )
821+ ? alternate
822+ : arg . _cylcObjects . find ( ( t ) => tokens [ t ] )
823+ value = tokens [ token ]
824+ }
825+ if ( value ) {
826+ argspec [ arg . name ] = arg . _multiple ? [ value ] : value
890827 }
891828 }
892- if ( ! argspec [ arg . name ] ) {
893- argspec [ arg . name ] = arg . _default
894- }
829+ argspec [ arg . name ] ||= arg . _default
895830 }
896831 return argspec
897832}
0 commit comments