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.
- package/.claude/launch.json +11 -0
- package/.dockerignore +8 -0
- package/.quackage.json +19 -0
- package/Dockerfile +26 -0
- package/bin/retold-facto.js +909 -0
- package/examples/facto-government-data.sqlite +0 -0
- package/examples/government-data-catalog.json +137 -0
- package/examples/government-data-loader.js +1432 -0
- package/package.json +91 -0
- package/scripts/facto-download.js +425 -0
- package/source/Retold-Facto.js +1042 -0
- package/source/services/Retold-Facto-BeaconProvider.js +511 -0
- package/source/services/Retold-Facto-CatalogManager.js +1252 -0
- package/source/services/Retold-Facto-DataLakeService.js +1642 -0
- package/source/services/Retold-Facto-DatasetManager.js +417 -0
- package/source/services/Retold-Facto-IngestEngine.js +1315 -0
- package/source/services/Retold-Facto-ProjectionEngine.js +3960 -0
- package/source/services/Retold-Facto-RecordManager.js +360 -0
- package/source/services/Retold-Facto-SchemaManager.js +1110 -0
- package/source/services/Retold-Facto-SourceFolderScanner.js +2243 -0
- package/source/services/Retold-Facto-SourceManager.js +730 -0
- package/source/services/Retold-Facto-StoreConnectionManager.js +441 -0
- package/source/services/Retold-Facto-ThroughputMonitor.js +478 -0
- package/source/services/web-app/codemirror-entry.js +7 -0
- package/source/services/web-app/pict-app/Pict-Application-Facto-Configuration.json +9 -0
- package/source/services/web-app/pict-app/Pict-Application-Facto.js +70 -0
- package/source/services/web-app/pict-app/Pict-Facto-Bundle.js +11 -0
- package/source/services/web-app/pict-app/providers/Pict-Provider-Facto-UI.js +66 -0
- package/source/services/web-app/pict-app/providers/Pict-Provider-Facto.js +69 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Catalog.js +93 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Connections.js +42 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Datasets.js +605 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Projections.js +188 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Scanner.js +80 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Schema.js +116 -0
- package/source/services/web-app/pict-app/providers/facto-api/Facto-API-Sources.js +104 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Catalog.js +526 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Datasets.js +173 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Ingest.js +259 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Layout.js +191 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Projections.js +231 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Records.js +326 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Scanner.js +624 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Sources.js +201 -0
- package/source/services/web-app/pict-app/views/PictView-Facto-Throughput.js +456 -0
- package/source/services/web-app/pict-app-full/Pict-Application-Facto-Full-Configuration.json +14 -0
- package/source/services/web-app/pict-app-full/Pict-Application-Facto-Full.js +391 -0
- package/source/services/web-app/pict-app-full/providers/PictRouter-Facto-Configuration.json +56 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-BottomBar.js +68 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Connections.js +340 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Dashboard.js +149 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Dashboards.js +819 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Datasets.js +178 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-IngestJobs.js +99 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Layout.js +62 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-MappingEditor.js +158 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-ProjectionDetail.js +1120 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Projections.js +172 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-QueryPanel.js +119 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-RecordViewer.js +663 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Records.js +648 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Scanner.js +1017 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaDetail.js +1404 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaDocEditor.js +1036 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaEditor.js +636 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SchemaResearch.js +357 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SourceDetail.js +822 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SourceEditor.js +1036 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-SourceResearch.js +487 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Sources.js +165 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-Throughput.js +439 -0
- package/source/services/web-app/pict-app-full/views/PictView-Facto-Full-TopBar.js +335 -0
- package/source/services/web-app/pict-app-full/views/projections/Facto-Projections-Constants.js +71 -0
- package/source/services/web-app/web/chart.min.js +20 -0
- package/source/services/web-app/web/codemirror-bundle.js +30099 -0
- package/source/services/web-app/web/css/facto-themes.css +467 -0
- package/source/services/web-app/web/css/facto.css +502 -0
- package/source/services/web-app/web/index.html +28 -0
- package/source/services/web-app/web/retold-facto.js +12138 -0
- package/source/services/web-app/web/retold-facto.js.map +1 -0
- package/source/services/web-app/web/retold-facto.min.js +2 -0
- package/source/services/web-app/web/retold-facto.min.js.map +1 -0
- package/source/services/web-app/web/simple/index.html +17 -0
- package/test/Facto_Browser_Integration_tests.js +798 -0
- package/test/RetoldFacto_tests.js +4117 -0
- package/test/fixtures/weather-readings.csv +17 -0
- package/test/fixtures/weather-stations.csv +9 -0
- package/test/model/MeadowModel-Extended.json +8497 -0
- package/test/model/MeadowModel-PICT.json +1 -0
- package/test/model/MeadowModel.json +1355 -0
- package/test/model/ddl/Facto.ddl +225 -0
- package/test/model/fable-configuration.json +14 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: "Facto-Full-Datasets",
|
|
6
|
+
|
|
7
|
+
DefaultRenderable: "Facto-Full-Datasets-Content",
|
|
8
|
+
DefaultDestinationAddress: "#Facto-Full-Content-Container",
|
|
9
|
+
|
|
10
|
+
AutoRender: false,
|
|
11
|
+
|
|
12
|
+
Templates:
|
|
13
|
+
[
|
|
14
|
+
{
|
|
15
|
+
Hash: "Facto-Full-Datasets-Template",
|
|
16
|
+
Template: /*html*/`
|
|
17
|
+
<div class="facto-content">
|
|
18
|
+
<div class="facto-content-header">
|
|
19
|
+
<h1>Data Sets</h1>
|
|
20
|
+
<p>Manage datasets and their configurations.</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div id="Facto-Full-Datasets-List"></div>
|
|
24
|
+
<div id="Facto-Full-Datasets-Stats" style="display:none; margin-top:1.25em; padding-top:1.25em; border-top:1px solid var(--facto-border-subtle);"></div>
|
|
25
|
+
|
|
26
|
+
<div class="facto-section" style="margin-top:2em;">
|
|
27
|
+
<div class="facto-section-title">Add Dataset</div>
|
|
28
|
+
<div class="facto-inline-group">
|
|
29
|
+
<div>
|
|
30
|
+
<label>Name</label>
|
|
31
|
+
<input type="text" id="Facto-Full-Dataset-Name" placeholder="Dataset name">
|
|
32
|
+
</div>
|
|
33
|
+
<div>
|
|
34
|
+
<label>Type</label>
|
|
35
|
+
<select id="Facto-Full-Dataset-Type">
|
|
36
|
+
<option value="Raw">Raw</option>
|
|
37
|
+
<option value="Compositional">Compositional</option>
|
|
38
|
+
<option value="Projection">Projection</option>
|
|
39
|
+
<option value="Derived">Derived</option>
|
|
40
|
+
</select>
|
|
41
|
+
</div>
|
|
42
|
+
<div>
|
|
43
|
+
<label>Description</label>
|
|
44
|
+
<input type="text" id="Facto-Full-Dataset-Desc" placeholder="Description">
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<button class="facto-btn facto-btn-primary" onclick="{~P~}.views['Facto-Full-Datasets'].addDataset()">Add Dataset</button>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
</div>
|
|
51
|
+
`
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
|
|
55
|
+
Renderables:
|
|
56
|
+
[
|
|
57
|
+
{
|
|
58
|
+
RenderableHash: "Facto-Full-Datasets-Content",
|
|
59
|
+
TemplateHash: "Facto-Full-Datasets-Template",
|
|
60
|
+
DestinationAddress: "#Facto-Full-Content-Container",
|
|
61
|
+
RenderMethod: "replace"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
class FactoFullDatasetsView extends libPictView
|
|
67
|
+
{
|
|
68
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
69
|
+
{
|
|
70
|
+
super(pFable, pOptions, pServiceHash);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
|
|
74
|
+
{
|
|
75
|
+
this.pict.providers.Facto.loadDatasets().then(
|
|
76
|
+
() => { this.refreshList(); }).catch(
|
|
77
|
+
(pError) =>
|
|
78
|
+
{
|
|
79
|
+
this.pict.views['Pict-Section-Modal'].toast('Error loading datasets: ' + pError.message, {type: 'error'});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
refreshList()
|
|
88
|
+
{
|
|
89
|
+
let tmpContainer = document.getElementById('Facto-Full-Datasets-List');
|
|
90
|
+
if (!tmpContainer) return;
|
|
91
|
+
|
|
92
|
+
let tmpDatasets = this.pict.AppData.Facto.Datasets;
|
|
93
|
+
if (!tmpDatasets || tmpDatasets.length === 0)
|
|
94
|
+
{
|
|
95
|
+
tmpContainer.innerHTML = '<div class="facto-empty">No datasets yet. Add one below or provision from Source Research.</div>';
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let tmpHtml = '<table><thead><tr><th>ID</th><th>Hash</th><th>Name</th><th>Type</th><th>Description</th><th>Version Policy</th><th>Actions</th></tr></thead><tbody>';
|
|
100
|
+
for (let i = 0; i < tmpDatasets.length; i++)
|
|
101
|
+
{
|
|
102
|
+
let tmpDS = tmpDatasets[i];
|
|
103
|
+
let tmpTypeBadge = 'facto-badge-primary';
|
|
104
|
+
if (tmpDS.Type === 'Projection') tmpTypeBadge = 'facto-badge-warning';
|
|
105
|
+
else if (tmpDS.Type === 'Derived') tmpTypeBadge = 'facto-badge-muted';
|
|
106
|
+
|
|
107
|
+
tmpHtml += '<tr>';
|
|
108
|
+
tmpHtml += '<td>' + (tmpDS.IDDataset || '') + '</td>';
|
|
109
|
+
tmpHtml += '<td><code>' + (tmpDS.Hash || '-') + '</code></td>';
|
|
110
|
+
tmpHtml += '<td>' + (tmpDS.Name || '') + '</td>';
|
|
111
|
+
tmpHtml += '<td><span class="facto-badge ' + tmpTypeBadge + '">' + (tmpDS.Type || '') + '</span></td>';
|
|
112
|
+
tmpHtml += '<td>' + (tmpDS.Description || '') + '</td>';
|
|
113
|
+
tmpHtml += '<td>' + (tmpDS.VersionPolicy || 'Append') + '</td>';
|
|
114
|
+
tmpHtml += '<td><button class="facto-btn facto-btn-secondary facto-btn-small" onclick="pict.views[\'Facto-Full-Datasets\'].viewStats(' + tmpDS.IDDataset + ')">Stats</button></td>';
|
|
115
|
+
tmpHtml += '</tr>';
|
|
116
|
+
}
|
|
117
|
+
tmpHtml += '</tbody></table>';
|
|
118
|
+
tmpContainer.innerHTML = tmpHtml;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
viewStats(pIDDataset)
|
|
122
|
+
{
|
|
123
|
+
let tmpStatsContainer = document.getElementById('Facto-Full-Datasets-Stats');
|
|
124
|
+
if (!tmpStatsContainer) return;
|
|
125
|
+
tmpStatsContainer.style.display = 'block';
|
|
126
|
+
tmpStatsContainer.innerHTML = '<p style="color:var(--facto-text-secondary);">Loading stats for Dataset #' + pIDDataset + '...</p>';
|
|
127
|
+
|
|
128
|
+
this.pict.providers.Facto.loadDatasetStats(pIDDataset).then(
|
|
129
|
+
(pResponse) =>
|
|
130
|
+
{
|
|
131
|
+
if (pResponse)
|
|
132
|
+
{
|
|
133
|
+
let tmpHtml = '<h3>Dataset #' + pIDDataset + ' Statistics</h3>';
|
|
134
|
+
tmpHtml += '<div class="facto-card-grid" style="margin-top:0.75em;">';
|
|
135
|
+
tmpHtml += '<div class="facto-card facto-dashboard-stat"><div class="facto-dashboard-stat-value">' + (pResponse.RecordCount || 0) + '</div><div class="facto-dashboard-stat-label">Records</div></div>';
|
|
136
|
+
tmpHtml += '<div class="facto-card facto-dashboard-stat"><div class="facto-dashboard-stat-value">' + (pResponse.SourceCount || 0) + '</div><div class="facto-dashboard-stat-label">Sources</div></div>';
|
|
137
|
+
tmpHtml += '<div class="facto-card facto-dashboard-stat"><div class="facto-dashboard-stat-value">' + (pResponse.CurrentVersion || 0) + '</div><div class="facto-dashboard-stat-label">Current Version</div></div>';
|
|
138
|
+
tmpHtml += '</div>';
|
|
139
|
+
tmpHtml += '<div style="margin-top:0.75em;"><button class="facto-btn facto-btn-secondary" onclick="document.getElementById(\'Facto-Full-Datasets-Stats\').style.display=\'none\'">Close</button></div>';
|
|
140
|
+
tmpStatsContainer.innerHTML = tmpHtml;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
addDataset()
|
|
146
|
+
{
|
|
147
|
+
let tmpName = this.pict.providers.FactoUI.getVal('Facto-Full-Dataset-Name');
|
|
148
|
+
let tmpType = this.pict.providers.FactoUI.getVal('Facto-Full-Dataset-Type');
|
|
149
|
+
let tmpDesc = this.pict.providers.FactoUI.getVal('Facto-Full-Dataset-Desc');
|
|
150
|
+
|
|
151
|
+
if (!tmpName)
|
|
152
|
+
{
|
|
153
|
+
this.pict.views['Pict-Section-Modal'].toast('Dataset name is required', {type: 'warning'});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
this.pict.providers.Facto.createDataset({ Name: tmpName, Type: tmpType, Description: tmpDesc }).then(
|
|
158
|
+
(pResponse) =>
|
|
159
|
+
{
|
|
160
|
+
if (pResponse && pResponse.IDDataset)
|
|
161
|
+
{
|
|
162
|
+
this.pict.views['Pict-Section-Modal'].toast('Dataset created: ' + tmpName, {type: 'success'});
|
|
163
|
+
document.getElementById('Facto-Full-Dataset-Name').value = '';
|
|
164
|
+
document.getElementById('Facto-Full-Dataset-Desc').value = '';
|
|
165
|
+
return this.pict.providers.Facto.loadDatasets();
|
|
166
|
+
}
|
|
167
|
+
else
|
|
168
|
+
{
|
|
169
|
+
this.pict.views['Pict-Section-Modal'].toast('Error creating dataset', {type: 'error'});
|
|
170
|
+
}
|
|
171
|
+
}).then(
|
|
172
|
+
() => { this.refreshList(); });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
module.exports = FactoFullDatasetsView;
|
|
177
|
+
|
|
178
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: "Facto-Full-IngestJobs",
|
|
6
|
+
|
|
7
|
+
DefaultRenderable: "Facto-Full-IngestJobs-Content",
|
|
8
|
+
DefaultDestinationAddress: "#Facto-Full-Content-Container",
|
|
9
|
+
|
|
10
|
+
AutoRender: false,
|
|
11
|
+
|
|
12
|
+
Templates:
|
|
13
|
+
[
|
|
14
|
+
{
|
|
15
|
+
Hash: "Facto-Full-IngestJobs-Template",
|
|
16
|
+
Template: /*html*/`
|
|
17
|
+
<div class="facto-content">
|
|
18
|
+
<div class="facto-content-header">
|
|
19
|
+
<h1>Ingestion Jobs</h1>
|
|
20
|
+
<p>Monitor and manage data ingestion jobs.</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div id="Facto-Full-IngestJobs-List"></div>
|
|
24
|
+
<div id="Facto-Full-IngestJobs-Status" class="facto-status" style="display:none;"></div>
|
|
25
|
+
</div>
|
|
26
|
+
`
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
|
|
30
|
+
Renderables:
|
|
31
|
+
[
|
|
32
|
+
{
|
|
33
|
+
RenderableHash: "Facto-Full-IngestJobs-Content",
|
|
34
|
+
TemplateHash: "Facto-Full-IngestJobs-Template",
|
|
35
|
+
DestinationAddress: "#Facto-Full-Content-Container",
|
|
36
|
+
RenderMethod: "replace"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
class FactoFullIngestJobsView extends libPictView
|
|
42
|
+
{
|
|
43
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
44
|
+
{
|
|
45
|
+
super(pFable, pOptions, pServiceHash);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
|
|
49
|
+
{
|
|
50
|
+
this.pict.providers.Facto.loadIngestJobs().then(
|
|
51
|
+
() => { this.refreshList(); }).catch(
|
|
52
|
+
(pError) =>
|
|
53
|
+
{
|
|
54
|
+
this.pict.views['Pict-Section-Modal'].toast('Error loading ingest jobs: ' + pError.message, {type: 'error'});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
refreshList()
|
|
61
|
+
{
|
|
62
|
+
let tmpContainer = document.getElementById('Facto-Full-IngestJobs-List');
|
|
63
|
+
if (!tmpContainer) return;
|
|
64
|
+
|
|
65
|
+
let tmpJobs = this.pict.AppData.Facto.IngestJobs;
|
|
66
|
+
if (!tmpJobs || tmpJobs.length === 0)
|
|
67
|
+
{
|
|
68
|
+
tmpContainer.innerHTML = '<div class="facto-empty">No ingestion jobs yet. Jobs are created automatically when data is ingested.</div>';
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let tmpHtml = '<table><thead><tr><th>ID</th><th>Source</th><th>Dataset</th><th>Status</th><th>Version</th><th>Records</th><th>Errors</th><th>Created</th></tr></thead><tbody>';
|
|
73
|
+
for (let i = 0; i < tmpJobs.length; i++)
|
|
74
|
+
{
|
|
75
|
+
let tmpJob = tmpJobs[i];
|
|
76
|
+
let tmpStatusBadge = 'facto-badge-muted';
|
|
77
|
+
if (tmpJob.Status === 'Complete') tmpStatusBadge = 'facto-badge-success';
|
|
78
|
+
else if (tmpJob.Status === 'Running') tmpStatusBadge = 'facto-badge-primary';
|
|
79
|
+
else if (tmpJob.Status === 'Error') tmpStatusBadge = 'facto-badge-error';
|
|
80
|
+
|
|
81
|
+
tmpHtml += '<tr>';
|
|
82
|
+
tmpHtml += '<td>' + (tmpJob.IDIngestJob || '') + '</td>';
|
|
83
|
+
tmpHtml += '<td>' + (tmpJob.IDSource || '') + '</td>';
|
|
84
|
+
tmpHtml += '<td>' + (tmpJob.IDDataset || '') + '</td>';
|
|
85
|
+
tmpHtml += '<td><span class="facto-badge ' + tmpStatusBadge + '">' + (tmpJob.Status || 'Pending') + '</span></td>';
|
|
86
|
+
tmpHtml += '<td>' + (tmpJob.DatasetVersion || '') + '</td>';
|
|
87
|
+
tmpHtml += '<td>' + (tmpJob.RecordsIngested || 0) + '</td>';
|
|
88
|
+
tmpHtml += '<td>' + (tmpJob.RecordsErrored || 0) + '</td>';
|
|
89
|
+
tmpHtml += '<td>' + (tmpJob.CreatingIDUser ? new Date(tmpJob.CreateDate).toLocaleString() : (tmpJob.CreateDate || '')) + '</td>';
|
|
90
|
+
tmpHtml += '</tr>';
|
|
91
|
+
}
|
|
92
|
+
tmpHtml += '</tbody></table>';
|
|
93
|
+
tmpContainer.innerHTML = tmpHtml;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = FactoFullIngestJobsView;
|
|
98
|
+
|
|
99
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: "Facto-Full-Layout",
|
|
6
|
+
|
|
7
|
+
DefaultRenderable: "Facto-Full-Layout-Shell",
|
|
8
|
+
DefaultDestinationAddress: "#Facto-Full-Application-Container",
|
|
9
|
+
|
|
10
|
+
AutoRender: false,
|
|
11
|
+
|
|
12
|
+
Templates:
|
|
13
|
+
[
|
|
14
|
+
{
|
|
15
|
+
Hash: "Facto-Full-Layout-Shell-Template",
|
|
16
|
+
Template: /*html*/`
|
|
17
|
+
<div id="Facto-Full-TopBar-Container"></div>
|
|
18
|
+
<div id="Facto-Full-Content-Container"></div>
|
|
19
|
+
<div id="Facto-Full-BottomBar-Container"></div>
|
|
20
|
+
`
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
|
|
24
|
+
Renderables:
|
|
25
|
+
[
|
|
26
|
+
{
|
|
27
|
+
RenderableHash: "Facto-Full-Layout-Shell",
|
|
28
|
+
TemplateHash: "Facto-Full-Layout-Shell-Template",
|
|
29
|
+
DestinationAddress: "#Facto-Full-Application-Container",
|
|
30
|
+
RenderMethod: "replace"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class FactoFullLayoutView extends libPictView
|
|
36
|
+
{
|
|
37
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
38
|
+
{
|
|
39
|
+
super(pFable, pOptions, pServiceHash);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
|
|
43
|
+
{
|
|
44
|
+
// Render shell views
|
|
45
|
+
this.pict.views['Facto-Full-TopBar'].render();
|
|
46
|
+
this.pict.views['Facto-Full-BottomBar'].render();
|
|
47
|
+
|
|
48
|
+
// Render the dashboard as default content.
|
|
49
|
+
// The application will call resolve() after this, which will
|
|
50
|
+
// override with the correct view if a hash route is present.
|
|
51
|
+
this.pict.views['Facto-Full-Dashboard'].render();
|
|
52
|
+
|
|
53
|
+
// Inject all view CSS into the PICT-CSS style element
|
|
54
|
+
this.pict.CSSMap.injectCSS();
|
|
55
|
+
|
|
56
|
+
return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = FactoFullLayoutView;
|
|
61
|
+
|
|
62
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const libMeadowMappingEditorView = require('meadow-integration').MeadowMappingEditorView;
|
|
2
|
+
|
|
3
|
+
// Facto-specific view configuration: same template HTML as the generic editor
|
|
4
|
+
// but with 'Facto-Full-MappingEditor' in all onclick handlers so pict can
|
|
5
|
+
// resolve the registered view name. DOM IDs are the generic MeadowMap-*
|
|
6
|
+
// set so inherited JS methods work without modification.
|
|
7
|
+
const _ViewConfiguration =
|
|
8
|
+
{
|
|
9
|
+
ViewIdentifier: "Facto-Full-MappingEditor",
|
|
10
|
+
|
|
11
|
+
DefaultRenderable: "Facto-Full-MappingEditor-Content",
|
|
12
|
+
DefaultDestinationAddress: "#Facto-Proj-Mapping-Editor-Container",
|
|
13
|
+
|
|
14
|
+
AutoRender: false,
|
|
15
|
+
|
|
16
|
+
CSS: libMeadowMappingEditorView.default_configuration.CSS,
|
|
17
|
+
|
|
18
|
+
Templates:
|
|
19
|
+
[
|
|
20
|
+
{
|
|
21
|
+
Hash: "Facto-Full-MappingEditor-Template",
|
|
22
|
+
Template: /*html*/`
|
|
23
|
+
<div>
|
|
24
|
+
<div id="MeadowMap-Editor" class="meadow-mapping-editor">
|
|
25
|
+
<div class="meadow-mapping-header">
|
|
26
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-secondary meadow-mapping-btn-small" onclick="{~P~}.views['Facto-Full-MappingEditor'].closeMappingEditor()">← Back</button>
|
|
27
|
+
<h3 id="MeadowMap-Title">Mapping Editor</h3>
|
|
28
|
+
<div class="meadow-schema-mode-tabs">
|
|
29
|
+
<button class="meadow-schema-mode-tab active" id="MeadowMap-Mode-Flow" onclick="{~P~}.views['Facto-Full-MappingEditor'].switchMapMode('flow')">Visual Mapper</button>
|
|
30
|
+
<button class="meadow-schema-mode-tab" id="MeadowMap-Mode-JSON" onclick="{~P~}.views['Facto-Full-MappingEditor'].switchMapMode('json')">JSON Config</button>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div id="MeadowMap-List-Wrap">
|
|
35
|
+
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:0.75em;">
|
|
36
|
+
<div class="meadow-section-title" style="margin:0;">Existing Mappings</div>
|
|
37
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-primary meadow-mapping-btn-small" onclick="{~P~}.views['Facto-Full-MappingEditor'].newMapping()">+ New Mapping</button>
|
|
38
|
+
</div>
|
|
39
|
+
<div id="MeadowMap-List"></div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div id="MeadowMap-Detail" style="display:none;">
|
|
43
|
+
<div style="display:flex; gap:0.5em; align-items:center; margin-bottom:0.75em;">
|
|
44
|
+
<label style="font-size:0.78em; font-weight:600;">Mapping Name</label>
|
|
45
|
+
<input type="text" id="MeadowMap-Name" placeholder="Mapping name" style="flex:1; padding:0.3em 0.5em; font-size:0.85em; border:1px solid var(--facto-border); border-radius:4px; background:var(--facto-bg-input); color:var(--facto-text);">
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div style="display:flex; gap:0.5em; align-items:center; margin-bottom:0.75em;">
|
|
49
|
+
<label style="font-size:0.78em; font-weight:600;">Source</label>
|
|
50
|
+
<select id="MeadowMap-Source" style="flex:1; padding:0.3em 0.5em; font-size:0.85em; border:1px solid var(--facto-border); border-radius:4px;"></select>
|
|
51
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-secondary meadow-mapping-btn-small" onclick="{~P~}.views['Facto-Full-MappingEditor'].discoverSourceFields()">Discover Fields</button>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div id="MeadowMap-Flow-Wrap">
|
|
55
|
+
<div id="MeadowMap-Flow-Container" class="meadow-flow-container"></div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div id="MeadowMap-JSON-Wrap" style="display:none;">
|
|
59
|
+
<textarea class="meadow-mapping-json-editor" id="MeadowMap-JSON" placeholder='{"Entity":"MyTable","GUIDTemplate":"{~D:Record.IDRecord~}","Mappings":{},"Solvers":[],"ManyfestAddresses":false}'></textarea>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div style="margin-top:0.75em;">
|
|
63
|
+
<div style="font-size:0.72em; font-weight:600; text-transform:uppercase; letter-spacing:0.5px; color:var(--facto-text-tertiary); margin-bottom:0.35em;">Target Stores</div>
|
|
64
|
+
<div id="MeadowMap-Stores" class="meadow-mapping-store-checklist"></div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div style="margin-top:0.75em; display:flex; gap:0.5em; flex-wrap:wrap; align-items:center;">
|
|
68
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-primary" onclick="{~P~}.views['Facto-Full-MappingEditor'].saveMapping()">Save Mapping</button>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
`
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
|
|
77
|
+
Renderables:
|
|
78
|
+
[
|
|
79
|
+
{
|
|
80
|
+
RenderableHash: "Facto-Full-MappingEditor-Content",
|
|
81
|
+
TemplateHash: "Facto-Full-MappingEditor-Template",
|
|
82
|
+
DestinationAddress: "#Facto-Proj-Mapping-Editor-Container",
|
|
83
|
+
RenderMethod: "replace"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* FactoFullMappingEditorView
|
|
90
|
+
*
|
|
91
|
+
* Thin wrapper around MeadowMappingEditorView that wires the generic editor
|
|
92
|
+
* to retold-facto's API provider. All visual/canvas/serialization logic
|
|
93
|
+
* lives in the base class; this subclass only supplies data access and the
|
|
94
|
+
* close callback.
|
|
95
|
+
*/
|
|
96
|
+
class FactoFullMappingEditorView extends libMeadowMappingEditorView
|
|
97
|
+
{
|
|
98
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
99
|
+
{
|
|
100
|
+
super(pFable, pOptions, pServiceHash);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ── Facto-specific data methods ──────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
_doLoadMappings(pContextID)
|
|
106
|
+
{
|
|
107
|
+
return this.pict.providers.Facto.loadProjectionMappings(pContextID);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
_doLoadSources()
|
|
111
|
+
{
|
|
112
|
+
return this.pict.providers.Facto.loadSources();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_doLoadStores(pContextID)
|
|
116
|
+
{
|
|
117
|
+
return this.pict.providers.Facto.loadProjectionStores(pContextID);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
_doLoadTargetSchema(pContextID)
|
|
121
|
+
{
|
|
122
|
+
return this.pict.providers.Facto.loadProjectionSchema(pContextID);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
_doLoadMapping(pMappingID)
|
|
126
|
+
{
|
|
127
|
+
return this.pict.providers.Facto.loadProjectionMapping(pMappingID);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
_doDeleteMapping(pMappingID)
|
|
131
|
+
{
|
|
132
|
+
return this.pict.providers.Facto.deleteProjectionMapping(pMappingID);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
_doDiscoverSourceFields(pContextID, pSourceID, pRecordLimit)
|
|
136
|
+
{
|
|
137
|
+
return this.pict.providers.Facto.discoverFields(pContextID, pSourceID, pRecordLimit);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
_doCreateMapping(pContextID, pData)
|
|
141
|
+
{
|
|
142
|
+
return this.pict.providers.Facto.createProjectionMapping(pContextID, pData);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_doUpdateMapping(pMappingID, pData)
|
|
146
|
+
{
|
|
147
|
+
return this.pict.providers.Facto.updateProjectionMapping(pMappingID, pData);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
_onClose()
|
|
151
|
+
{
|
|
152
|
+
this.pict.views['Facto-Full-ProjectionDetail'].closeMappingEditor();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = FactoFullMappingEditorView;
|
|
157
|
+
|
|
158
|
+
module.exports.default_configuration = _ViewConfiguration;
|