@hpcc-js/marshaller 2.28.6 → 2.28.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +43 -43
- package/dist/index.es6.js +19 -19
- package/dist/index.es6.js.map +1 -1
- package/dist/index.js +17 -17
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +16 -16
- package/src/__package__.ts +3 -3
- package/src/dashy.css +239 -239
- package/src/dashy.ts +521 -521
- package/src/ddl1/DDLApi.ts +229 -229
- package/src/ddl1/FlyoutButton.ts +120 -120
- package/src/ddl1/Graph.ts +93 -93
- package/src/ddl1/HTML.ts +77 -77
- package/src/ddl1/HipieDDL.ts +2437 -2437
- package/src/ddl1/HipieDDLMixin.ts +380 -380
- package/src/ddl1/Tabbed.ts +91 -91
- package/src/ddl1/TargetMarshaller.ts +57 -57
- package/src/ddl2/PopupManager.ts +89 -89
- package/src/ddl2/activities/activity.ts +431 -431
- package/src/ddl2/activities/databomb.ts +237 -237
- package/src/ddl2/activities/datasource.ts +52 -52
- package/src/ddl2/activities/dspicker.ts +106 -106
- package/src/ddl2/activities/filter.ts +542 -542
- package/src/ddl2/activities/form.ts +153 -153
- package/src/ddl2/activities/groupby.ts +439 -439
- package/src/ddl2/activities/hipiepipeline.ts +114 -114
- package/src/ddl2/activities/limit.ts +49 -49
- package/src/ddl2/activities/logicalfile.ts +62 -62
- package/src/ddl2/activities/nullview.ts +12 -12
- package/src/ddl2/activities/project.ts +764 -764
- package/src/ddl2/activities/rest.ts +568 -568
- package/src/ddl2/activities/roxie.ts +490 -490
- package/src/ddl2/activities/sampledata.json +16264 -16264
- package/src/ddl2/activities/sort.ts +176 -176
- package/src/ddl2/activities/wuresult.ts +395 -395
- package/src/ddl2/dashboard.css +13 -13
- package/src/ddl2/dashboard.ts +330 -330
- package/src/ddl2/dashboardDockPanel.ts +123 -123
- package/src/ddl2/dashboardGrid.ts +202 -202
- package/src/ddl2/ddl.ts +410 -410
- package/src/ddl2/ddleditor.ts +60 -60
- package/src/ddl2/dsTable.ts +238 -238
- package/src/ddl2/dvTable.ts +31 -31
- package/src/ddl2/graphadapter.ts +297 -297
- package/src/ddl2/javascriptadapter.ts +354 -354
- package/src/ddl2/model/element.ts +398 -398
- package/src/ddl2/model/visualization.ts +351 -351
- package/src/ddl2/model/vizChartPanel.ts +149 -149
- package/src/ddl2/pipelinePanel.css +4 -4
- package/src/ddl2/pipelinePanel.ts +465 -465
- package/src/index.ts +26 -26
|
@@ -1,354 +1,354 @@
|
|
|
1
|
-
import { PropertyExt } from "@hpcc-js/common";
|
|
2
|
-
import { DDL2 } from "@hpcc-js/ddl-shim";
|
|
3
|
-
import { classID2Meta, ClassMeta, isArray } from "@hpcc-js/util";
|
|
4
|
-
import { Activity, stringify } from "./activities/activity";
|
|
5
|
-
import { Dashboard } from "./dashboard";
|
|
6
|
-
import { DDLAdapter } from "./ddl";
|
|
7
|
-
import { ElementContainer } from "./model/element";
|
|
8
|
-
|
|
9
|
-
type WidgetImport = { [moduleID: string]: { [classID: string]: boolean } };
|
|
10
|
-
|
|
11
|
-
class Imports {
|
|
12
|
-
_moduleMap: WidgetImport = {};
|
|
13
|
-
|
|
14
|
-
append(widgetMeta: ClassMeta) {
|
|
15
|
-
if (!this._moduleMap[widgetMeta.module]) {
|
|
16
|
-
this._moduleMap[widgetMeta.module] = {};
|
|
17
|
-
}
|
|
18
|
-
this._moduleMap[widgetMeta.module][widgetMeta.class] = true;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
write(): string {
|
|
22
|
-
const importJS: string[] = [];
|
|
23
|
-
for (const moduleID in this._moduleMap) {
|
|
24
|
-
const classIDs: string[] = [];
|
|
25
|
-
for (const classID in this._moduleMap[moduleID]) {
|
|
26
|
-
classIDs.push(classID);
|
|
27
|
-
}
|
|
28
|
-
classIDs.sort();
|
|
29
|
-
importJS.push(`import { ${classIDs.join(", ")} } from "${moduleID}";`);
|
|
30
|
-
}
|
|
31
|
-
return importJS.join("\n");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function createProps(pe: PropertyExt): { [key: string]: any } {
|
|
36
|
-
const retVal: { [key: string]: any } = {};
|
|
37
|
-
for (const meta of pe.publishedProperties()) {
|
|
38
|
-
if (pe[meta.id + "_modified"]() && meta.id !== "fields") {
|
|
39
|
-
const val = pe[meta.id]();
|
|
40
|
-
switch (meta.type) {
|
|
41
|
-
case "propertyArray":
|
|
42
|
-
const serialization = val.map(createProps);
|
|
43
|
-
if (serialization) {
|
|
44
|
-
retVal[meta.id] = serialization;
|
|
45
|
-
}
|
|
46
|
-
break;
|
|
47
|
-
default:
|
|
48
|
-
retVal[meta.id] = val;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return retVal;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export class JavaScriptAdapter {
|
|
56
|
-
private _dashboard: Dashboard;
|
|
57
|
-
private _ec: ElementContainer;
|
|
58
|
-
private _ddlAdapter: DDLAdapter;
|
|
59
|
-
private _ddlSchema: DDL2.Schema;
|
|
60
|
-
|
|
61
|
-
constructor(dashboard: Dashboard) {
|
|
62
|
-
this._dashboard = dashboard;
|
|
63
|
-
this._ec = this._dashboard.elementContainer();
|
|
64
|
-
this._ddlAdapter = new DDLAdapter(this._dashboard);
|
|
65
|
-
this._ddlSchema = this._ddlAdapter.write();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
createProps(prefix: string, pe: PropertyExt, postfix: string = ""): string[] {
|
|
69
|
-
let retVal: string[] = [];
|
|
70
|
-
for (const meta of pe.publishedProperties()) {
|
|
71
|
-
if ((pe as any)[meta.id + "_exists"]()) {
|
|
72
|
-
switch (meta.type) {
|
|
73
|
-
case "string":
|
|
74
|
-
case "set":
|
|
75
|
-
retVal.push(`${prefix}.${meta.id}("${(pe as any)[meta.id]()}")${postfix};`);
|
|
76
|
-
break;
|
|
77
|
-
case "number":
|
|
78
|
-
case "boolean":
|
|
79
|
-
retVal.push(`${prefix}.${meta.id}(${(pe as any)[meta.id]()})${postfix};`);
|
|
80
|
-
break;
|
|
81
|
-
case "widget":
|
|
82
|
-
retVal = retVal.concat(this.createProps(`${prefix}.${meta.id}()`, (pe as any)[meta.id]()));
|
|
83
|
-
break;
|
|
84
|
-
case "propertyArray":
|
|
85
|
-
if (meta.ext)
|
|
86
|
-
retVal.push(`${prefix}.${meta.id}([${(pe as any)[meta.id]()}])${postfix};`);
|
|
87
|
-
break;
|
|
88
|
-
default:
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return retVal;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
writeMeta(dsDetails: Activity) {
|
|
97
|
-
return "";
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private safeID(id: string): string {
|
|
101
|
-
if (!id) return id;
|
|
102
|
-
return id.replace(/ /g, "_").replace(/\./g, "_");
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private datasourceRefID(view: DDL2.IView): string {
|
|
106
|
-
const datasourceRef = view.datasource;
|
|
107
|
-
if (DDL2.isRoxieServiceRef(datasourceRef)) {
|
|
108
|
-
return `${this.safeID(datasourceRef.id)}_${this.safeID(datasourceRef.output)}_${this.safeID(view.id)}`;
|
|
109
|
-
} else if (DDL2.isWUResultRef(datasourceRef)) {
|
|
110
|
-
return `${this.safeID(datasourceRef.id)}_${this.safeID(datasourceRef.output)}`;
|
|
111
|
-
}
|
|
112
|
-
return `${this.safeID(datasourceRef.id)}`;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
_dedup: { [key: string]: boolean } = {};
|
|
116
|
-
private writeDatasource(view: DDL2.IView): string[] {
|
|
117
|
-
const datasourceRef = view.datasource;
|
|
118
|
-
const retVal: string[] = [];
|
|
119
|
-
const datasource = this._ddlSchema.datasources.filter(ds => ds.id === datasourceRef.id)[0];
|
|
120
|
-
const outputID = (datasourceRef as any).output;
|
|
121
|
-
const id = this.datasourceRefID(view);
|
|
122
|
-
if (!this._dedup[id]) {
|
|
123
|
-
this._dedup[id] = true;
|
|
124
|
-
switch (datasource.type) {
|
|
125
|
-
case "wuresult":
|
|
126
|
-
const wuID = this.safeID(view.datasource.id);
|
|
127
|
-
if (!this._dedup[wuID]) {
|
|
128
|
-
this._dedup[wuID] = true;
|
|
129
|
-
retVal.push(` export const ${wuID} = new marshaller.WU()
|
|
130
|
-
.url("${datasource.url}")
|
|
131
|
-
.wuid("${datasource.wuid}")
|
|
132
|
-
;`);
|
|
133
|
-
}
|
|
134
|
-
retVal.push(` export const ${id} = new marshaller.WUResult()
|
|
135
|
-
.wu(${wuID})
|
|
136
|
-
.resultName("${outputID}")
|
|
137
|
-
.responseFields(${stringify(datasource.outputs[outputID].fields)})
|
|
138
|
-
;`);
|
|
139
|
-
break;
|
|
140
|
-
case "logicalfile":
|
|
141
|
-
retVal.push(` export const ${id} = new marshaller.LogicalFile()
|
|
142
|
-
.url("${datasource.url}")
|
|
143
|
-
.logicalFile("${datasource.logicalFile}")
|
|
144
|
-
.responseFields(${stringify(datasource.fields)})
|
|
145
|
-
;`);
|
|
146
|
-
break;
|
|
147
|
-
case "hipie":
|
|
148
|
-
case "roxie":
|
|
149
|
-
const serviceID = this.safeID(view.datasource.id);
|
|
150
|
-
if (!this._dedup[serviceID]) {
|
|
151
|
-
this._dedup[serviceID] = true;
|
|
152
|
-
retVal.push(` export const ${serviceID} = new marshaller.RoxieService(ec)
|
|
153
|
-
.url("${datasource.url}")
|
|
154
|
-
.querySet("${datasource.querySet}")
|
|
155
|
-
.queryID("${datasource.queryID}")
|
|
156
|
-
.requestFields(${stringify(datasource.inputs)})
|
|
157
|
-
;`);
|
|
158
|
-
}
|
|
159
|
-
const resultID = serviceID + "_" + this.safeID(outputID);
|
|
160
|
-
if (!this._dedup[resultID]) {
|
|
161
|
-
this._dedup[resultID] = true;
|
|
162
|
-
retVal.push(` export const ${resultID} = new marshaller.RoxieResult(ec)
|
|
163
|
-
.service(${serviceID})
|
|
164
|
-
.resultName("${outputID}")
|
|
165
|
-
.responseFields(${stringify(datasource.outputs[outputID].fields)})
|
|
166
|
-
;`);
|
|
167
|
-
}
|
|
168
|
-
retVal.push(` export const ${id} = new marshaller.HipieResultRef(ec)
|
|
169
|
-
.datasource(${resultID})
|
|
170
|
-
.requestFieldRefs(${stringify((datasourceRef as DDL2.IRoxieServiceRef).request)})
|
|
171
|
-
;`);
|
|
172
|
-
break;
|
|
173
|
-
case "databomb":
|
|
174
|
-
{
|
|
175
|
-
retVal.push(` export const ${id} = new marshaller.Databomb()
|
|
176
|
-
.format("${datasource.format}")
|
|
177
|
-
.payload(${JSON.stringify(datasource.payload)})
|
|
178
|
-
;`);
|
|
179
|
-
}
|
|
180
|
-
break;
|
|
181
|
-
case "form":
|
|
182
|
-
{
|
|
183
|
-
const fromFields: string[] = [];
|
|
184
|
-
for (const field of datasource.fields) {
|
|
185
|
-
fromFields.push(`new marshaller.FormField().fieldID("${field.id}").default("${field.default || ""}")`);
|
|
186
|
-
}
|
|
187
|
-
retVal.push(` export const ${id} = new marshaller.Form()
|
|
188
|
-
.formFields([
|
|
189
|
-
${fromFields.join(",\n ")}
|
|
190
|
-
])
|
|
191
|
-
;`);
|
|
192
|
-
}
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return retVal;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
private writeActivity(activity: DDL2.ActivityType): string {
|
|
200
|
-
switch (activity.type) {
|
|
201
|
-
case "filter":
|
|
202
|
-
return `new marshaller.Filters(ec).conditions(${stringify(activity.conditions)})`;
|
|
203
|
-
case "project":
|
|
204
|
-
return `new marshaller.Project().transformations(${stringify(activity.transformations)})`;
|
|
205
|
-
case "groupby":
|
|
206
|
-
return `new marshaller.GroupBy().fieldIDs(${JSON.stringify(activity.groupByIDs)}).aggregates(${stringify(activity.aggregates)})`;
|
|
207
|
-
case "sort":
|
|
208
|
-
return `new marshaller.Sort().conditions(${stringify(activity.conditions)})`;
|
|
209
|
-
case "limit":
|
|
210
|
-
return `new marshaller.Limit().rows(${activity.limit})`;
|
|
211
|
-
case "mappings":
|
|
212
|
-
return `new marshaller.Mappings().transformations(${stringify(activity.transformations)})`;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
writeWidgetProps(pe: PropertyExt): string[] {
|
|
217
|
-
const retVal: string[] = [];
|
|
218
|
-
for (const meta of pe.publishedProperties()) {
|
|
219
|
-
if ((pe as any)[meta.id + "_modified"]() && meta.id !== "fields") {
|
|
220
|
-
retVal.push(`.${meta.id}(${JSON.stringify((pe as any)[meta.id]())})`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return retVal;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
private joinWithPrefix(props: DDL2.IWidgetProperties, imports: Imports, joinStr: string, postFix: string): string {
|
|
227
|
-
let retVal: string = "";
|
|
228
|
-
let meta: ClassMeta;
|
|
229
|
-
if (props.__class) {
|
|
230
|
-
meta = classID2Meta(props.__class);
|
|
231
|
-
imports.append(meta);
|
|
232
|
-
retVal += `new ${meta.class}()`;
|
|
233
|
-
}
|
|
234
|
-
for (const prop in props) {
|
|
235
|
-
if (prop === "__class") {
|
|
236
|
-
} else if (isArray(props[prop])) {
|
|
237
|
-
const arr = `${(props[prop] as any[]).map(item => this.joinWithPrefix(item, imports, joinStr + " ", "")).join(`,${joinStr} `)}`;
|
|
238
|
-
if (arr) {
|
|
239
|
-
retVal += `${joinStr} .${prop}([${joinStr} ${arr}${joinStr} ])${postFix}`;
|
|
240
|
-
}
|
|
241
|
-
} else {
|
|
242
|
-
retVal += `${joinStr} .${prop}(${JSON.stringify(props[prop])})${postFix}`;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return retVal;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
private writeWidget(dataview: DDL2.IView, imports: Imports): string {
|
|
249
|
-
return ` export const ${dataview.visualization.id} = new marshaller.VizChartPanel()
|
|
250
|
-
.id("${dataview.visualization.id}")
|
|
251
|
-
.title("${dataview.visualization.title}")
|
|
252
|
-
.widget(${this.joinWithPrefix(dataview.visualization.properties["widget"] as any, imports, "\n ", "")})
|
|
253
|
-
;`;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
private writeElement(dataview: DDL2.IView) {
|
|
257
|
-
const activities: string[] = [`data.${this.datasourceRefID(dataview)}`];
|
|
258
|
-
for (const activity of dataview.activities) {
|
|
259
|
-
activities.push(this.writeActivity(activity));
|
|
260
|
-
}
|
|
261
|
-
const updates: string[] = [];
|
|
262
|
-
for (const filteredViz of this._ec.filteredBy(dataview.id)) {
|
|
263
|
-
updates.push(`${filteredViz.id()}.refresh();`);
|
|
264
|
-
}
|
|
265
|
-
return `
|
|
266
|
-
const ${dataview.id} = new marshaller.Element(ec)
|
|
267
|
-
.id("${dataview.id}")
|
|
268
|
-
.pipeline([
|
|
269
|
-
${activities.join(",\n ")}
|
|
270
|
-
])
|
|
271
|
-
.mappings(new marshaller.Mappings().transformations(${stringify(dataview.visualization.mappings.transformations)}))
|
|
272
|
-
.chartPanel(viz.${dataview.visualization.id})
|
|
273
|
-
.on("selectionChanged", () => {
|
|
274
|
-
${updates.join("\n ")}
|
|
275
|
-
}, true)
|
|
276
|
-
;
|
|
277
|
-
${dataview.id}.visualization()
|
|
278
|
-
.visibility("${dataview.visualization.visibility}")
|
|
279
|
-
.secondaryDataviewID("${dataview.visualization.secondaryDataviewID || ""}")
|
|
280
|
-
;
|
|
281
|
-
ec.append(${dataview.id});
|
|
282
|
-
`;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
private writeDatasources(): string[] {
|
|
286
|
-
let retVal: string[] = [];
|
|
287
|
-
for (const dataview of this._ddlSchema.dataviews) {
|
|
288
|
-
retVal = retVal.concat(this.writeDatasource(dataview));
|
|
289
|
-
}
|
|
290
|
-
return retVal;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
private writeWidgets(): { widgetImports: string, widgetDefs: string } {
|
|
294
|
-
const jsDef: string[] = [];
|
|
295
|
-
const imports = new Imports();
|
|
296
|
-
for (const dataview of this._ddlSchema.dataviews) {
|
|
297
|
-
jsDef.push(this.writeWidget(dataview, imports));
|
|
298
|
-
}
|
|
299
|
-
return {
|
|
300
|
-
widgetImports: imports.write(),
|
|
301
|
-
widgetDefs: jsDef.join("\n\n")
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
private writeElements(): string {
|
|
306
|
-
let retVal = "";
|
|
307
|
-
for (const dataview of this._ddlSchema.dataviews) {
|
|
308
|
-
retVal += this.writeElement(dataview);
|
|
309
|
-
}
|
|
310
|
-
return retVal;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
createJavaScript(): string {
|
|
314
|
-
const widgets = this.writeWidgets();
|
|
315
|
-
|
|
316
|
-
return `\
|
|
317
|
-
${widgets.widgetImports}
|
|
318
|
-
import * as marshaller from "@hpcc-js/marshaller";
|
|
319
|
-
|
|
320
|
-
// Dashboard Element Container (Model) ---
|
|
321
|
-
const ec = new marshaller.ElementContainer();
|
|
322
|
-
|
|
323
|
-
namespace data {
|
|
324
|
-
${this.writeDatasources().join("\n")}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
namespace viz {
|
|
328
|
-
${widgets.widgetDefs}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// Dashboard Elements (Controller) ---
|
|
332
|
-
${this.writeElements().trim()}
|
|
333
|
-
|
|
334
|
-
ec.refresh();
|
|
335
|
-
|
|
336
|
-
// Optional ---
|
|
337
|
-
const errors = ec.validate();
|
|
338
|
-
for (const error of errors) {
|
|
339
|
-
console.error(error.elementID + " (" + error.source + "): " + error.msg);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export const dashboard = new marshaller.Dashboard(ec)
|
|
343
|
-
.target("placeholder")
|
|
344
|
-
.titleVisible(false)
|
|
345
|
-
.hideSingleTabs(true)
|
|
346
|
-
.layoutObj(${stringify(this._dashboard.layout())})
|
|
347
|
-
.render()
|
|
348
|
-
;
|
|
349
|
-
|
|
350
|
-
// @ts-ignore
|
|
351
|
-
const ddl = ${JSON.stringify(this._ddlSchema)};
|
|
352
|
-
`;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
1
|
+
import { PropertyExt } from "@hpcc-js/common";
|
|
2
|
+
import { DDL2 } from "@hpcc-js/ddl-shim";
|
|
3
|
+
import { classID2Meta, ClassMeta, isArray } from "@hpcc-js/util";
|
|
4
|
+
import { Activity, stringify } from "./activities/activity";
|
|
5
|
+
import { Dashboard } from "./dashboard";
|
|
6
|
+
import { DDLAdapter } from "./ddl";
|
|
7
|
+
import { ElementContainer } from "./model/element";
|
|
8
|
+
|
|
9
|
+
type WidgetImport = { [moduleID: string]: { [classID: string]: boolean } };
|
|
10
|
+
|
|
11
|
+
class Imports {
|
|
12
|
+
_moduleMap: WidgetImport = {};
|
|
13
|
+
|
|
14
|
+
append(widgetMeta: ClassMeta) {
|
|
15
|
+
if (!this._moduleMap[widgetMeta.module]) {
|
|
16
|
+
this._moduleMap[widgetMeta.module] = {};
|
|
17
|
+
}
|
|
18
|
+
this._moduleMap[widgetMeta.module][widgetMeta.class] = true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
write(): string {
|
|
22
|
+
const importJS: string[] = [];
|
|
23
|
+
for (const moduleID in this._moduleMap) {
|
|
24
|
+
const classIDs: string[] = [];
|
|
25
|
+
for (const classID in this._moduleMap[moduleID]) {
|
|
26
|
+
classIDs.push(classID);
|
|
27
|
+
}
|
|
28
|
+
classIDs.sort();
|
|
29
|
+
importJS.push(`import { ${classIDs.join(", ")} } from "${moduleID}";`);
|
|
30
|
+
}
|
|
31
|
+
return importJS.join("\n");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createProps(pe: PropertyExt): { [key: string]: any } {
|
|
36
|
+
const retVal: { [key: string]: any } = {};
|
|
37
|
+
for (const meta of pe.publishedProperties()) {
|
|
38
|
+
if (pe[meta.id + "_modified"]() && meta.id !== "fields") {
|
|
39
|
+
const val = pe[meta.id]();
|
|
40
|
+
switch (meta.type) {
|
|
41
|
+
case "propertyArray":
|
|
42
|
+
const serialization = val.map(createProps);
|
|
43
|
+
if (serialization) {
|
|
44
|
+
retVal[meta.id] = serialization;
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
retVal[meta.id] = val;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return retVal;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class JavaScriptAdapter {
|
|
56
|
+
private _dashboard: Dashboard;
|
|
57
|
+
private _ec: ElementContainer;
|
|
58
|
+
private _ddlAdapter: DDLAdapter;
|
|
59
|
+
private _ddlSchema: DDL2.Schema;
|
|
60
|
+
|
|
61
|
+
constructor(dashboard: Dashboard) {
|
|
62
|
+
this._dashboard = dashboard;
|
|
63
|
+
this._ec = this._dashboard.elementContainer();
|
|
64
|
+
this._ddlAdapter = new DDLAdapter(this._dashboard);
|
|
65
|
+
this._ddlSchema = this._ddlAdapter.write();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
createProps(prefix: string, pe: PropertyExt, postfix: string = ""): string[] {
|
|
69
|
+
let retVal: string[] = [];
|
|
70
|
+
for (const meta of pe.publishedProperties()) {
|
|
71
|
+
if ((pe as any)[meta.id + "_exists"]()) {
|
|
72
|
+
switch (meta.type) {
|
|
73
|
+
case "string":
|
|
74
|
+
case "set":
|
|
75
|
+
retVal.push(`${prefix}.${meta.id}("${(pe as any)[meta.id]()}")${postfix};`);
|
|
76
|
+
break;
|
|
77
|
+
case "number":
|
|
78
|
+
case "boolean":
|
|
79
|
+
retVal.push(`${prefix}.${meta.id}(${(pe as any)[meta.id]()})${postfix};`);
|
|
80
|
+
break;
|
|
81
|
+
case "widget":
|
|
82
|
+
retVal = retVal.concat(this.createProps(`${prefix}.${meta.id}()`, (pe as any)[meta.id]()));
|
|
83
|
+
break;
|
|
84
|
+
case "propertyArray":
|
|
85
|
+
if (meta.ext)
|
|
86
|
+
retVal.push(`${prefix}.${meta.id}([${(pe as any)[meta.id]()}])${postfix};`);
|
|
87
|
+
break;
|
|
88
|
+
default:
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return retVal;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
writeMeta(dsDetails: Activity) {
|
|
97
|
+
return "";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private safeID(id: string): string {
|
|
101
|
+
if (!id) return id;
|
|
102
|
+
return id.replace(/ /g, "_").replace(/\./g, "_");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private datasourceRefID(view: DDL2.IView): string {
|
|
106
|
+
const datasourceRef = view.datasource;
|
|
107
|
+
if (DDL2.isRoxieServiceRef(datasourceRef)) {
|
|
108
|
+
return `${this.safeID(datasourceRef.id)}_${this.safeID(datasourceRef.output)}_${this.safeID(view.id)}`;
|
|
109
|
+
} else if (DDL2.isWUResultRef(datasourceRef)) {
|
|
110
|
+
return `${this.safeID(datasourceRef.id)}_${this.safeID(datasourceRef.output)}`;
|
|
111
|
+
}
|
|
112
|
+
return `${this.safeID(datasourceRef.id)}`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_dedup: { [key: string]: boolean } = {};
|
|
116
|
+
private writeDatasource(view: DDL2.IView): string[] {
|
|
117
|
+
const datasourceRef = view.datasource;
|
|
118
|
+
const retVal: string[] = [];
|
|
119
|
+
const datasource = this._ddlSchema.datasources.filter(ds => ds.id === datasourceRef.id)[0];
|
|
120
|
+
const outputID = (datasourceRef as any).output;
|
|
121
|
+
const id = this.datasourceRefID(view);
|
|
122
|
+
if (!this._dedup[id]) {
|
|
123
|
+
this._dedup[id] = true;
|
|
124
|
+
switch (datasource.type) {
|
|
125
|
+
case "wuresult":
|
|
126
|
+
const wuID = this.safeID(view.datasource.id);
|
|
127
|
+
if (!this._dedup[wuID]) {
|
|
128
|
+
this._dedup[wuID] = true;
|
|
129
|
+
retVal.push(` export const ${wuID} = new marshaller.WU()
|
|
130
|
+
.url("${datasource.url}")
|
|
131
|
+
.wuid("${datasource.wuid}")
|
|
132
|
+
;`);
|
|
133
|
+
}
|
|
134
|
+
retVal.push(` export const ${id} = new marshaller.WUResult()
|
|
135
|
+
.wu(${wuID})
|
|
136
|
+
.resultName("${outputID}")
|
|
137
|
+
.responseFields(${stringify(datasource.outputs[outputID].fields)})
|
|
138
|
+
;`);
|
|
139
|
+
break;
|
|
140
|
+
case "logicalfile":
|
|
141
|
+
retVal.push(` export const ${id} = new marshaller.LogicalFile()
|
|
142
|
+
.url("${datasource.url}")
|
|
143
|
+
.logicalFile("${datasource.logicalFile}")
|
|
144
|
+
.responseFields(${stringify(datasource.fields)})
|
|
145
|
+
;`);
|
|
146
|
+
break;
|
|
147
|
+
case "hipie":
|
|
148
|
+
case "roxie":
|
|
149
|
+
const serviceID = this.safeID(view.datasource.id);
|
|
150
|
+
if (!this._dedup[serviceID]) {
|
|
151
|
+
this._dedup[serviceID] = true;
|
|
152
|
+
retVal.push(` export const ${serviceID} = new marshaller.RoxieService(ec)
|
|
153
|
+
.url("${datasource.url}")
|
|
154
|
+
.querySet("${datasource.querySet}")
|
|
155
|
+
.queryID("${datasource.queryID}")
|
|
156
|
+
.requestFields(${stringify(datasource.inputs)})
|
|
157
|
+
;`);
|
|
158
|
+
}
|
|
159
|
+
const resultID = serviceID + "_" + this.safeID(outputID);
|
|
160
|
+
if (!this._dedup[resultID]) {
|
|
161
|
+
this._dedup[resultID] = true;
|
|
162
|
+
retVal.push(` export const ${resultID} = new marshaller.RoxieResult(ec)
|
|
163
|
+
.service(${serviceID})
|
|
164
|
+
.resultName("${outputID}")
|
|
165
|
+
.responseFields(${stringify(datasource.outputs[outputID].fields)})
|
|
166
|
+
;`);
|
|
167
|
+
}
|
|
168
|
+
retVal.push(` export const ${id} = new marshaller.HipieResultRef(ec)
|
|
169
|
+
.datasource(${resultID})
|
|
170
|
+
.requestFieldRefs(${stringify((datasourceRef as DDL2.IRoxieServiceRef).request)})
|
|
171
|
+
;`);
|
|
172
|
+
break;
|
|
173
|
+
case "databomb":
|
|
174
|
+
{
|
|
175
|
+
retVal.push(` export const ${id} = new marshaller.Databomb()
|
|
176
|
+
.format("${datasource.format}")
|
|
177
|
+
.payload(${JSON.stringify(datasource.payload)})
|
|
178
|
+
;`);
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
case "form":
|
|
182
|
+
{
|
|
183
|
+
const fromFields: string[] = [];
|
|
184
|
+
for (const field of datasource.fields) {
|
|
185
|
+
fromFields.push(`new marshaller.FormField().fieldID("${field.id}").default("${field.default || ""}")`);
|
|
186
|
+
}
|
|
187
|
+
retVal.push(` export const ${id} = new marshaller.Form()
|
|
188
|
+
.formFields([
|
|
189
|
+
${fromFields.join(",\n ")}
|
|
190
|
+
])
|
|
191
|
+
;`);
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return retVal;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private writeActivity(activity: DDL2.ActivityType): string {
|
|
200
|
+
switch (activity.type) {
|
|
201
|
+
case "filter":
|
|
202
|
+
return `new marshaller.Filters(ec).conditions(${stringify(activity.conditions)})`;
|
|
203
|
+
case "project":
|
|
204
|
+
return `new marshaller.Project().transformations(${stringify(activity.transformations)})`;
|
|
205
|
+
case "groupby":
|
|
206
|
+
return `new marshaller.GroupBy().fieldIDs(${JSON.stringify(activity.groupByIDs)}).aggregates(${stringify(activity.aggregates)})`;
|
|
207
|
+
case "sort":
|
|
208
|
+
return `new marshaller.Sort().conditions(${stringify(activity.conditions)})`;
|
|
209
|
+
case "limit":
|
|
210
|
+
return `new marshaller.Limit().rows(${activity.limit})`;
|
|
211
|
+
case "mappings":
|
|
212
|
+
return `new marshaller.Mappings().transformations(${stringify(activity.transformations)})`;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
writeWidgetProps(pe: PropertyExt): string[] {
|
|
217
|
+
const retVal: string[] = [];
|
|
218
|
+
for (const meta of pe.publishedProperties()) {
|
|
219
|
+
if ((pe as any)[meta.id + "_modified"]() && meta.id !== "fields") {
|
|
220
|
+
retVal.push(`.${meta.id}(${JSON.stringify((pe as any)[meta.id]())})`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return retVal;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private joinWithPrefix(props: DDL2.IWidgetProperties, imports: Imports, joinStr: string, postFix: string): string {
|
|
227
|
+
let retVal: string = "";
|
|
228
|
+
let meta: ClassMeta;
|
|
229
|
+
if (props.__class) {
|
|
230
|
+
meta = classID2Meta(props.__class);
|
|
231
|
+
imports.append(meta);
|
|
232
|
+
retVal += `new ${meta.class}()`;
|
|
233
|
+
}
|
|
234
|
+
for (const prop in props) {
|
|
235
|
+
if (prop === "__class") {
|
|
236
|
+
} else if (isArray(props[prop])) {
|
|
237
|
+
const arr = `${(props[prop] as any[]).map(item => this.joinWithPrefix(item, imports, joinStr + " ", "")).join(`,${joinStr} `)}`;
|
|
238
|
+
if (arr) {
|
|
239
|
+
retVal += `${joinStr} .${prop}([${joinStr} ${arr}${joinStr} ])${postFix}`;
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
retVal += `${joinStr} .${prop}(${JSON.stringify(props[prop])})${postFix}`;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return retVal;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private writeWidget(dataview: DDL2.IView, imports: Imports): string {
|
|
249
|
+
return ` export const ${dataview.visualization.id} = new marshaller.VizChartPanel()
|
|
250
|
+
.id("${dataview.visualization.id}")
|
|
251
|
+
.title("${dataview.visualization.title}")
|
|
252
|
+
.widget(${this.joinWithPrefix(dataview.visualization.properties["widget"] as any, imports, "\n ", "")})
|
|
253
|
+
;`;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private writeElement(dataview: DDL2.IView) {
|
|
257
|
+
const activities: string[] = [`data.${this.datasourceRefID(dataview)}`];
|
|
258
|
+
for (const activity of dataview.activities) {
|
|
259
|
+
activities.push(this.writeActivity(activity));
|
|
260
|
+
}
|
|
261
|
+
const updates: string[] = [];
|
|
262
|
+
for (const filteredViz of this._ec.filteredBy(dataview.id)) {
|
|
263
|
+
updates.push(`${filteredViz.id()}.refresh();`);
|
|
264
|
+
}
|
|
265
|
+
return `
|
|
266
|
+
const ${dataview.id} = new marshaller.Element(ec)
|
|
267
|
+
.id("${dataview.id}")
|
|
268
|
+
.pipeline([
|
|
269
|
+
${activities.join(",\n ")}
|
|
270
|
+
])
|
|
271
|
+
.mappings(new marshaller.Mappings().transformations(${stringify(dataview.visualization.mappings.transformations)}))
|
|
272
|
+
.chartPanel(viz.${dataview.visualization.id})
|
|
273
|
+
.on("selectionChanged", () => {
|
|
274
|
+
${updates.join("\n ")}
|
|
275
|
+
}, true)
|
|
276
|
+
;
|
|
277
|
+
${dataview.id}.visualization()
|
|
278
|
+
.visibility("${dataview.visualization.visibility}")
|
|
279
|
+
.secondaryDataviewID("${dataview.visualization.secondaryDataviewID || ""}")
|
|
280
|
+
;
|
|
281
|
+
ec.append(${dataview.id});
|
|
282
|
+
`;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private writeDatasources(): string[] {
|
|
286
|
+
let retVal: string[] = [];
|
|
287
|
+
for (const dataview of this._ddlSchema.dataviews) {
|
|
288
|
+
retVal = retVal.concat(this.writeDatasource(dataview));
|
|
289
|
+
}
|
|
290
|
+
return retVal;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private writeWidgets(): { widgetImports: string, widgetDefs: string } {
|
|
294
|
+
const jsDef: string[] = [];
|
|
295
|
+
const imports = new Imports();
|
|
296
|
+
for (const dataview of this._ddlSchema.dataviews) {
|
|
297
|
+
jsDef.push(this.writeWidget(dataview, imports));
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
widgetImports: imports.write(),
|
|
301
|
+
widgetDefs: jsDef.join("\n\n")
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private writeElements(): string {
|
|
306
|
+
let retVal = "";
|
|
307
|
+
for (const dataview of this._ddlSchema.dataviews) {
|
|
308
|
+
retVal += this.writeElement(dataview);
|
|
309
|
+
}
|
|
310
|
+
return retVal;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
createJavaScript(): string {
|
|
314
|
+
const widgets = this.writeWidgets();
|
|
315
|
+
|
|
316
|
+
return `\
|
|
317
|
+
${widgets.widgetImports}
|
|
318
|
+
import * as marshaller from "@hpcc-js/marshaller";
|
|
319
|
+
|
|
320
|
+
// Dashboard Element Container (Model) ---
|
|
321
|
+
const ec = new marshaller.ElementContainer();
|
|
322
|
+
|
|
323
|
+
namespace data {
|
|
324
|
+
${this.writeDatasources().join("\n")}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
namespace viz {
|
|
328
|
+
${widgets.widgetDefs}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Dashboard Elements (Controller) ---
|
|
332
|
+
${this.writeElements().trim()}
|
|
333
|
+
|
|
334
|
+
ec.refresh();
|
|
335
|
+
|
|
336
|
+
// Optional ---
|
|
337
|
+
const errors = ec.validate();
|
|
338
|
+
for (const error of errors) {
|
|
339
|
+
console.error(error.elementID + " (" + error.source + "): " + error.msg);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export const dashboard = new marshaller.Dashboard(ec)
|
|
343
|
+
.target("placeholder")
|
|
344
|
+
.titleVisible(false)
|
|
345
|
+
.hideSingleTabs(true)
|
|
346
|
+
.layoutObj(${stringify(this._dashboard.layout())})
|
|
347
|
+
.render()
|
|
348
|
+
;
|
|
349
|
+
|
|
350
|
+
// @ts-ignore
|
|
351
|
+
const ddl = ${JSON.stringify(this._ddlSchema)};
|
|
352
|
+
`;
|
|
353
|
+
}
|
|
354
|
+
}
|