@@ -25,8 +25,69 @@ const populateFieldsFromURL = () => {
2525 if ( urlParams . has ( 'schedule_mode' ) ) {
2626 document . querySelector ( 'select[name="schedule_mode"]' ) . value = escapeString ( urlParams . get ( 'schedule_mode' ) ) ;
2727 }
28+ if ( urlParams . has ( 'usage_scenario_variables' ) ) {
29+ try {
30+ const variables = JSON . parse ( urlParams . get ( 'usage_scenario_variables' ) ) ;
31+ const variablesContainer = document . getElementById ( 'variables-container' ) ;
32+ variablesContainer . innerHTML = '' ;
33+
34+ for ( const key in variables ) {
35+ if ( Object . hasOwnProperty . call ( variables , key ) ) {
36+ const match = key . match ( / ^ _ _ G M T _ V A R _ ( [ \w ] + ) _ _ $ / ) ;
37+ if ( match ) {
38+ addVariableField ( match [ 1 ] , variables [ key ] ) ;
39+ }
40+ }
41+ }
42+ } catch ( e ) {
43+ console . error ( 'Failed to parse usage_scenario_variables from URL:' , e ) ;
44+ }
45+ }
2846}
2947
48+ const addVariableField = ( keyPart = '' , value = '' ) => {
49+ const variablesContainer = document . getElementById ( 'variables-container' ) ;
50+ const newVariableRow = document . createElement ( 'div' ) ;
51+ newVariableRow . classList . add ( 'variable-row' , 'ui' , 'grid' , 'middle' , 'aligned' , 'stackable' ) ;
52+
53+ newVariableRow . innerHTML = `
54+ <div class="seven wide column">
55+ <div class="ui right labeled input fluid">
56+ <div class="ui label">__GMT_VAR_</div>
57+ <input type="text" placeholder="Key (Variables are optional. Leave empty if not needed)" class="variable-key" pattern="[\\w]+" title="Only alphanumeric characters and underscores are allowed." value="${ escapeString ( keyPart ) } ">
58+ <div class="ui label">__</div>
59+ </div>
60+ </div>
61+ <div class="one wide column computer only tablet only" style="text-align: center; padding: 0;">
62+ =
63+ </div>
64+ <div class="eight wide column">
65+ <div class="ui action input fluid">
66+ <input type="text" placeholder="Value (Variables are optional. Leave empty if not needed)" class="variable-value" value="${ escapeString ( value ) } ">
67+ <button type="button" class="ui red mini icon button remove-variable">
68+ <i class="times icon"></i>
69+ </button>
70+ </div>
71+ </div>
72+ ` ;
73+
74+ variablesContainer . appendChild ( newVariableRow ) ;
75+
76+ const divider = document . createElement ( 'div' ) ;
77+ divider . classList . add ( 'ui' , 'divider' , 'custom-mobile-divider' ) ;
78+ variablesContainer . appendChild ( divider ) ;
79+
80+ updateRemoveButtonsVisibility ( ) ;
81+ } ;
82+
83+ const updateRemoveButtonsVisibility = ( ) => {
84+ const variableRows = document . querySelectorAll ( '#variables-container .variable-row' ) ;
85+ variableRows . forEach ( row => {
86+ row . querySelector ( '.remove-variable' ) . style . display = 'inline-block' ;
87+ } ) ;
88+
89+ } ;
90+
3091
3192( async ( ) => {
3293
@@ -48,6 +109,14 @@ const populateFieldsFromURL = () => {
48109 showNotification ( 'Could not get machines data from API' , err ) ;
49110 }
50111
112+ $ ( '#add-variable' ) . on ( 'click' , ( ) => addVariableField ( ) ) ;
113+ addVariableField ( ) // always add one empty row
114+
115+ $ ( '#variables-container' ) . on ( 'click' , '.remove-variable' , function ( e ) {
116+ $ ( this ) . closest ( '.variable-row' ) . remove ( ) ;
117+ updateRemoveButtonsVisibility ( ) ;
118+ } ) ;
119+
51120
52121 document . forms [ 0 ] . onsubmit = async ( event ) => {
53122 event . preventDefault ( ) ;
@@ -56,6 +125,28 @@ const populateFieldsFromURL = () => {
56125 const data = new FormData ( form ) ;
57126 const values = Object . fromEntries ( data . entries ( ) ) ;
58127
128+ const usageScenarioVariables = { } ;
129+ let validationError = false ;
130+ document . querySelectorAll ( '#variables-container .variable-row' ) . forEach ( row => {
131+ const keyPart = row . querySelector ( '.variable-key' ) . value . trim ( ) ;
132+ const value = row . querySelector ( '.variable-value' ) . value . trim ( ) ;
133+ if ( keyPart ) {
134+ if ( ! / ^ [ \w ] + $ / . test ( keyPart ) ) {
135+ showNotification ( 'Validation Error' , `Variable part "${ keyPart } " must only contain alphanumeric characters.` , 'error' ) ;
136+ validationError = true ;
137+ return ;
138+ }
139+ const key = `__GMT_VAR_${ keyPart } __` ;
140+ usageScenarioVariables [ key ] = value ;
141+ }
142+ } ) ;
143+
144+ if ( validationError ) {
145+ return ;
146+ }
147+
148+ values . usage_scenario_variables = usageScenarioVariables ;
149+
59150 for ( let key in values ) {
60151 if ( typeof values [ key ] === 'string' ) {
61152 values [ key ] = values [ key ] . trim ( ) ;
@@ -65,12 +156,11 @@ const populateFieldsFromURL = () => {
65156 try {
66157 await makeAPICall ( '/v1/software/add' , values ) ;
67158 form . reset ( )
159+ document . getElementById ( 'variables-container' ) . innerHTML = '' ;
68160 showNotification ( 'Success' , 'Save successful. Check your mail in 10-15 minutes' , 'success' ) ;
69161 } catch ( err ) {
70162 showNotification ( 'Could not get data from API' , err ) ;
71163 }
72164
73165 }
74-
75-
76166} ) ( ) ;
0 commit comments