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.
Files changed (51) hide show
  1. package/README.md +24 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +14 -0
  4. package/src/lib/action-form/action-form.component.html +13 -0
  5. package/src/lib/action-form/action-form.component.scss +0 -0
  6. package/src/lib/action-form/action-form.component.spec.ts +23 -0
  7. package/src/lib/action-form/action-form.component.ts +124 -0
  8. package/src/lib/common/constant.ts +4 -0
  9. package/src/lib/common/enum.ts +46 -0
  10. package/src/lib/components/action-card/action-card.component.html +1 -0
  11. package/src/lib/components/action-card/action-card.component.scss +0 -0
  12. package/src/lib/components/action-card/action-card.component.spec.ts +21 -0
  13. package/src/lib/components/action-card/action-card.component.ts +21 -0
  14. package/src/lib/components/button/button.component.html +3 -0
  15. package/src/lib/components/button/button.component.scss +0 -0
  16. package/src/lib/components/button/button.component.spec.ts +21 -0
  17. package/src/lib/components/button/button.component.ts +11 -0
  18. package/src/lib/components/dropdown/dropdown.component.html +10 -0
  19. package/src/lib/components/dropdown/dropdown.component.scss +0 -0
  20. package/src/lib/components/dropdown/dropdown.component.spec.ts +21 -0
  21. package/src/lib/components/dropdown/dropdown.component.ts +46 -0
  22. package/src/lib/components/input-field/input-field.component.html +9 -0
  23. package/src/lib/components/input-field/input-field.component.scss +0 -0
  24. package/src/lib/components/input-field/input-field.component.spec.ts +21 -0
  25. package/src/lib/components/input-field/input-field.component.ts +16 -0
  26. package/src/lib/components/loader/loader.component.html +1 -0
  27. package/src/lib/components/loader/loader.component.scss +0 -0
  28. package/src/lib/components/loader/loader.component.spec.ts +21 -0
  29. package/src/lib/components/loader/loader.component.ts +11 -0
  30. package/src/lib/components/select/select.component.html +10 -0
  31. package/src/lib/components/select/select.component.scss +43 -0
  32. package/src/lib/components/select/select.component.spec.ts +21 -0
  33. package/src/lib/components/select/select.component.ts +46 -0
  34. package/src/lib/input-selector/input-selector.component.html +23 -0
  35. package/src/lib/input-selector/input-selector.component.scss +0 -0
  36. package/src/lib/input-selector/input-selector.component.spec.ts +21 -0
  37. package/src/lib/input-selector/input-selector.component.ts +38 -0
  38. package/src/lib/interfaces/api.interface.ts +51 -0
  39. package/src/lib/interfaces/interface.ts +81 -0
  40. package/src/lib/material.scss +439 -0
  41. package/src/lib/mstate-angular/mstate-angular.component.html +40 -0
  42. package/src/lib/mstate-angular/mstate-angular.component.scss +36 -0
  43. package/src/lib/mstate-angular/mstate-angular.component.spec.ts +21 -0
  44. package/src/lib/mstate-angular/mstate-angular.component.ts +186 -0
  45. package/src/lib/mstate-angular.helper.ts +35 -0
  46. package/src/lib/mstate-angular.module.ts +9 -0
  47. package/src/lib/mstate-angular.service.ts +77 -0
  48. package/src/public-api.ts +6 -0
  49. package/tsconfig.lib.json +14 -0
  50. package/tsconfig.lib.prod.json +10 -0
  51. package/tsconfig.spec.json +14 -0
@@ -0,0 +1,36 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
2
+
3
+ .mstate-angular {
4
+ * {
5
+ font-family: "Poppins", serif;
6
+ }
7
+
8
+ @import ".././material.scss";
9
+
10
+ .logo {
11
+ width: 70%;
12
+ margin: auto;
13
+ max-width: 300px;
14
+ margin-block: 12px;
15
+ }
16
+
17
+ .form-control {
18
+ display: block;
19
+ width: 100%;
20
+ height: calc(1.5em + 0.75rem + 2px);
21
+ padding: 0.375rem 0.75rem;
22
+ font-size: 1rem;
23
+ font-weight: 400;
24
+ line-height: 1.5;
25
+ color: #495057;
26
+ background-color: #fff;
27
+ background-clip: padding-box;
28
+ border: 1px solid #ced4da;
29
+ border-radius: 0.25rem;
30
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
31
+ }
32
+
33
+ .form-group {
34
+ margin-bottom: 1rem;
35
+ }
36
+ }
@@ -0,0 +1,21 @@
1
+ import { ComponentFixture, TestBed } from "@angular/core/testing";
2
+ import { MstateAngularComponent } from "./mstate-angular.component";
3
+
4
+ describe("MstateAngularComponent", () => {
5
+ let component: MstateAngularComponent;
6
+ let fixture: ComponentFixture<MstateAngularComponent>;
7
+
8
+ beforeEach(async () => {
9
+ await TestBed.configureTestingModule({
10
+ imports: [MstateAngularComponent],
11
+ }).compileComponents();
12
+
13
+ fixture = TestBed.createComponent(MstateAngularComponent);
14
+ component = fixture.componentInstance;
15
+ fixture.detectChanges();
16
+ });
17
+
18
+ it("should create", () => {
19
+ expect(component).toBeTruthy();
20
+ });
21
+ });
@@ -0,0 +1,186 @@
1
+ import {
2
+ Component,
3
+ Input,
4
+ OnChanges,
5
+ OnInit,
6
+ SimpleChanges,
7
+ } from '@angular/core';
8
+ import { CommonModule } from '@angular/common';
9
+ import { Theme, Variable } from '../common/enum';
10
+ import { ActionFormComponent } from '../action-form/action-form.component';
11
+ import { MstateAngularHelper } from '../mstate-angular.helper';
12
+ import { MstateAngularService } from '../mstate-angular.service';
13
+ import { catchError, finalize } from 'rxjs';
14
+ import { EvaluatedAction } from '../interfaces/api.interface';
15
+ import { ActionConfig } from '../interfaces/interface';
16
+ import { ActionCardComponent } from '../components/action-card/action-card.component';
17
+ import { LoaderComponent } from '../components/loader/loader.component';
18
+
19
+ @Component({
20
+ selector: 'mstate-angular',
21
+ standalone: true,
22
+ imports: [
23
+ CommonModule,
24
+ ActionFormComponent,
25
+ ActionCardComponent,
26
+ LoaderComponent,
27
+ ],
28
+ providers: [MstateAngularHelper, MstateAngularService],
29
+ templateUrl: './mstate-angular.component.html',
30
+ styleUrl: './mstate-angular.component.scss',
31
+ })
32
+ export class MstateAngularComponent implements OnChanges, OnInit {
33
+ @Input({ required: true }) token: string = '';
34
+ @Input({ required: true }) workflow: string = '';
35
+ @Input() instanceID?: string;
36
+ /**
37
+ * @type {boolean}
38
+ * @default true
39
+ * @description Trigger if to start workflow.
40
+ */
41
+ @Input() start: boolean = true;
42
+ /**
43
+ * @type {'dark' | 'light' | 'system'}
44
+ * @default 'light'
45
+ * @description To change the color theme of mstate.
46
+ */
47
+ @Input() theme?: Theme;
48
+ /**
49
+ * @type {string}
50
+ * @description To Validate who are allowed to perform or see action.
51
+ */
52
+ @Input() who?: string;
53
+ /**
54
+ * Triggers whenever your current workflow moved to other.
55
+ * @param {string} newInstanceID - The new instance ID on which your current workflow moved.
56
+ * @returns {void}.
57
+ */
58
+ @Input() onInstanceChange?: (newInstanceID: string) => void;
59
+ /**
60
+ * Triggers when The Action execution is completed.
61
+ * @param {string} actionName - action name which you have executed at this moment.
62
+ * @returns {void}.
63
+ */
64
+ @Input() onSuccess?: (actionName: string) => void;
65
+ /**
66
+ * Triggers when Error occurs while performing any action.
67
+ * @param {unknown[]} errors - Error response from the api call done by Mstate.
68
+ * @returns {void}.
69
+ */
70
+ @Input() onError?: (errors: unknown[]) => void;
71
+ /**
72
+ * Handles your steps which contain Custom field module.
73
+ * @param {string} key - Which key you expect for getting the value.
74
+ * @returns {unknown} - whatever value you want to save in that custom field.
75
+ */
76
+ @Input() handleCustomField?: (key: string) => unknown;
77
+
78
+ //#region Variables & Events
79
+
80
+ protected isLoading = true;
81
+ protected triggerAgain = false;
82
+ protected errors: any[] = [];
83
+ protected errorMessages: string[] = [];
84
+ protected allowedActions: (EvaluatedAction | ActionConfig)[] = [];
85
+
86
+ constructor(
87
+ private mstateAngularHelper: MstateAngularHelper,
88
+ private mstateAngularService: MstateAngularService
89
+ ) {}
90
+
91
+ ngOnInit(): void {
92
+ if (this.start) this.setAllowedActions();
93
+ }
94
+
95
+ ngOnChanges(changes: SimpleChanges): void {
96
+ if (
97
+ this.mstateAngularHelper.detectChange(changes, [
98
+ Variable.START,
99
+ Variable.TRIGGER_AGAIN,
100
+ ])
101
+ ) {
102
+ if (this.start) this.setAllowedActions();
103
+ }
104
+
105
+ if (this.mstateAngularHelper.detectChange(changes, [Variable.ERRORS])) {
106
+ console.log({ mstateErrors: this.errors });
107
+ this.errorMessages = this.errors.filter((e) => typeof e === 'string');
108
+ }
109
+ }
110
+
111
+ //#endregion
112
+
113
+ //#region Handlers
114
+
115
+ private setAllowedActions() {
116
+ this.isLoading = true;
117
+
118
+ if (this.instanceID) {
119
+ this.mstateAngularService
120
+ .getCurrentActionsWithInstanceID({
121
+ instanceID: this.instanceID,
122
+ token: this.token,
123
+ })
124
+ .pipe(
125
+ catchError((err: any) => {
126
+ console.log(err);
127
+ throw err;
128
+ }),
129
+ finalize(() => {
130
+ this.isLoading = false;
131
+ })
132
+ )
133
+ .subscribe((data) => {
134
+ this.allowedActions = Object.values(data.data);
135
+ });
136
+ } else {
137
+ this.mstateAngularService
138
+ .getCurrentActionsWithoutInstanceID({
139
+ workflow: this.workflow,
140
+ token: this.token,
141
+ })
142
+ .pipe(
143
+ catchError((err: any) => {
144
+ console.log(err);
145
+ throw err;
146
+ }),
147
+ finalize(() => {
148
+ this.isLoading = false;
149
+ })
150
+ )
151
+ .subscribe((data) => {
152
+ this.allowedActions = Object.values(data.data);
153
+ });
154
+ }
155
+ }
156
+
157
+ handleExecuteAction(value: any, errors?: string[]) {
158
+ if (errors?.length) {
159
+ this.errors = errors;
160
+ value.instanceID = errors[0]
161
+ ?.split("instanceID='")
162
+ ?.pop()
163
+ ?.replace("'", '');
164
+ } else {
165
+ this.allowedActions = value.actions;
166
+ }
167
+
168
+ if (
169
+ value?.instanceID &&
170
+ value?.instanceID !== this.instanceID &&
171
+ !errors?.length
172
+ ) {
173
+ this.instanceID = value?.instanceID;
174
+
175
+ if (this.onInstanceChange) {
176
+ this.onInstanceChange(value?.instanceID);
177
+ }
178
+ }
179
+ }
180
+
181
+ handleError(config: ActionConfig) {
182
+ this.allowedActions = [config];
183
+ }
184
+
185
+ //#endregion
186
+ }
@@ -0,0 +1,35 @@
1
+ import { Injectable, SimpleChanges } from '@angular/core';
2
+ import { Step, UserInput } from './interfaces/interface';
3
+
4
+ @Injectable({
5
+ providedIn: 'root',
6
+ })
7
+ export class MstateAngularHelper {
8
+ detectChange(change: SimpleChanges, keys: string[]) {
9
+ for (const key of keys) {
10
+ if (change[key] && change[key].currentValue !== change[key].previousValue)
11
+ return true;
12
+ }
13
+
14
+ return false;
15
+ }
16
+
17
+ formatString(str: string = '') {
18
+ return str.toUpperCase().replace(/_/gi, ' ');
19
+ }
20
+
21
+ getObjectValue<T>(obj: any, target: string) {
22
+ const keys = target ? target.split('.') : [];
23
+
24
+ let cur: any = obj;
25
+ for (const key of keys) {
26
+ cur = cur?.[key];
27
+ }
28
+
29
+ return cur as T | undefined;
30
+ }
31
+
32
+ checkIsStep(step: Step | UserInput): step is Step {
33
+ return (step as Step)?.config !== undefined;
34
+ }
35
+ }
@@ -0,0 +1,9 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { MstateAngularComponent } from './mstate-angular/mstate-angular.component';
4
+
5
+ @NgModule({
6
+ imports: [CommonModule, MstateAngularComponent], // Import other necessary modules like CommonModule
7
+ exports: [MstateAngularComponent], // Export the pipe so it can be used externally
8
+ })
9
+ export class MstateAngularModule {}
@@ -0,0 +1,77 @@
1
+ import { HttpClient, HttpHeaders } from '@angular/common/http';
2
+ import { Injectable } from '@angular/core';
3
+ import { MSTATE_URL, TOKEN_KEY } from './common/constant';
4
+ import { Route } from './common/enum';
5
+
6
+ import {
7
+ GetCurrentActionsWithInstanceIDRequest,
8
+ GetCurrentActionsWithoutInstanceIDRequest,
9
+ GetCurrentActionsWithoutInstanceIDResponse,
10
+ MstateResponse,
11
+ PostExecuteActionRequest,
12
+ PostExecuteActionResponse,
13
+ } from './interfaces/api.interface';
14
+ import axios, { AxiosRequestConfig } from 'axios';
15
+ import { ListMapper } from './interfaces/interface';
16
+ import { MstateAngularHelper } from './mstate-angular.helper';
17
+
18
+ @Injectable({
19
+ providedIn: 'root',
20
+ })
21
+ export class MstateAngularService {
22
+ private getHeaders(token: string) {
23
+ return new HttpHeaders({
24
+ 'Content-Type': 'application/json',
25
+ [TOKEN_KEY]: token,
26
+ });
27
+ }
28
+
29
+ constructor(
30
+ private http: HttpClient,
31
+ private mstateHelper: MstateAngularHelper
32
+ ) {}
33
+
34
+ executeAction<T>(payload: PostExecuteActionRequest<T>) {
35
+ return this.http.post<MstateResponse<PostExecuteActionResponse>>(
36
+ `${MSTATE_URL}/${Route.EXECUTE_ACTION}`,
37
+ {
38
+ instanceID: payload.instanceID ?? '',
39
+ name: payload.workflow,
40
+ action: payload.action,
41
+ },
42
+ { headers: this.getHeaders(payload.token) }
43
+ );
44
+ }
45
+
46
+ getCurrentActionsWithInstanceID(
47
+ payload: GetCurrentActionsWithInstanceIDRequest
48
+ ) {
49
+ return this.http.get<
50
+ MstateResponse<GetCurrentActionsWithoutInstanceIDResponse>
51
+ >(
52
+ `${MSTATE_URL}/${Route.GET_CURRENT_ACTIONS_WITH_INSTANCE}/${payload.instanceID}`,
53
+ {
54
+ headers: this.getHeaders(payload.token),
55
+ }
56
+ );
57
+ }
58
+
59
+ getCurrentActionsWithoutInstanceID(
60
+ payload: GetCurrentActionsWithoutInstanceIDRequest
61
+ ) {
62
+ return this.http.get<
63
+ MstateResponse<GetCurrentActionsWithoutInstanceIDResponse>
64
+ >(
65
+ `${MSTATE_URL}/${Route.GET_CURRENT_ACTIONS_WITHOUT_INSTANCE}?name=${payload.workflow}`,
66
+ {
67
+ headers: this.getHeaders(payload.token),
68
+ }
69
+ );
70
+ }
71
+
72
+ async handleDropdownAPI(request: AxiosRequestConfig, target: string) {
73
+ const { data } = await axios(request);
74
+
75
+ return this.mstateHelper.getObjectValue<any>(data, target) ?? [];
76
+ }
77
+ }
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Public API Surface of mstate-angular
3
+ */
4
+
5
+ export * from './lib/mstate-angular/mstate-angular.component';
6
+ export * from './lib/mstate-angular.module';
@@ -0,0 +1,14 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "../../tsconfig.json",
4
+ "compilerOptions": {
5
+ "outDir": "../../out-tsc/lib",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "inlineSources": true,
9
+ "types": []
10
+ },
11
+ "exclude": [
12
+ "**/*.spec.ts"
13
+ ]
14
+ }
@@ -0,0 +1,10 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "./tsconfig.lib.json",
4
+ "compilerOptions": {
5
+ "declarationMap": false
6
+ },
7
+ "angularCompilerOptions": {
8
+ "compilationMode": "partial"
9
+ }
10
+ }
@@ -0,0 +1,14 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "../../tsconfig.json",
4
+ "compilerOptions": {
5
+ "outDir": "../../out-tsc/spec",
6
+ "types": [
7
+ "jasmine"
8
+ ]
9
+ },
10
+ "include": [
11
+ "**/*.spec.ts",
12
+ "**/*.d.ts"
13
+ ]
14
+ }