5
5
import { inject } from '@theia/core/shared/inversify' ;
6
6
import { LabelProvider } from '@theia/core/lib/browser' ;
7
7
import { WorkspaceInputDialog , WorkspaceInputDialogProps } from '@theia/workspace/lib/browser/workspace-input-dialog' ;
8
- import { toPascal } from '@crossbreeze/protocol' ;
9
8
10
- const DataModelInputDialogProps = Symbol ( 'DataModelInputDialogProps ' ) ;
11
- interface DataModelInputDialogProps extends WorkspaceInputDialogProps {
12
- dataModelTypes : string [ ] ;
9
+ const GridInputDialogProps = Symbol ( 'GridInputDialogProps ' ) ;
10
+ interface GridInputDialogProps < T extends readonly InputOptions [ ] = readonly InputOptions [ ] > extends WorkspaceInputDialogProps {
11
+ inputs : T ;
13
12
}
14
13
15
- export class DataModelInputDialog extends WorkspaceInputDialog {
16
- protected readonly versionInput : HTMLInputElement ;
17
- protected readonly typeSelector : HTMLSelectElement ;
14
+ export interface InputOptions {
15
+ placeholder ?: string ;
16
+ value ?: string ;
17
+ id : string ;
18
+ label : string ;
19
+ options ?: Record < string , string > ;
20
+ }
21
+
22
+ export type FieldValues < T extends readonly InputOptions [ ] > = Record < T [ number ] [ 'id' ] , string > ;
23
+
24
+ interface LabelOptions {
25
+ text : string ;
26
+ for : string ;
27
+ }
28
+
29
+ export class GridInputDialog extends WorkspaceInputDialog {
18
30
protected readonly grid : HTMLDivElement ;
19
31
20
32
constructor (
21
- @inject ( DataModelInputDialogProps ) protected override readonly props : DataModelInputDialogProps ,
33
+ @inject ( GridInputDialogProps ) protected override readonly props : GridInputDialogProps ,
22
34
@inject ( LabelProvider ) protected override readonly labelProvider : LabelProvider
23
35
) {
24
36
super ( props , labelProvider ) ;
25
37
this . grid = this . getGrid ( ) ;
26
- this . contentNode . appendChild ( this . grid ) ;
38
+ this . contentNode . insertBefore ( this . grid , this . inputField ) ;
39
+ this . addInputs ( ) ;
40
+ }
41
+
42
+ protected addInputs ( ) : void {
27
43
const idBase = Date . now ( ) . toString ( 26 ) ;
28
- const nameInputId = idBase + '-name' ;
29
- this . grid . appendChild ( createLabel ( { text : 'Model Name' , for : nameInputId } ) ) ;
30
- this . inputField . id = nameInputId ;
31
- this . grid . appendChild ( this . inputField ) ;
32
- const versionInputId = idBase + '-version' ;
33
- this . grid . appendChild ( createLabel ( { text : 'Version' , for : versionInputId } ) ) ;
34
- this . versionInput = createInput ( { placeholder : '1.0.0' , value : '1.0.0' , id : versionInputId } ) ;
35
- this . grid . appendChild ( this . versionInput ) ;
36
- const typeInputId = idBase + '-type' ;
37
- this . grid . appendChild ( createLabel ( { text : 'Type' , for : typeInputId } ) ) ;
38
- this . typeSelector = createInput ( {
39
- value : 'logical' ,
40
- id : typeInputId ,
41
- options : Object . fromEntries ( props . dataModelTypes . map ( key => [ key , toPascal ( key ) ] ) )
44
+ let inputFieldSet = false ;
45
+ this . props . inputs . forEach ( inputProps => {
46
+ const computedId = idBase + '-' + inputProps . id ;
47
+ const label = createLabel ( { text : inputProps . label , for : computedId } ) ;
48
+ this . grid . appendChild ( label ) ;
49
+ if ( ! inputFieldSet && ! inputProps . options ) {
50
+ inputFieldSet = true ;
51
+ this . inputField . id = computedId ;
52
+ this . grid . appendChild ( this . inputField ) ;
53
+ } else {
54
+ const input = createInput ( { ...inputProps , id : computedId } ) ;
55
+ this . grid . appendChild ( input ) ;
56
+ }
42
57
} ) ;
43
- this . grid . appendChild ( this . typeSelector ) ;
44
58
}
45
59
46
60
protected getGrid ( ) : HTMLDivElement {
@@ -53,31 +67,31 @@ export class DataModelInputDialog extends WorkspaceInputDialog {
53
67
}
54
68
55
69
override get value ( ) : string {
56
- const name = this . inputField . value ;
57
- const version = this . versionInput . value ;
58
- const type = this . typeSelector . value ;
59
- return JSON . stringify ( { name, version, type } ) ;
70
+ const data : Record < string , string > = { } ;
71
+ for ( let i = 0 ; i < this . grid . children . length ; i ++ ) {
72
+ const child = this . grid . children [ i ] ;
73
+ if ( child instanceof HTMLLabelElement ) {
74
+ continue ;
75
+ }
76
+ const value = ( child as HTMLInputElement | HTMLSelectElement ) . value ;
77
+ const id = child . id . slice ( child . id . indexOf ( '-' ) + 1 ) ;
78
+ data [ id ] = value ;
79
+ }
80
+ return JSON . stringify ( data ) ;
60
81
}
61
82
}
62
83
63
- export async function getNewDataModelOptions (
64
- props : DataModelInputDialogProps ,
84
+ export async function getGridInputOptions < T extends readonly InputOptions [ ] > (
85
+ props : GridInputDialogProps < T > ,
65
86
labelProvider : LabelProvider
66
- ) : Promise < { name : string ; version : string ; type : string } | undefined > {
67
- const userSelection = await new DataModelInputDialog ( props , labelProvider ) . open ( ) ;
87
+ ) : Promise < FieldValues < T > | undefined > {
88
+ const userSelection = await new GridInputDialog ( props , labelProvider ) . open ( ) ;
68
89
if ( ! userSelection ) {
69
90
return undefined ;
70
91
}
71
92
return JSON . parse ( userSelection ) ;
72
93
}
73
94
74
- interface InputOptions {
75
- placeholder ?: string ;
76
- value ?: string ;
77
- id ?: string ;
78
- options ?: Record < string , string > ;
79
- }
80
-
81
95
function createInput < T extends InputOptions , U = T extends { options : Record < string , string > } ? HTMLSelectElement : HTMLInputElement > (
82
96
options : T
83
97
) : U {
@@ -90,12 +104,6 @@ function createInput<T extends InputOptions, U = T extends { options: Record<str
90
104
inputField . placeholder = options . placeholder || '' ;
91
105
inputField . type = 'text' ;
92
106
}
93
- if ( options . value ) {
94
- inputField . value = options . value ;
95
- }
96
- if ( options . id ) {
97
- inputField . id = options . id ;
98
- }
99
107
if ( options . options ) {
100
108
Object . entries ( options . options ) . forEach ( ( [ key , value ] ) => {
101
109
const option = document . createElement ( 'option' ) ;
@@ -104,14 +112,15 @@ function createInput<T extends InputOptions, U = T extends { options: Record<str
104
112
inputField . appendChild ( option ) ;
105
113
} ) ;
106
114
}
115
+ if ( options . value ) {
116
+ inputField . value = options . value ;
117
+ }
118
+ if ( options . id ) {
119
+ inputField . id = options . id ;
120
+ }
107
121
return inputField as U ;
108
122
}
109
123
110
- interface LabelOptions {
111
- text : string ;
112
- for : string ;
113
- }
114
-
115
124
function createLabel ( options : LabelOptions ) : HTMLLabelElement {
116
125
const label = document . createElement ( 'label' ) ;
117
126
label . setAttribute ( 'for' , options . for ) ;
0 commit comments