mstate-angular 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/ng-package.json +7 -0
- package/package.json +14 -0
- package/src/lib/action-form/action-form.component.html +13 -0
- package/src/lib/action-form/action-form.component.scss +0 -0
- package/src/lib/action-form/action-form.component.spec.ts +23 -0
- package/src/lib/action-form/action-form.component.ts +124 -0
- package/src/lib/common/constant.ts +4 -0
- package/src/lib/common/enum.ts +46 -0
- package/src/lib/components/action-card/action-card.component.html +1 -0
- package/src/lib/components/action-card/action-card.component.scss +0 -0
- package/src/lib/components/action-card/action-card.component.spec.ts +21 -0
- package/src/lib/components/action-card/action-card.component.ts +21 -0
- package/src/lib/components/button/button.component.html +3 -0
- package/src/lib/components/button/button.component.scss +0 -0
- package/src/lib/components/button/button.component.spec.ts +21 -0
- package/src/lib/components/button/button.component.ts +11 -0
- package/src/lib/components/dropdown/dropdown.component.html +10 -0
- package/src/lib/components/dropdown/dropdown.component.scss +0 -0
- package/src/lib/components/dropdown/dropdown.component.spec.ts +21 -0
- package/src/lib/components/dropdown/dropdown.component.ts +46 -0
- package/src/lib/components/input-field/input-field.component.html +9 -0
- package/src/lib/components/input-field/input-field.component.scss +0 -0
- package/src/lib/components/input-field/input-field.component.spec.ts +21 -0
- package/src/lib/components/input-field/input-field.component.ts +16 -0
- package/src/lib/components/loader/loader.component.html +1 -0
- package/src/lib/components/loader/loader.component.scss +0 -0
- package/src/lib/components/loader/loader.component.spec.ts +21 -0
- package/src/lib/components/loader/loader.component.ts +11 -0
- package/src/lib/components/select/select.component.html +10 -0
- package/src/lib/components/select/select.component.scss +43 -0
- package/src/lib/components/select/select.component.spec.ts +21 -0
- package/src/lib/components/select/select.component.ts +46 -0
- package/src/lib/input-selector/input-selector.component.html +23 -0
- package/src/lib/input-selector/input-selector.component.scss +0 -0
- package/src/lib/input-selector/input-selector.component.spec.ts +21 -0
- package/src/lib/input-selector/input-selector.component.ts +38 -0
- package/src/lib/interfaces/api.interface.ts +51 -0
- package/src/lib/interfaces/interface.ts +81 -0
- package/src/lib/material.scss +439 -0
- package/src/lib/mstate-angular/mstate-angular.component.html +40 -0
- package/src/lib/mstate-angular/mstate-angular.component.scss +36 -0
- package/src/lib/mstate-angular/mstate-angular.component.spec.ts +21 -0
- package/src/lib/mstate-angular/mstate-angular.component.ts +186 -0
- package/src/lib/mstate-angular.helper.ts +35 -0
- package/src/lib/mstate-angular.module.ts +9 -0
- package/src/lib/mstate-angular.service.ts +77 -0
- package/src/public-api.ts +6 -0
- package/tsconfig.lib.json +14 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# MstateAngular
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project mstate-angular` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project mstate-angular`.
|
|
8
|
+
> Note: Don't forget to add `--project mstate-angular` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build mstate-angular` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build mstate-angular`, go to the dist folder `cd dist/mstate-angular` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test mstate-angular` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
package/ng-package.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mstate-angular",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^17.3.0",
|
|
6
|
+
"@angular/core": "^17.3.0",
|
|
7
|
+
"@ng-select/ng-select": "^14.1.0",
|
|
8
|
+
"axios": "^1.7.9"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tslib": "^2.3.0"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<h4>{{ config.meta?.title ?? config.name }}</h4>
|
|
3
|
+
|
|
4
|
+
<form #userForm="ngForm">
|
|
5
|
+
@for (step of config.steps; track $index) {
|
|
6
|
+
<mobi-office-input-selector [step]="step" [mstateModel]="mstateModel" />
|
|
7
|
+
}
|
|
8
|
+
</form>
|
|
9
|
+
|
|
10
|
+
<mobi-office-button (click)="handleExecuteAction()"
|
|
11
|
+
>Submit</mobi-office-button
|
|
12
|
+
>
|
|
13
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { ActionFormComponent } from './action-form.component';
|
|
4
|
+
|
|
5
|
+
describe('ActionFormComponent', () => {
|
|
6
|
+
let component: ActionFormComponent;
|
|
7
|
+
let fixture: ComponentFixture<ActionFormComponent>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
imports: [ActionFormComponent]
|
|
12
|
+
})
|
|
13
|
+
.compileComponents();
|
|
14
|
+
|
|
15
|
+
fixture = TestBed.createComponent(ActionFormComponent);
|
|
16
|
+
component = fixture.componentInstance;
|
|
17
|
+
fixture.detectChanges();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should create', () => {
|
|
21
|
+
expect(component).toBeTruthy();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
Input,
|
|
4
|
+
OnChanges,
|
|
5
|
+
OnInit,
|
|
6
|
+
SimpleChanges,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
import { MstateAngularService } from '../mstate-angular.service';
|
|
9
|
+
import { catchError, finalize } from 'rxjs';
|
|
10
|
+
import { ActionConfig, UserInput } from '../interfaces/interface';
|
|
11
|
+
import { EvaluatedAction } from '../interfaces/api.interface';
|
|
12
|
+
import { ActionType, ManualStepModule } from '../common/enum';
|
|
13
|
+
import { InputSelectorComponent } from '../input-selector/input-selector.component';
|
|
14
|
+
import { ButtonComponent } from '../components/button/button.component';
|
|
15
|
+
import { FormsModule } from '@angular/forms';
|
|
16
|
+
import { MstateAngularHelper } from '../mstate-angular.helper';
|
|
17
|
+
|
|
18
|
+
@Component({
|
|
19
|
+
selector: 'lib-action-form',
|
|
20
|
+
standalone: true,
|
|
21
|
+
imports: [FormsModule, InputSelectorComponent, ButtonComponent],
|
|
22
|
+
providers: [MstateAngularService, MstateAngularHelper],
|
|
23
|
+
templateUrl: './action-form.component.html',
|
|
24
|
+
styleUrl: './action-form.component.scss',
|
|
25
|
+
})
|
|
26
|
+
export class ActionFormComponent implements OnInit, OnChanges {
|
|
27
|
+
@Input({ required: true }) token: string = '';
|
|
28
|
+
@Input({ required: true }) workflow: string = '';
|
|
29
|
+
@Input({ required: true }) config: ActionConfig | EvaluatedAction = {
|
|
30
|
+
name: '',
|
|
31
|
+
type: ActionType.MANUAL,
|
|
32
|
+
steps: [],
|
|
33
|
+
};
|
|
34
|
+
@Input({ required: true }) onExecuteAction: (
|
|
35
|
+
response: any,
|
|
36
|
+
errors?: string[]
|
|
37
|
+
) => void = () => {};
|
|
38
|
+
@Input() updateCustomFieldValue?: (key: string) => unknown;
|
|
39
|
+
|
|
40
|
+
@Input() instanceID?: string;
|
|
41
|
+
@Input() onSuccess?: (actionName: string) => void;
|
|
42
|
+
|
|
43
|
+
//#region Custom Declaration
|
|
44
|
+
protected isLoading = true;
|
|
45
|
+
protected mstateModel: any = {};
|
|
46
|
+
|
|
47
|
+
constructor(
|
|
48
|
+
private mstateAngularService: MstateAngularService,
|
|
49
|
+
private mstateAngularHelper: MstateAngularHelper
|
|
50
|
+
) {}
|
|
51
|
+
|
|
52
|
+
ngOnInit(): void {
|
|
53
|
+
if (Boolean(this.config?.steps?.length) === false) {
|
|
54
|
+
this.handleExecuteAction();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.handleStepConfigFilter();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
ngOnChanges(changes: SimpleChanges): void {
|
|
62
|
+
console.log({ changes });
|
|
63
|
+
if (this.mstateAngularHelper.detectChange(changes, ['mstateModel'])) {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//#region handlers
|
|
68
|
+
|
|
69
|
+
protected handleExecuteAction() {
|
|
70
|
+
this.isLoading = true;
|
|
71
|
+
console.log(this.mstateModel);
|
|
72
|
+
// this.mstateAngularService
|
|
73
|
+
// .executeAction({
|
|
74
|
+
// action: {
|
|
75
|
+
// name: this.config.name,
|
|
76
|
+
// payload: this.mstateModel,
|
|
77
|
+
// },
|
|
78
|
+
// token: this.token,
|
|
79
|
+
// workflow: this.workflow,
|
|
80
|
+
// })
|
|
81
|
+
// .pipe(
|
|
82
|
+
// catchError(e => {
|
|
83
|
+
// throw e;
|
|
84
|
+
// }),
|
|
85
|
+
// finalize(() => {
|
|
86
|
+
// this.isLoading = false;
|
|
87
|
+
// })
|
|
88
|
+
// )
|
|
89
|
+
// .subscribe(data => {
|
|
90
|
+
// this.onExecuteAction(data.data);
|
|
91
|
+
// });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private handleStepConfigFilter = () => {
|
|
95
|
+
const keyForAPISet = new Set();
|
|
96
|
+
|
|
97
|
+
this.config.steps = this.config?.steps?.filter(stepConfig => {
|
|
98
|
+
const step = stepConfig as UserInput;
|
|
99
|
+
|
|
100
|
+
switch (step?.module) {
|
|
101
|
+
case ManualStepModule.CUSTOM_FIELD: {
|
|
102
|
+
if (this.updateCustomFieldValue) {
|
|
103
|
+
this.mstateModel[step?.context?.as] = this.updateCustomFieldValue(
|
|
104
|
+
step?.context?.key
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case ManualStepModule.CONTEXT_FIELD:
|
|
111
|
+
this.mstateModel[step?.context?.as] = step?.context?.value;
|
|
112
|
+
return true;
|
|
113
|
+
|
|
114
|
+
default: {
|
|
115
|
+
const isDuplicate = keyForAPISet.has(step?.field?.keyForAPI);
|
|
116
|
+
keyForAPISet.add(step?.field?.keyForAPI);
|
|
117
|
+
return isDuplicate === false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}) as UserInput[];
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
//#endregion
|
|
124
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export enum Route {
|
|
2
|
+
EXECUTE_ACTION = 'workflow/v2/execute',
|
|
3
|
+
GET_WORKFLOW_CONFIG = 'workflow/config',
|
|
4
|
+
GET_CURRENT_ACTIONS_WITHOUT_INSTANCE = 'workflow/v2/actions',
|
|
5
|
+
GET_CURRENT_ACTIONS_WITH_INSTANCE = 'workflow/actions',
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export enum FieldType {
|
|
9
|
+
DATE_PICKER = 'datePicker',
|
|
10
|
+
TIME_PICKER = 'timePicker',
|
|
11
|
+
INPUT_FIELD = 'inputField',
|
|
12
|
+
TEXT_AREA = 'textArea',
|
|
13
|
+
CHECKBOX = 'checkBox',
|
|
14
|
+
RADIO_LIST = 'radioList',
|
|
15
|
+
DROP_DOWN = 'dropDown',
|
|
16
|
+
SUMMARY = 'summary',
|
|
17
|
+
CONTEXT_FIELD = 'CONTEXT_FIELD',
|
|
18
|
+
CUSTOM_FIELD = 'CUSTOM_FIELD',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export enum ManualStepModule {
|
|
22
|
+
CONTEXT_FIELD = 'CONTEXT_FIELD',
|
|
23
|
+
CUSTOM_FIELD = 'CUSTOM_FIELD',
|
|
24
|
+
USER_INPUT = 'USER_INPUT',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export enum Theme {
|
|
28
|
+
DARK = 'dark',
|
|
29
|
+
LIGHT = 'light',
|
|
30
|
+
SYSTEM = 'system',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export enum Variable {
|
|
34
|
+
WORKFLOW = 'workflow',
|
|
35
|
+
TOKEN = 'token',
|
|
36
|
+
INSTANCE_ID = 'instanceID',
|
|
37
|
+
START = 'start',
|
|
38
|
+
TRIGGER_AGAIN = 'triggerAgain',
|
|
39
|
+
ERRORS = 'errors',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export enum ActionType {
|
|
43
|
+
MANUAL = 'MANUAL',
|
|
44
|
+
AUTO = 'AUTO',
|
|
45
|
+
CHAINED = 'CHAINED',
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>action-card works!</p>
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { ActionCardComponent } from './action-card.component';
|
|
3
|
+
|
|
4
|
+
describe('ActionCardComponent', () => {
|
|
5
|
+
let component: ActionCardComponent;
|
|
6
|
+
let fixture: ComponentFixture<ActionCardComponent>;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await TestBed.configureTestingModule({
|
|
10
|
+
imports: [ActionCardComponent],
|
|
11
|
+
}).compileComponents();
|
|
12
|
+
|
|
13
|
+
fixture = TestBed.createComponent(ActionCardComponent);
|
|
14
|
+
component = fixture.componentInstance;
|
|
15
|
+
fixture.detectChanges();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should create', () => {
|
|
19
|
+
expect(component).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { EvaluatedAction } from '../../interfaces/api.interface';
|
|
4
|
+
import { ActionConfig } from '../../interfaces/interface';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'mobi-office-action-card',
|
|
8
|
+
standalone: true,
|
|
9
|
+
imports: [CommonModule],
|
|
10
|
+
templateUrl: './action-card.component.html',
|
|
11
|
+
styleUrl: './action-card.component.scss',
|
|
12
|
+
})
|
|
13
|
+
export class ActionCardComponent {
|
|
14
|
+
@Input({ required: true }) error?: EvaluatedAction | ActionConfig;
|
|
15
|
+
|
|
16
|
+
@Output() retryEmitter = new EventEmitter<EvaluatedAction | ActionConfig>();
|
|
17
|
+
|
|
18
|
+
handleRetry() {
|
|
19
|
+
this.retryEmitter.emit(this.error);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { ButtonComponent } from './button.component';
|
|
3
|
+
|
|
4
|
+
describe('ButtonComponent', () => {
|
|
5
|
+
let component: ButtonComponent;
|
|
6
|
+
let fixture: ComponentFixture<ButtonComponent>;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await TestBed.configureTestingModule({
|
|
10
|
+
imports: [ButtonComponent],
|
|
11
|
+
}).compileComponents();
|
|
12
|
+
|
|
13
|
+
fixture = TestBed.createComponent(ButtonComponent);
|
|
14
|
+
component = fixture.componentInstance;
|
|
15
|
+
fixture.detectChanges();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should create', () => {
|
|
19
|
+
expect(component).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'mobi-office-button',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
templateUrl: './button.component.html',
|
|
9
|
+
styleUrl: './button.component.scss',
|
|
10
|
+
})
|
|
11
|
+
export class ButtonComponent {}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<div class="form-group">
|
|
2
|
+
<ng-select
|
|
3
|
+
[items]="list"
|
|
4
|
+
[multiple]="config.field.placeholder"
|
|
5
|
+
[bindLabel]="this.config.field.mapper?.label ?? 'label'"
|
|
6
|
+
[placeholder]="config.field.placeholder"
|
|
7
|
+
[(ngModel)]="mstateModel[config.field.keyForAPI]"
|
|
8
|
+
>
|
|
9
|
+
</ng-select>
|
|
10
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { DropdownComponent } from './dropdown.component';
|
|
3
|
+
|
|
4
|
+
describe('DropdownComponent', () => {
|
|
5
|
+
let component: DropdownComponent;
|
|
6
|
+
let fixture: ComponentFixture<DropdownComponent>;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await TestBed.configureTestingModule({
|
|
10
|
+
imports: [DropdownComponent],
|
|
11
|
+
}).compileComponents();
|
|
12
|
+
|
|
13
|
+
fixture = TestBed.createComponent(DropdownComponent);
|
|
14
|
+
component = fixture.componentInstance;
|
|
15
|
+
fixture.detectChanges();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should create', () => {
|
|
19
|
+
expect(component).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Component, Input, OnInit } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { UserInput } from '../../interfaces/interface';
|
|
4
|
+
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { MstateAngularService } from '../../mstate-angular.service';
|
|
6
|
+
import { MstateAngularHelper } from '../../mstate-angular.helper';
|
|
7
|
+
import { NgSelectModule } from '@ng-select/ng-select';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'mobi-office-dropdown',
|
|
11
|
+
standalone: true,
|
|
12
|
+
imports: [FormsModule, NgSelectModule, CommonModule],
|
|
13
|
+
providers: [MstateAngularService],
|
|
14
|
+
templateUrl: './dropdown.component.html',
|
|
15
|
+
styleUrl: './dropdown.component.scss',
|
|
16
|
+
})
|
|
17
|
+
export class DropdownComponent implements OnInit {
|
|
18
|
+
@Input({ required: true }) config!: UserInput;
|
|
19
|
+
@Input({ required: true }) mstateModel!: any;
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private mstateService: MstateAngularService,
|
|
23
|
+
private mstateHelper: MstateAngularHelper
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
protected list: any[] = [];
|
|
27
|
+
|
|
28
|
+
ngOnInit(): void {
|
|
29
|
+
const field = this.config.field ?? {};
|
|
30
|
+
|
|
31
|
+
if (field.request) {
|
|
32
|
+
this.mstateService
|
|
33
|
+
.handleDropdownAPI(field.request, field?.mapper?.target ?? '')
|
|
34
|
+
.then((data) => {
|
|
35
|
+
this.list = data;
|
|
36
|
+
})
|
|
37
|
+
.catch((e) => console.log(e));
|
|
38
|
+
} else {
|
|
39
|
+
this.list = field.itemList ?? [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getObjectValue(obj: any, target: string) {
|
|
44
|
+
return this.mstateHelper.getObjectValue(obj, target);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { InputFieldComponent } from './input-field.component';
|
|
3
|
+
|
|
4
|
+
describe('InputFieldComponent', () => {
|
|
5
|
+
let component: InputFieldComponent;
|
|
6
|
+
let fixture: ComponentFixture<InputFieldComponent>;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await TestBed.configureTestingModule({
|
|
10
|
+
imports: [InputFieldComponent],
|
|
11
|
+
}).compileComponents();
|
|
12
|
+
|
|
13
|
+
fixture = TestBed.createComponent(InputFieldComponent);
|
|
14
|
+
component = fixture.componentInstance;
|
|
15
|
+
fixture.detectChanges();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should create', () => {
|
|
19
|
+
expect(component).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { UserInput } from '../../interfaces/interface';
|
|
4
|
+
import { FormsModule } from '@angular/forms';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'mobi-office-input-field',
|
|
8
|
+
standalone: true,
|
|
9
|
+
imports: [CommonModule, FormsModule],
|
|
10
|
+
templateUrl: './input-field.component.html',
|
|
11
|
+
styleUrl: './input-field.component.scss',
|
|
12
|
+
})
|
|
13
|
+
export class InputFieldComponent {
|
|
14
|
+
@Input({ required: true }) config!: UserInput;
|
|
15
|
+
@Input({ required: true }) mstateModel!: any;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>Loading...</p>
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { LoaderComponent } from './loader.component';
|
|
3
|
+
|
|
4
|
+
describe('LoaderComponent', () => {
|
|
5
|
+
let component: LoaderComponent;
|
|
6
|
+
let fixture: ComponentFixture<LoaderComponent>;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await TestBed.configureTestingModule({
|
|
10
|
+
imports: [LoaderComponent],
|
|
11
|
+
}).compileComponents();
|
|
12
|
+
|
|
13
|
+
fixture = TestBed.createComponent(LoaderComponent);
|
|
14
|
+
component = fixture.componentInstance;
|
|
15
|
+
fixture.detectChanges();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should create', () => {
|
|
19
|
+
expect(component).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'mobi-office-loader',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
templateUrl: './loader.component.html',
|
|
9
|
+
styleUrl: './loader.component.scss',
|
|
10
|
+
})
|
|
11
|
+
export class LoaderComponent {}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<div class="form-group">
|
|
2
|
+
<ng-select
|
|
3
|
+
[items]="list"
|
|
4
|
+
[multiple]="config.field.placeholder"
|
|
5
|
+
[bindLabel]="this.config.field.mapper?.label ?? 'label'"
|
|
6
|
+
[placeholder]="config.field.placeholder"
|
|
7
|
+
[(ngModel)]="mstateModel[config.field.keyForAPI]"
|
|
8
|
+
>
|
|
9
|
+
</ng-select>
|
|
10
|
+
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.dropdown {
|
|
2
|
+
position: relative;
|
|
3
|
+
width: 300px;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.search-input {
|
|
7
|
+
width: 100%;
|
|
8
|
+
padding: 8px;
|
|
9
|
+
border: 1px solid #ccc;
|
|
10
|
+
border-radius: 4px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.dropdown-menu {
|
|
14
|
+
position: absolute;
|
|
15
|
+
width: 100%;
|
|
16
|
+
max-height: 150px;
|
|
17
|
+
overflow-y: auto;
|
|
18
|
+
background: white;
|
|
19
|
+
border: 1px solid #ccc;
|
|
20
|
+
border-radius: 4px;
|
|
21
|
+
margin-top: 5px;
|
|
22
|
+
z-index: 10;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.dropdown-item {
|
|
26
|
+
padding: 8px;
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.dropdown-item:hover {
|
|
31
|
+
background-color: #f0f0f0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.no-results {
|
|
35
|
+
padding: 8px;
|
|
36
|
+
color: #888;
|
|
37
|
+
text-align: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.selected-option {
|
|
41
|
+
margin-top: 10px;
|
|
42
|
+
font-weight: bold;
|
|
43
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { SelectComponent } from './select.component';
|
|
3
|
+
|
|
4
|
+
describe('SelectComponent', () => {
|
|
5
|
+
let component: SelectComponent;
|
|
6
|
+
let fixture: ComponentFixture<SelectComponent>;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await TestBed.configureTestingModule({
|
|
10
|
+
imports: [SelectComponent],
|
|
11
|
+
}).compileComponents();
|
|
12
|
+
|
|
13
|
+
fixture = TestBed.createComponent(SelectComponent);
|
|
14
|
+
component = fixture.componentInstance;
|
|
15
|
+
fixture.detectChanges();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should create', () => {
|
|
19
|
+
expect(component).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Component, Input, OnInit } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { UserInput } from '../../interfaces/interface';
|
|
4
|
+
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { MstateAngularService } from '../../mstate-angular.service';
|
|
6
|
+
import { MstateAngularHelper } from '../../mstate-angular.helper';
|
|
7
|
+
import { NgSelectModule } from '@ng-select/ng-select';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'mobi-office-select',
|
|
11
|
+
standalone: true,
|
|
12
|
+
imports: [FormsModule, NgSelectModule, CommonModule],
|
|
13
|
+
providers: [MstateAngularService],
|
|
14
|
+
templateUrl: './select.component.html',
|
|
15
|
+
styleUrl: './select.component.scss',
|
|
16
|
+
})
|
|
17
|
+
export class SelectComponent implements OnInit {
|
|
18
|
+
@Input({ required: true }) config!: UserInput;
|
|
19
|
+
@Input({ required: true }) mstateModel!: any;
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private mstateService: MstateAngularService,
|
|
23
|
+
private mstateHelper: MstateAngularHelper
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
protected list: any[] = [];
|
|
27
|
+
|
|
28
|
+
ngOnInit(): void {
|
|
29
|
+
const field = this.config.field ?? {};
|
|
30
|
+
|
|
31
|
+
if (field.request) {
|
|
32
|
+
this.mstateService
|
|
33
|
+
.handleDropdownAPI(field.request, field?.mapper?.target ?? '')
|
|
34
|
+
.then((data) => {
|
|
35
|
+
this.list = data;
|
|
36
|
+
})
|
|
37
|
+
.catch((e) => console.log(e));
|
|
38
|
+
} else {
|
|
39
|
+
this.list = field.itemList ?? [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getObjectValue(obj: any, target: string) {
|
|
44
|
+
return this.mstateHelper.getObjectValue(obj, target);
|
|
45
|
+
}
|
|
46
|
+
}
|