1
1
import { message } from "antd" ;
2
2
import { ActionConfig , ActionExecuteParams } from "../types" ;
3
+ import ApplicationApi from "api/applicationApi" ;
4
+ import { getApplicationIdInReducer } from "comps/utils/reduceContext" ;
5
+ import { executeQueryAction } from "lowcoder-core" ;
6
+ import { getPromiseAfterDispatch } from "util/promiseUtils" ;
7
+ import { runScript } from "../utils" ;
8
+
3
9
4
10
export const configureAppMetaAction : ActionConfig = {
5
11
key : 'configure-app-meta' ,
@@ -43,4 +49,250 @@ export const configureAppMetaAction: ActionConfig = {
43
49
message . error ( 'Failed to update app configuration' ) ;
44
50
}
45
51
}
46
- } ;
52
+ } ;
53
+
54
+ export const publishAppAction : ActionConfig = {
55
+ key : 'publish-app' ,
56
+ label : 'Publish app' ,
57
+ category : 'app-configuration' ,
58
+ requiresInput : false ,
59
+ execute : async ( ) => {
60
+ try {
61
+ const applicationId = getApplicationIdInReducer ( ) ;
62
+
63
+ if ( ! applicationId ) {
64
+ message . error ( 'Application ID not found' ) ;
65
+ return ;
66
+ }
67
+
68
+ const response = await ApplicationApi . publishApplication ( { applicationId } ) ;
69
+
70
+ if ( response . data . success ) {
71
+ message . success ( 'Application published successfully' ) ;
72
+ window . open ( `/applications/${ applicationId } /view` , '_blank' ) ;
73
+ } else {
74
+ message . error ( 'Failed to publish application' ) ;
75
+ }
76
+
77
+ } catch ( error ) {
78
+ console . error ( 'Error publishing application:' , error ) ;
79
+ message . error ( 'Failed to publish application' ) ;
80
+ }
81
+ }
82
+ } ;
83
+
84
+ export const shareAppAction : ActionConfig = {
85
+ key : 'share-app' ,
86
+ label : 'Share app' ,
87
+ category : 'app-configuration' ,
88
+ requiresInput : false ,
89
+ execute : async ( ) => {
90
+ // TODO: Implement share app
91
+ console . log ( 'Share app' ) ;
92
+ }
93
+ } ;
94
+
95
+ export const testAllDatasourcesAction : ActionConfig = {
96
+ key : 'test-all-datasources' ,
97
+ label : 'Test all datasources' ,
98
+ category : 'app-configuration' ,
99
+ requiresInput : false ,
100
+ execute : async ( params : ActionExecuteParams ) => {
101
+ const { editorState } = params ;
102
+
103
+ try {
104
+ const allQueries = editorState . getQueriesComp ( ) . getView ( ) ;
105
+
106
+ if ( ! allQueries || ! allQueries . length ) {
107
+ message . info ( 'No queries found in the application' ) ;
108
+ return ;
109
+ }
110
+
111
+ console . log ( `Found ${ allQueries . length } queries to test` ) ;
112
+
113
+ const results = {
114
+ total : allQueries . length ,
115
+ successful : 0 ,
116
+ failed : 0 ,
117
+ errors : [ ] as Array < { queryName : string ; error : string } >
118
+ } ;
119
+
120
+ message . loading ( `Testing ${ allQueries . length } queries...` , 0 ) ;
121
+
122
+ for ( let i = 0 ; i < allQueries . length ; i ++ ) {
123
+ const query = allQueries [ i ] ;
124
+ const queryName = query . children . name . getView ( ) ;
125
+
126
+ try {
127
+ await getPromiseAfterDispatch (
128
+ query . dispatch ,
129
+ executeQueryAction ( {
130
+ // In some data queries, we need to pass args to the query
131
+ // Currently, we don't have a way to pass args to the query
132
+ // So we are passing an empty object
133
+ args : { } ,
134
+ afterExecFunc : ( ) => {
135
+ console . log ( `Query ${ queryName } executed successfully` ) ;
136
+ }
137
+ } ) ,
138
+ {
139
+ notHandledError : `Failed to execute query: ${ queryName } `
140
+ }
141
+ ) ;
142
+
143
+ results . successful ++ ;
144
+
145
+ } catch ( error ) {
146
+ const errorMessage = error instanceof Error ? error . message : 'Unknown error' ;
147
+ console . error ( `Query ${ queryName } failed:` , error ) ;
148
+
149
+ results . failed ++ ;
150
+ results . errors . push ( {
151
+ queryName,
152
+ error : errorMessage
153
+ } ) ;
154
+ }
155
+
156
+ if ( i < allQueries . length - 1 ) {
157
+ await new Promise ( resolve => setTimeout ( resolve , 500 ) ) ;
158
+ }
159
+ }
160
+
161
+ message . destroy ( ) ;
162
+
163
+ if ( results . failed === 0 ) {
164
+ message . success ( `All ${ results . total } queries executed successfully!` ) ;
165
+ } else if ( results . successful === 0 ) {
166
+ message . error ( `All ${ results . total } queries failed. Check console for details.` ) ;
167
+ } else {
168
+ message . warning (
169
+ `Query test completed: ${ results . successful } successful, ${ results . failed } failed`
170
+ ) ;
171
+ }
172
+
173
+ console . group ( 'Query Test Results' ) ;
174
+ console . log ( `Total queries: ${ results . total } ` ) ;
175
+ console . log ( `Successful: ${ results . successful } ` ) ;
176
+ console . log ( `Failed: ${ results . failed } ` ) ;
177
+
178
+ if ( results . errors . length > 0 ) {
179
+ console . group ( 'Failed Queries:' ) ;
180
+ results . errors . forEach ( ( { queryName, error } ) => {
181
+ console . error ( `${ queryName } : ${ error } ` ) ;
182
+ } ) ;
183
+ console . groupEnd ( ) ;
184
+ }
185
+ console . groupEnd ( ) ;
186
+
187
+ } catch ( error ) {
188
+ message . destroy ( ) ;
189
+ console . error ( 'Error during application testing:' , error ) ;
190
+ message . error ( 'Failed to test application. Check console for details.' ) ;
191
+ }
192
+ }
193
+ } ;
194
+
195
+ export const applyGlobalJSAction : ActionConfig = {
196
+ key : 'apply-global-js' ,
197
+ label : 'Apply global JS' ,
198
+ category : 'app-configuration' ,
199
+ requiresInput : true ,
200
+ inputPlaceholder : 'Enter JavaScript code to apply globally...' ,
201
+ inputType : 'textarea' ,
202
+ validation : ( value : string ) => {
203
+ if ( ! value . trim ( ) ) {
204
+ return 'JavaScript code is required' ;
205
+ }
206
+ try {
207
+ new Function ( value ) ;
208
+ return null ;
209
+ } catch ( error ) {
210
+ return 'Invalid JavaScript syntax' ;
211
+ }
212
+ } ,
213
+ execute : async ( params : ActionExecuteParams ) => {
214
+ const { editorState, actionValue } = params ;
215
+
216
+ try {
217
+ const defaultJS = `console.log('Please provide a valid JavaScript code');` . trim ( ) ;
218
+
219
+ const jsCode = actionValue . trim ( ) || defaultJS ;
220
+
221
+ const preloadComp = editorState . rootComp . children . preload ;
222
+ if ( ! preloadComp ) {
223
+ message . error ( 'Preload component not found' ) ;
224
+ return ;
225
+ }
226
+
227
+ const scriptComp = preloadComp . children . script ;
228
+ if ( ! scriptComp ) {
229
+ message . error ( 'Script component not found' ) ;
230
+ return ;
231
+ }
232
+
233
+ scriptComp . dispatchChangeValueAction ( jsCode ) ;
234
+ runScript ( jsCode , false ) ;
235
+
236
+ message . success ( 'Global JavaScript applied successfully!' ) ;
237
+
238
+ } catch ( error ) {
239
+ console . error ( 'Error applying global JavaScript:' , error ) ;
240
+ message . error ( 'Failed to apply global JavaScript. Check console for details.' ) ;
241
+ }
242
+ }
243
+ } ;
244
+
245
+ export const applyGlobalCSSAction : ActionConfig = {
246
+ key : 'apply-global-css' ,
247
+ label : 'Apply global CSS' ,
248
+ category : 'app-configuration' ,
249
+ requiresInput : true ,
250
+ requiresStyle : true ,
251
+ inputPlaceholder : 'Enter CSS code to apply globally...' ,
252
+ inputType : 'textarea' ,
253
+ validation : ( value : string ) => {
254
+ if ( ! value . trim ( ) ) {
255
+ return 'CSS code is required' ;
256
+ }
257
+ const css = value . trim ( ) ;
258
+ if ( ! css . includes ( '{' ) || ! css . includes ( '}' ) ) {
259
+ return 'Invalid CSS syntax - missing braces' ;
260
+ }
261
+ return null ;
262
+ } ,
263
+ execute : async ( params : ActionExecuteParams ) => {
264
+ const { editorState, actionValue } = params ;
265
+
266
+ try {
267
+ const defaultCSS = `
268
+ body {
269
+ font-family: Arial, sans-serif;
270
+ }
271
+ ` . trim ( ) ;
272
+
273
+ const cssCode = actionValue . trim ( ) || defaultCSS ;
274
+
275
+ const preloadComp = editorState . rootComp . children . preload ;
276
+ if ( ! preloadComp ) {
277
+ message . error ( 'Preload component not found' ) ;
278
+ return ;
279
+ }
280
+
281
+ const globalCSSComp = preloadComp . children . globalCSS ;
282
+ if ( ! globalCSSComp ) {
283
+ message . error ( 'Global CSS component not found' ) ;
284
+ return ;
285
+ }
286
+
287
+ globalCSSComp . dispatchChangeValueAction ( cssCode ) ;
288
+
289
+ await globalCSSComp . run ( 'global-css' , cssCode ) ;
290
+
291
+ message . success ( 'Global CSS applied successfully!' ) ;
292
+
293
+ } catch ( error ) {
294
+ console . error ( 'Error applying global CSS:' , error ) ;
295
+ message . error ( 'Failed to apply global CSS. Check console for details.' ) ;
296
+ }
297
+ }
298
+ } ;
0 commit comments