fx-form-builder-wrapper 0.0.49 → 0.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/ng-package.json +9 -0
  2. package/package.json +16 -29
  3. package/src/lib/components/button/button.component.css +0 -0
  4. package/src/lib/components/button/button.component.html +1 -0
  5. package/src/lib/components/button/button.component.ts +24 -0
  6. package/src/lib/components/dynamic-table/dynamic-table.component.css +31 -0
  7. package/src/lib/components/dynamic-table/dynamic-table.component.html +69 -0
  8. package/src/lib/components/dynamic-table/dynamic-table.component.ts +258 -0
  9. package/src/lib/components/fx-form-component/fx-form-component.component.ts +86 -0
  10. package/src/lib/components/toggle/toggle.component.css +51 -0
  11. package/src/lib/components/toggle/toggle.component.html +12 -0
  12. package/src/lib/components/toggle/toggle.component.ts +33 -0
  13. package/src/lib/components/toggle-button/toggle-button.component.css +22 -0
  14. package/src/lib/components/toggle-button/toggle-button.component.html +10 -0
  15. package/src/lib/components/toggle-button/toggle-button.component.ts +40 -0
  16. package/src/lib/components/uploader/uploader.component.css +49 -0
  17. package/src/lib/components/uploader/uploader.component.html +23 -0
  18. package/src/lib/components/uploader/uploader.component.ts +59 -0
  19. package/src/lib/custom-controls/dispatch-to-clinic/dispatch-to-clinic.component.html +78 -0
  20. package/src/lib/custom-controls/dispatch-to-clinic/dispatch-to-clinic.component.ts +44 -0
  21. package/src/lib/form-builder.css +9 -0
  22. package/src/lib/fx-builder-wrapper.component.ts +68 -0
  23. package/src/lib/fx-builder-wrapper.service.ts +38 -0
  24. package/src/lib/panel/configuration-panel/configuration-panel.component.css +154 -0
  25. package/src/lib/panel/configuration-panel/configuration-panel.component.html +162 -0
  26. package/src/lib/panel/configuration-panel/configuration-panel.component.ts +120 -0
  27. package/src/lib/panel/settings-panel/settings-panel.component.css +30 -0
  28. package/src/lib/panel/settings-panel/settings-panel.component.html +28 -0
  29. package/src/lib/panel/settings-panel/settings-panel.component.ts +23 -0
  30. package/src/public-api.ts +8 -0
  31. package/tsconfig.lib.json +15 -0
  32. package/tsconfig.lib.prod.json +13 -0
  33. package/tsconfig.spec.json +15 -0
  34. package/esm2022/fx-form-builder-wrapper.mjs +0 -5
  35. package/esm2022/lib/components/dynamic-table/dynamic-table.component.mjs +0 -235
  36. package/esm2022/lib/components/fx-form-component/fx-form-component.component.mjs +0 -103
  37. package/esm2022/lib/components/toggle/toggle.component.mjs +0 -33
  38. package/esm2022/lib/components/toggle-button/toggle-button.component.mjs +0 -38
  39. package/esm2022/lib/components/uploader/uploader.component.mjs +0 -58
  40. package/esm2022/lib/custom-controls/dispatch-to-clinic/dispatch-to-clinic.component.mjs +0 -42
  41. package/esm2022/lib/fx-builder-wrapper.component.mjs +0 -79
  42. package/esm2022/lib/fx-builder-wrapper.service.mjs +0 -44
  43. package/esm2022/lib/panel/configuration-panel/configuration-panel.component.mjs +0 -117
  44. package/esm2022/lib/panel/settings-panel/settings-panel.component.mjs +0 -24
  45. package/esm2022/public-api.mjs +0 -7
  46. package/fesm2022/fx-form-builder-wrapper.mjs +0 -718
  47. package/fesm2022/fx-form-builder-wrapper.mjs.map +0 -1
  48. package/index.d.ts +0 -5
  49. package/lib/components/dynamic-table/dynamic-table.component.d.ts +0 -52
  50. package/lib/components/fx-form-component/fx-form-component.component.d.ts +0 -19
  51. package/lib/components/toggle/toggle.component.d.ts +0 -13
  52. package/lib/components/toggle-button/toggle-button.component.d.ts +0 -15
  53. package/lib/components/uploader/uploader.component.d.ts +0 -16
  54. package/lib/custom-controls/dispatch-to-clinic/dispatch-to-clinic.component.d.ts +0 -17
  55. package/lib/fx-builder-wrapper.component.d.ts +0 -19
  56. package/lib/fx-builder-wrapper.service.d.ts +0 -14
  57. package/lib/panel/configuration-panel/configuration-panel.component.d.ts +0 -27
  58. package/lib/panel/settings-panel/settings-panel.component.d.ts +0 -10
  59. package/public-api.d.ts +0 -3
@@ -0,0 +1,162 @@
1
+ <p-dialog header="Edit Configurations" [modal]="true" [draggable]="false" [(visible)]="visible" [style]="{width: '70rem'}" class="customDialogClass">
2
+ <!-- <ng-template pTemplate="header">
3
+ <div class="flex p-2 bg-white border-2">
4
+ <p class="text-base">Edit Configurations</p>
5
+ </div>
6
+ </ng-template> -->
7
+ <div class="flex flex-col gap-4 bg-white p-2 border-2 border-gray-200">
8
+ <div class="flex items-center gap-4 mb-8 w-full">
9
+ <div class="w-1/3">
10
+ <label for="rows" class="font-semibold w-24">Rows</label>
11
+ <input type="text" [disabled]="enableAPI" [(ngModel)]="rows" placeholder="rows" class="form__input" id="name" autocomplete="rows" />
12
+ </div>
13
+ <div class="w-1/3">
14
+ <label for="enableAPI" class="font-semibold w-24">Enable API</label>
15
+ <input type="checkbox" [(ngModel)]="enableAPI" placeholder="API Url" id="enableAPI" autocomplete="enableAPI" />
16
+ </div>
17
+ <div class="w-1/3">
18
+ @if (enableAPI) {
19
+ <ng-container>
20
+ <label for="api" class="font-semibold w-24">API</label>
21
+ <input type="text" [(ngModel)]="api" placeholder="Enter API Url" id="api" class="form__input" autocomplete="api" />
22
+ </ng-container>
23
+ }
24
+ </div>
25
+
26
+ </div>
27
+ <!-- <div class="flex items-center gap-4 mb-8">
28
+ <div class="w-1/2">
29
+
30
+ </div>
31
+ <div class="w-1/2">
32
+
33
+
34
+ </div>
35
+
36
+
37
+ </div>
38
+
39
+ <div class="flex items-center gap-4 mb-8">
40
+ <div class="w-1/2">
41
+
42
+ </div>
43
+ <div class="w-1/2">
44
+
45
+ </div>
46
+
47
+
48
+ </div> -->
49
+
50
+ <div class="flex flex-wrap gap-4 mb-8">
51
+
52
+ <div class="w-full flex items-center justify-between">
53
+ <p class="text-sm font-semibold">Columns:</p>
54
+ <!-- <button type="button" (click)="addColumn()" class="custom-save-button">Add Column</button> -->
55
+ </div>
56
+
57
+ <div class="w-full overflow-x-auto">
58
+ <form [formGroup]="dynamicForm" (ngSubmit)="onSubmit()">
59
+ <!-- Flex container with nowrap to keep all columns in a single row -->
60
+ <div formArrayName="columns" class="flex gap-4 flex-nowrap whitespace-nowrap">
61
+ <div *ngFor="let column of columns.controls; let i = index" [formGroupName]="i"
62
+ class="border p-4 rounded-lg min-w-[20rem] flex-shrink-0 card-width">
63
+ <div class="top-2 right-2 flex gap-2 justify-end">
64
+ <button type="button" (click)="duplicateColumn(i)"
65
+ class="bg-green-500 text-white px-3 py-1 rounded-md hover:bg-green-600">
66
+
67
+ </button>
68
+ <button type="button" (click)="removeColumn(i)"
69
+ class="text-white px-3 py-1 rounded-md hover:bg-red-600" *ngIf="columns.length>1">
70
+
71
+ </button>
72
+ </div>
73
+ <!-- Columns in a Single Row -->
74
+ <div class="grid grid-cols-1 gap-4 items-center mb-2">
75
+ <div class="col-span-3">
76
+ <label class="font-semibold">Column Name:</label>
77
+ <input formControlName="header" placeholder="Enter Column Name"
78
+ class="w-full border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
79
+ </div>
80
+ <div class="col-span-3">
81
+ <label class="font-semibold">Column Type:</label>
82
+ <select formControlName="cellType" class="w-full border rounded-md px-3 py-2">
83
+ <option *ngFor="let type of columnTypes" [value]="type">{{ type }}</option>
84
+ </select>
85
+ </div>
86
+ @if (enableAPI) {
87
+ <div class="col-span-3">
88
+ <label class="font-semibold">API Value Key:</label>
89
+ <input formControlName="apiKey" placeholder="Enter Value Key"
90
+ class="w-full border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
91
+ </div>
92
+ }
93
+
94
+ </div>
95
+ <div *ngIf="['radio-group', 'dropdown'].includes(column.value.cellType)" class="mt-2">
96
+
97
+ <label class="font-semibold">Options:</label>
98
+
99
+ <div formArrayName="options">
100
+ <div *ngFor="let option of getOptions(i).controls; let j = index" [formGroupName]="j"
101
+ class="grid grid-cols-1 gap-4 items-center mt-2">
102
+ <input formControlName="optionName" placeholder="Enter Option Name"
103
+ class="col-span-4 border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
104
+ <input formControlName="optionValue" placeholder="Enter Option Value"
105
+ class="col-span-4 border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
106
+ <button type="button" (click)="getOptions(i).removeAt(j)"
107
+ class="col-span-2 bg-red-500 text-white px-2 py-1 rounded-md hover:bg-red-600">
108
+ Remove
109
+ </button>
110
+ </div>
111
+ </div>
112
+ <button type="button" (click)="addOption(i)" class="custom-save-button justify-end">Add Option</button>
113
+ </div>
114
+
115
+
116
+ <div *ngIf="['smart-dropdown'].includes(column.value.cellType)" class="grid grid-cols-1 gap-4 mt-4">
117
+ <div class="col-span-4">
118
+ <label class="font-semibold">API Url:</label>
119
+ <input formControlName="apiUrl" placeholder="Enter API URL"
120
+ class="w-full border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
121
+ </div>
122
+ <div class="col-span-4">
123
+ <label class="font-semibold">Value Key:</label>
124
+ <input formControlName="valueKey" placeholder="Enter Value Key"
125
+ class="w-full border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
126
+ </div>
127
+ <div class="col-span-4">
128
+ <label class="font-semibold">Label Key:</label>
129
+ <input formControlName="labelKey" placeholder="Enter Label Key"
130
+ class="w-full border rounded-md px-3 py-2 focus:ring focus:ring-blue-200" />
131
+ </div>
132
+ </div>
133
+
134
+ </div>
135
+ </div>
136
+ </form>
137
+ </div>
138
+
139
+
140
+
141
+
142
+ </div>
143
+
144
+ </div>
145
+
146
+
147
+
148
+ <ng-template pTemplate="footer">
149
+ <!-- <hr class="mt-3 mx-2 mb-0 opacity-10"> -->
150
+ <!-- <div class="flex justify-end gap-4 w-full">
151
+ <p-button label="Cancel" severity="secondary" (click)="closeDialog()" />
152
+ <p-button styleClass="border border-indigo-600" label="Save" (click)="saveConfiguration()" />
153
+ </div> -->
154
+ <div class="flex justify-center my-3">
155
+ <p-button label="Cancel" severity="secondary" (click)="closeDialog()"
156
+ styleClass="border-gray-400" />
157
+ <p-button label="Attach" label="Save" (click)="saveConfiguration()"
158
+ styleClass="cta_buttons text-medium button_text_white secondary-color border-1 stroke_secondary no_hightlight no_hightlight_stroke h-max mr-2 w-6rem custom-save-button"
159
+ />
160
+ </div>
161
+ </ng-template>
162
+ </p-dialog>
@@ -0,0 +1,120 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
3
+ import { ButtonModule } from 'primeng/button';
4
+ import { DialogModule } from 'primeng/dialog';
5
+ import { InputTextModule } from 'primeng/inputtext';
6
+ import { DropdownModule } from 'primeng/dropdown';
7
+ import { FormArray, FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
8
+
9
+ @Component({
10
+ selector: 'fx-configuration-panel',
11
+ standalone: true,
12
+ imports: [CommonModule, ReactiveFormsModule, ButtonModule, DialogModule, InputTextModule, FormsModule, DropdownModule, ButtonModule],
13
+ templateUrl: './configuration-panel.component.html',
14
+ styleUrl: './configuration-panel.component.css',
15
+ })
16
+ export class ConfigurationPanelComponent implements OnInit{
17
+ @Input() visible: boolean = false;
18
+ @Output() isVisible = new EventEmitter<boolean>();
19
+ @Output() configuration = new EventEmitter<any>();
20
+
21
+ public rows: number = 1;
22
+ public enableAPI: boolean = false;
23
+ public api: string = '';
24
+
25
+ public dynamicForm: FormGroup;
26
+ public columnTypes: string[] = ['text', 'input-text', 'input-number', 'dropdown', 'smart-dropdown', 'checkbox', 'radio', 'radio-group', 'file-upload', 'textarea'];
27
+
28
+ constructor(private fb: FormBuilder) {
29
+ this.dynamicForm = this.fb.group({
30
+ columns: this.fb.array([])
31
+ });
32
+ }
33
+ ngOnInit(): void {
34
+ this.addColumn();
35
+ }
36
+
37
+ get columns(): FormArray {
38
+ return this.dynamicForm.get('columns') as FormArray;
39
+ }
40
+
41
+ // **🔹 Add Column Dynamically**
42
+ public addColumn(): void {
43
+ const columnFormGroup = this.fb.group({
44
+ header: ['', Validators.required],
45
+ cellType: ['', Validators.required],
46
+ placeholder: '',
47
+ options: this.fb.array([]),
48
+ apiUrl: '',
49
+ valueKey: '',
50
+ labelKey: '',
51
+ className: '',
52
+ apiKey: ''
53
+ });
54
+ this.columns.push(columnFormGroup);
55
+ }
56
+
57
+
58
+ public removeColumn(index: number): void {
59
+ if (this.columns.length > 1) {
60
+ this.columns.removeAt(index);
61
+ }
62
+ }
63
+
64
+ // **🔹 Duplicate Column**
65
+ public duplicateColumn(index: number): void {
66
+ const currentColumn = this.columns.at(index).value;
67
+ const duplicateColumn = this.fb.group({
68
+ header: [currentColumn.header, Validators.required],
69
+ cellType: [currentColumn.cellType, Validators.required],
70
+ placeholder: [currentColumn.placeholder],
71
+ apiUrl: [currentColumn.apiUrl],
72
+ valueKey: [currentColumn.valueKey],
73
+ labelKey: [currentColumn.labelKey],
74
+ className: [currentColumn.className],
75
+ apiKey: [currentColumn.apiKey],
76
+ options: this.fb.array(
77
+ currentColumn.options.map((option: any) => this.fb.group({
78
+ optionName: [option.optionName, Validators.required],
79
+ optionValue: [option.optionValue, Validators.required]
80
+ }))
81
+ )
82
+ });
83
+ this.columns.insert(index + 1, duplicateColumn);
84
+ }
85
+
86
+ // **🔹 Add Options Dynamically**
87
+ public addOption(columnIndex: number): void {
88
+ const optionGroup = this.fb.group({
89
+ optionName: ['', Validators.required],
90
+ optionValue: ['', Validators.required]
91
+ });
92
+
93
+ this.getOptions(columnIndex).push(optionGroup);
94
+ }
95
+
96
+ // **🔹 Get Options FormArray for a Specific Column**
97
+ public getOptions(columnIndex: number): FormArray {
98
+ return this.columns.at(columnIndex).get('options') as FormArray;
99
+ }
100
+
101
+ // **🔹 Close Dialog**
102
+ public closeDialog(): void {
103
+ this.isVisible.emit(false);
104
+ }
105
+
106
+ // **🔹 Save Configuration**
107
+ public saveConfiguration(): void {
108
+ this.configuration.emit({
109
+ rows: this.rows,
110
+ columns: this.dynamicForm.value?.columns,
111
+ enableAPI: this.enableAPI,
112
+ api: this.api
113
+ });
114
+ this.isVisible.emit(false);
115
+ }
116
+
117
+ public onSubmit(): void {
118
+ console.log("Value columns formArray", this.dynamicForm.value);
119
+ }
120
+ }
@@ -0,0 +1,30 @@
1
+ .fx-element {
2
+ position: relative;
3
+ }
4
+
5
+ .fx-element .fx-overlay {
6
+ position: absolute;
7
+ top: 0;
8
+ left: 0;
9
+ width: 100%;
10
+ height: 100%;
11
+ background: rgba(0, 0, 0, 0.1); /* Light gray with 0.5 transparency */
12
+ z-index: -1; /* Place it below the content by default */
13
+ pointer-events: none; /* Allow interaction with the underlying content */
14
+ opacity: 0; /* Initially hidden */
15
+ }
16
+
17
+ .fx-element:hover .fx-overlay {
18
+ z-index: 1; /* Bring the overlay above content */
19
+ opacity: 1; /* Make the overlay visible */
20
+ pointer-events: auto; /* Allow interaction with the overlay */
21
+ }
22
+
23
+ .fx-element:hover .fx-overlay .fx-actions{
24
+ position: absolute;
25
+ margin-top: -26px;
26
+ height: 25px;
27
+ border-top-right-radius: 10px;
28
+ width: 100%;
29
+ border-top-left-radius: 10px;
30
+ }
@@ -0,0 +1,28 @@
1
+ <fx-configuration-panel [visible]="visible" (isVisible)="visible = $event" (configuration)="configuration.emit($event)"></fx-configuration-panel>
2
+
3
+ <div class="fx-element">
4
+ <ng-content></ng-content>
5
+ <ng-container *ngIf="fxData.$fxForm?.$mode !== FxMode.VIEW">
6
+ <div class="fx-overlay border-gray-400 border rounded cursor-pointer" (click)="onElementSelect(fxData)"
7
+ (dblclick)="openSettingDialog()">
8
+ <div class="fx-actions flex justify-between">
9
+
10
+ <div class="bg-gray-700 text-gray-300 px-2 rounded-t ml-2 text-xs flex justify-center items-center">
11
+ <div>#{{ fxData.name }}-<span class="text-xs italic">{{ fxData.id }}</span></div>
12
+ </div>
13
+
14
+ <div class="flex justify-around items-end mr-2">
15
+ <div class="cursor-pointer bg-secondary text-white w-8 mr-1 text-center rounded-t" title="Settings"
16
+ (click)="fxSettingService.openSetting(fxData)">
17
+ <i class="fa fa-cog text-xs"></i>
18
+ </div>
19
+ <div (click)="deleteElement(fxData)"
20
+ class="cursor-pointer bg-red-600 text-white w-8 mr-1 text-center rounded-t" title="Delete">
21
+ <i class="fa fa-times text-xs"></i>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <ng-container #dynamicComponentContainer></ng-container>
27
+ </ng-container>
28
+ </div>
@@ -0,0 +1,23 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectorRef, Component, EventEmitter, inject, Input, OnInit, Output, ViewChild, ViewContainerRef } from '@angular/core';
3
+ import { FxComponent, FxData, FxMode, FxSettingComponent, FxSettingsService, FxUtils } from '@instantsys-labs/fx';
4
+ import { Dialog } from 'primeng/dialog';
5
+ import { ButtonModule } from 'primeng/button';
6
+ import { InputTextModule } from 'primeng/inputtext';
7
+ import { ConfigurationPanelComponent } from '../configuration-panel/configuration-panel.component';
8
+
9
+ @Component({
10
+ selector: 'fx-settings-panel',
11
+ standalone: true,
12
+ imports: [CommonModule, ButtonModule, InputTextModule, ConfigurationPanelComponent],
13
+ templateUrl: './settings-panel.component.html',
14
+ styleUrl: './settings-panel.component.css'
15
+ })
16
+ export class SettingsPanelComponent extends FxComponent implements OnInit {
17
+ @Output() configuration = new EventEmitter<any>();
18
+ public visible: boolean = false;
19
+
20
+ public openSettingDialog(): void {
21
+ this.visible = true;
22
+ }
23
+ }
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Public API Surface of fx-builder-wrapper
3
+ */
4
+
5
+ export * from './lib/fx-builder-wrapper.service';
6
+ export * from './lib/fx-builder-wrapper.component'; // builder // admin
7
+ export * from './lib/components/fx-form-component/fx-form-component.component'; // form preview
8
+
@@ -0,0 +1,15 @@
1
+ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
+ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
+ {
4
+ "extends": "../../tsconfig.json",
5
+ "compilerOptions": {
6
+ "outDir": "../../out-tsc/lib",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "inlineSources": true,
10
+ "types": []
11
+ },
12
+ "exclude": [
13
+ "**/*.spec.ts"
14
+ ]
15
+ }
@@ -0,0 +1,13 @@
1
+ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
+ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
+ {
4
+ "extends": "./tsconfig.lib.json",
5
+ "compilerOptions": {
6
+ "declarationMap": false
7
+ },
8
+ "angularCompilerOptions": {
9
+ "compilationMode": "partial",
10
+ "enableIvy": true,
11
+ "fullTemplateTypeCheck": true
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
+ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
+ {
4
+ "extends": "../../tsconfig.json",
5
+ "compilerOptions": {
6
+ "outDir": "../../out-tsc/spec",
7
+ "types": [
8
+ "jasmine"
9
+ ]
10
+ },
11
+ "include": [
12
+ "**/*.spec.ts",
13
+ "**/*.d.ts"
14
+ ]
15
+ }
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- export * from './public-api';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZngtZm9ybS1idWlsZGVyLXdyYXBwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9meC1idWlsZGVyLXdyYXBwZXIvc3JjL2Z4LWZvcm0tYnVpbGRlci13cmFwcGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0=