retold-facto 0.0.4

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.
Files changed (92) hide show
  1. package/.claude/launch.json +11 -0
  2. package/.dockerignore +8 -0
  3. package/.quackage.json +19 -0
  4. package/Dockerfile +26 -0
  5. package/bin/retold-facto.js +909 -0
  6. package/examples/facto-government-data.sqlite +0 -0
  7. package/examples/government-data-catalog.json +137 -0
  8. package/examples/government-data-loader.js +1432 -0
  9. package/package.json +91 -0
  10. package/scripts/facto-download.js +425 -0
  11. package/source/Retold-Facto.js +1042 -0
  12. package/source/services/Retold-Facto-BeaconProvider.js +511 -0
  13. package/source/services/Retold-Facto-CatalogManager.js +1252 -0
  14. package/source/services/Retold-Facto-DataLakeService.js +1642 -0
  15. package/source/services/Retold-Facto-DatasetManager.js +417 -0
  16. package/source/services/Retold-Facto-IngestEngine.js +1315 -0
  17. package/source/services/Retold-Facto-ProjectionEngine.js +3960 -0
  18. package/source/services/Retold-Facto-RecordManager.js +360 -0
  19. package/source/services/Retold-Facto-SchemaManager.js +1110 -0
  20. package/source/services/Retold-Facto-SourceFolderScanner.js +2243 -0
  21. package/source/services/Retold-Facto-SourceManager.js +730 -0
  22. package/source/services/Retold-Facto-StoreConnectionManager.js +441 -0
  23. package/source/services/Retold-Facto-ThroughputMonitor.js +478 -0
  24. package/source/services/web-app/codemirror-entry.js +7 -0
  25. package/source/services/web-app/pict-app/Pict-Application-Facto-Configuration.json +9 -0
  26. package/source/services/web-app/pict-app/Pict-Application-Facto.js +70 -0
  27. package/source/services/web-app/pict-app/Pict-Facto-Bundle.js +11 -0
  28. package/source/services/web-app/pict-app/providers/Pict-Provider-Facto-UI.js +66 -0
  29. package/source/services/web-app/pict-app/providers/Pict-Provider-Facto.js +69 -0
  30. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Catalog.js +93 -0
  31. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Connections.js +42 -0
  32. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Datasets.js +605 -0
  33. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Projections.js +188 -0
  34. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Scanner.js +80 -0
  35. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Schema.js +116 -0
  36. package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Sources.js +104 -0
  37. package/source/services/web-app/pict-app/views/PictView-Facto-Catalog.js +526 -0
  38. package/source/services/web-app/pict-app/views/PictView-Facto-Datasets.js +173 -0
  39. package/source/services/web-app/pict-app/views/PictView-Facto-Ingest.js +259 -0
  40. package/source/services/web-app/pict-app/views/PictView-Facto-Layout.js +191 -0
  41. package/source/services/web-app/pict-app/views/PictView-Facto-Projections.js +231 -0
  42. package/source/services/web-app/pict-app/views/PictView-Facto-Records.js +326 -0
  43. package/source/services/web-app/pict-app/views/PictView-Facto-Scanner.js +624 -0
  44. package/source/services/web-app/pict-app/views/PictView-Facto-Sources.js +201 -0
  45. package/source/services/web-app/pict-app/views/PictView-Facto-Throughput.js +456 -0
  46. package/source/services/web-app/pict-app-full/Pict-Application-Facto-Full-Configuration.json +14 -0
  47. package/source/services/web-app/pict-app-full/Pict-Application-Facto-Full.js +391 -0
  48. package/source/services/web-app/pict-app-full/providers/PictRouter-Facto-Configuration.json +56 -0
  49. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-BottomBar.js +68 -0
  50. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Connections.js +340 -0
  51. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Dashboard.js +149 -0
  52. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Dashboards.js +819 -0
  53. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Datasets.js +178 -0
  54. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-IngestJobs.js +99 -0
  55. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Layout.js +62 -0
  56. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-MappingEditor.js +158 -0
  57. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-ProjectionDetail.js +1120 -0
  58. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Projections.js +172 -0
  59. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-QueryPanel.js +119 -0
  60. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-RecordViewer.js +663 -0
  61. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Records.js +648 -0
  62. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Scanner.js +1017 -0
  63. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaDetail.js +1404 -0
  64. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaDocEditor.js +1036 -0
  65. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaEditor.js +636 -0
  66. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaResearch.js +357 -0
  67. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SourceDetail.js +822 -0
  68. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SourceEditor.js +1036 -0
  69. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SourceResearch.js +487 -0
  70. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Sources.js +165 -0
  71. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Throughput.js +439 -0
  72. package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-TopBar.js +335 -0
  73. package/source/services/web-app/pict-app-full/views/projections/Facto-Projections-Constants.js +71 -0
  74. package/source/services/web-app/web/chart.min.js +20 -0
  75. package/source/services/web-app/web/codemirror-bundle.js +30099 -0
  76. package/source/services/web-app/web/css/facto-themes.css +467 -0
  77. package/source/services/web-app/web/css/facto.css +502 -0
  78. package/source/services/web-app/web/index.html +28 -0
  79. package/source/services/web-app/web/retold-facto.js +12138 -0
  80. package/source/services/web-app/web/retold-facto.js.map +1 -0
  81. package/source/services/web-app/web/retold-facto.min.js +2 -0
  82. package/source/services/web-app/web/retold-facto.min.js.map +1 -0
  83. package/source/services/web-app/web/simple/index.html +17 -0
  84. package/test/Facto_Browser_Integration_tests.js +798 -0
  85. package/test/RetoldFacto_tests.js +4117 -0
  86. package/test/fixtures/weather-readings.csv +17 -0
  87. package/test/fixtures/weather-stations.csv +9 -0
  88. package/test/model/MeadowModel-Extended.json +8497 -0
  89. package/test/model/MeadowModel-PICT.json +1 -0
  90. package/test/model/MeadowModel.json +1355 -0
  91. package/test/model/ddl/Facto.ddl +225 -0
  92. package/test/model/fable-configuration.json +14 -0
@@ -0,0 +1,391 @@
1
+ const libPictApplication = require('pict-application');
2
+ const libPictRouter = require('pict-router');
3
+ const libPictSectionModal = require('pict-section-modal');
4
+
5
+ const THEME_LIST =
6
+ [
7
+ { Key: 'turquoise-deluxe', Label: 'Turquoise Deluxe', Colors: ['#f6f0e4', '#18a5a0', '#3a9468', '#c44836', '#12908c'] },
8
+ { Key: 'facto-dark', Label: 'Facto Dark', Colors: ['#12151e', '#4a90d9', '#28a745', '#dc3545', '#6366f1'] },
9
+ { Key: 'facto-light', Label: 'Facto Light', Colors: ['#f5f6f8', '#3b82f6', '#22c55e', '#ef4444', '#6366f1'] },
10
+ { Key: 'midnight-blue', Label: 'Midnight Blue', Colors: ['#0a0e1a', '#3b82f6', '#10b981', '#f87171', '#60a5fa'] },
11
+ { Key: 'slate', Label: 'Slate', Colors: ['#1e2228', '#6b8aae', '#5ea37a', '#c85a5a', '#82a0c4'] },
12
+ { Key: 'warm-earth', Label: 'Warm Earth', Colors: ['#1a1610', '#c4956a', '#8a9a5a', '#b04050', '#4a9090'] },
13
+ { Key: 'high-contrast', Label: 'High Contrast', Colors: ['#000000', '#58a6ff', '#3fb950', '#f85149', '#d29922'] }
14
+ ];
15
+
16
+ // Shared providers
17
+ const libProvider = require('../pict-app/providers/Pict-Provider-Facto.js');
18
+ const libUIProvider = require('../pict-app/providers/Pict-Provider-Facto-UI.js');
19
+
20
+ // Shell views
21
+ const libViewLayout = require('./views/PictView-Facto-Full-Layout.js');
22
+ const libViewTopBar = require('./views/PictView-Facto-Full-TopBar.js');
23
+ const libViewBottomBar = require('./views/PictView-Facto-Full-BottomBar.js');
24
+
25
+ // Content views
26
+ const libViewDashboard = require('./views/PictView-Facto-Full-Dashboard.js');
27
+ const libViewSourceResearch = require('./views/PictView-Facto-Full-SourceResearch.js');
28
+ const libViewIngestJobs = require('./views/PictView-Facto-Full-IngestJobs.js');
29
+ const libViewSources = require('./views/PictView-Facto-Full-Sources.js');
30
+ const libViewDatasets = require('./views/PictView-Facto-Full-Datasets.js');
31
+ const libViewRecords = require('./views/PictView-Facto-Full-Records.js');
32
+ const libViewProjections = require('./views/PictView-Facto-Full-Projections.js');
33
+ const libViewSchemaEditor = require('./views/PictView-Facto-Full-SchemaEditor.js');
34
+ const libViewMappingEditor = require('./views/PictView-Facto-Full-MappingEditor.js');
35
+ const libViewQueryPanel = require('./views/PictView-Facto-Full-QueryPanel.js');
36
+ const libViewDashboards = require('./views/PictView-Facto-Full-Dashboards.js');
37
+ const libViewRecordViewer = require('./views/PictView-Facto-Full-RecordViewer.js');
38
+ const libViewSourceDetail = require('./views/PictView-Facto-Full-SourceDetail.js');
39
+ const libViewSourceEditor = require('./views/PictView-Facto-Full-SourceEditor.js');
40
+ const libViewScanner = require('./views/PictView-Facto-Full-Scanner.js');
41
+ const libViewConnections = require('./views/PictView-Facto-Full-Connections.js');
42
+ const libViewProjectionDetail = require('./views/PictView-Facto-Full-ProjectionDetail.js');
43
+ const libViewThroughput = require('./views/PictView-Facto-Full-Throughput.js');
44
+ const libViewSchemaResearch = require('./views/PictView-Facto-Full-SchemaResearch.js');
45
+ const libViewSchemaDetail = require('./views/PictView-Facto-Full-SchemaDetail.js');
46
+ const libViewSchemaDocEditor = require('./views/PictView-Facto-Full-SchemaDocEditor.js');
47
+
48
+ class FactoFullApplication extends libPictApplication
49
+ {
50
+ constructor(pFable, pOptions, pServiceHash)
51
+ {
52
+ super(pFable, pOptions, pServiceHash);
53
+
54
+ // Skip premature route resolution during addRoute(); the Layout view
55
+ // calls resolve() explicitly after the DOM is ready.
56
+ this.pict.settings.RouterSkipRouteResolveOnAdd = true;
57
+
58
+ // Register modal/notification service
59
+ this.pict.addView('Pict-Section-Modal', libPictSectionModal.default_configuration, libPictSectionModal);
60
+
61
+ // Register providers
62
+ this.pict.addProvider('Facto', libProvider.default_configuration, libProvider);
63
+ this.pict.addProvider('FactoUI', libUIProvider.default_configuration, libUIProvider);
64
+
65
+ // Register router
66
+ this.pict.addProvider('PictRouter',
67
+ require('./providers/PictRouter-Facto-Configuration.json'), libPictRouter);
68
+
69
+ // Shell views
70
+ this.pict.addView('Facto-Full-Layout', libViewLayout.default_configuration, libViewLayout);
71
+ this.pict.addView('Facto-Full-TopBar', libViewTopBar.default_configuration, libViewTopBar);
72
+ this.pict.addView('Facto-Full-BottomBar', libViewBottomBar.default_configuration, libViewBottomBar);
73
+
74
+ // Content views
75
+ this.pict.addView('Facto-Full-Dashboard', libViewDashboard.default_configuration, libViewDashboard);
76
+ this.pict.addView('Facto-Full-SourceResearch', libViewSourceResearch.default_configuration, libViewSourceResearch);
77
+ this.pict.addView('Facto-Full-IngestJobs', libViewIngestJobs.default_configuration, libViewIngestJobs);
78
+ this.pict.addView('Facto-Full-Sources', libViewSources.default_configuration, libViewSources);
79
+ this.pict.addView('Facto-Full-Datasets', libViewDatasets.default_configuration, libViewDatasets);
80
+ this.pict.addView('Facto-Full-Records', libViewRecords.default_configuration, libViewRecords);
81
+ this.pict.addView('Facto-Full-Projections', libViewProjections.default_configuration, libViewProjections);
82
+ this.pict.addView('Facto-Full-SchemaEditor', libViewSchemaEditor.default_configuration, libViewSchemaEditor);
83
+ this.pict.addView('Facto-Full-MappingEditor', libViewMappingEditor.default_configuration, libViewMappingEditor);
84
+ this.pict.addView('Facto-Full-QueryPanel', libViewQueryPanel.default_configuration, libViewQueryPanel);
85
+ this.pict.addView('Facto-Full-Dashboards', libViewDashboards.default_configuration, libViewDashboards);
86
+ this.pict.addView('Facto-Full-RecordViewer', libViewRecordViewer.default_configuration, libViewRecordViewer);
87
+ this.pict.addView('Facto-Full-SourceDetail', libViewSourceDetail.default_configuration, libViewSourceDetail);
88
+ this.pict.addView('Facto-Full-SourceEditor', libViewSourceEditor.default_configuration, libViewSourceEditor);
89
+ this.pict.addView('Facto-Full-Scanner', libViewScanner.default_configuration, libViewScanner);
90
+ this.pict.addView('Facto-Full-Connections', libViewConnections.default_configuration, libViewConnections);
91
+ this.pict.addView('Facto-Full-ProjectionDetail', libViewProjectionDetail.default_configuration, libViewProjectionDetail);
92
+ this.pict.addView('Facto-Full-Throughput', libViewThroughput.default_configuration, libViewThroughput);
93
+ this.pict.addView('Facto-Full-SchemaResearch', libViewSchemaResearch.default_configuration, libViewSchemaResearch);
94
+ this.pict.addView('Facto-Full-SchemaDetail', libViewSchemaDetail.default_configuration, libViewSchemaDetail);
95
+ this.pict.addView('Facto-Full-SchemaDocEditor', libViewSchemaDocEditor.default_configuration, libViewSchemaDocEditor);
96
+ }
97
+
98
+ onAfterInitializeAsync(fCallback)
99
+ {
100
+ // Apply saved theme before first render
101
+ this.loadSavedTheme();
102
+
103
+ // Initialize application state
104
+ this.pict.AppData.Facto =
105
+ {
106
+ CatalogEntries: [],
107
+ Sources: [],
108
+ Datasets: [],
109
+ Records: [],
110
+ IngestJobs: [],
111
+ Projections: [],
112
+ SelectedSource: null,
113
+ SelectedDataset: null,
114
+ RecordPage: 0,
115
+ RecordPageSize: 50,
116
+ RecordFilterSources: [],
117
+ RecordFilterDatasets: [],
118
+ RecordFilterDateFrom: '',
119
+ RecordFilterDateTo: '',
120
+ CurrentRecordContent: {},
121
+ CurrentDocumentSegments: [],
122
+ StoreConnections: [],
123
+ AvailableConnectionTypes: [],
124
+ ProjectionMappings: [],
125
+ DiscoveredFields: {},
126
+ ScannerPaths: [],
127
+ ScannerDatasets: [],
128
+ Schemas: [],
129
+ SelectedSchema: null,
130
+ SchemaVersions: [],
131
+ CurrentTheme: 'turquoise-deluxe',
132
+ CurrentRoute: ''
133
+ };
134
+
135
+ // Expose pict globally for inline onclick handlers
136
+ window.pict = this.pict;
137
+
138
+ // Register all parameterized routes BEFORE rendering the layout,
139
+ // so they are available when resolve() fires after the DOM is ready.
140
+ let tmpSelf = this;
141
+ this.pict.providers.PictRouter.addRoute('/Record/:IDRecord',
142
+ (pMatch) =>
143
+ {
144
+ let tmpIDRecord = pMatch && pMatch.data ? pMatch.data.IDRecord : null;
145
+ if (tmpIDRecord)
146
+ {
147
+ tmpSelf.showRecordView(tmpIDRecord);
148
+ }
149
+ });
150
+
151
+ this.pict.providers.PictRouter.addRoute('/Records/FilteredTo/:Filter/:Begin/:Cap',
152
+ (pMatch) =>
153
+ {
154
+ let tmpFilter = pMatch && pMatch.data ? pMatch.data.Filter : null;
155
+ let tmpBegin = pMatch && pMatch.data ? parseInt(pMatch.data.Begin, 10) : 0;
156
+ let tmpCap = pMatch && pMatch.data ? parseInt(pMatch.data.Cap, 10) : 50;
157
+ if (tmpFilter)
158
+ {
159
+ tmpSelf.showFilteredRecordsView(tmpFilter, tmpBegin, tmpCap);
160
+ }
161
+ });
162
+
163
+ this.pict.providers.PictRouter.addRoute('/Projection/:EntityName/Record/:IDRecord',
164
+ (pMatch) =>
165
+ {
166
+ let tmpEntityName = pMatch && pMatch.data ? pMatch.data.EntityName : null;
167
+ let tmpIDRecord = pMatch && pMatch.data ? pMatch.data.IDRecord : null;
168
+ if (tmpEntityName && tmpIDRecord)
169
+ {
170
+ tmpSelf.showProjectionRecordView(tmpEntityName, tmpIDRecord);
171
+ }
172
+ });
173
+
174
+ this.pict.providers.PictRouter.addRoute('/Source/:IDSource',
175
+ (pMatch) =>
176
+ {
177
+ let tmpIDSource = pMatch && pMatch.data ? pMatch.data.IDSource : null;
178
+ if (tmpIDSource)
179
+ {
180
+ tmpSelf.showSourceView(tmpIDSource);
181
+ }
182
+ });
183
+
184
+ this.pict.providers.PictRouter.addRoute('/Projection/:IDDataset',
185
+ (pMatch) =>
186
+ {
187
+ let tmpIDDataset = pMatch && pMatch.data ? pMatch.data.IDDataset : null;
188
+ if (tmpIDDataset)
189
+ {
190
+ tmpSelf.showProjectionView(tmpIDDataset);
191
+ }
192
+ });
193
+
194
+ this.pict.providers.PictRouter.addRoute('/Source/:IDSource/Doc/:IDDoc',
195
+ (pMatch) =>
196
+ {
197
+ let tmpIDSource = pMatch && pMatch.data ? pMatch.data.IDSource : null;
198
+ let tmpIDDoc = pMatch && pMatch.data ? pMatch.data.IDDoc : null;
199
+ if (tmpIDSource)
200
+ {
201
+ tmpSelf.showSourceView(tmpIDSource, tmpIDDoc);
202
+ }
203
+ });
204
+
205
+ this.pict.providers.PictRouter.addRoute('/Schema/:IDSchema',
206
+ (pMatch) =>
207
+ {
208
+ let tmpIDSchema = pMatch && pMatch.data ? pMatch.data.IDSchema : null;
209
+ if (tmpIDSchema)
210
+ {
211
+ tmpSelf.showSchemaView(tmpIDSchema);
212
+ }
213
+ });
214
+
215
+ this.pict.providers.PictRouter.addRoute('/Schema/:IDSchema/Doc/:IDDoc',
216
+ (pMatch) =>
217
+ {
218
+ let tmpIDSchema = pMatch && pMatch.data ? pMatch.data.IDSchema : null;
219
+ let tmpIDDoc = pMatch && pMatch.data ? pMatch.data.IDDoc : null;
220
+ if (tmpIDSchema)
221
+ {
222
+ tmpSelf.showSchemaView(tmpIDSchema, tmpIDDoc);
223
+ }
224
+ });
225
+
226
+ // Render the layout shell — this cascades into TopBar, BottomBar
227
+ this.pict.views['Facto-Full-Layout'].render();
228
+
229
+ // Resolve the router now that all routes are registered and the DOM
230
+ // is ready. This picks up the current hash URL for deep links / reloads.
231
+ this.pict.providers.PictRouter.resolve();
232
+
233
+ return super.onAfterInitializeAsync(fCallback);
234
+ }
235
+
236
+ navigateTo(pRoute)
237
+ {
238
+ this.pict.providers.PictRouter.navigate(pRoute);
239
+ }
240
+
241
+ showRecordView(pIDRecord)
242
+ {
243
+ let tmpView = this.pict.views['Facto-Full-RecordViewer'];
244
+ if (tmpView)
245
+ {
246
+ tmpView.loadRecord(pIDRecord);
247
+ }
248
+ // Highlight "Records" in the nav since the record viewer is a child of Records
249
+ this._setActiveNav('Records');
250
+ }
251
+
252
+ showFilteredRecordsView(pFilterString, pBegin, pCap)
253
+ {
254
+ let tmpProvider = this.pict.providers.Facto;
255
+
256
+ // Parse the FilteredTo string into structured filter objects
257
+ let tmpFilters = tmpProvider.parseFilteredToString(pFilterString);
258
+
259
+ // Extract UI state (source IDs, dataset IDs, dates) from the filters
260
+ let tmpState = tmpProvider.extractRecordStateFromFilters(tmpFilters);
261
+
262
+ // Update AppData with the parsed filter state
263
+ this.pict.AppData.Facto.RecordFilterSources = tmpState.SourceIDs;
264
+ this.pict.AppData.Facto.RecordFilterDatasets = tmpState.DatasetIDs;
265
+ this.pict.AppData.Facto.RecordFilterDateFrom = tmpState.DateFrom;
266
+ this.pict.AppData.Facto.RecordFilterDateTo = tmpState.DateTo;
267
+
268
+ // Set pagination from URL
269
+ let tmpPageSize = pCap || this.pict.AppData.Facto.RecordPageSize || 50;
270
+ this.pict.AppData.Facto.RecordPage = Math.floor((pBegin || 0) / tmpPageSize);
271
+ this.pict.AppData.Facto.RecordPageSize = tmpPageSize;
272
+
273
+ // Store the raw filter string so the Records view can use it directly
274
+ this.pict.AppData.Facto.RecordFilterString = pFilterString;
275
+
276
+ // Show the Records view — it will pick up the filter state from AppData
277
+ let tmpView = this.pict.views['Facto-Full-Records'];
278
+ if (tmpView)
279
+ {
280
+ tmpView.render();
281
+ }
282
+ this._setActiveNav('Records');
283
+ }
284
+
285
+ showProjectionRecordView(pEntityName, pIDRecord)
286
+ {
287
+ let tmpView = this.pict.views['Facto-Full-RecordViewer'];
288
+ if (tmpView)
289
+ {
290
+ tmpView.loadProjectionRecord(pEntityName, pIDRecord);
291
+ }
292
+ this._setActiveNav('Records');
293
+ }
294
+
295
+ showSourceView(pIDSource, pIDDoc)
296
+ {
297
+ let tmpView = this.pict.views['Facto-Full-SourceDetail'];
298
+ if (tmpView)
299
+ {
300
+ tmpView.loadSource(pIDSource, pIDDoc);
301
+ }
302
+ // Highlight "SourceResearch" in the nav since source detail is a child of Source Research
303
+ this._setActiveNav('SourceResearch');
304
+ }
305
+
306
+ showSchemaView(pIDSchema, pIDDoc)
307
+ {
308
+ let tmpView = this.pict.views['Facto-Full-SchemaDetail'];
309
+ if (tmpView)
310
+ {
311
+ tmpView.loadSchema(pIDSchema, pIDDoc);
312
+ }
313
+ this._setActiveNav('SchemaResearch');
314
+ }
315
+
316
+ showProjectionView(pIDDataset)
317
+ {
318
+ let tmpView = this.pict.views['Facto-Full-ProjectionDetail'];
319
+ if (tmpView)
320
+ {
321
+ tmpView.loadProjection(pIDDataset);
322
+ }
323
+ this._setActiveNav('Projections');
324
+ }
325
+
326
+ showView(pViewIdentifier)
327
+ {
328
+ if (pViewIdentifier in this.pict.views)
329
+ {
330
+ this.pict.views[pViewIdentifier].render();
331
+ }
332
+ else
333
+ {
334
+ this.pict.log.warn(`View [${pViewIdentifier}] not found; falling back to dashboard.`);
335
+ this.pict.views['Facto-Full-Dashboard'].render();
336
+ }
337
+
338
+ // Derive the route name from the view identifier for nav highlighting
339
+ // e.g. "Facto-Full-SourceResearch" → "SourceResearch"
340
+ let tmpRoute = pViewIdentifier.replace('Facto-Full-', '');
341
+ this._setActiveNav(tmpRoute);
342
+ }
343
+
344
+ _setActiveNav(pRoute)
345
+ {
346
+ this.pict.AppData.Facto.CurrentRoute = pRoute;
347
+
348
+ let tmpTopBar = this.pict.views['Facto-Full-TopBar'];
349
+ if (tmpTopBar && typeof tmpTopBar.highlightRoute === 'function')
350
+ {
351
+ tmpTopBar.highlightRoute(pRoute);
352
+ }
353
+ }
354
+
355
+ // --- Theme ---
356
+ applyTheme(pThemeKey)
357
+ {
358
+ let tmpThemeKey = pThemeKey || 'turquoise-deluxe';
359
+
360
+ if (tmpThemeKey === 'turquoise-deluxe')
361
+ {
362
+ delete document.body.dataset.theme;
363
+ }
364
+ else
365
+ {
366
+ document.body.dataset.theme = tmpThemeKey;
367
+ }
368
+
369
+ localStorage.setItem('facto-theme', tmpThemeKey);
370
+
371
+ if (this.pict.AppData.Facto)
372
+ {
373
+ this.pict.AppData.Facto.CurrentTheme = tmpThemeKey;
374
+ }
375
+ }
376
+
377
+ loadSavedTheme()
378
+ {
379
+ let tmpSavedTheme = localStorage.getItem('facto-theme') || 'turquoise-deluxe';
380
+ this.applyTheme(tmpSavedTheme);
381
+ }
382
+
383
+ getThemeList()
384
+ {
385
+ return THEME_LIST;
386
+ }
387
+ }
388
+
389
+ module.exports = FactoFullApplication;
390
+
391
+ module.exports.default_configuration = require('./Pict-Application-Facto-Full-Configuration.json');
@@ -0,0 +1,56 @@
1
+ {
2
+ "ProviderIdentifier": "Pict-Router",
3
+ "AutoInitialize": true,
4
+ "AutoInitializeOrdinal": 0,
5
+ "Routes":
6
+ [
7
+ {
8
+ "path": "/Home",
9
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Dashboard`)~}"
10
+ },
11
+ {
12
+ "path": "/Scanner",
13
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Scanner`)~}"
14
+ },
15
+ {
16
+ "path": "/SourceResearch",
17
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-SourceResearch`)~}"
18
+ },
19
+ {
20
+ "path": "/SchemaResearch",
21
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-SchemaResearch`)~}"
22
+ },
23
+ {
24
+ "path": "/IngestJobs",
25
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-IngestJobs`)~}"
26
+ },
27
+ {
28
+ "path": "/Sources",
29
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Sources`)~}"
30
+ },
31
+ {
32
+ "path": "/Datasets",
33
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Datasets`)~}"
34
+ },
35
+ {
36
+ "path": "/Records",
37
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Records`)~}"
38
+ },
39
+ {
40
+ "path": "/Projections",
41
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Projections`)~}"
42
+ },
43
+ {
44
+ "path": "/Connections",
45
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Connections`)~}"
46
+ },
47
+ {
48
+ "path": "/Dashboards",
49
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Dashboards`)~}"
50
+ },
51
+ {
52
+ "path": "/Throughput",
53
+ "template": "{~LV:Pict.PictApplication.showView(`Facto-Full-Throughput`)~}"
54
+ }
55
+ ]
56
+ }
@@ -0,0 +1,68 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "Facto-Full-BottomBar",
6
+
7
+ DefaultRenderable: "Facto-Full-BottomBar-Content",
8
+ DefaultDestinationAddress: "#Facto-Full-BottomBar-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ .facto-bottombar {
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ padding: 0.6em 1.25em;
18
+ background: var(--facto-topbar-bg);
19
+ border-top: 1px solid var(--facto-border-subtle);
20
+ font-size: 0.78em;
21
+ color: var(--facto-text-tertiary);
22
+ }
23
+
24
+ .facto-bottombar a {
25
+ color: var(--facto-text-tertiary);
26
+ text-decoration: none;
27
+ }
28
+
29
+ .facto-bottombar a:hover {
30
+ color: var(--facto-text-secondary);
31
+ }
32
+ `,
33
+
34
+ Templates:
35
+ [
36
+ {
37
+ Hash: "Facto-Full-BottomBar-Template",
38
+ Template: /*html*/`
39
+ <div class="facto-bottombar">
40
+ <span>Retold Facto Data Warehouse</span>
41
+ <span>Retold</span>
42
+ </div>
43
+ `
44
+ }
45
+ ],
46
+
47
+ Renderables:
48
+ [
49
+ {
50
+ RenderableHash: "Facto-Full-BottomBar-Content",
51
+ TemplateHash: "Facto-Full-BottomBar-Template",
52
+ DestinationAddress: "#Facto-Full-BottomBar-Container",
53
+ RenderMethod: "replace"
54
+ }
55
+ ]
56
+ };
57
+
58
+ class FactoFullBottomBarView extends libPictView
59
+ {
60
+ constructor(pFable, pOptions, pServiceHash)
61
+ {
62
+ super(pFable, pOptions, pServiceHash);
63
+ }
64
+ }
65
+
66
+ module.exports = FactoFullBottomBarView;
67
+
68
+ module.exports.default_configuration = _ViewConfiguration;