22define ( [
33 'q' ,
44 'js/Dialogs/PluginConfig/PluginConfigDialog' ,
5+ './ConfigDialogEntries/CustomConfigEntries' ,
56 'deepforge/utils' ,
7+ 'js/Utils/ComponentSettings' ,
8+ 'panel/FloatingActionButton/styles/Materialize' ,
69 'text!js/Dialogs/PluginConfig/templates/PluginConfigDialog.html' ,
710 'css!./ConfigDialog.css'
811] , function (
912 Q ,
1013 PluginConfigDialog ,
14+ CustomConfigEntries ,
1115 utils ,
12- pluginConfigDialogTemplate ,
16+ ComponentSettings ,
17+ Materialize ,
18+ pluginConfigDialogTemplate
1319) {
1420 var SECTION_DATA_KEY = 'section' ,
1521 ATTRIBUTE_DATA_KEY = 'attribute' ,
@@ -18,38 +24,66 @@ define([
1824 ENTRY_BASE = $ ( '<div class="form-group"><div class="row"><label class="col-sm-4 control-label">NAME</label><div class="col-sm-8 controls"></div></div><div class="row description"><div class="col-sm-4"></div></div></div>' ) ,
1925 //jscs:enable maximumLineLength
2026 DESCRIPTION_BASE = $ ( '<div class="desc muted col-sm-8"></div>' ) ,
21- SECTION_HEADER = $ ( '<h6 class="config-section-header" >' ) ;
27+ SPINNER_BASE = $ ( '<span class="text-primary glyphicon glyphicon-refresh glyphicon-refresh-animate"></span >' ) ;
2228
2329 var ConfigDialog = function ( client ) {
2430 PluginConfigDialog . call ( this , { client : client } ) ;
2531 this . _widgets = { } ;
32+ this . _customEntriesManager = new CustomConfigEntries ( ) ;
33+ this . _initCustomEntriesManagerMethods ( ) ;
34+ this . imported = this . _registerCustomPropertyGridWidgets ( ) ;
2635 } ;
2736
2837 ConfigDialog . prototype = Object . create ( PluginConfigDialog . prototype ) ;
2938
39+ ConfigDialog . prototype . _initCustomEntriesManagerMethods = function ( ) {
40+ this . _customEntriesManager . getEntryForProperty = this . getEntryForProperty . bind ( this ) ;
41+ this . _customEntriesManager . getBaseStorageDir = this . getBaseStorageDir . bind ( this ) ;
42+ } ;
43+
44+ ConfigDialog . prototype . _registerCustomPropertyGridWidgets = async function ( ) {
45+ const self = this ;
46+ const customWidgets = ComponentSettings . resolveWithWebGMEGlobal (
47+ { } ,
48+ 'PropertyGridWidgets'
49+ ) . widgets || [ ] ;
50+
51+ const promises = customWidgets . map ( widgetInfo => {
52+ return new Promise ( ( resolve , reject ) => {
53+ require ( [ widgetInfo . path ] , function ( customWidget ) {
54+ const targetType = widgetInfo . type ;
55+ self . _propertyGridWidgetManager
56+ . registerWidgetForType ( targetType , customWidget ) ;
57+ resolve ( ) ;
58+ } , reject ) ;
59+ } ) ;
60+ } ) ;
61+ return Promise . all ( promises ) ;
62+ } ;
63+
3064 ConfigDialog . prototype . show = async function ( pluginMetadata , options = { } ) {
3165 const deferred = Q . defer ( ) ;
32-
3366 this . _pluginMetadata = pluginMetadata ;
3467 const prevConfig = await this . getSavedConfig ( ) ;
68+ await this . imported ;
3569 this . _initDialog ( pluginMetadata , prevConfig , options ) ;
3670
3771 this . _dialog . on ( 'shown' , ( ) => {
3872 this . _dialog . find ( 'input' ) . first ( ) . focus ( ) ;
3973 } ) ;
4074
41- this . _btnSave . on ( 'click' , event => {
42- this . submit ( deferred . resolve ) ;
75+ this . _btnSave . on ( 'click' , async event => {
4376 event . stopPropagation ( ) ;
4477 event . preventDefault ( ) ;
78+ await this . submit ( deferred . resolve ) ;
4579 } ) ;
4680
4781 //save&run on CTRL + Enter
48- this . _dialog . on ( 'keydown.PluginConfigDialog' , event => {
82+ this . _dialog . on ( 'keydown.PluginConfigDialog' , async event => {
4983 if ( event . keyCode === 13 && ( event . ctrlKey || event . metaKey ) ) {
5084 event . stopPropagation ( ) ;
5185 event . preventDefault ( ) ;
52- this . submit ( deferred . resolve ) ;
86+ await this . submit ( deferred . resolve ) ;
5387 }
5488 } ) ;
5589 this . _dialog . modal ( 'show' ) ;
@@ -63,6 +97,7 @@ define([
6397 this . _divContainer = this . _dialog . find ( '.modal-body' ) ;
6498 this . _saveConfigurationCb = this . _dialog . find ( '.save-configuration' ) ;
6599 this . _modalHeader = this . _dialog . find ( '.modal-header' ) ;
100+ this . _modalFooter = this . _dialog . find ( '.modal-footer' ) ;
66101 this . _saveConfigurationCb . find ( 'input' ) . prop ( 'checked' , true ) ;
67102
68103 // Create the header
@@ -85,8 +120,10 @@ define([
85120 } ;
86121 } ;
87122
88- ConfigDialog . prototype . submit = function ( callback ) {
89- const config = this . _getAllConfigValues ( ) ;
123+ ConfigDialog . prototype . submit = async function ( callback ) {
124+ this . _btnSave . attr ( 'disabled' , true ) ;
125+ SPINNER_BASE . insertAfter ( this . _modalFooter . find ( 'form' ) ) ;
126+ const config = await this . _getAllConfigValues ( ) ;
90127 const saveConfig = this . _saveConfigurationCb . find ( 'input' )
91128 . prop ( 'checked' ) ;
92129
@@ -159,16 +196,23 @@ define([
159196 return response . status < 399 ? await response . json ( ) : null ;
160197 } ;
161198
162- ConfigDialog . prototype . _getAllConfigValues = function ( ) {
199+ ConfigDialog . prototype . _getAllConfigValues = async function ( ) {
163200 var settings = { } ;
164-
165- Object . keys ( this . _widgets ) . forEach ( namespace => {
201+ for ( const namespace of Object . keys ( this . _widgets ) ) {
166202 settings [ namespace ] = { } ;
167203
168- Object . keys ( this . _widgets [ namespace ] ) . forEach ( name => {
169- settings [ namespace ] [ name ] = this . _widgets [ namespace ] [ name ] . getValue ( ) ;
170- } ) ;
171- } ) ;
204+ for ( const name of Object . keys ( this . _widgets [ namespace ] ) ) {
205+ let value ;
206+ try {
207+ value = await this . _widgets [ namespace ] [ name ] . getValue ( ) ;
208+ } catch ( e ) {
209+ Materialize . toast ( e . message , 4000 ) ;
210+ this . _dialog . modal ( 'hide' ) ;
211+ throw e ;
212+ }
213+ settings [ namespace ] [ name ] = value ;
214+ }
215+ }
172216
173217 return settings ;
174218 } ;
@@ -224,8 +268,8 @@ define([
224268
225269 ConfigDialog . prototype . getEntryForProperty = function ( configEntry , prevConfig = { } ) {
226270 let entry = null ;
227- if ( ConfigDialog . ENTRIES [ configEntry . valueType ] ) {
228- entry = ConfigDialog . ENTRIES [ configEntry . valueType ] . call ( this , configEntry , prevConfig ) ;
271+ if ( CustomConfigEntries . isCustomEntryValueType ( configEntry . valueType ) ) {
272+ entry = this . _customEntriesManager [ configEntry . valueType ] ( configEntry , prevConfig ) ;
229273 } else {
230274 const widget = this . getWidgetForProperty ( configEntry ) ;
231275 const el = ENTRY_BASE . clone ( ) ;
@@ -274,127 +318,15 @@ define([
274318 }
275319 } ;
276320
277- ConfigDialog . WIDGETS = { } ;
278- ConfigDialog . ENTRIES = { } ;
279- ConfigDialog . ENTRIES . section = function ( configEntry ) {
280- const sectionHeader = SECTION_HEADER . clone ( ) ;
281- sectionHeader . text ( configEntry . displayName ) ;
282- return { el : sectionHeader } ;
321+ ConfigDialog . prototype . getBaseStorageDir = function ( ) {
322+ return `${ this . _client . getActiveProjectId ( ) } /artifacts` ;
283323 } ;
284324
285- ConfigDialog . ENTRIES . group = function ( configEntry , config ) {
286- const widget = { el : null } ;
287- widget . el = $ ( '<div>' , { class : configEntry . name } ) ;
288-
289- const entries = configEntry . valueItems
290- . map ( item => this . getEntryForProperty ( item , config ) ) ;
291-
292- entries . forEach ( entry => widget . el . append ( entry . el ) ) ;
293-
294- widget . getValue = ( ) => {
295- const config = { } ;
296- entries . forEach ( entry => {
297- if ( entry . widget ) {
298- config [ entry . id || entry . name ] = entry . widget . getValue ( ) ;
299- }
300- } ) ;
301- return config ;
302- } ;
303-
304- widget . setValue = config => {
305- entries . forEach ( entry => {
306- const value = config [ entry . id || entry . name ] ;
307- if ( entry . widget && value !== undefined ) {
308- entry . widget . setValue ( value ) ;
309- }
310- } ) ;
311- return config ;
312- } ;
313-
314- return { widget, el : widget . el } ;
325+ ConfigDialog . prototype . getComponentId = function ( ) {
326+ return 'ConfigDialog' ;
315327 } ;
316328
317- ConfigDialog . ENTRIES . dict = function ( configEntry , config ) {
318- const widget = { el : null , active : null } ;
319- widget . el = $ ( '<div>' , { class : configEntry . name } ) ;
320-
321- const entriesForItem = { } ;
322- const valueItemsDict = { } ;
323- for ( let i = 0 ; i < configEntry . valueItems . length ; i ++ ) {
324- const valueItem = configEntry . valueItems [ i ] ;
325- const entries = valueItem . configStructure
326- . map ( item => {
327- const entry = this . getEntryForProperty ( item , config ) ;
328- return entry ;
329- } ) ;
330-
331- entries . forEach ( entry => {
332- if ( i > 0 ) {
333- entry . el . css ( 'display' , 'none' ) ;
334- }
335- widget . el . append ( entry . el ) ;
336- } ) ;
337-
338- const displayName = valueItem . displayName || valueItem . name ;
339- entriesForItem [ displayName ] = entries ;
340- valueItemsDict [ displayName ] = valueItem ;
341- }
342-
343- const itemNames = Object . keys ( valueItemsDict ) ;
344- const defaultValue = itemNames [ 0 ] ;
345-
346- const configForKeys = {
347- name : configEntry . name ,
348- displayName : configEntry . displayName ,
349- value : defaultValue ,
350- valueType : 'string' ,
351- valueItems : itemNames
352- } ;
353- const selector = this . getEntryForProperty ( configForKeys ) ;
354-
355- widget . active = defaultValue ;
356- widget . onSetSelector = value => {
357- const oldEntries = entriesForItem [ widget . active ] ;
358- oldEntries . forEach ( entry => entry . el . css ( 'display' , 'none' ) ) ;
359-
360- widget . active = value ;
361- entriesForItem [ widget . active ]
362- . forEach ( entry => entry . el . css ( 'display' , '' ) ) ;
363- } ;
364-
365- selector . el . find ( 'select' ) . on ( 'change' , event => {
366- const { value} = event . target ;
367- widget . onSetSelector ( value ) ;
368- } ) ;
369-
370- widget . getValue = ( ) => {
371- const displayName = widget . active ;
372- const name = valueItemsDict [ displayName ] . name ;
373- const config = { } ;
374- entriesForItem [ name ] . forEach ( entry => {
375- if ( entry . widget ) {
376- config [ entry . id ] = entry . widget . getValue ( ) ;
377- }
378- } ) ;
379- return { name, config} ;
380- } ;
381-
382- widget . setValue = value => {
383- const { name, config} = value ;
384- selector . widget . setValue ( name ) ;
385- widget . onSetSelector ( name ) ;
386- entriesForItem [ name ] . forEach ( entry => {
387- if ( entry . widget ) {
388- entry . widget . setValue ( config [ entry . id ] ) ;
389- }
390- } ) ;
391- return { name, config} ;
392- } ;
393-
394- widget . el . prepend ( selector . el ) ;
395-
396- return { widget, el : widget . el } ;
397- } ;
329+ ConfigDialog . WIDGETS = { } ;
398330
399331 return ConfigDialog ;
400332} ) ;
0 commit comments