@@ -389,13 +389,19 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
389389 return list ;
390390 } ,
391391
392+ __uuidToNumber : function ( uuid ) {
393+ const nThumbnails = 25 ;
394+ const lastCharacters = uuid . substr ( uuid . length - 10 ) ;
395+ const aNumber = parseInt ( lastCharacters , 16 ) ;
396+ return aNumber % nThumbnails ;
397+ } ,
398+
392399 /**
393400 * Delegates appearance and binding of each study item
394401 */
395402 __getDelegate : function ( fromTemplate , list ) {
396403 const thumbnailWidth = 200 ;
397404 const thumbnailHeight = 120 ;
398- const nThumbnails = 25 ;
399405 let that = this ;
400406 let delegate = {
401407 // Item's Layout
@@ -433,12 +439,15 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
433439 } ,
434440 // Item's data binding
435441 bindItem : function ( controller , item , id ) {
436- controller . bindProperty ( "uuid" , "icon" , {
442+ controller . bindProperty ( "uuid" , "model" , null , item , id ) ;
443+ controller . bindProperty ( "thumbnail" , "icon" , {
437444 converter : function ( data ) {
438- if ( data ) {
439- const lastCharacters = data . substr ( data . length - 10 ) ;
440- const aNumber = parseInt ( lastCharacters , 16 ) ;
441- const thumbnailId = aNumber % nThumbnails ;
445+ const uuid = item . getModel ( ) ;
446+ if ( uuid ) {
447+ if ( data ) {
448+ return data ;
449+ }
450+ const thumbnailId = that . __uuidToNumber ( uuid ) ; // eslint-disable-line no-underscore-dangle
442451 return "qxapp/img" + thumbnailId + ".jpg" ;
443452 }
444453 return "@FontAwesome5Solid/plus-circle/80" ;
@@ -459,11 +468,6 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
459468 return data ? new Date ( data ) : null ;
460469 }
461470 } , item , id ) ;
462- controller . bindProperty ( "uuid" , "model" , {
463- converter : function ( data ) {
464- return data ;
465- }
466- } , item , id ) ;
467471 } ,
468472 configureItem : item => {
469473 item . getChildControl ( "icon" ) . set ( {
@@ -509,13 +513,19 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
509513 } ) ;
510514 } ,
511515
512- __createForm : function ( studyData , fromTemplate ) {
516+ __createForm : function ( studyData , isTemplate ) {
513517 while ( this . __editStudyLayout . getChildren ( ) . length > 1 ) {
514518 this . __editStudyLayout . removeAt ( 1 ) ;
515519 }
516520
517- const itemsToBeDisplayed = [ "name" , "description" , "prjOwner" , "creationDate" , "lastChangeDate" ] ;
518- const itemsToBeModified = fromTemplate ? [ ] : [ "name" , "description" ] ;
521+ const canCreateTemplate = qxapp . data . Permissions . getInstance ( ) . canDo ( "studies.template.create" ) ;
522+ const canUpdateTemplate = qxapp . data . Permissions . getInstance ( ) . canDo ( "studies.template.update" ) ;
523+ const canDeleteTemplate = qxapp . data . Permissions . getInstance ( ) . canDo ( "studies.template.delete" ) ;
524+ const isMyTemplate = studyData [ "prjOwner" ] === qxapp . data . Permissions . getInstance ( ) . getLogin ( ) ;
525+
526+ const itemsToBeDisplayed = [ "name" , "description" , "thumbnail" , "prjOwner" , "creationDate" , "lastChangeDate" ] ;
527+ const itemsToBeModified = ( isTemplate && ! ( canUpdateTemplate && isMyTemplate ) ) ? [ ] : [ "name" , "description" , "thumbnail" ] ;
528+
519529 let form = new qx . ui . form . Form ( ) ;
520530 let control ;
521531 for ( const dataId in studyData ) {
@@ -529,6 +539,10 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
529539 control = new qx . ui . form . TextField ( ) ;
530540 form . add ( control , this . tr ( "Description" ) ) ;
531541 break ;
542+ case "thumbnail" :
543+ control = new qx . ui . form . TextField ( ) ;
544+ form . add ( control , this . tr ( "Thumbnail" ) ) ;
545+ break ;
532546 case "prjOwner" :
533547 control = new qx . ui . form . TextField ( ) ;
534548 form . add ( control , this . tr ( "Owner" ) ) ;
@@ -563,7 +577,7 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
563577 // buttons
564578 let saveButton = new qx . ui . form . Button ( this . tr ( "Save" ) ) ;
565579 saveButton . setMinWidth ( 70 ) ;
566- saveButton . setEnabled ( ! fromTemplate ) ;
580+ saveButton . setEnabled ( ! isTemplate || ( canUpdateTemplate && isMyTemplate ) ) ;
567581 saveButton . addListener ( "execute" , e => {
568582 for ( let i = 0 ; i < itemsToBeModified . length ; i ++ ) {
569583 const key = itemsToBeModified [ i ] ;
@@ -574,7 +588,11 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
574588 let resource = this . __studyResources . project ;
575589
576590 resource . addListenerOnce ( "putSuccess" , ev => {
577- this . reloadUserStudies ( ) ;
591+ if ( isTemplate ) {
592+ this . reloadTemplateStudies ( ) ;
593+ } else {
594+ this . reloadUserStudies ( ) ;
595+ }
578596 } , this ) ;
579597
580598 resource . put ( {
@@ -585,6 +603,35 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
585603 } , this ) ;
586604 form . addButton ( saveButton ) ;
587605
606+ if ( ! isTemplate && canCreateTemplate ) {
607+ const saveAsButton = new qx . ui . form . Button ( this . tr ( "Save As Template" ) ) ;
608+ saveAsButton . setMinWidth ( 70 ) ;
609+
610+ saveAsButton . addListener ( "execute" , e => {
611+ for ( let i = 0 ; i < itemsToBeModified . length ; i ++ ) {
612+ const key = itemsToBeModified [ i ] ;
613+ let getter = "get" + qx . lang . String . firstUp ( key ) ;
614+ let newVal = model [ getter ] ( ) ;
615+ studyData [ key ] = newVal ;
616+ }
617+
618+ const resources = this . __studyResources . projects ;
619+
620+ resources . addListenerOnce ( "postSaveAsTemplateSuccess" , ev => {
621+ console . log ( ev ) ;
622+ this . reloadTemplateStudies ( ) ;
623+ } , this ) ;
624+ resources . addListenerOnce ( "postSaveAsTemplateError" , ev => {
625+ console . error ( ev ) ;
626+ } ) ;
627+ resources . postSaveAsTemplate ( {
628+ "study_id" : studyData [ "uuid" ]
629+ } , studyData ) ;
630+ } , this ) ;
631+
632+ form . addButton ( saveAsButton ) ;
633+ }
634+
588635 let cancelButton = new qx . ui . form . Button ( this . tr ( "Cancel" ) ) ;
589636 cancelButton . setMinWidth ( 70 ) ;
590637 cancelButton . addListener ( "execute" , e => {
@@ -594,14 +641,14 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
594641
595642 let deleteButton = new qx . ui . form . Button ( this . tr ( "Delete" ) ) ;
596643 deleteButton . setMinWidth ( 70 ) ;
597- deleteButton . setEnabled ( ! fromTemplate ) ;
644+ deleteButton . setEnabled ( ! isTemplate || ( canDeleteTemplate && isMyTemplate ) ) ;
598645 deleteButton . addListener ( "execute" , e => {
599646 let win = this . __createConfirmWindow ( ) ;
600647 win . center ( ) ;
601648 win . open ( ) ;
602649 win . addListener ( "close" , ( ) => {
603650 if ( win [ "value" ] === 1 ) {
604- this . __deleteStudy ( studyData ) ;
651+ this . __deleteStudy ( studyData , isTemplate ) ;
605652 }
606653 } , this ) ;
607654 } , this ) ;
@@ -610,13 +657,17 @@ qx.Class.define("qxapp.desktop.StudyBrowser", {
610657 this . __editStudyLayout . add ( new qx . ui . form . renderer . Single ( form ) ) ;
611658 } ,
612659
613- __deleteStudy : function ( studyData ) {
660+ __deleteStudy : function ( studyData , isTemplate = false ) {
614661 this . __stopInteractiveServicesInStudy ( studyData ) ;
615662
616663 let resource = this . __studyResources . project ;
617664
618665 resource . addListenerOnce ( "delSuccess" , ev => {
619- this . reloadUserStudies ( ) ;
666+ if ( isTemplate ) {
667+ this . reloadTemplateStudies ( ) ;
668+ } else {
669+ this . reloadUserStudies ( ) ;
670+ }
620671 } , this ) ;
621672
622673 resource . del ( {
0 commit comments