meadow-integration 1.0.20 → 1.0.21
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/example-applications/mapping-demo/.quackage.json +10 -0
- package/example-applications/mapping-demo/README.md +99 -0
- package/example-applications/mapping-demo/data/books-sample.csv +21 -0
- package/example-applications/mapping-demo/generate-build-config.js +44 -0
- package/example-applications/mapping-demo/mappings/books-to-book.json +14 -0
- package/example-applications/mapping-demo/package.json +14 -0
- package/example-applications/mapping-demo/server.js +814 -0
- package/example-applications/mapping-demo/source/MappingDemoApp.js +52 -0
- package/example-applications/mapping-demo/source/views/MappingDemoEditorView.js +186 -0
- package/example-applications/mapping-demo/web/index.html +892 -0
- package/example-applications/mapping-demo/web/mapping-demo-editor.js +3195 -0
- package/example-applications/mapping-demo/web/mapping-demo-editor.js.map +1 -0
- package/example-applications/mapping-demo/web/mapping-demo-editor.min.js +2 -0
- package/example-applications/mapping-demo/web/mapping-demo-editor.min.js.map +1 -0
- package/example-applications/mapping-demo/web/pict.min.js +12 -0
- package/package.json +8 -4
- package/source/Meadow-Integration-Browser.js +31 -0
- package/source/Meadow-Integration.js +16 -1
- package/source/services/certainty/Service-CertaintyAccumulator.js +402 -0
- package/source/services/clone/Meadow-Service-Sync-Entity-Initial.js +16 -3
- package/source/services/clone/Meadow-Service-Sync-Entity-Ongoing.js +15 -2
- package/source/services/clone/Meadow-Service-Sync.js +21 -0
- package/source/views/MappingEditor-SchemaUtils.js +71 -0
- package/source/views/PictView-MeadowMappingEditor.js +1299 -0
- package/source/views/flow-cards/FlowCard-MappingSource.js +50 -0
- package/source/views/flow-cards/FlowCard-MappingTarget.js +49 -0
- package/source/views/flow-cards/FlowCard-SolverExpression.js +78 -0
- package/source/views/flow-cards/FlowCard-TemplateExpression.js +77 -0
- package/test/Meadow-Integration-CloneDeleteSync_test.js +809 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const libPictApplication = require('pict-application');
|
|
4
|
+
const libMappingDemoEditorView = require('./views/MappingDemoEditorView.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MappingDemoApplication
|
|
8
|
+
*
|
|
9
|
+
* Minimal pict application that hosts the MappingDemoEditorView.
|
|
10
|
+
* Loaded client-side by Pict.safeLoadPictApplication(MappingDemoApplication, 2).
|
|
11
|
+
*
|
|
12
|
+
* After initialization it exposes window.openMappingEditor() so the static
|
|
13
|
+
* HTML pipeline UI can activate the visual editor from a plain onclick handler.
|
|
14
|
+
*/
|
|
15
|
+
class MappingDemoApplication extends libPictApplication
|
|
16
|
+
{
|
|
17
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
18
|
+
{
|
|
19
|
+
super(pFable, pOptions, pServiceHash);
|
|
20
|
+
|
|
21
|
+
this.pict.addView(
|
|
22
|
+
'MappingDemoEditor',
|
|
23
|
+
libMappingDemoEditorView.default_configuration,
|
|
24
|
+
libMappingDemoEditorView);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onAfterInitializeAsync(fCallback)
|
|
28
|
+
{
|
|
29
|
+
// Expose a global hook so the outer HTML can open the editor
|
|
30
|
+
window.openMappingEditor = () =>
|
|
31
|
+
{
|
|
32
|
+
let tmpPlaceholder = document.getElementById('mapping-editor-placeholder');
|
|
33
|
+
if (tmpPlaceholder)
|
|
34
|
+
{
|
|
35
|
+
tmpPlaceholder.style.display = 'none';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
window._Pict.views['MappingDemoEditor'].editMappings(1, 'Book');
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return super.onAfterInitializeAsync(fCallback);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = MappingDemoApplication;
|
|
46
|
+
|
|
47
|
+
module.exports.default_configuration =
|
|
48
|
+
{
|
|
49
|
+
Name: 'MappingDemoApp',
|
|
50
|
+
Hash: 'MappingDemo',
|
|
51
|
+
AutoSolveAfterInitialize: true
|
|
52
|
+
};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Path: mapping-demo/source/views/ → ../../../../source/views/PictView-MeadowMappingEditor.js
|
|
4
|
+
const libMeadowMappingEditorView = require('../../../../source/views/PictView-MeadowMappingEditor.js');
|
|
5
|
+
|
|
6
|
+
// ── View configuration ────────────────────────────────────────────────────────
|
|
7
|
+
// Same template HTML as the generic base editor, but with 'MappingDemoEditor'
|
|
8
|
+
// in all onclick handlers so pict resolves this registered view name.
|
|
9
|
+
// DOM IDs stay as MeadowMap-* so inherited JS methods work without changes.
|
|
10
|
+
|
|
11
|
+
const _ViewConfiguration =
|
|
12
|
+
{
|
|
13
|
+
ViewIdentifier: 'MappingDemoEditor',
|
|
14
|
+
|
|
15
|
+
DefaultRenderable: 'MappingDemoEditor-Content',
|
|
16
|
+
DefaultDestinationAddress: '#MeadowMap-Editor-Container',
|
|
17
|
+
|
|
18
|
+
AutoRender: false,
|
|
19
|
+
|
|
20
|
+
CSS: libMeadowMappingEditorView.default_configuration.CSS,
|
|
21
|
+
|
|
22
|
+
Templates:
|
|
23
|
+
[
|
|
24
|
+
{
|
|
25
|
+
Hash: 'MappingDemoEditor-Template',
|
|
26
|
+
Template: /*html*/`
|
|
27
|
+
<div>
|
|
28
|
+
<div id="MeadowMap-Editor" class="meadow-mapping-editor">
|
|
29
|
+
<div class="meadow-mapping-header">
|
|
30
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-secondary meadow-mapping-btn-small" onclick="{~P~}.views['MappingDemoEditor'].closeMappingEditor()">← Back</button>
|
|
31
|
+
<h3 id="MeadowMap-Title">Mapping Editor</h3>
|
|
32
|
+
<div class="meadow-schema-mode-tabs">
|
|
33
|
+
<button class="meadow-schema-mode-tab active" id="MeadowMap-Mode-Flow" onclick="{~P~}.views['MappingDemoEditor'].switchMapMode('flow')">Visual Mapper</button>
|
|
34
|
+
<button class="meadow-schema-mode-tab" id="MeadowMap-Mode-JSON" onclick="{~P~}.views['MappingDemoEditor'].switchMapMode('json')">JSON Config</button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div id="MeadowMap-List-Wrap">
|
|
39
|
+
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:0.75em;">
|
|
40
|
+
<div class="meadow-section-title" style="margin:0;">Existing Mappings</div>
|
|
41
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-primary meadow-mapping-btn-small" onclick="{~P~}.views['MappingDemoEditor'].newMapping()">+ New Mapping</button>
|
|
42
|
+
</div>
|
|
43
|
+
<div id="MeadowMap-List"></div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div id="MeadowMap-Detail" style="display:none;">
|
|
47
|
+
<div style="display:flex; gap:0.5em; align-items:center; margin-bottom:0.75em;">
|
|
48
|
+
<label style="font-size:0.78em; font-weight:600;">Mapping Name</label>
|
|
49
|
+
<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(--border); border-radius:4px; background:var(--bg-card); color:var(--text);">
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div style="display:flex; gap:0.5em; align-items:center; margin-bottom:0.75em;">
|
|
53
|
+
<label style="font-size:0.78em; font-weight:600;">Source</label>
|
|
54
|
+
<select id="MeadowMap-Source" style="flex:1; padding:0.3em 0.5em; font-size:0.85em; border:1px solid var(--border); border-radius:4px;"></select>
|
|
55
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-secondary meadow-mapping-btn-small" onclick="{~P~}.views['MappingDemoEditor'].discoverSourceFields()">Discover Fields</button>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div id="MeadowMap-Flow-Wrap">
|
|
59
|
+
<div id="MeadowMap-Flow-Container" class="meadow-flow-container"></div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div id="MeadowMap-JSON-Wrap" style="display:none;">
|
|
63
|
+
<textarea class="meadow-mapping-json-editor" id="MeadowMap-JSON" placeholder='{"Entity":"Book","GUIDTemplate":"{~D:Record.id~}","Mappings":{},"Solvers":[],"ManyfestAddresses":false}'></textarea>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div style="margin-top:0.75em;">
|
|
67
|
+
<div style="font-size:0.72em; font-weight:600; text-transform:uppercase; letter-spacing:0.5px; color:var(--text-dim); margin-bottom:0.35em;">Target Stores</div>
|
|
68
|
+
<div id="MeadowMap-Stores" class="meadow-mapping-store-checklist"></div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div style="margin-top:0.75em; display:flex; gap:0.5em; flex-wrap:wrap; align-items:center;">
|
|
72
|
+
<button class="meadow-mapping-btn meadow-mapping-btn-primary" onclick="{~P~}.views['MappingDemoEditor'].saveMapping()">Save Mapping</button>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
`
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
|
|
81
|
+
Renderables:
|
|
82
|
+
[
|
|
83
|
+
{
|
|
84
|
+
RenderableHash: 'MappingDemoEditor-Content',
|
|
85
|
+
TemplateHash: 'MappingDemoEditor-Template',
|
|
86
|
+
ContentDestinationAddress: '#MeadowMap-Editor-Container',
|
|
87
|
+
RenderMethod: 'replace'
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* MappingDemoEditorView
|
|
94
|
+
*
|
|
95
|
+
* Extends MeadowMappingEditorView and wires the _do* data methods to the
|
|
96
|
+
* mapping-demo server's REST API endpoints. All visual/canvas/serialization
|
|
97
|
+
* logic lives in the base class; this subclass only supplies data access.
|
|
98
|
+
*/
|
|
99
|
+
class MappingDemoEditorView extends libMeadowMappingEditorView
|
|
100
|
+
{
|
|
101
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
102
|
+
{
|
|
103
|
+
super(pFable, pOptions, pServiceHash);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ── Data methods ─────────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
_doLoadMappings(pContextID)
|
|
109
|
+
{
|
|
110
|
+
return fetch('/1.0/Demo/VisualMapping').then(function(r) { return r.json(); });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
_doLoadSources()
|
|
114
|
+
{
|
|
115
|
+
return fetch('/1.0/Demo/Sources').then(function(r) { return r.json(); });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
_doLoadStores(pContextID)
|
|
119
|
+
{
|
|
120
|
+
return Promise.resolve({ Stores: [] });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_doLoadTargetSchema(pContextID)
|
|
124
|
+
{
|
|
125
|
+
return fetch('/1.0/Demo/TargetSchema').then(function(r) { return r.json(); });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
_doLoadMapping(pMappingID)
|
|
129
|
+
{
|
|
130
|
+
return fetch('/1.0/Demo/VisualMapping/' + pMappingID).then(function(r) { return r.json(); });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
_doDeleteMapping(pMappingID)
|
|
134
|
+
{
|
|
135
|
+
return fetch('/1.0/Demo/VisualMapping/' + pMappingID,
|
|
136
|
+
{ method: 'DELETE' }).then(function(r) { return r.json(); });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
_doDiscoverSourceFields(pContextID, pSourceID, pRecordLimit)
|
|
140
|
+
{
|
|
141
|
+
return fetch('/1.0/Demo/SourceSchema').then(function(r) { return r.json(); });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
_doCreateMapping(pContextID, pData)
|
|
145
|
+
{
|
|
146
|
+
return fetch('/1.0/Demo/VisualMapping',
|
|
147
|
+
{
|
|
148
|
+
method: 'POST',
|
|
149
|
+
headers: { 'Content-Type': 'application/json' },
|
|
150
|
+
body: JSON.stringify(pData)
|
|
151
|
+
}).then(function(r) { return r.json(); });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
_doUpdateMapping(pMappingID, pData)
|
|
155
|
+
{
|
|
156
|
+
return fetch('/1.0/Demo/VisualMapping/' + pMappingID,
|
|
157
|
+
{
|
|
158
|
+
method: 'PUT',
|
|
159
|
+
headers: { 'Content-Type': 'application/json' },
|
|
160
|
+
body: JSON.stringify(pData)
|
|
161
|
+
}).then(function(r) { return r.json(); });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
_onClose()
|
|
165
|
+
{
|
|
166
|
+
// Hide the editor and restore the step placeholder
|
|
167
|
+
let tmpEditor = document.getElementById('MeadowMap-Editor');
|
|
168
|
+
if (tmpEditor)
|
|
169
|
+
{
|
|
170
|
+
tmpEditor.classList.remove('active');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let tmpPlaceholder = document.getElementById('mapping-editor-placeholder');
|
|
174
|
+
if (tmpPlaceholder)
|
|
175
|
+
{
|
|
176
|
+
tmpPlaceholder.style.display = '';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Dispatch an event so the outer UI can mark this step done
|
|
180
|
+
document.dispatchEvent(new CustomEvent('mapping-editor-closed'));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
module.exports = MappingDemoEditorView;
|
|
185
|
+
|
|
186
|
+
module.exports.default_configuration = _ViewConfiguration;
|