ngx-emfular-integration 0.0.7 → 0.2.0

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.
@@ -0,0 +1,30 @@
1
+ /* Backdrop: slightly darkened */
2
+ .cdk-overlay-dark-backdrop {
3
+ background: rgba(0, 0, 0, 0.35);
4
+ }
5
+
6
+ /* Outer container of the details panel */
7
+ .basic-details-panel {
8
+ background: #ffffff;
9
+ border-radius: 12px;
10
+ padding: 24px;
11
+ box-sizing: border-box;
12
+ max-width: 700px;
13
+ max-height: 90vh;
14
+ overflow: hidden;
15
+ box-shadow:
16
+ 0 4px 12px rgba(0, 0, 0, 0.15),
17
+ 0 2px 4px rgba(0, 0, 0, 0.1);
18
+ animation: detailsFadeIn 120ms ease-out;
19
+ }
20
+
21
+ @keyframes detailsFadeIn {
22
+ from {
23
+ opacity: 0;
24
+ transform: scale(0.96);
25
+ }
26
+ to {
27
+ opacity: 1;
28
+ transform: scale(1);
29
+ }
30
+ }
@@ -1,14 +1,27 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Inject, Injectable } from '@angular/core';
3
- import { Deserializer } from 'emfular';
2
+ import { InjectionToken, PLATFORM_ID, Inject, Injectable, Input, Component, EventEmitter, Output, ViewChild } from '@angular/core';
3
+ import { Deserializer, getAllAttributes } from 'emfular';
4
4
  import * as i1 from 'ngx-emfular-helper';
5
- import { HistoryService } from 'ngx-emfular-helper';
5
+ import { HistoryService, InputHandler } from 'ngx-emfular-helper';
6
+ import { NgForOf, NgIf, CommonModule } from '@angular/common';
7
+ import { PositionHelper, RectangleWithTextComponent, ArrowBetweenElemsComponent } from 'ngx-svg-graphics';
8
+ import * as i1$1 from '@angular/forms';
9
+ import { FormsModule } from '@angular/forms';
10
+ import { ComponentPortal } from '@angular/cdk/portal';
11
+ import { Subject } from 'rxjs';
12
+ import * as i1$2 from '@angular/cdk/overlay';
13
+ import * as i2 from '@angular/material/toolbar';
14
+ import { MatToolbarModule } from '@angular/material/toolbar';
15
+ import * as i3 from '@angular/material/icon';
16
+ import { MatIconModule } from '@angular/material/icon';
17
+ import { MatButtonModule } from '@angular/material/button';
6
18
 
7
19
  const HISTORY_SERVICE = new InjectionToken('HistoryService');
8
20
  function provideHistoryForModel(prefix = 'history_', bufferSize = 50) {
9
21
  return {
10
22
  provide: HISTORY_SERVICE,
11
- useFactory: () => new HistoryService(prefix, bufferSize)
23
+ useFactory: (platformId) => new HistoryService(prefix, bufferSize, platformId),
24
+ deps: [PLATFORM_ID]
12
25
  };
13
26
  }
14
27
  class ModelService {
@@ -47,6 +60,10 @@ class ModelService {
47
60
  fileTitle() {
48
61
  return "model";
49
62
  }
63
+ newModel() {
64
+ this.model = new this.modelClass();
65
+ this.saveCurrentState();
66
+ }
50
67
  serialize() {
51
68
  return this.model.toJson();
52
69
  }
@@ -88,6 +105,396 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
88
105
  args: [HISTORY_SERVICE]
89
106
  }] }, { type: i1.IoService }, { type: undefined }] });
90
107
 
108
+ class FileLevelBarComponent {
109
+ ioService;
110
+ svg;
111
+ modelService;
112
+ InputHandler = InputHandler;
113
+ constructor(ioService) {
114
+ this.ioService = ioService;
115
+ }
116
+ openModel() {
117
+ document.getElementById('openModel')?.click();
118
+ }
119
+ saveSVG() {
120
+ const svgContent = this.svg;
121
+ if (svgContent) {
122
+ this.ioService.saveSVG(svgContent, this.modelService.fileTitle());
123
+ }
124
+ }
125
+ saveSVGasPNG() {
126
+ const svgContent = this.svg;
127
+ if (svgContent) {
128
+ this.ioService.saveSvgAsPng(svgContent, this.modelService.fileTitle());
129
+ }
130
+ }
131
+ saveSVGasJPEG() {
132
+ const svgContent = this.svg;
133
+ if (svgContent) {
134
+ this.ioService.saveSvgAsJpeg(svgContent, this.modelService.fileTitle());
135
+ }
136
+ }
137
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FileLevelBarComponent, deps: [{ token: i1.IoService }], target: i0.ɵɵFactoryTarget.Component });
138
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: FileLevelBarComponent, isStandalone: true, selector: "emfular-file-level-bar", inputs: { svg: "svg", modelService: "modelService" }, ngImport: i0, template: "<input id=\"openModel\" type=\"file\" class=\"file-upload\" style=\"display:none\"\n (change)=\"modelService.loadFromFile($event)\"\n (click)=\"InputHandler.clearElem($event)\">\n\n<div class=\"file-level-bar\">\n <button (click)=\"modelService.newModel()\">New</button>\n <button (click)=\"openModel()\">Open</button>\n <span class=\"separator\"></span>\n <button (click)=\"modelService.historyService.undo()\" [disabled]=\"modelService.historyService.isUndoNotPossible()\">Undo</button>\n <button (click)=\"modelService.historyService.redo()\" [disabled]=\"modelService.historyService.isRedoNotPossible()\">Redo</button>\n <span class=\"separator\"></span>\n <button (click)=\"modelService.save()\">Save</button>\n <button (click)=\"saveSVG()\">Save SVG</button>\n <button (click)=\"saveSVGasPNG()\">Save PNG</button>\n <button (click)=\"saveSVGasJPEG()\">Save JPEG</button>\n</div>\n", styles: [".file-level-bar{display:flex;align-items:center;gap:.4rem;padding:.3rem .5rem;background:#f0f0f0;border-bottom:1px solid #ccc}.file-level-bar button{padding:.25rem .5rem;font-size:.85rem;cursor:pointer}.file-level-bar button:disabled{opacity:.5;cursor:default}.separator{width:1px;height:1rem;background:#ccc;margin:0 .3rem}\n"] });
139
+ }
140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FileLevelBarComponent, decorators: [{
141
+ type: Component,
142
+ args: [{ selector: 'emfular-file-level-bar', imports: [], template: "<input id=\"openModel\" type=\"file\" class=\"file-upload\" style=\"display:none\"\n (change)=\"modelService.loadFromFile($event)\"\n (click)=\"InputHandler.clearElem($event)\">\n\n<div class=\"file-level-bar\">\n <button (click)=\"modelService.newModel()\">New</button>\n <button (click)=\"openModel()\">Open</button>\n <span class=\"separator\"></span>\n <button (click)=\"modelService.historyService.undo()\" [disabled]=\"modelService.historyService.isUndoNotPossible()\">Undo</button>\n <button (click)=\"modelService.historyService.redo()\" [disabled]=\"modelService.historyService.isRedoNotPossible()\">Redo</button>\n <span class=\"separator\"></span>\n <button (click)=\"modelService.save()\">Save</button>\n <button (click)=\"saveSVG()\">Save SVG</button>\n <button (click)=\"saveSVGasPNG()\">Save PNG</button>\n <button (click)=\"saveSVGasJPEG()\">Save JPEG</button>\n</div>\n", styles: [".file-level-bar{display:flex;align-items:center;gap:.4rem;padding:.3rem .5rem;background:#f0f0f0;border-bottom:1px solid #ccc}.file-level-bar button{padding:.25rem .5rem;font-size:.85rem;cursor:pointer}.file-level-bar button:disabled{opacity:.5;cursor:default}.separator{width:1px;height:1rem;background:#ccc;margin:0 .3rem}\n"] }]
143
+ }], ctorParameters: () => [{ type: i1.IoService }], propDecorators: { svg: [{
144
+ type: Input
145
+ }], modelService: [{
146
+ type: Input
147
+ }] } });
148
+
149
+ class ModelEditingBarComponent {
150
+ buttons = null;
151
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelEditingBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
152
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: ModelEditingBarComponent, isStandalone: true, selector: "emfular-model-editing-bar", inputs: { buttons: "buttons" }, ngImport: i0, template: "<div class=\"model-editing-bar\">\n <button *ngFor=\"let b of buttons\" (click)=\"b.action()\">\n <span *ngIf=\"b.icon\" class=\"icon\">{{ b.icon }}</span>\n {{ b.label }}\n </button>\n</div>\n", styles: [".model-editing-bar{display:flex;flex-direction:column;gap:.3rem;padding:.4rem;width:60px;background:#f5f5f5;border-right:1px solid #ccc;overflow-y:auto}.model-editing-bar button{padding:.3rem;font-size:.75rem;cursor:pointer;text-align:left;width:100%;box-sizing:border-box}.icon{margin-right:.2rem}\n"], dependencies: [{ kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
153
+ }
154
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelEditingBarComponent, decorators: [{
155
+ type: Component,
156
+ args: [{ selector: 'emfular-model-editing-bar', imports: [
157
+ NgForOf,
158
+ NgIf
159
+ ], template: "<div class=\"model-editing-bar\">\n <button *ngFor=\"let b of buttons\" (click)=\"b.action()\">\n <span *ngIf=\"b.icon\" class=\"icon\">{{ b.icon }}</span>\n {{ b.label }}\n </button>\n</div>\n", styles: [".model-editing-bar{display:flex;flex-direction:column;gap:.3rem;padding:.4rem;width:60px;background:#f5f5f5;border-right:1px solid #ccc;overflow-y:auto}.model-editing-bar button{padding:.3rem;font-size:.75rem;cursor:pointer;text-align:left;width:100%;box-sizing:border-box}.icon{margin-right:.2rem}\n"] }]
160
+ }], propDecorators: { buttons: [{
161
+ type: Input
162
+ }] } });
163
+
164
+ class GraphicalHelper {
165
+ //todo, refactor into emfular
166
+ static getAsList(refs) {
167
+ const items = refs.get();
168
+ if (items) {
169
+ if (Array.isArray(items)) {
170
+ return items;
171
+ }
172
+ const result = [];
173
+ result.push(items);
174
+ return result;
175
+ }
176
+ else {
177
+ return [];
178
+ }
179
+ }
180
+ }
181
+
182
+ class IdHelper {
183
+ static getLabel(ref) {
184
+ // 1. If the model has a "name" attribute → use it
185
+ if (ref.name) {
186
+ return `${ref.name}`;
187
+ }
188
+ // 2. Otherwise: first primitive attribute
189
+ const attrs = getAllAttributes(ref.constructor);
190
+ for (const [key] of attrs) {
191
+ const value = ref[key];
192
+ if (typeof value === "string" || typeof value === "number") {
193
+ return `${value}`;
194
+ }
195
+ }
196
+ /*
197
+ // 3. Otherwise: use ID (EMFular always has stable IDs)
198
+ if ((ref as any).id) {
199
+ return `(id=${(ref as any).id})`;
200
+ }*/
201
+ // 4. Otherwise: fallback
202
+ return "(unnamed)";
203
+ }
204
+ }
205
+
206
+ class ReferencableBoxComponent {
207
+ referencable;
208
+ position;
209
+ color = "#efad78";
210
+ chooseElement = new EventEmitter();
211
+ isExpandedArray = [];
212
+ toggleExpand(i) {
213
+ this.isExpandedArray[i] = !this.isExpandedArray[i];
214
+ }
215
+ choose(element) {
216
+ this.chooseElement.emit(element);
217
+ }
218
+ constructor() { }
219
+ GraphicalHelper = GraphicalHelper;
220
+ PositionHelper = PositionHelper;
221
+ IdHelper = IdHelper;
222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ReferencableBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ReferencableBoxComponent, isStandalone: true, selector: "[referencable-box]", inputs: { referencable: "referencable", position: "position", color: "color" }, outputs: { chooseElement: "chooseElement" }, ngImport: i0, template: "<svg:g [attr.id]=\"referencable.$gId\">\n\n <g rectangle-with-text\n (click)=\"choose(referencable)\"\n [id]=\"referencable.$gId + '_main'\"\n [text]=\"IdHelper.getLabel(referencable)\"\n [position]=\"position\"\n [color]=\"color\"\n >\n </g>\n\n <!-- containers -->\n @for (container of referencable.$treeChildren;\n track referencable.$gId + '_' + container.referenceName\n ; let i = $index) {\n\n @let containerKey = referencable.$gId + '_' + container.referenceName;\n @let containerAnchorBox = PositionHelper.computeChildBBox(\n i,\n referencable.$treeChildren.length,\n position\n );\n\n <!-- reference box -->\n <g rectangle-with-text\n (click)=\"toggleExpand(i)\"\n [id]=\"containerKey + '_ref'\"\n [text]=\"container.referenceName\"\n [position]=\"containerAnchorBox\"\n color=\"#ede679\"\n >\n </g>\n\n <!-- arrow from main box to reference -->\n <g arrowElems\n [startGID]=\"referencable.$gId\"\n startSuffix=\"_main\"\n [endGID]=\"containerKey\"\n endSuffix=\"_ref\">\n </g>\n\n @if (isExpandedArray[i]) {\n <!-- real children inside this reference -->\n @let realChildren = GraphicalHelper.getAsList(container);\n\n @for (elem of realChildren; track elem.$gId; let j = $index) {\n\n @let elemBox = PositionHelper.computeChildBBox(\n j,\n realChildren.length,\n containerAnchorBox\n );\n <g referencable-box\n (chooseElement)=\"choose($event)\"\n [referencable]=\"elem\"\n [position]=\"elemBox\"\n >\n </g>\n <!-- arrow from reference to child box -->\n <g arrowElems\n [startGID]=\"containerKey\"\n startSuffix=\"_ref\"\n [endGID]=\"elem.$gId\"\n endSuffix=\"_main\">\n </g>\n }\n\n }\n }\n</svg:g>\n", styles: [""], dependencies: [{ kind: "component", type: ReferencableBoxComponent, selector: "[referencable-box]", inputs: ["referencable", "position", "color"], outputs: ["chooseElement"] }, { kind: "component", type: RectangleWithTextComponent, selector: "[rectangle-with-text]", inputs: ["id", "text", "position", "color"], outputs: ["textChange"] }, { kind: "component", type: ArrowBetweenElemsComponent, selector: "[arrowElems]", inputs: ["startGID", "startSuffix", "endGID", "endSuffix", "arrowType", "breaks", "text", "style"] }] });
224
+ }
225
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ReferencableBoxComponent, decorators: [{
226
+ type: Component,
227
+ args: [{ selector: '[referencable-box]', imports: [RectangleWithTextComponent, ArrowBetweenElemsComponent], template: "<svg:g [attr.id]=\"referencable.$gId\">\n\n <g rectangle-with-text\n (click)=\"choose(referencable)\"\n [id]=\"referencable.$gId + '_main'\"\n [text]=\"IdHelper.getLabel(referencable)\"\n [position]=\"position\"\n [color]=\"color\"\n >\n </g>\n\n <!-- containers -->\n @for (container of referencable.$treeChildren;\n track referencable.$gId + '_' + container.referenceName\n ; let i = $index) {\n\n @let containerKey = referencable.$gId + '_' + container.referenceName;\n @let containerAnchorBox = PositionHelper.computeChildBBox(\n i,\n referencable.$treeChildren.length,\n position\n );\n\n <!-- reference box -->\n <g rectangle-with-text\n (click)=\"toggleExpand(i)\"\n [id]=\"containerKey + '_ref'\"\n [text]=\"container.referenceName\"\n [position]=\"containerAnchorBox\"\n color=\"#ede679\"\n >\n </g>\n\n <!-- arrow from main box to reference -->\n <g arrowElems\n [startGID]=\"referencable.$gId\"\n startSuffix=\"_main\"\n [endGID]=\"containerKey\"\n endSuffix=\"_ref\">\n </g>\n\n @if (isExpandedArray[i]) {\n <!-- real children inside this reference -->\n @let realChildren = GraphicalHelper.getAsList(container);\n\n @for (elem of realChildren; track elem.$gId; let j = $index) {\n\n @let elemBox = PositionHelper.computeChildBBox(\n j,\n realChildren.length,\n containerAnchorBox\n );\n <g referencable-box\n (chooseElement)=\"choose($event)\"\n [referencable]=\"elem\"\n [position]=\"elemBox\"\n >\n </g>\n <!-- arrow from reference to child box -->\n <g arrowElems\n [startGID]=\"containerKey\"\n startSuffix=\"_ref\"\n [endGID]=\"elem.$gId\"\n endSuffix=\"_main\">\n </g>\n }\n\n }\n }\n</svg:g>\n" }]
228
+ }], ctorParameters: () => [], propDecorators: { referencable: [{
229
+ type: Input
230
+ }], position: [{
231
+ type: Input
232
+ }], color: [{
233
+ type: Input
234
+ }], chooseElement: [{
235
+ type: Output
236
+ }] } });
237
+
238
+ class ModelCanvasComponent {
239
+ svgwidth = 1500;
240
+ svgheigth = 1000;
241
+ initialBBox = { x: this.svgwidth / 2, y: 20, w: 200, h: 25 };
242
+ modelService;
243
+ chooseElement = new EventEmitter();
244
+ svgReady = new EventEmitter();
245
+ svg;
246
+ ngOnInit() {
247
+ // Safe because static: true
248
+ this.svgReady.emit(this.svg.nativeElement);
249
+ }
250
+ choose(element) {
251
+ this.chooseElement.emit(element);
252
+ }
253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
254
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: ModelCanvasComponent, isStandalone: true, selector: "model-canvas", inputs: { modelService: "modelService" }, outputs: { chooseElement: "chooseElement", svgReady: "svgReady" }, viewQueries: [{ propertyName: "svg", first: true, predicate: ["svg"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"modeling-container\">\n <svg #svg id=\"svg\" class=\"canvas-svg\" [attr.width]=\"svgwidth\" [attr.height]=\"svgheigth\">\n <g referencable-box\n [referencable]=\"modelService.model\"\n [position]=\"initialBBox\"\n (chooseElement)=\"choose($event)\"\n >\n </g>\n </svg>\n</div>\n", styles: [".modeling-container{flex:1 1 auto;overflow:auto;background:#fff}.canvas-svg{display:block}\n"], dependencies: [{ kind: "component", type: ReferencableBoxComponent, selector: "[referencable-box]", inputs: ["referencable", "position", "color"], outputs: ["chooseElement"] }] });
255
+ }
256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelCanvasComponent, decorators: [{
257
+ type: Component,
258
+ args: [{ selector: 'model-canvas', imports: [
259
+ ReferencableBoxComponent
260
+ ], template: "<div class=\"modeling-container\">\n <svg #svg id=\"svg\" class=\"canvas-svg\" [attr.width]=\"svgwidth\" [attr.height]=\"svgheigth\">\n <g referencable-box\n [referencable]=\"modelService.model\"\n [position]=\"initialBBox\"\n (chooseElement)=\"choose($event)\"\n >\n </g>\n </svg>\n</div>\n", styles: [".modeling-container{flex:1 1 auto;overflow:auto;background:#fff}.canvas-svg{display:block}\n"] }]
261
+ }], propDecorators: { modelService: [{
262
+ type: Input
263
+ }], chooseElement: [{
264
+ type: Output
265
+ }], svgReady: [{
266
+ type: Output
267
+ }], svg: [{
268
+ type: ViewChild,
269
+ args: ['svg', { static: true }]
270
+ }] } });
271
+
272
+ class ContainerDetailsComponent {
273
+ container;
274
+ isTree;
275
+ modelService;
276
+ detailsService; //todo just enforce interface?
277
+ open(ref) {
278
+ this.detailsService.openDetails(ref, this.modelService);
279
+ }
280
+ remove(ref) {
281
+ //todo service should do this... in order for single source of truth
282
+ if (this.container.remove(ref))
283
+ this.modelService.saveCurrentState();
284
+ }
285
+ add() {
286
+ //create on tree and open choice by graphical model on other links
287
+ if (this.isTree) {
288
+ console.log("Creation for several possible sub types is not solved in a meta-agnostic scenario");
289
+ }
290
+ else {
291
+ this.detailsService
292
+ .openModelChoice(this.modelService)
293
+ .subscribe(chosen => {
294
+ if (!chosen)
295
+ return; // user cancelled
296
+ // todo what about type mismatches?
297
+ if (this.container.add(chosen)) {
298
+ this.modelService.saveCurrentState();
299
+ }
300
+ });
301
+ }
302
+ }
303
+ GraphicalHelper = GraphicalHelper;
304
+ IdHelper = IdHelper;
305
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ContainerDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
306
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: ContainerDetailsComponent, isStandalone: true, selector: "container-details", inputs: { container: "container", isTree: "isTree", modelService: "modelService", detailsService: "detailsService" }, ngImport: i0, template: "<h4>{{container.referenceName+\":\"}}</h4>\n\n<button *ngIf=\"!isTree\" class=\"add-ref\" (click)=\"add()\">Add</button>\n\n<div class=\"container-row\"\n *ngFor=\"let elem of GraphicalHelper.getAsList(container)\">\n <div class=\"ref-info\">\n <span class=\"ref-icon\">\uD83D\uDD17</span>\n <span class=\"ref-type\">{{ elem.getEClass() }}</span>\n <span class=\"ref-label\">{{ IdHelper.getLabel(elem) }}</span>\n </div>\n\n <div class=\"ref-actions\">\n <button (click)=\"open(elem)\">Open</button>\n <button (click)=\"remove(elem)\">Remove</button>\n </div>\n</div>\n\n", styles: ["h4{margin-top:0;margin-bottom:4px}.add-ref{margin-top:0;margin-bottom:8px;padding:6px 12px;border-radius:6px;border:1px solid #b5b5b5;background:#fff;cursor:pointer;font-size:13px;transition:background .12s ease,border-color .12s ease}.add-ref:hover{background:#f2f2f2;border-color:#999}.add-ref:active{background:#e6e6e6}.reference-list{display:flex;flex-direction:column;gap:8px;margin-top:12px}.reference-row{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border:1px solid #d0d0d0;border-radius:6px;background:#fafafa;transition:background .12s ease}.reference-row:hover{background:#f2f2f2}.ref-info{display:flex;align-items:center;gap:8px;min-width:0}.ref-icon{opacity:.7;font-size:14px}.ref-type{font-weight:600;font-size:13px;color:#333;white-space:nowrap}.ref-label{font-size:13px;color:#555;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ref-actions{display:flex;gap:6px}.ref-actions button{border:1px solid #b5b5b5;background:#fff;cursor:pointer;padding:4px 8px;border-radius:4px;font-size:12px;color:#333;min-width:32px;text-align:center;transition:background .12s ease,border-color .12s ease}.ref-actions button:hover{background:#e6e6e6;border-color:#999}.ref-actions button:active{background:#dcdcdc}\n"], dependencies: [{ kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
307
+ }
308
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ContainerDetailsComponent, decorators: [{
309
+ type: Component,
310
+ args: [{ selector: 'container-details', imports: [
311
+ NgForOf,
312
+ NgIf,
313
+ ], template: "<h4>{{container.referenceName+\":\"}}</h4>\n\n<button *ngIf=\"!isTree\" class=\"add-ref\" (click)=\"add()\">Add</button>\n\n<div class=\"container-row\"\n *ngFor=\"let elem of GraphicalHelper.getAsList(container)\">\n <div class=\"ref-info\">\n <span class=\"ref-icon\">\uD83D\uDD17</span>\n <span class=\"ref-type\">{{ elem.getEClass() }}</span>\n <span class=\"ref-label\">{{ IdHelper.getLabel(elem) }}</span>\n </div>\n\n <div class=\"ref-actions\">\n <button (click)=\"open(elem)\">Open</button>\n <button (click)=\"remove(elem)\">Remove</button>\n </div>\n</div>\n\n", styles: ["h4{margin-top:0;margin-bottom:4px}.add-ref{margin-top:0;margin-bottom:8px;padding:6px 12px;border-radius:6px;border:1px solid #b5b5b5;background:#fff;cursor:pointer;font-size:13px;transition:background .12s ease,border-color .12s ease}.add-ref:hover{background:#f2f2f2;border-color:#999}.add-ref:active{background:#e6e6e6}.reference-list{display:flex;flex-direction:column;gap:8px;margin-top:12px}.reference-row{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border:1px solid #d0d0d0;border-radius:6px;background:#fafafa;transition:background .12s ease}.reference-row:hover{background:#f2f2f2}.ref-info{display:flex;align-items:center;gap:8px;min-width:0}.ref-icon{opacity:.7;font-size:14px}.ref-type{font-weight:600;font-size:13px;color:#333;white-space:nowrap}.ref-label{font-size:13px;color:#555;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ref-actions{display:flex;gap:6px}.ref-actions button{border:1px solid #b5b5b5;background:#fff;cursor:pointer;padding:4px 8px;border-radius:4px;font-size:12px;color:#333;min-width:32px;text-align:center;transition:background .12s ease,border-color .12s ease}.ref-actions button:hover{background:#e6e6e6;border-color:#999}.ref-actions button:active{background:#dcdcdc}\n"] }]
314
+ }], propDecorators: { container: [{
315
+ type: Input
316
+ }], isTree: [{
317
+ type: Input
318
+ }], modelService: [{
319
+ type: Input
320
+ }], detailsService: [{
321
+ type: Input
322
+ }] } });
323
+
324
+ class ModelDetailsComponent {
325
+ model;
326
+ modelService;
327
+ detailsService;
328
+ attributes = [];
329
+ ngOnInit() {
330
+ const map = getAllAttributes(this.model.constructor);
331
+ this.attributes = Array.from(map.entries()).map(([key, options]) => ({
332
+ key,
333
+ options
334
+ }));
335
+ }
336
+ getLinks() {
337
+ return this.model.$otherReferences;
338
+ }
339
+ getChildren() {
340
+ return this.model.$treeChildren;
341
+ }
342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: ModelDetailsComponent, isStandalone: true, selector: "lib-model-details", inputs: { model: "model", modelService: "modelService", detailsService: "detailsService" }, ngImport: i0, template: "<h1>Detail-Editor</h1>\n<h2>{{model.getEClass()}}</h2>\n<div class=\"attribute-list\">\n <div class=\"attribute-row\" *ngFor=\"let attr of attributes\">\n <label>{{ attr.key }}</label>\n <input\n type=\"text\"\n [(ngModel)]=\"$any(model)[attr.key]\"\n />\n </div>\n</div>\n<h3>References</h3>\n<div class=\"reference-list\">\n <container-details\n *ngFor=\"let container of getChildren()\"\n [container]=\"container\"\n [isTree]=\"true\"\n [modelService]=\"modelService\"\n [detailsService]=\"detailsService\"\n >\n </container-details>\n <container-details\n *ngFor=\"let container of getLinks()\"\n [container]=\"container\"\n [isTree]=\"false\"\n [modelService]=\"modelService\"\n [detailsService]=\"detailsService\"\n >\n </container-details>\n</div>\n\n", styles: [".attribute-list{display:flex;flex-direction:column;gap:16px}.attribute-row{display:flex;flex-direction:column}.attribute-row label{font-weight:600;margin-bottom:4px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ContainerDetailsComponent, selector: "container-details", inputs: ["container", "isTree", "modelService", "detailsService"] }] });
344
+ }
345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelDetailsComponent, decorators: [{
346
+ type: Component,
347
+ args: [{ selector: 'lib-model-details', imports: [
348
+ FormsModule,
349
+ NgForOf,
350
+ ContainerDetailsComponent
351
+ ], template: "<h1>Detail-Editor</h1>\n<h2>{{model.getEClass()}}</h2>\n<div class=\"attribute-list\">\n <div class=\"attribute-row\" *ngFor=\"let attr of attributes\">\n <label>{{ attr.key }}</label>\n <input\n type=\"text\"\n [(ngModel)]=\"$any(model)[attr.key]\"\n />\n </div>\n</div>\n<h3>References</h3>\n<div class=\"reference-list\">\n <container-details\n *ngFor=\"let container of getChildren()\"\n [container]=\"container\"\n [isTree]=\"true\"\n [modelService]=\"modelService\"\n [detailsService]=\"detailsService\"\n >\n </container-details>\n <container-details\n *ngFor=\"let container of getLinks()\"\n [container]=\"container\"\n [isTree]=\"false\"\n [modelService]=\"modelService\"\n [detailsService]=\"detailsService\"\n >\n </container-details>\n</div>\n\n", styles: [".attribute-list{display:flex;flex-direction:column;gap:16px}.attribute-row{display:flex;flex-direction:column}.attribute-row label{font-weight:600;margin-bottom:4px}\n"] }]
352
+ }], propDecorators: { model: [{
353
+ type: Input
354
+ }], modelService: [{
355
+ type: Input
356
+ }], detailsService: [{
357
+ type: Input
358
+ }] } });
359
+
360
+ class BasicModelDetailsService {
361
+ overlay;
362
+ constructor(overlay) {
363
+ this.overlay = overlay;
364
+ }
365
+ //actually T must be somewhere on M
366
+ openDetails(elem, modelService) {
367
+ // instead of opening the generic ModeldetailsCompoennt you might like to consider opening a specific one
368
+ //by determining the eClass and switching based on elem.getEClass()
369
+ const overlayRef = this.overlay.create({ hasBackdrop: true,
370
+ backdropClass: 'cdk-overlay-dark-backdrop',
371
+ panelClass: 'basic-details-panel',
372
+ positionStrategy: this.overlay.position()
373
+ .global().centerHorizontally().centerVertically()
374
+ });
375
+ const portal = new ComponentPortal((ModelDetailsComponent));
376
+ const ref = overlayRef.attach(portal);
377
+ ref.instance.model = elem;
378
+ ref.instance.modelService = modelService;
379
+ ref.instance.detailsService = this;
380
+ overlayRef.backdropClick().subscribe(() => overlayRef.dispose());
381
+ }
382
+ openModelChoice(modelService) {
383
+ const subject = new Subject();
384
+ const overlayRef = this.overlay.create({
385
+ hasBackdrop: true,
386
+ backdropClass: 'cdk-overlay-dark-backdrop',
387
+ panelClass: 'basic-details-panel',
388
+ positionStrategy: this.overlay.position()
389
+ .global().centerHorizontally().centerVertically()
390
+ });
391
+ const portal = new ComponentPortal((ModelCanvasComponent));
392
+ const ref = overlayRef.attach(portal);
393
+ ref.instance.modelService = modelService;
394
+ ref.instance.chooseElement.subscribe(next => {
395
+ subject.next(next);
396
+ subject.complete();
397
+ overlayRef.dispose();
398
+ });
399
+ overlayRef.backdropClick().subscribe(() => {
400
+ subject.complete();
401
+ overlayRef.dispose();
402
+ });
403
+ return subject.asObservable();
404
+ }
405
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: BasicModelDetailsService, deps: [{ token: i1$2.Overlay }], target: i0.ɵɵFactoryTarget.Injectable });
406
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: BasicModelDetailsService, providedIn: 'root' });
407
+ }
408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: BasicModelDetailsService, decorators: [{
409
+ type: Injectable,
410
+ args: [{
411
+ providedIn: 'root'
412
+ }]
413
+ }], ctorParameters: () => [{ type: i1$2.Overlay }] });
414
+
415
+ class TreeEditorComponent {
416
+ basicDetailsService;
417
+ svgElement;
418
+ modelService;
419
+ detailsService;
420
+ customButtons = null;
421
+ constructor(basicDetailsService) {
422
+ this.basicDetailsService = basicDetailsService;
423
+ }
424
+ get sidebarButtons() {
425
+ if (this.customButtons)
426
+ return this.customButtons;
427
+ else //todo replace by default create buttons
428
+ return [{ label: "test", action: () => { console.log("Button on model edition works"); } }];
429
+ }
430
+ get effectiveDetailsService() {
431
+ return this.detailsService ?? this.basicDetailsService;
432
+ }
433
+ onSvgReady(svg) {
434
+ this.svgElement = svg;
435
+ }
436
+ choose(element) {
437
+ this.effectiveDetailsService.openDetails(element, this.modelService);
438
+ }
439
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TreeEditorComponent, deps: [{ token: BasicModelDetailsService }], target: i0.ɵɵFactoryTarget.Component });
440
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TreeEditorComponent, isStandalone: true, selector: "emfular-tree-editor", inputs: { modelService: "modelService", detailsService: "detailsService", customButtons: "customButtons" }, ngImport: i0, template: "<div class=\"tree-editor\" id=\"tree-editor\">\n <emfular-file-level-bar\n [svg]=\"svgElement\"\n [modelService]=\"modelService\">\n </emfular-file-level-bar>\n <div class=\"editor-main\">\n <!-- vertical model bar -->\n <emfular-model-editing-bar\n class=\"model-bar\"\n [buttons]=\"sidebarButtons\">\n </emfular-model-editing-bar>\n\n\n <model-canvas\n [modelService]=\"modelService\"\n (svgReady)=\"onSvgReady($event)\"\n (chooseElement)=\"choose($event)\"\n >\n </model-canvas>\n </div>\n</div>\n\n", styles: [".tree-editor{display:flex;flex-direction:column;width:100%;height:100%}emfular-file-level-bar{flex:0 0 auto}.editor-main{flex:1 1 auto;display:flex;overflow:hidden}.model-bar{flex:0 0 60px;background:#f5f5f5;border-right:1px solid #ccc;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "component", type: FileLevelBarComponent, selector: "emfular-file-level-bar", inputs: ["svg", "modelService"] }, { kind: "component", type: ModelEditingBarComponent, selector: "emfular-model-editing-bar", inputs: ["buttons"] }, { kind: "component", type: ModelCanvasComponent, selector: "model-canvas", inputs: ["modelService"], outputs: ["chooseElement", "svgReady"] }] });
441
+ }
442
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TreeEditorComponent, decorators: [{
443
+ type: Component,
444
+ args: [{ selector: 'emfular-tree-editor', imports: [
445
+ FileLevelBarComponent,
446
+ ModelEditingBarComponent,
447
+ ModelCanvasComponent
448
+ ], template: "<div class=\"tree-editor\" id=\"tree-editor\">\n <emfular-file-level-bar\n [svg]=\"svgElement\"\n [modelService]=\"modelService\">\n </emfular-file-level-bar>\n <div class=\"editor-main\">\n <!-- vertical model bar -->\n <emfular-model-editing-bar\n class=\"model-bar\"\n [buttons]=\"sidebarButtons\">\n </emfular-model-editing-bar>\n\n\n <model-canvas\n [modelService]=\"modelService\"\n (svgReady)=\"onSvgReady($event)\"\n (chooseElement)=\"choose($event)\"\n >\n </model-canvas>\n </div>\n</div>\n\n", styles: [".tree-editor{display:flex;flex-direction:column;width:100%;height:100%}emfular-file-level-bar{flex:0 0 auto}.editor-main{flex:1 1 auto;display:flex;overflow:hidden}.model-bar{flex:0 0 60px;background:#f5f5f5;border-right:1px solid #ccc;display:flex;flex-direction:column}\n"] }]
449
+ }], ctorParameters: () => [{ type: BasicModelDetailsService }], propDecorators: { modelService: [{
450
+ type: Input
451
+ }], detailsService: [{
452
+ type: Input
453
+ }], customButtons: [{
454
+ type: Input
455
+ }] } });
456
+
457
+ class FileLevelBarMaterialComponent {
458
+ ioService;
459
+ svg;
460
+ modelService;
461
+ InputHandler = InputHandler;
462
+ constructor(ioService) {
463
+ this.ioService = ioService;
464
+ }
465
+ openModel() {
466
+ document.getElementById('openModel')?.click();
467
+ }
468
+ saveSVG() {
469
+ const svgContent = this.svg;
470
+ if (svgContent) {
471
+ this.ioService.saveSVG(svgContent, this.modelService.fileTitle());
472
+ }
473
+ }
474
+ saveSVGasPNG() {
475
+ const svgContent = this.svg;
476
+ if (svgContent) {
477
+ this.ioService.saveSvgAsPng(svgContent, this.modelService.fileTitle());
478
+ }
479
+ }
480
+ saveSVGasJPEG() {
481
+ const svgContent = this.svg;
482
+ if (svgContent) {
483
+ this.ioService.saveSvgAsJpeg(svgContent, this.modelService.fileTitle());
484
+ }
485
+ }
486
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FileLevelBarMaterialComponent, deps: [{ token: i1.IoService }], target: i0.ɵɵFactoryTarget.Component });
487
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: FileLevelBarMaterialComponent, isStandalone: true, selector: "emfular-file-level-bar-material", inputs: { svg: "svg", modelService: "modelService" }, ngImport: i0, template: "<input id=\"openModel\" type=\"file\" class=\"file-upload\" style=\"display: none\" (change)=\"modelService.loadFromFile($event)\" (click)=\"InputHandler.clearElem($event)\">\n<mat-toolbar class=\"file-level-bar\">\n <button (click)=\"modelService.newModel()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"insert_drive_file\" ></mat-icon>\n New\n </button>\n <button (click)=\"openModel()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"file_upload\" ></mat-icon>\n Open\n </button>\n <hr/>\n <button (click)=\"modelService.historyService.undo()\" [disabled]=\"modelService.historyService.isUndoNotPossible()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"undo\" ></mat-icon>\n Undo</button>\n <button (click)=\"modelService.historyService.redo()\" [disabled]=\"modelService.historyService.isRedoNotPossible()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"redo\" ></mat-icon>\n Redo</button>\n <hr />\n <button (click)=\"modelService.save()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"file_download\" ></mat-icon>\n Save\n </button>\n <button (click)=\"saveSVG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save SVG\n </button>\n <button (click)=\"saveSVGasPNG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save PNG\n </button>\n <button (click)=\"saveSVGasJPEG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save JPEG\n </button>\n</mat-toolbar>\n", styles: [".file-level-bar{display:flex;align-items:center;gap:.4rem;padding:.3rem .5rem;background:#f0f0f0;border-bottom:1px solid #ccc}.file-level-bar button{padding:.25rem .5rem;font-size:.85rem;cursor:pointer}.file-level-bar button:disabled{opacity:.5;cursor:default}.separator{width:1px;height:1rem;background:#ccc;margin:0 .3rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }] });
488
+ }
489
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FileLevelBarMaterialComponent, decorators: [{
490
+ type: Component,
491
+ args: [{ selector: 'emfular-file-level-bar-material', imports: [CommonModule, MatToolbarModule, MatIconModule, MatButtonModule], template: "<input id=\"openModel\" type=\"file\" class=\"file-upload\" style=\"display: none\" (change)=\"modelService.loadFromFile($event)\" (click)=\"InputHandler.clearElem($event)\">\n<mat-toolbar class=\"file-level-bar\">\n <button (click)=\"modelService.newModel()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"insert_drive_file\" ></mat-icon>\n New\n </button>\n <button (click)=\"openModel()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"file_upload\" ></mat-icon>\n Open\n </button>\n <hr/>\n <button (click)=\"modelService.historyService.undo()\" [disabled]=\"modelService.historyService.isUndoNotPossible()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"undo\" ></mat-icon>\n Undo</button>\n <button (click)=\"modelService.historyService.redo()\" [disabled]=\"modelService.historyService.isRedoNotPossible()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"redo\" ></mat-icon>\n Redo</button>\n <hr />\n <button (click)=\"modelService.save()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"file_download\" ></mat-icon>\n Save\n </button>\n <button (click)=\"saveSVG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save SVG\n </button>\n <button (click)=\"saveSVGasPNG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save PNG\n </button>\n <button (click)=\"saveSVGasJPEG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save JPEG\n </button>\n</mat-toolbar>\n", styles: [".file-level-bar{display:flex;align-items:center;gap:.4rem;padding:.3rem .5rem;background:#f0f0f0;border-bottom:1px solid #ccc}.file-level-bar button{padding:.25rem .5rem;font-size:.85rem;cursor:pointer}.file-level-bar button:disabled{opacity:.5;cursor:default}.separator{width:1px;height:1rem;background:#ccc;margin:0 .3rem}\n"] }]
492
+ }], ctorParameters: () => [{ type: i1.IoService }], propDecorators: { svg: [{
493
+ type: Input
494
+ }], modelService: [{
495
+ type: Input
496
+ }] } });
497
+
91
498
  /*
92
499
  * Public API Surface of ngx-emfular-integration
93
500
  */
@@ -96,5 +503,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
96
503
  * Generated bundle index. Do not edit.
97
504
  */
98
505
 
99
- export { HISTORY_SERVICE, ModelService, provideHistoryForModel };
506
+ export { BasicModelDetailsService, ContainerDetailsComponent, FileLevelBarComponent, FileLevelBarMaterialComponent, HISTORY_SERVICE, IdHelper, ModelCanvasComponent, ModelDetailsComponent, ModelEditingBarComponent, ModelService, ReferencableBoxComponent, TreeEditorComponent, provideHistoryForModel };
100
507
  //# sourceMappingURL=ngx-emfular-integration.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-emfular-integration.mjs","sources":["../../../projects/ngx-emfular-integration/src/lib/model.service.ts","../../../projects/ngx-emfular-integration/src/public-api.ts","../../../projects/ngx-emfular-integration/src/ngx-emfular-integration.ts"],"sourcesContent":["import {Inject, Injectable, InjectionToken} from '@angular/core';\nimport {Deserializer, JsonDeserializable, JsonOf, Referencable} from \"emfular\";\nimport {HistoryService, IoService} from \"ngx-emfular-helper\";\n\nexport const HISTORY_SERVICE = new InjectionToken<HistoryService<any>>(\n 'HistoryService'\n);\nexport function provideHistoryForModel<M>(\n prefix: string = 'history_',\n bufferSize: number = 50\n) {\n return {\n provide: HISTORY_SERVICE,\n useFactory: () => new HistoryService<JsonOf<M>>(prefix, bufferSize)\n };\n}\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class ModelService<M extends Referencable<any>> {\n\n private _model!: M\n get model(): M {\n return this._model;\n }\n protected set model(model: M) {\n this._model = this.adjustModel(model);\n this.adaptToModel()\n }\n\n protected constructor(\n @Inject(HISTORY_SERVICE) readonly historyService: HistoryService<JsonOf<M>>,\n readonly ioService: IoService,\n protected readonly modelClass: JsonDeserializable<M>,\n ) {\n this._model = new modelClass() //default initialization without calling set, since adjustments might need not yet initialized properties\n queueMicrotask(() => { //necessary to avoid timing issues if adjust model or adapt to model call services or other not initialized properties of the inheriting class\n this.historyService.state$.subscribe(state => {\n if (state) {\n this.applyJson(state);\n }\n });\n })\n }\n\n //default implementation to override if you need any normalization on a model before setting it\n adjustModel(model: M): M {\n return model;\n }\n\n //default implementation to override if you need adaptation of surroundings,\n // e.g. other attributes, notifications, signals etc\n adaptToModel() {}\n\n // override by either a fixed string or sth from the current model itself\n public fileTitle(): string {\n return \"model\"\n }\n\n serialize(): JsonOf<M> {\n return this.model.toJson()\n }\n\n deserialize(modelJson: JsonOf<M>): M {\n let modelEClass = new this.modelClass().getEClass();\n return Deserializer.fromJSON<M>(modelJson, modelEClass);\n }\n\n saveCurrentState() {\n this.historyService.save(this.serialize())\n }\n\n protected applyJson(modelJson: JsonOf<M>): M {\n this.model = this.deserialize(modelJson);\n return this.model;\n }\n\n loadFromJson(modelJson: JsonOf<M>): void {\n this.applyJson(modelJson);\n this.saveCurrentState()\n }\n\n loadFromFile(event: Event) {\n this.ioService.loadStringFromFile(event).then(txt => {\n //todo insert detection code for wrong files (no json, not appropriately structured\n this.loadFromJson(JSON.parse(txt));\n });\n }\n\n save() {\n const jsonString = JSON.stringify(this.serialize());\n this.ioService.saveJson(jsonString, this.fileTitle())\n }\n\n}\n","/*\n * Public API Surface of ngx-emfular-integration\n */\n\nexport * from './lib/model.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-emfular-integration.mjs","sources":["../../../projects/ngx-emfular-integration/src/lib/model.service.ts","../../../projects/ngx-emfular-integration/src/lib/editor/file-level-bar/file-level-bar.component.ts","../../../projects/ngx-emfular-integration/src/lib/editor/file-level-bar/file-level-bar.component.html","../../../projects/ngx-emfular-integration/src/lib/editor/model-editing-bar/model-editing-bar.component.ts","../../../projects/ngx-emfular-integration/src/lib/editor/model-editing-bar/model-editing-bar.component.html","../../../projects/ngx-emfular-integration/src/lib/utils/graphical-helper.ts","../../../projects/ngx-emfular-integration/src/lib/utils/id-helper.ts","../../../projects/ngx-emfular-integration/src/lib/graphical/referencable-box/referencable-box.component.ts","../../../projects/ngx-emfular-integration/src/lib/graphical/referencable-box/referencable-box.component.svg","../../../projects/ngx-emfular-integration/src/lib/editor/model-canvas/model-canvas.component.ts","../../../projects/ngx-emfular-integration/src/lib/editor/model-canvas/model-canvas.component.html","../../../projects/ngx-emfular-integration/src/lib/details/container-details/container-details.component.ts","../../../projects/ngx-emfular-integration/src/lib/details/container-details/container-details.component.html","../../../projects/ngx-emfular-integration/src/lib/details/model-details/model-details.component.ts","../../../projects/ngx-emfular-integration/src/lib/details/model-details/model-details.component.html","../../../projects/ngx-emfular-integration/src/lib/details/basic-model-details.service.ts","../../../projects/ngx-emfular-integration/src/lib/editor/tree-editor/tree-editor.component.ts","../../../projects/ngx-emfular-integration/src/lib/editor/tree-editor/tree-editor.component.html","../../../projects/ngx-emfular-integration/src/lib/editor/file-level-bar-material/file-level-bar-material.component.ts","../../../projects/ngx-emfular-integration/src/lib/editor/file-level-bar-material/file-level-bar-material.component.html","../../../projects/ngx-emfular-integration/src/public-api.ts","../../../projects/ngx-emfular-integration/src/ngx-emfular-integration.ts"],"sourcesContent":["import {Inject, Injectable, InjectionToken, PLATFORM_ID} from '@angular/core';\nimport {Deserializer, JsonDeserializable, JsonOf, Referencable} from \"emfular\";\nimport {HistoryService, IoService} from \"ngx-emfular-helper\";\n\nexport const HISTORY_SERVICE = new InjectionToken<HistoryService<any>>(\n 'HistoryService'\n);\nexport function provideHistoryForModel<M>(\n prefix: string = 'history_',\n bufferSize: number = 50\n) {\n return {\n provide: HISTORY_SERVICE,\n useFactory: (platformId: Object) => new HistoryService<JsonOf<M>>(prefix, bufferSize, platformId),\n deps: [PLATFORM_ID]\n };\n}\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class ModelService<M extends Referencable<any>> {\n\n private _model!: M\n get model(): M {\n return this._model;\n }\n protected set model(model: M) {\n this._model = this.adjustModel(model);\n this.adaptToModel()\n }\n\n protected constructor(\n @Inject(HISTORY_SERVICE) readonly historyService: HistoryService<JsonOf<M>>,\n readonly ioService: IoService,\n protected readonly modelClass: JsonDeserializable<M>,\n ) {\n this._model = new modelClass() //default initialization without calling set, since adjustments might need not yet initialized properties\n queueMicrotask(() => { //necessary to avoid timing issues if adjust model or adapt to model call services or other not initialized properties of the inheriting class\n this.historyService.state$.subscribe(state => {\n if (state) {\n this.applyJson(state);\n }\n });\n })\n }\n\n //default implementation to override if you need any normalization on a model before setting it\n adjustModel(model: M): M {\n return model;\n }\n\n //default implementation to override if you need adaptation of surroundings,\n // e.g. other attributes, notifications, signals etc\n adaptToModel() {}\n\n // override by either a fixed string or sth from the current model itself\n public fileTitle(): string {\n return \"model\"\n }\n\n newModel() {\n this.model = new this.modelClass()\n this.saveCurrentState()\n }\n\n serialize(): JsonOf<M> {\n return this.model.toJson()\n }\n\n deserialize(modelJson: JsonOf<M>): M {\n let modelEClass = new this.modelClass().getEClass();\n return Deserializer.fromJSON<M>(modelJson, modelEClass);\n }\n\n saveCurrentState() {\n this.historyService.save(this.serialize())\n }\n\n protected applyJson(modelJson: JsonOf<M>): M {\n this.model = this.deserialize(modelJson);\n return this.model;\n }\n\n loadFromJson(modelJson: JsonOf<M>): void {\n this.applyJson(modelJson);\n this.saveCurrentState()\n }\n\n loadFromFile(event: Event) {\n this.ioService.loadStringFromFile(event).then(txt => {\n //todo insert detection code for wrong files (no json, not appropriately structured\n this.loadFromJson(JSON.parse(txt));\n });\n }\n\n save() {\n const jsonString = JSON.stringify(this.serialize());\n this.ioService.saveJson(jsonString, this.fileTitle())\n }\n\n}\n","import {Component, Input} from '@angular/core';\nimport {InputHandler, IoService} from \"ngx-emfular-helper\";\nimport {Referencable} from \"emfular\";\nimport {ModelService} from \"../../model.service\";\n\n@Component({\n selector: 'emfular-file-level-bar',\n imports: [],\n templateUrl: './file-level-bar.component.html',\n styleUrl: './file-level-bar.component.css'\n})\nexport class FileLevelBarComponent<M extends Referencable<any>> {\n @Input() svg!: SVGElement\n @Input() modelService!: ModelService<M>\n protected readonly InputHandler = InputHandler;\n\n constructor(public ioService: IoService) {\n }\n\n openModel() {\n document.getElementById('openModel')?.click();\n }\n\n\n saveSVG() {\n const svgContent = this.svg;\n if(svgContent) {\n this.ioService.saveSVG(svgContent, this.modelService.fileTitle())\n }\n }\n\n saveSVGasPNG() {\n const svgContent = this.svg;\n if(svgContent) {\n this.ioService.saveSvgAsPng(svgContent, this.modelService.fileTitle())\n }\n }\n\n saveSVGasJPEG() {\n const svgContent = this.svg;\n if(svgContent) {\n this.ioService.saveSvgAsJpeg(svgContent, this.modelService.fileTitle())\n }\n }\n\n\n}\n","<input id=\"openModel\" type=\"file\" class=\"file-upload\" style=\"display:none\"\n (change)=\"modelService.loadFromFile($event)\"\n (click)=\"InputHandler.clearElem($event)\">\n\n<div class=\"file-level-bar\">\n <button (click)=\"modelService.newModel()\">New</button>\n <button (click)=\"openModel()\">Open</button>\n <span class=\"separator\"></span>\n <button (click)=\"modelService.historyService.undo()\" [disabled]=\"modelService.historyService.isUndoNotPossible()\">Undo</button>\n <button (click)=\"modelService.historyService.redo()\" [disabled]=\"modelService.historyService.isRedoNotPossible()\">Redo</button>\n <span class=\"separator\"></span>\n <button (click)=\"modelService.save()\">Save</button>\n <button (click)=\"saveSVG()\">Save SVG</button>\n <button (click)=\"saveSVGasPNG()\">Save PNG</button>\n <button (click)=\"saveSVGasJPEG()\">Save JPEG</button>\n</div>\n","import {Component, Input} from '@angular/core';\nimport {NgForOf, NgIf} from \"@angular/common\";\n\n@Component({\n selector: 'emfular-model-editing-bar',\n imports: [\n NgForOf,\n NgIf\n ],\n templateUrl: './model-editing-bar.component.html',\n styleUrl: './model-editing-bar.component.css'\n})\nexport class ModelEditingBarComponent {\n @Input() buttons: Array<{\n label: string;\n icon?: string;\n action: () => void;\n }> | null = null;\n\n\n}\n","<div class=\"model-editing-bar\">\n <button *ngFor=\"let b of buttons\" (click)=\"b.action()\">\n <span *ngIf=\"b.icon\" class=\"icon\">{{ b.icon }}</span>\n {{ b.label }}\n </button>\n</div>\n","import {ReContainer, Referencable } from \"emfular\";\n\nexport class GraphicalHelper {\n\n //todo, refactor into emfular\n static getAsList<T extends Referencable<any>>(refs: ReContainer<T, any>): T[] {\n const items: T[]|T|undefined = refs.get()\n if(items) {\n if(Array.isArray(items)) {\n return items\n }\n const result: T[] = [];\n result.push(items)\n return result\n } else {\n return [];\n }\n }\n\n}\n","import {getAllAttributes, Referencable } from \"emfular\";\n\nexport class IdHelper {\n\n static getLabel(ref: Referencable<any>): string {\n // 1. If the model has a \"name\" attribute → use it\n if ((ref as any).name) {\n return `${(ref as any).name}`;\n }\n\n // 2. Otherwise: first primitive attribute\n const attrs = getAllAttributes(ref.constructor);\n for (const [key] of attrs) {\n const value = (ref as any)[key];\n if (typeof value === \"string\" || typeof value === \"number\") {\n return `${value}`;\n }\n }\n\n /*\n // 3. Otherwise: use ID (EMFular always has stable IDs)\n if ((ref as any).id) {\n return `(id=${(ref as any).id})`;\n }*/\n\n // 4. Otherwise: fallback\n return \"(unnamed)\";\n }\n\n}\n","import {Component, EventEmitter, Input, Output} from '@angular/core';\nimport {Referencable} from 'emfular';\nimport {ArrowBetweenElemsComponent, BoundingBox, RectangleWithTextComponent, PositionHelper} from 'ngx-svg-graphics';\nimport {GraphicalHelper} from \"../../utils/graphical-helper\";\nimport {IdHelper} from \"../../utils/id-helper\";\n\n@Component({\n selector: '[referencable-box]',\n imports: [RectangleWithTextComponent, ArrowBetweenElemsComponent],\n templateUrl: './referencable-box.component.svg',\n styleUrl: './referencable-box.component.css'\n})\nexport class ReferencableBoxComponent {\n @Input() referencable!: Referencable<any>;\n @Input() position!: BoundingBox\n @Input() color?: string = \"#efad78\"\n @Output() chooseElement: EventEmitter<Referencable<any>> = new EventEmitter();\n\n\n isExpandedArray: boolean[] = []\n\n toggleExpand(i: number) {\n this.isExpandedArray[i]= !this.isExpandedArray[i];\n }\n\n choose(element: Referencable<any>) {\n this.chooseElement.emit(element);\n }\n\n constructor() {}\n\n protected readonly GraphicalHelper = GraphicalHelper;\n protected readonly PositionHelper = PositionHelper\n protected readonly IdHelper = IdHelper;\n}\n","<svg:g [attr.id]=\"referencable.$gId\">\n\n <g rectangle-with-text\n (click)=\"choose(referencable)\"\n [id]=\"referencable.$gId + '_main'\"\n [text]=\"IdHelper.getLabel(referencable)\"\n [position]=\"position\"\n [color]=\"color\"\n >\n </g>\n\n <!-- containers -->\n @for (container of referencable.$treeChildren;\n track referencable.$gId + '_' + container.referenceName\n ; let i = $index) {\n\n @let containerKey = referencable.$gId + '_' + container.referenceName;\n @let containerAnchorBox = PositionHelper.computeChildBBox(\n i,\n referencable.$treeChildren.length,\n position\n );\n\n <!-- reference box -->\n <g rectangle-with-text\n (click)=\"toggleExpand(i)\"\n [id]=\"containerKey + '_ref'\"\n [text]=\"container.referenceName\"\n [position]=\"containerAnchorBox\"\n color=\"#ede679\"\n >\n </g>\n\n <!-- arrow from main box to reference -->\n <g arrowElems\n [startGID]=\"referencable.$gId\"\n startSuffix=\"_main\"\n [endGID]=\"containerKey\"\n endSuffix=\"_ref\">\n </g>\n\n @if (isExpandedArray[i]) {\n <!-- real children inside this reference -->\n @let realChildren = GraphicalHelper.getAsList(container);\n\n @for (elem of realChildren; track elem.$gId; let j = $index) {\n\n @let elemBox = PositionHelper.computeChildBBox(\n j,\n realChildren.length,\n containerAnchorBox\n );\n <g referencable-box\n (chooseElement)=\"choose($event)\"\n [referencable]=\"elem\"\n [position]=\"elemBox\"\n >\n </g>\n <!-- arrow from reference to child box -->\n <g arrowElems\n [startGID]=\"containerKey\"\n startSuffix=\"_ref\"\n [endGID]=\"elem.$gId\"\n endSuffix=\"_main\">\n </g>\n }\n\n }\n }\n</svg:g>\n","import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';\nimport {ReferencableBoxComponent} from \"../../graphical/referencable-box/referencable-box.component\";\nimport {ModelService} from \"../../model.service\";\nimport { Referencable } from 'emfular';\nimport { BoundingBox } from 'ngx-svg-graphics';\n\n@Component({\n selector: 'model-canvas',\n imports: [\n ReferencableBoxComponent\n ],\n templateUrl: './model-canvas.component.html',\n styleUrl: './model-canvas.component.css'\n})\nexport class ModelCanvasComponent<M extends Referencable<any>> implements OnInit {\n svgwidth = 1500;\n svgheigth = 1000;\n initialBBox : BoundingBox = {x: this.svgwidth/2, y: 20, w: 200, h: 25}\n\n @Input() modelService!: ModelService<M>\n @Output() chooseElement: EventEmitter<Referencable<any>> = new EventEmitter();\n @Output() svgReady: EventEmitter<SVGSVGElement> = new EventEmitter<SVGSVGElement>();\n @ViewChild('svg', { static: true })\n svg!: ElementRef<SVGSVGElement>;\n\n ngOnInit() {\n // Safe because static: true\n this.svgReady.emit(this.svg.nativeElement);\n }\n\n choose(element: Referencable<any>): void {\n this.chooseElement.emit(element);\n }\n\n}\n","<div class=\"modeling-container\">\n <svg #svg id=\"svg\" class=\"canvas-svg\" [attr.width]=\"svgwidth\" [attr.height]=\"svgheigth\">\n <g referencable-box\n [referencable]=\"modelService.model\"\n [position]=\"initialBBox\"\n (chooseElement)=\"choose($event)\"\n >\n </g>\n </svg>\n</div>\n","import {Component, Input} from '@angular/core';\nimport {ReContainer, Referencable } from 'emfular';\nimport {GraphicalHelper} from \"../../utils/graphical-helper\";\nimport {NgForOf, NgIf} from \"@angular/common\";\nimport {IdHelper} from \"../../utils/id-helper\";\nimport {ModelService} from \"../../model.service\";\nimport {ModelDetailsService} from \"../model-details-service\";\n\n@Component({\n selector: 'container-details',\n imports: [\n NgForOf,\n NgIf,\n ],\n templateUrl: './container-details.component.html',\n styleUrl: './container-details.component.css'\n})\nexport class ContainerDetailsComponent<M extends Referencable<any>> {\n @Input() container!: ReContainer<any, any>\n @Input() isTree!: boolean\n @Input() modelService!: ModelService<M>\n @Input() detailsService!: ModelDetailsService<M> //todo just enforce interface?\n\n open(ref: Referencable<any>) {\n this.detailsService.openDetails(ref, this.modelService)\n }\n\n remove(ref: Referencable<any>) {\n //todo service should do this... in order for single source of truth\n if(this.container.remove(ref))\n this.modelService.saveCurrentState()\n }\n\n add() {\n //create on tree and open choice by graphical model on other links\n if(this.isTree) {\n console.log(\"Creation for several possible sub types is not solved in a meta-agnostic scenario\")\n } else {\n this.detailsService\n .openModelChoice(this.modelService)\n .subscribe(chosen => {\n if (!chosen) return; // user cancelled\n // todo what about type mismatches?\n if (this.container.add(chosen)) {\n this.modelService.saveCurrentState();\n }\n });\n }\n }\n\n protected readonly GraphicalHelper = GraphicalHelper;\n protected readonly IdHelper = IdHelper;\n}\n","<h4>{{container.referenceName+\":\"}}</h4>\n\n<button *ngIf=\"!isTree\" class=\"add-ref\" (click)=\"add()\">Add</button>\n\n<div class=\"container-row\"\n *ngFor=\"let elem of GraphicalHelper.getAsList(container)\">\n <div class=\"ref-info\">\n <span class=\"ref-icon\">🔗</span>\n <span class=\"ref-type\">{{ elem.getEClass() }}</span>\n <span class=\"ref-label\">{{ IdHelper.getLabel(elem) }}</span>\n </div>\n\n <div class=\"ref-actions\">\n <button (click)=\"open(elem)\">Open</button>\n <button (click)=\"remove(elem)\">Remove</button>\n </div>\n</div>\n\n","import {Component, Input, OnInit} from '@angular/core';\nimport {AttributeOptions, Referencable, ReLinkContainer, ReTreeChildrenContainer } from 'emfular';\nimport {ModelService} from \"../../model.service\";\nimport { getAllAttributes } from \"emfular\";\nimport {FormsModule} from \"@angular/forms\";\nimport {NgForOf} from \"@angular/common\";\nimport {\n ContainerDetailsComponent\n} from \"../container-details/container-details.component\";\nimport {ModelDetailsService} from \"../model-details-service\";\n\n@Component({\n selector: 'lib-model-details',\n imports: [\n FormsModule,\n NgForOf,\n ContainerDetailsComponent\n ],\n templateUrl: './model-details.component.html',\n styleUrl: './model-details.component.css'\n})\nexport class ModelDetailsComponent<T extends Referencable<any>, M extends Referencable<any>> implements OnInit {\n @Input() model!: T\n @Input() modelService!: ModelService<M>\n @Input() detailsService!: ModelDetailsService<M>\n\n attributes: Array<{ key: string; options: AttributeOptions }> = [];\n\n ngOnInit() {\n const map = getAllAttributes(this.model.constructor);\n this.attributes = Array.from(map.entries()).map(([key, options]) => ({\n key,\n options\n }));\n }\n \n getLinks(): ReLinkContainer<any, any>[] {\n return this.model.$otherReferences\n }\n\n getChildren(): ReTreeChildrenContainer<any>[] {\n return this.model.$treeChildren\n }\n\n}\n","<h1>Detail-Editor</h1>\n<h2>{{model.getEClass()}}</h2>\n<div class=\"attribute-list\">\n <div class=\"attribute-row\" *ngFor=\"let attr of attributes\">\n <label>{{ attr.key }}</label>\n <input\n type=\"text\"\n [(ngModel)]=\"$any(model)[attr.key]\"\n />\n </div>\n</div>\n<h3>References</h3>\n<div class=\"reference-list\">\n <container-details\n *ngFor=\"let container of getChildren()\"\n [container]=\"container\"\n [isTree]=\"true\"\n [modelService]=\"modelService\"\n [detailsService]=\"detailsService\"\n >\n </container-details>\n <container-details\n *ngFor=\"let container of getLinks()\"\n [container]=\"container\"\n [isTree]=\"false\"\n [modelService]=\"modelService\"\n [detailsService]=\"detailsService\"\n >\n </container-details>\n</div>\n\n","import { Injectable } from '@angular/core';\nimport { Referencable } from 'emfular';\nimport {ModelService} from \"../model.service\";\nimport {ModelDetailsComponent} from \"./model-details/model-details.component\";\nimport { Overlay } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {ModelCanvasComponent} from \"../editor/model-canvas/model-canvas.component\";\nimport {Observable, Subject} from \"rxjs\";\nimport {ModelDetailsService} from \"./model-details-service\";\n\n@Injectable({\n providedIn: 'root'\n})\nexport class BasicModelDetailsService<M extends Referencable<any>> implements ModelDetailsService<M> {\n\n constructor( private overlay: Overlay) { }\n\n //actually T must be somewhere on M\n openDetails<\n T extends Referencable<any>\n >(elem: T, modelService: ModelService<M>) {\n // instead of opening the generic ModeldetailsCompoennt you might like to consider opening a specific one\n //by determining the eClass and switching based on elem.getEClass()\n\n const overlayRef = this.overlay.create(\n { hasBackdrop: true,\n backdropClass: 'cdk-overlay-dark-backdrop',\n panelClass: 'basic-details-panel',\n positionStrategy: this.overlay.position()\n .global() .centerHorizontally() .centerVertically()\n });\n const portal = new ComponentPortal(ModelDetailsComponent<T,M>);\n const ref = overlayRef.attach(portal);\n ref.instance.model = elem;\n ref.instance.modelService = modelService;\n ref.instance.detailsService = this\n overlayRef.backdropClick().subscribe(\n () => overlayRef.dispose()\n );\n }\n\n openModelChoice(\n modelService: ModelService<M>\n ): Observable<Referencable<any>> {\n\n const subject = new Subject<Referencable<any>>();\n\n const overlayRef = this.overlay.create({\n hasBackdrop: true,\n backdropClass: 'cdk-overlay-dark-backdrop',\n panelClass: 'basic-details-panel',\n positionStrategy: this.overlay.position()\n .global().centerHorizontally().centerVertically()\n });\n\n const portal = new ComponentPortal(ModelCanvasComponent<M>);\n const ref = overlayRef.attach(portal);\n\n ref.instance.modelService = modelService;\n ref.instance.chooseElement.subscribe(next => {\n subject.next(next);\n subject.complete();\n overlayRef.dispose();\n });\n\n overlayRef.backdropClick().subscribe(() => {\n subject.complete();\n overlayRef.dispose();\n });\n\n return subject.asObservable();\n }\n\n}\n","import {Component, Input} from '@angular/core';\nimport { Referencable} from \"emfular\";\nimport {FileLevelBarComponent} from \"../file-level-bar/file-level-bar.component\";\nimport {ModelEditingBarComponent} from \"../model-editing-bar/model-editing-bar.component\";\nimport {ModelService} from \"../../model.service\";\nimport {ModelCanvasComponent} from \"../model-canvas/model-canvas.component\";\nimport {ModelDetailsService} from \"../../details/model-details-service\";\nimport {BasicModelDetailsService} from \"../../details/basic-model-details.service\";\n\n@Component({\n selector: 'emfular-tree-editor',\n imports: [\n FileLevelBarComponent,\n ModelEditingBarComponent,\n ModelCanvasComponent\n ],\n templateUrl: './tree-editor.component.html',\n styleUrl: './tree-editor.component.css'\n})\nexport class TreeEditorComponent<M extends Referencable<any>> {\n svgElement!: SVGSVGElement;\n @Input() modelService!: ModelService<M>\n @Input() detailsService?: ModelDetailsService<M>\n @Input() customButtons: Array<{\n label: string;\n icon?: string;\n action: () => void;\n }> | null = null;\n\n constructor(private basicDetailsService: BasicModelDetailsService<M>) {}\n\n get sidebarButtons() {\n if (this.customButtons) return this.customButtons;\n else //todo replace by default create buttons\n return[{label: \"test\", action: () => {console.log(\"Button on model edition works\")}}];\n }\n\n get effectiveDetailsService(): ModelDetailsService<M> {\n return this.detailsService ?? this.basicDetailsService;\n }\n\n onSvgReady(svg: SVGSVGElement) {\n this.svgElement = svg;\n }\n\n choose(element: Referencable<any>) {\n this.effectiveDetailsService.openDetails(element, this.modelService)\n }\n}\n","<div class=\"tree-editor\" id=\"tree-editor\">\n <emfular-file-level-bar\n [svg]=\"svgElement\"\n [modelService]=\"modelService\">\n </emfular-file-level-bar>\n <div class=\"editor-main\">\n <!-- vertical model bar -->\n <emfular-model-editing-bar\n class=\"model-bar\"\n [buttons]=\"sidebarButtons\">\n </emfular-model-editing-bar>\n\n\n <model-canvas\n [modelService]=\"modelService\"\n (svgReady)=\"onSvgReady($event)\"\n (chooseElement)=\"choose($event)\"\n >\n </model-canvas>\n </div>\n</div>\n\n","import {Component, Input} from '@angular/core';\nimport {InputHandler, IoService} from \"ngx-emfular-helper\";\nimport {Referencable} from \"emfular\";\nimport { CommonModule } from '@angular/common';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport {ModelService} from \"../../model.service\";\n\n@Component({\n selector: 'emfular-file-level-bar-material',\n imports: [CommonModule, MatToolbarModule, MatIconModule, MatButtonModule],\n templateUrl: './file-level-bar-material.component.html',\n styleUrl: './file-level-bar-material.component.css'\n})\nexport class FileLevelBarMaterialComponent<M extends Referencable<any>> {\n @Input() svg!: SVGElement\n @Input() modelService!: ModelService<M>\n protected readonly InputHandler = InputHandler;\n\n constructor(public ioService: IoService) {\n }\n\n openModel() {\n document.getElementById('openModel')?.click();\n }\n\n\n saveSVG() {\n const svgContent = this.svg;\n if(svgContent) {\n this.ioService.saveSVG(svgContent, this.modelService.fileTitle())\n }\n }\n\n saveSVGasPNG() {\n const svgContent = this.svg;\n if(svgContent) {\n this.ioService.saveSvgAsPng(svgContent, this.modelService.fileTitle())\n }\n }\n\n saveSVGasJPEG() {\n const svgContent = this.svg;\n if(svgContent) {\n this.ioService.saveSvgAsJpeg(svgContent, this.modelService.fileTitle())\n }\n }\n\n\n}\n","<input id=\"openModel\" type=\"file\" class=\"file-upload\" style=\"display: none\" (change)=\"modelService.loadFromFile($event)\" (click)=\"InputHandler.clearElem($event)\">\n<mat-toolbar class=\"file-level-bar\">\n <button (click)=\"modelService.newModel()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"insert_drive_file\" ></mat-icon>\n New\n </button>\n <button (click)=\"openModel()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"file_upload\" ></mat-icon>\n Open\n </button>\n <hr/>\n <button (click)=\"modelService.historyService.undo()\" [disabled]=\"modelService.historyService.isUndoNotPossible()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"undo\" ></mat-icon>\n Undo</button>\n <button (click)=\"modelService.historyService.redo()\" [disabled]=\"modelService.historyService.isRedoNotPossible()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"redo\" ></mat-icon>\n Redo</button>\n <hr />\n <button (click)=\"modelService.save()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"file_download\" ></mat-icon>\n Save\n </button>\n <button (click)=\"saveSVG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save SVG\n </button>\n <button (click)=\"saveSVGasPNG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save PNG\n </button>\n <button (click)=\"saveSVGasJPEG()\">\n <mat-icon aria-hidden=\"false\" fontIcon=\"photo_library\" ></mat-icon>\n Save JPEG\n </button>\n</mat-toolbar>\n","/*\n * Public API Surface of ngx-emfular-integration\n */\n\nexport * from './lib/model.service';\n\nexport * from './lib/editor/tree-editor/tree-editor.component'\nexport * from './lib/editor/file-level-bar/file-level-bar.component';\nexport * from './lib/editor/file-level-bar-material/file-level-bar-material.component';\nexport * from './lib/editor/model-editing-bar/model-editing-bar.component';\nexport * from './lib/editor/model-canvas/model-canvas.component';\n\nexport * from './lib/graphical/referencable-box/referencable-box.component';\n\nexport * from './lib/details/model-details-service'\nexport * from './lib/details/basic-model-details.service'\nexport * from './lib/details/model-details/model-details.component';\nexport * from './lib/details/container-details/container-details.component'\n\nexport * from './lib/utils/id-helper'","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.BasicModelDetailsService"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Referencable } from 'emfular';
2
+ import { ModelService } from "../model.service";
3
+ import { Overlay } from '@angular/cdk/overlay';
4
+ import { Observable } from "rxjs";
5
+ import { ModelDetailsService } from "./model-details-service";
6
+ import * as i0 from "@angular/core";
7
+ export declare class BasicModelDetailsService<M extends Referencable<any>> implements ModelDetailsService<M> {
8
+ private overlay;
9
+ constructor(overlay: Overlay);
10
+ openDetails<T extends Referencable<any>>(elem: T, modelService: ModelService<M>): void;
11
+ openModelChoice(modelService: ModelService<M>): Observable<Referencable<any>>;
12
+ static ɵfac: i0.ɵɵFactoryDeclaration<BasicModelDetailsService<any>, never>;
13
+ static ɵprov: i0.ɵɵInjectableDeclaration<BasicModelDetailsService<any>>;
14
+ }
@@ -0,0 +1,19 @@
1
+ import { ReContainer, Referencable } from 'emfular';
2
+ import { GraphicalHelper } from "../../utils/graphical-helper";
3
+ import { IdHelper } from "../../utils/id-helper";
4
+ import { ModelService } from "../../model.service";
5
+ import { ModelDetailsService } from "../model-details-service";
6
+ import * as i0 from "@angular/core";
7
+ export declare class ContainerDetailsComponent<M extends Referencable<any>> {
8
+ container: ReContainer<any, any>;
9
+ isTree: boolean;
10
+ modelService: ModelService<M>;
11
+ detailsService: ModelDetailsService<M>;
12
+ open(ref: Referencable<any>): void;
13
+ remove(ref: Referencable<any>): void;
14
+ add(): void;
15
+ protected readonly GraphicalHelper: typeof GraphicalHelper;
16
+ protected readonly IdHelper: typeof IdHelper;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<ContainerDetailsComponent<any>, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<ContainerDetailsComponent<any>, "container-details", never, { "container": { "alias": "container"; "required": false; }; "isTree": { "alias": "isTree"; "required": false; }; "modelService": { "alias": "modelService"; "required": false; }; "detailsService": { "alias": "detailsService"; "required": false; }; }, {}, never, never, true, never>;
19
+ }
@@ -0,0 +1,19 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { AttributeOptions, Referencable, ReLinkContainer, ReTreeChildrenContainer } from 'emfular';
3
+ import { ModelService } from "../../model.service";
4
+ import { ModelDetailsService } from "../model-details-service";
5
+ import * as i0 from "@angular/core";
6
+ export declare class ModelDetailsComponent<T extends Referencable<any>, M extends Referencable<any>> implements OnInit {
7
+ model: T;
8
+ modelService: ModelService<M>;
9
+ detailsService: ModelDetailsService<M>;
10
+ attributes: Array<{
11
+ key: string;
12
+ options: AttributeOptions;
13
+ }>;
14
+ ngOnInit(): void;
15
+ getLinks(): ReLinkContainer<any, any>[];
16
+ getChildren(): ReTreeChildrenContainer<any>[];
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<ModelDetailsComponent<any, any>, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<ModelDetailsComponent<any, any>, "lib-model-details", never, { "model": { "alias": "model"; "required": false; }; "modelService": { "alias": "modelService"; "required": false; }; "detailsService": { "alias": "detailsService"; "required": false; }; }, {}, never, never, true, never>;
19
+ }
@@ -0,0 +1,7 @@
1
+ import { Referencable } from "emfular";
2
+ import { ModelService } from "../model.service";
3
+ import { Observable } from "rxjs";
4
+ export interface ModelDetailsService<M extends Referencable<any>> {
5
+ openDetails<T extends Referencable<any>>(elem: T, modelService: ModelService<M>): void;
6
+ openModelChoice(modelService: ModelService<M>): Observable<Referencable<any>>;
7
+ }
@@ -0,0 +1,17 @@
1
+ import { InputHandler, IoService } from "ngx-emfular-helper";
2
+ import { Referencable } from "emfular";
3
+ import { ModelService } from "../../model.service";
4
+ import * as i0 from "@angular/core";
5
+ export declare class FileLevelBarComponent<M extends Referencable<any>> {
6
+ ioService: IoService;
7
+ svg: SVGElement;
8
+ modelService: ModelService<M>;
9
+ protected readonly InputHandler: typeof InputHandler;
10
+ constructor(ioService: IoService);
11
+ openModel(): void;
12
+ saveSVG(): void;
13
+ saveSVGasPNG(): void;
14
+ saveSVGasJPEG(): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<FileLevelBarComponent<any>, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<FileLevelBarComponent<any>, "emfular-file-level-bar", never, { "svg": { "alias": "svg"; "required": false; }; "modelService": { "alias": "modelService"; "required": false; }; }, {}, never, never, true, never>;
17
+ }
@@ -0,0 +1,17 @@
1
+ import { InputHandler, IoService } from "ngx-emfular-helper";
2
+ import { Referencable } from "emfular";
3
+ import { ModelService } from "../../model.service";
4
+ import * as i0 from "@angular/core";
5
+ export declare class FileLevelBarMaterialComponent<M extends Referencable<any>> {
6
+ ioService: IoService;
7
+ svg: SVGElement;
8
+ modelService: ModelService<M>;
9
+ protected readonly InputHandler: typeof InputHandler;
10
+ constructor(ioService: IoService);
11
+ openModel(): void;
12
+ saveSVG(): void;
13
+ saveSVGasPNG(): void;
14
+ saveSVGasJPEG(): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<FileLevelBarMaterialComponent<any>, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<FileLevelBarMaterialComponent<any>, "emfular-file-level-bar-material", never, { "svg": { "alias": "svg"; "required": false; }; "modelService": { "alias": "modelService"; "required": false; }; }, {}, never, never, true, never>;
17
+ }
@@ -0,0 +1,18 @@
1
+ import { ElementRef, EventEmitter, OnInit } from '@angular/core';
2
+ import { ModelService } from "../../model.service";
3
+ import { Referencable } from 'emfular';
4
+ import { BoundingBox } from 'ngx-svg-graphics';
5
+ import * as i0 from "@angular/core";
6
+ export declare class ModelCanvasComponent<M extends Referencable<any>> implements OnInit {
7
+ svgwidth: number;
8
+ svgheigth: number;
9
+ initialBBox: BoundingBox;
10
+ modelService: ModelService<M>;
11
+ chooseElement: EventEmitter<Referencable<any>>;
12
+ svgReady: EventEmitter<SVGSVGElement>;
13
+ svg: ElementRef<SVGSVGElement>;
14
+ ngOnInit(): void;
15
+ choose(element: Referencable<any>): void;
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<ModelCanvasComponent<any>, never>;
17
+ static ɵcmp: i0.ɵɵComponentDeclaration<ModelCanvasComponent<any>, "model-canvas", never, { "modelService": { "alias": "modelService"; "required": false; }; }, { "chooseElement": "chooseElement"; "svgReady": "svgReady"; }, never, never, true, never>;
18
+ }
@@ -0,0 +1,10 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class ModelEditingBarComponent {
3
+ buttons: Array<{
4
+ label: string;
5
+ icon?: string;
6
+ action: () => void;
7
+ }> | null;
8
+ static ɵfac: i0.ɵɵFactoryDeclaration<ModelEditingBarComponent, never>;
9
+ static ɵcmp: i0.ɵɵComponentDeclaration<ModelEditingBarComponent, "emfular-model-editing-bar", never, { "buttons": { "alias": "buttons"; "required": false; }; }, {}, never, never, true, never>;
10
+ }
@@ -0,0 +1,27 @@
1
+ import { Referencable } from "emfular";
2
+ import { ModelService } from "../../model.service";
3
+ import { ModelDetailsService } from "../../details/model-details-service";
4
+ import { BasicModelDetailsService } from "../../details/basic-model-details.service";
5
+ import * as i0 from "@angular/core";
6
+ export declare class TreeEditorComponent<M extends Referencable<any>> {
7
+ private basicDetailsService;
8
+ svgElement: SVGSVGElement;
9
+ modelService: ModelService<M>;
10
+ detailsService?: ModelDetailsService<M>;
11
+ customButtons: Array<{
12
+ label: string;
13
+ icon?: string;
14
+ action: () => void;
15
+ }> | null;
16
+ constructor(basicDetailsService: BasicModelDetailsService<M>);
17
+ get sidebarButtons(): {
18
+ label: string;
19
+ icon?: string;
20
+ action: () => void;
21
+ }[];
22
+ get effectiveDetailsService(): ModelDetailsService<M>;
23
+ onSvgReady(svg: SVGSVGElement): void;
24
+ choose(element: Referencable<any>): void;
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<TreeEditorComponent<any>, never>;
26
+ static ɵcmp: i0.ɵɵComponentDeclaration<TreeEditorComponent<any>, "emfular-tree-editor", never, { "modelService": { "alias": "modelService"; "required": false; }; "detailsService": { "alias": "detailsService"; "required": false; }; "customButtons": { "alias": "customButtons"; "required": false; }; }, {}, never, never, true, never>;
27
+ }
@@ -0,0 +1,21 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { Referencable } from 'emfular';
3
+ import { BoundingBox, PositionHelper } from 'ngx-svg-graphics';
4
+ import { GraphicalHelper } from "../../utils/graphical-helper";
5
+ import { IdHelper } from "../../utils/id-helper";
6
+ import * as i0 from "@angular/core";
7
+ export declare class ReferencableBoxComponent {
8
+ referencable: Referencable<any>;
9
+ position: BoundingBox;
10
+ color?: string;
11
+ chooseElement: EventEmitter<Referencable<any>>;
12
+ isExpandedArray: boolean[];
13
+ toggleExpand(i: number): void;
14
+ choose(element: Referencable<any>): void;
15
+ constructor();
16
+ protected readonly GraphicalHelper: typeof GraphicalHelper;
17
+ protected readonly PositionHelper: typeof PositionHelper;
18
+ protected readonly IdHelper: typeof IdHelper;
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReferencableBoxComponent, never>;
20
+ static ɵcmp: i0.ɵɵComponentDeclaration<ReferencableBoxComponent, "[referencable-box]", never, { "referencable": { "alias": "referencable"; "required": false; }; "position": { "alias": "position"; "required": false; }; "color": { "alias": "color"; "required": false; }; }, { "chooseElement": "chooseElement"; }, never, never, true, never>;
21
+ }
@@ -5,7 +5,8 @@ import * as i0 from "@angular/core";
5
5
  export declare const HISTORY_SERVICE: InjectionToken<HistoryService<any>>;
6
6
  export declare function provideHistoryForModel<M>(prefix?: string, bufferSize?: number): {
7
7
  provide: InjectionToken<HistoryService<any>>;
8
- useFactory: () => HistoryService<JsonOf<M>>;
8
+ useFactory: (platformId: Object) => HistoryService<JsonOf<M>>;
9
+ deps: InjectionToken<Object>[];
9
10
  };
10
11
  export declare abstract class ModelService<M extends Referencable<any>> {
11
12
  readonly historyService: HistoryService<JsonOf<M>>;
@@ -18,6 +19,7 @@ export declare abstract class ModelService<M extends Referencable<any>> {
18
19
  adjustModel(model: M): M;
19
20
  adaptToModel(): void;
20
21
  fileTitle(): string;
22
+ newModel(): void;
21
23
  serialize(): JsonOf<M>;
22
24
  deserialize(modelJson: JsonOf<M>): M;
23
25
  saveCurrentState(): void;
@@ -0,0 +1,4 @@
1
+ import { ReContainer, Referencable } from "emfular";
2
+ export declare class GraphicalHelper {
3
+ static getAsList<T extends Referencable<any>>(refs: ReContainer<T, any>): T[];
4
+ }
@@ -0,0 +1,4 @@
1
+ import { Referencable } from "emfular";
2
+ export declare class IdHelper {
3
+ static getLabel(ref: Referencable<any>): string;
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-emfular-integration",
3
- "version": "0.0.7",
3
+ "version": "0.2.0",
4
4
  "description": "Integrates emfular with its ngx-helper to provide modeling services",
5
5
  "keywords": [
6
6
  "EMFular",
@@ -15,25 +15,37 @@
15
15
  "type": "git",
16
16
  "url": "https://github.com/softlang/EMFular/tree/main/projects/ngx-emfular-integration"
17
17
  },
18
+ "exports": {
19
+ "./*": {
20
+ "default": "./*"
21
+ },
22
+ "./public-api": {
23
+ "default": "./public-api.js"
24
+ },
25
+ "./details-overlay.css": {
26
+ "default": "./details-overlay.css"
27
+ },
28
+ "./package.json": {
29
+ "default": "./package.json"
30
+ },
31
+ ".": {
32
+ "types": "./index.d.ts",
33
+ "default": "./fesm2022/ngx-emfular-integration.mjs"
34
+ }
35
+ },
18
36
  "peerDependencies": {
19
37
  "@angular/common": "^19.2.0",
20
38
  "@angular/core": "^19.2.0",
39
+ "@angular/cdk": "^19.2.0",
40
+ "@angular/material": "^19.2.0",
21
41
  "emfular": ">=9.0.0 <11.0.0",
22
- "ngx-emfular-helper": "^0.3.1"
42
+ "ngx-emfular-helper": "^1.0.0",
43
+ "ngx-svg-graphics": "^3.0.0"
23
44
  },
24
45
  "dependencies": {
25
46
  "tslib": "^2.3.0"
26
47
  },
27
48
  "sideEffects": false,
28
49
  "module": "fesm2022/ngx-emfular-integration.mjs",
29
- "typings": "index.d.ts",
30
- "exports": {
31
- "./package.json": {
32
- "default": "./package.json"
33
- },
34
- ".": {
35
- "types": "./index.d.ts",
36
- "default": "./fesm2022/ngx-emfular-integration.mjs"
37
- }
38
- }
50
+ "typings": "index.d.ts"
39
51
  }
package/public-api.d.ts CHANGED
@@ -1 +1,12 @@
1
1
  export * from './lib/model.service';
2
+ export * from './lib/editor/tree-editor/tree-editor.component';
3
+ export * from './lib/editor/file-level-bar/file-level-bar.component';
4
+ export * from './lib/editor/file-level-bar-material/file-level-bar-material.component';
5
+ export * from './lib/editor/model-editing-bar/model-editing-bar.component';
6
+ export * from './lib/editor/model-canvas/model-canvas.component';
7
+ export * from './lib/graphical/referencable-box/referencable-box.component';
8
+ export * from './lib/details/model-details-service';
9
+ export * from './lib/details/basic-model-details.service';
10
+ export * from './lib/details/model-details/model-details.component';
11
+ export * from './lib/details/container-details/container-details.component';
12
+ export * from './lib/utils/id-helper';