@cccteam/ccc-lib 0.0.15 → 0.0.16

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 (221) hide show
  1. package/README.md +38 -13
  2. package/fesm2022/cccteam-ccc-lib-src-auth-authentication-guard.mjs +36 -0
  3. package/fesm2022/cccteam-ccc-lib-src-auth-authentication-guard.mjs.map +1 -0
  4. package/fesm2022/cccteam-ccc-lib-src-auth-authorization-guard.mjs +25 -0
  5. package/fesm2022/cccteam-ccc-lib-src-auth-authorization-guard.mjs.map +1 -0
  6. package/fesm2022/cccteam-ccc-lib-src-auth-forms.mjs +83 -0
  7. package/fesm2022/cccteam-ccc-lib-src-auth-forms.mjs.map +1 -0
  8. package/fesm2022/cccteam-ccc-lib-src-auth-has-permission.mjs +44 -0
  9. package/fesm2022/cccteam-ccc-lib-src-auth-has-permission.mjs.map +1 -0
  10. package/fesm2022/cccteam-ccc-lib-src-auth-service.mjs +82 -0
  11. package/fesm2022/cccteam-ccc-lib-src-auth-service.mjs.map +1 -0
  12. package/fesm2022/cccteam-ccc-lib-src-ccc-camel-case-to-title.mjs +33 -0
  13. package/fesm2022/cccteam-ccc-lib-src-ccc-camel-case-to-title.mjs.map +1 -0
  14. package/fesm2022/cccteam-ccc-lib-src-ccc-grid.mjs +256 -0
  15. package/fesm2022/cccteam-ccc-lib-src-ccc-grid.mjs.map +1 -0
  16. package/fesm2022/cccteam-ccc-lib-src-ccc-resource.mjs +3129 -0
  17. package/fesm2022/cccteam-ccc-lib-src-ccc-resource.mjs.map +1 -0
  18. package/fesm2022/cccteam-ccc-lib-src-forms.mjs +79 -0
  19. package/fesm2022/cccteam-ccc-lib-src-forms.mjs.map +1 -0
  20. package/fesm2022/cccteam-ccc-lib-src-internal-types.mjs +6 -0
  21. package/fesm2022/cccteam-ccc-lib-src-internal-types.mjs.map +1 -0
  22. package/fesm2022/cccteam-ccc-lib-src-types.mjs +431 -0
  23. package/fesm2022/cccteam-ccc-lib-src-types.mjs.map +1 -0
  24. package/fesm2022/cccteam-ccc-lib-src-ui-alert.mjs +48 -0
  25. package/fesm2022/cccteam-ccc-lib-src-ui-alert.mjs.map +1 -0
  26. package/fesm2022/cccteam-ccc-lib-src-ui-core-service.mjs +41 -0
  27. package/fesm2022/cccteam-ccc-lib-src-ui-core-service.mjs.map +1 -0
  28. package/fesm2022/cccteam-ccc-lib-src-ui-idle-service.mjs +157 -0
  29. package/fesm2022/cccteam-ccc-lib-src-ui-idle-service.mjs.map +1 -0
  30. package/fesm2022/cccteam-ccc-lib-src-ui-interceptor.mjs +50 -0
  31. package/fesm2022/cccteam-ccc-lib-src-ui-interceptor.mjs.map +1 -0
  32. package/fesm2022/cccteam-ccc-lib-src-ui-notification-service.mjs +63 -0
  33. package/fesm2022/cccteam-ccc-lib-src-ui-notification-service.mjs.map +1 -0
  34. package/fesm2022/cccteam-ccc-lib-src-ui-sidenav.mjs +60 -0
  35. package/fesm2022/cccteam-ccc-lib-src-ui-sidenav.mjs.map +1 -0
  36. package/fesm2022/cccteam-ccc-lib-src-util-request-options.mjs +19 -0
  37. package/fesm2022/cccteam-ccc-lib-src-util-request-options.mjs.map +1 -0
  38. package/fesm2022/cccteam-ccc-lib.mjs +4444 -0
  39. package/fesm2022/cccteam-ccc-lib.mjs.map +1 -0
  40. package/package.json +88 -5
  41. package/types/cccteam-ccc-lib-src-auth-authentication-guard.d.ts +6 -0
  42. package/types/cccteam-ccc-lib-src-auth-authorization-guard.d.ts +6 -0
  43. package/types/cccteam-ccc-lib-src-auth-forms.d.ts +28 -0
  44. package/types/cccteam-ccc-lib-src-auth-has-permission.d.ts +15 -0
  45. package/types/cccteam-ccc-lib-src-auth-service.d.ts +38 -0
  46. package/types/cccteam-ccc-lib-src-ccc-camel-case-to-title.d.ts +10 -0
  47. package/types/cccteam-ccc-lib-src-ccc-grid.d.ts +35 -0
  48. package/types/cccteam-ccc-lib-src-ccc-resource.d.ts +674 -0
  49. package/types/cccteam-ccc-lib-src-forms.d.ts +27 -0
  50. package/types/cccteam-ccc-lib-src-types.d.ts +934 -0
  51. package/types/cccteam-ccc-lib-src-ui-alert.d.ts +16 -0
  52. package/types/cccteam-ccc-lib-src-ui-core-service.d.ts +20 -0
  53. package/types/cccteam-ccc-lib-src-ui-idle-service.d.ts +49 -0
  54. package/types/cccteam-ccc-lib-src-ui-interceptor.d.ts +16 -0
  55. package/types/cccteam-ccc-lib-src-ui-notification-service.d.ts +33 -0
  56. package/types/cccteam-ccc-lib-src-ui-sidenav.d.ts +33 -0
  57. package/types/cccteam-ccc-lib-src-util-request-options.d.ts +12 -0
  58. package/types/cccteam-ccc-lib.d.ts +1877 -0
  59. package/eslint.config.js +0 -32
  60. package/ng-package.json +0 -11
  61. package/src/auth-authentication-guard/authentication.guard.ts +0 -40
  62. package/src/auth-authentication-guard/index.ts +0 -1
  63. package/src/auth-authentication-guard/ng-package.json +0 -6
  64. package/src/auth-authorization-guard/authorization.guard.ts +0 -17
  65. package/src/auth-authorization-guard/index.ts +0 -1
  66. package/src/auth-authorization-guard/ng-package.json +0 -6
  67. package/src/auth-forms/ccc-field/ccc-field.component.html +0 -1
  68. package/src/auth-forms/ccc-field/ccc-field.component.scss +0 -0
  69. package/src/auth-forms/ccc-field/ccc-field.component.spec.ts +0 -22
  70. package/src/auth-forms/ccc-field/ccc-field.component.ts +0 -74
  71. package/src/auth-forms/form-helpers.ts +0 -39
  72. package/src/auth-forms/index.ts +0 -3
  73. package/src/auth-forms/ng-package.json +0 -6
  74. package/src/auth-has-permission/has-permission.directive.ts +0 -34
  75. package/src/auth-has-permission/index.ts +0 -1
  76. package/src/auth-has-permission/ng-package.json +0 -6
  77. package/src/auth-service/auth.service.ts +0 -92
  78. package/src/auth-service/index.ts +0 -1
  79. package/src/auth-service/ng-package.json +0 -6
  80. package/src/ccc-camel-case-to-title/camel-case-to-title.pipe.ts +0 -23
  81. package/src/ccc-camel-case-to-title/index.ts +0 -1
  82. package/src/ccc-camel-case-to-title/ng-package.json +0 -6
  83. package/src/ccc-grid/ccc-grid.component.ts +0 -155
  84. package/src/ccc-grid/index.ts +0 -3
  85. package/src/ccc-grid/ng-package.json +0 -6
  86. package/src/ccc-grid/table-button/table-button.component.html +0 -16
  87. package/src/ccc-grid/table-button/table-button.component.scss +0 -5
  88. package/src/ccc-grid/table-button/table-button.component.spec.ts +0 -22
  89. package/src/ccc-grid/table-button/table-button.component.ts +0 -49
  90. package/src/ccc-resource/can-deactivate.guard.ts +0 -41
  91. package/src/ccc-resource/compound-resource/compound-resource.component.html +0 -57
  92. package/src/ccc-resource/compound-resource/compound-resource.component.scss +0 -86
  93. package/src/ccc-resource/compound-resource/compound-resource.component.spec.ts +0 -22
  94. package/src/ccc-resource/compound-resource/compound-resource.component.ts +0 -158
  95. package/src/ccc-resource/concat-fns.ts +0 -162
  96. package/src/ccc-resource/empty-readonly-field/empty-readonly-field.component.html +0 -12
  97. package/src/ccc-resource/empty-readonly-field/empty-readonly-field.component.scss +0 -0
  98. package/src/ccc-resource/empty-readonly-field/empty-readonly-field.component.spec.ts +0 -23
  99. package/src/ccc-resource/empty-readonly-field/empty-readonly-field.component.ts +0 -17
  100. package/src/ccc-resource/form-state.service.ts +0 -24
  101. package/src/ccc-resource/format-fns.ts +0 -49
  102. package/src/ccc-resource/gui-constants.ts +0 -88
  103. package/src/ccc-resource/index.ts +0 -23
  104. package/src/ccc-resource/leave-page-confirmation-modal/leave-page-confirmation-modal.component.html +0 -8
  105. package/src/ccc-resource/leave-page-confirmation-modal/leave-page-confirmation-modal.component.scss +0 -0
  106. package/src/ccc-resource/leave-page-confirmation-modal/leave-page-confirmation-modal.component.spec.ts +0 -22
  107. package/src/ccc-resource/leave-page-confirmation-modal/leave-page-confirmation-modal.component.ts +0 -12
  108. package/src/ccc-resource/ng-package.json +0 -6
  109. package/src/ccc-resource/operation-types.ts +0 -19
  110. package/src/ccc-resource/padding-element/padding-element.component.html +0 -1
  111. package/src/ccc-resource/padding-element/padding-element.component.scss +0 -3
  112. package/src/ccc-resource/padding-element/padding-element.component.spec.ts +0 -22
  113. package/src/ccc-resource/padding-element/padding-element.component.ts +0 -20
  114. package/src/ccc-resource/resource-array-view/resource-array-view.component.html +0 -81
  115. package/src/ccc-resource/resource-array-view/resource-array-view.component.scss +0 -21
  116. package/src/ccc-resource/resource-array-view/resource-array-view.component.spec.ts +0 -22
  117. package/src/ccc-resource/resource-array-view/resource-array-view.component.ts +0 -143
  118. package/src/ccc-resource/resource-base/resource-base.component.spec.ts +0 -22
  119. package/src/ccc-resource/resource-base/resource-base.component.ts +0 -11
  120. package/src/ccc-resource/resource-cache.service.ts +0 -232
  121. package/src/ccc-resource/resource-create/resource-create.component.html +0 -31
  122. package/src/ccc-resource/resource-create/resource-create.component.scss +0 -130
  123. package/src/ccc-resource/resource-create/resource-create.component.spec.ts +0 -22
  124. package/src/ccc-resource/resource-create/resource-create.component.ts +0 -303
  125. package/src/ccc-resource/resource-field/base-field.directive.ts +0 -102
  126. package/src/ccc-resource/resource-field/fields/boolean-field/boolean-field.component.html +0 -16
  127. package/src/ccc-resource/resource-field/fields/boolean-field/boolean-field.component.scss +0 -0
  128. package/src/ccc-resource/resource-field/fields/boolean-field/boolean-field.component.spec.ts +0 -22
  129. package/src/ccc-resource/resource-field/fields/boolean-field/boolean-field.component.ts +0 -15
  130. package/src/ccc-resource/resource-field/fields/computed-field/computed-field.component.html +0 -13
  131. package/src/ccc-resource/resource-field/fields/computed-field/computed-field.component.scss +0 -0
  132. package/src/ccc-resource/resource-field/fields/computed-field/computed-field.component.spec.ts +0 -23
  133. package/src/ccc-resource/resource-field/fields/computed-field/computed-field.component.ts +0 -50
  134. package/src/ccc-resource/resource-field/fields/date-field/date-field.component.html +0 -22
  135. package/src/ccc-resource/resource-field/fields/date-field/date-field.component.scss +0 -0
  136. package/src/ccc-resource/resource-field/fields/date-field/date-field.component.spec.ts +0 -22
  137. package/src/ccc-resource/resource-field/fields/date-field/date-field.component.ts +0 -14
  138. package/src/ccc-resource/resource-field/fields/enumerated-field/enumerated-field.component.html +0 -71
  139. package/src/ccc-resource/resource-field/fields/enumerated-field/enumerated-field.component.scss +0 -9
  140. package/src/ccc-resource/resource-field/fields/enumerated-field/enumerated-field.component.spec.ts +0 -22
  141. package/src/ccc-resource/resource-field/fields/enumerated-field/enumerated-field.component.ts +0 -207
  142. package/src/ccc-resource/resource-field/fields/nullboolean-field/nullboolean-field.component.html +0 -38
  143. package/src/ccc-resource/resource-field/fields/nullboolean-field/nullboolean-field.component.scss +0 -3
  144. package/src/ccc-resource/resource-field/fields/nullboolean-field/nullboolean-field.component.spec.ts +0 -22
  145. package/src/ccc-resource/resource-field/fields/nullboolean-field/nullboolean-field.component.ts +0 -87
  146. package/src/ccc-resource/resource-field/fields/number-field/number-field.component.html +0 -23
  147. package/src/ccc-resource/resource-field/fields/number-field/number-field.component.scss +0 -6
  148. package/src/ccc-resource/resource-field/fields/number-field/number-field.component.spec.ts +0 -22
  149. package/src/ccc-resource/resource-field/fields/number-field/number-field.component.ts +0 -14
  150. package/src/ccc-resource/resource-field/fields/text-field/text-field.component.html +0 -29
  151. package/src/ccc-resource/resource-field/fields/text-field/text-field.component.scss +0 -6
  152. package/src/ccc-resource/resource-field/fields/text-field/text-field.component.spec.ts +0 -22
  153. package/src/ccc-resource/resource-field/fields/text-field/text-field.component.ts +0 -23
  154. package/src/ccc-resource/resource-field/resource-field.component.html +0 -112
  155. package/src/ccc-resource/resource-field/resource-field.component.scss +0 -7
  156. package/src/ccc-resource/resource-field/resource-field.component.spec.ts +0 -22
  157. package/src/ccc-resource/resource-field/resource-field.component.ts +0 -214
  158. package/src/ccc-resource/resource-layout/resource-layout.component.html +0 -73
  159. package/src/ccc-resource/resource-layout/resource-layout.component.scss +0 -26
  160. package/src/ccc-resource/resource-layout/resource-layout.component.spec.ts +0 -22
  161. package/src/ccc-resource/resource-layout/resource-layout.component.ts +0 -176
  162. package/src/ccc-resource/resource-list/ resource-list.component.spec.ts +0 -22
  163. package/src/ccc-resource/resource-list/resource-list.component.html +0 -27
  164. package/src/ccc-resource/resource-list/resource-list.component.scss +0 -67
  165. package/src/ccc-resource/resource-list/resource-list.component.ts +0 -376
  166. package/src/ccc-resource/resource-list-create/resource-list-create.component.html +0 -71
  167. package/src/ccc-resource/resource-list-create/resource-list-create.component.scss +0 -9
  168. package/src/ccc-resource/resource-list-create/resource-list-create.component.spec.ts +0 -22
  169. package/src/ccc-resource/resource-list-create/resource-list-create.component.ts +0 -103
  170. package/src/ccc-resource/resource-resolver/resource-resolver.component.html +0 -1
  171. package/src/ccc-resource/resource-resolver/resource-resolver.component.scss +0 -0
  172. package/src/ccc-resource/resource-resolver/resource-resolver.component.spec.ts +0 -22
  173. package/src/ccc-resource/resource-resolver/resource-resolver.component.ts +0 -69
  174. package/src/ccc-resource/resource-store.service.ts +0 -93
  175. package/src/ccc-resource/resource-view/resource-view.component.html +0 -133
  176. package/src/ccc-resource/resource-view/resource-view.component.scss +0 -150
  177. package/src/ccc-resource/resource-view/resource-view.component.spec.ts +0 -22
  178. package/src/ccc-resource/resource-view/resource-view.component.ts +0 -354
  179. package/src/ccc-resource/resources-helpers.ts +0 -262
  180. package/src/ccc-resource/utils/validator-utils.ts +0 -6
  181. package/src/index.ts +0 -44
  182. package/src/internal-types/ng-package.json +0 -6
  183. package/src/types/auth.actions.ts +0 -46
  184. package/src/types/configs.ts +0 -952
  185. package/src/types/constants.ts +0 -1
  186. package/src/types/core.actions.ts +0 -33
  187. package/src/types/index.ts +0 -9
  188. package/src/types/ng-package.json +0 -6
  189. package/src/types/notification-message.ts +0 -20
  190. package/src/types/permissions.ts +0 -17
  191. package/src/types/session-info.ts +0 -10
  192. package/src/types/tokens.ts +0 -20
  193. package/src/ui-alert/alert.component.html +0 -13
  194. package/src/ui-alert/alert.component.scss +0 -48
  195. package/src/ui-alert/alert.component.spec.ts +0 -22
  196. package/src/ui-alert/alert.component.ts +0 -35
  197. package/src/ui-alert/index.ts +0 -1
  198. package/src/ui-alert/ng-package.json +0 -6
  199. package/src/ui-core-service/index.ts +0 -1
  200. package/src/ui-core-service/ng-package.json +0 -6
  201. package/src/ui-core-service/ui-core.service.ts +0 -34
  202. package/src/ui-interceptor/api.interceptor.spec.ts +0 -16
  203. package/src/ui-interceptor/api.interceptor.ts +0 -45
  204. package/src/ui-interceptor/index.ts +0 -1
  205. package/src/ui-interceptor/ng-package.json +0 -6
  206. package/src/ui-notification-service/index.ts +0 -1
  207. package/src/ui-notification-service/ng-package.json +0 -6
  208. package/src/ui-notification-service/notification.service.ts +0 -59
  209. package/src/ui-sidenav/index.ts +0 -1
  210. package/src/ui-sidenav/ng-package.json +0 -6
  211. package/src/ui-sidenav/sidenav.component.html +0 -60
  212. package/src/ui-sidenav/sidenav.component.scss +0 -99
  213. package/src/ui-sidenav/sidenav.component.spec.ts +0 -22
  214. package/src/ui-sidenav/sidenav.component.ts +0 -64
  215. package/src/util-request-options/index.ts +0 -1
  216. package/src/util-request-options/ng-package.json +0 -6
  217. package/src/util-request-options/request-options.ts +0 -17
  218. package/tsconfig.lib.json +0 -13
  219. package/tsconfig.lib.prod.json +0 -11
  220. package/tsconfig.spec.json +0 -15
  221. /package/{src/internal-types/index.ts → types/cccteam-ccc-lib-src-internal-types.d.ts} +0 -0
@@ -1,354 +0,0 @@
1
- import { Location } from '@angular/common';
2
- import {
3
- Component,
4
- computed,
5
- DestroyRef,
6
- effect,
7
- inject,
8
- Injector,
9
- input,
10
- OnInit,
11
- output,
12
- signal,
13
- WritableSignal,
14
- } from '@angular/core';
15
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
16
- import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
17
- import { MatButtonModule } from '@angular/material/button';
18
- import { MatDialog } from '@angular/material/dialog';
19
- import { MatDividerModule } from '@angular/material/divider';
20
- import { MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle } from '@angular/material/expansion';
21
- import { MatIconModule } from '@angular/material/icon';
22
- import { MatInputModule } from '@angular/material/input';
23
- import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
24
- import { ActivatedRoute, Router, RouterModule } from '@angular/router';
25
- import { sparseFormData } from '@cccteam/ccc-lib/src/auth-forms';
26
- import {
27
- AlertLevel,
28
- DataType,
29
- FieldElement,
30
- ListViewConfig,
31
- RecordData,
32
- Resource,
33
- RESOURCE_META,
34
- ResourceMeta,
35
- RootConfig,
36
- RPCConfig,
37
- ViewConfig,
38
- } from '@cccteam/ccc-lib/src/types';
39
- import { NotificationService } from '@cccteam/ccc-lib/src/ui-notification-service';
40
- import { filter, tap } from 'rxjs';
41
- import { FormStateService } from '../form-state.service';
42
- import { civildateCoercion, flattenElements } from '../gui-constants';
43
- import { DeleteOperation, UpdateOperation } from '../operation-types';
44
- import { ResourceCacheService } from '../resource-cache.service';
45
- import { ResourceLayoutComponent } from '../resource-layout/resource-layout.component';
46
- import { ResourceStore } from '../resource-store.service';
47
- import { metadataTypeCoercion } from '../resources-helpers';
48
-
49
- @Component({
50
- selector: 'ccc-resource-view',
51
- imports: [
52
- FormsModule,
53
- ReactiveFormsModule,
54
- MatInputModule,
55
- RouterModule,
56
- MatButtonModule,
57
- MatIconModule,
58
- MatProgressSpinnerModule,
59
- MatDividerModule,
60
- ResourceLayoutComponent,
61
- MatExpansionPanel,
62
- MatExpansionPanelHeader,
63
- MatExpansionPanelTitle,
64
- ],
65
- templateUrl: './resource-view.component.html',
66
- styleUrl: './resource-view.component.scss',
67
- providers: [ResourceStore],
68
- })
69
- export class ResourceViewComponent implements OnInit {
70
- location = inject(Location);
71
- router = inject(Router);
72
- activatedRoute = inject(ActivatedRoute);
73
- notifications = inject(NotificationService);
74
- store = inject(ResourceStore);
75
- cache = inject(ResourceCacheService);
76
- injector = inject(Injector);
77
- destroyRef = inject(DestroyRef);
78
- formState = inject(FormStateService);
79
- dialog = inject(MatDialog);
80
-
81
- editMode: WritableSignal<'edit' | 'view'> = signal('view');
82
- uuid = input.required<string>();
83
- config = input.required<ViewConfig | ListViewConfig>();
84
- relatedData = input<RecordData>({});
85
- compoundResourceView = input<boolean>(false);
86
- isDirty = signal(false);
87
-
88
- displayFormInvalidMessage = signal<boolean>(false);
89
- deleted = output<boolean>();
90
-
91
- resourceMeta = inject(RESOURCE_META);
92
-
93
- rootConfig = computed(() => {
94
- return this.activatedRoute.snapshot.data['config'] as RootConfig;
95
- });
96
-
97
- shouldShowDelete = computed(() => {
98
- const config = this.config();
99
- if (config) {
100
- return config.primaryResource !== this.rootConfig().parentConfig.primaryResource;
101
- }
102
- return config === undefined;
103
- });
104
-
105
- inlineRpcConfigs = computed(() => {
106
- const config = this.config();
107
- if (config) {
108
- return config.rpcConfigs?.filter((rpc: RPCConfig) => rpc.placement === 'inline');
109
- }
110
- return [];
111
- });
112
-
113
- endRpcConfigs = computed(() => {
114
- const config = this.config();
115
- if (config) {
116
- return config.rpcConfigs?.filter((rpc: RPCConfig) => rpc.placement === 'end');
117
- }
118
- return [];
119
- });
120
-
121
- useExpansionPanel = computed(() => {
122
- const config = this.config();
123
- // TODO: Investigate why we're doing this check, it's weird because viewType is not part of the input configs
124
- if (config && 'viewType' in config && config.viewType !== 'View') {
125
- return false;
126
- }
127
-
128
- return config.collapsible || !this.compoundResourceView();
129
- });
130
-
131
- resourceConfigRouteSnapshot = computed(() => {
132
- return (
133
- this.config() ||
134
- (this.activatedRoute.snapshot.data['config'] as RootConfig)?.parentConfig ||
135
- ({} as ViewConfig | ListViewConfig)
136
- );
137
- });
138
-
139
- emptyFormGroup = new FormGroup({});
140
-
141
- form = computed(() => {
142
- const meta = this.store.resourceMeta();
143
- const resourceData = this.store.viewData();
144
- const config = this.config();
145
-
146
- if (meta === undefined || resourceData === undefined || config === undefined) {
147
- return this.emptyFormGroup;
148
- }
149
-
150
- const fg = new FormGroup({});
151
- const pristineValues: Record<string, DataType | null> = {};
152
- const allElements = flattenElements(config.elements);
153
-
154
- for (const field of meta.fields || []) {
155
- const isFieldNameRegistered = fg.get(field.fieldName) !== null;
156
- if (isFieldNameRegistered) {
157
- continue;
158
- }
159
-
160
- const findConfig = allElements.find((element) => element.type === 'field' && element.name === field.fieldName);
161
- const fieldConfig = findConfig as FieldElement | undefined;
162
- if (!fieldConfig) {
163
- continue;
164
- }
165
-
166
- let value: DataType | null = null;
167
- const stringValue = resourceData?.[field.fieldName] ? String(resourceData[field.fieldName]) : '';
168
-
169
- if (field.displayType === 'civildate' && stringValue) {
170
- value = civildateCoercion(stringValue);
171
- } else if (resourceData[field.fieldName] !== undefined) {
172
- value = resourceData[field.fieldName];
173
- }
174
-
175
- const control = new FormControl(value);
176
-
177
- if (fieldConfig.validators.length > 0) {
178
- control.setValidators(fieldConfig.validators);
179
- }
180
-
181
- fg.addControl(field.fieldName, control);
182
- pristineValues[field.fieldName] = value;
183
- }
184
- this.pristineFormValues = pristineValues;
185
-
186
- return fg;
187
- });
188
-
189
- pristineFormValues: Record<string, DataType | null> = {};
190
-
191
- route = computed(() => {
192
- const meta = this.store.resourceMeta();
193
- if (!meta) return '';
194
- return meta.consolidatedRoute || meta.route;
195
- });
196
-
197
- primaryKeys = computed(() => {
198
- const meta = this.store.resourceMeta() as ResourceMeta;
199
- if (!meta) return [];
200
- return meta.fields
201
- .filter((field) => field.primaryKey)
202
- .sort((a, b) => a.primaryKey!.ordinalPosition - b.primaryKey!.ordinalPosition);
203
- });
204
-
205
- primaryKeyPath = computed(() => {
206
- const meta = this.store.resourceMeta();
207
- const isConsolidated = !!meta.consolidatedRoute;
208
- let resourceIdentifier = '';
209
- if (isConsolidated) {
210
- resourceIdentifier = '/' + String(meta.route);
211
- }
212
- return (
213
- resourceIdentifier +
214
- '/' +
215
- this.primaryKeys()
216
- .map((field) => this.store.viewData()[field.fieldName])
217
- .join('/')
218
- );
219
- });
220
-
221
- ngOnInit(): void {
222
- if (this.resourceMeta(this.config().primaryResource as Resource)) {
223
- this.store.resourceName.set(this.config().primaryResource as Resource);
224
- this.store.resourceMeta.set(this.resourceMeta(this.config().primaryResource as Resource));
225
- }
226
-
227
- this.store.uuid.set(this.relatedId());
228
- this.store.resetResourceView();
229
- this.inlineRpcConfigs();
230
- this.endRpcConfigs();
231
- }
232
-
233
- setEditMode(mode: 'edit' | 'view'): void {
234
- if (mode === 'view') {
235
- const changeData = sparseFormData(this.form(), this.pristineFormValues);
236
- if (Object.keys(changeData).length !== 0) {
237
- this.notifications.addGlobalNotification({
238
- message: 'You have unsaved changes.',
239
- link: '',
240
- level: AlertLevel.ERROR,
241
- });
242
- return;
243
- }
244
- this.editMode.set('view');
245
- } else if (mode === 'edit') {
246
- this.editMode.set('edit');
247
- }
248
- }
249
-
250
- saveForm(): void {
251
- if (!this.form().valid) {
252
- this.displayFormInvalidMessage.set(true);
253
- this.form().markAllAsTouched();
254
- return;
255
- }
256
-
257
- this.displayFormInvalidMessage.set(false);
258
-
259
- const resourceMeta = this.store.resourceMeta();
260
- if (!resourceMeta) return;
261
-
262
- const sparseData = sparseFormData(this.form(), this.pristineFormValues);
263
- const coercedSparseData = metadataTypeCoercion(sparseData, resourceMeta);
264
-
265
- const updatePatch: UpdateOperation = {
266
- op: 'patch',
267
- value: coercedSparseData,
268
- path: this.primaryKeyPath(),
269
- };
270
-
271
- this.pristineFormValues = this.form().getRawValue();
272
-
273
- if (Object.keys(coercedSparseData).length === 0) return;
274
- this.cache
275
- .makePatches([updatePatch], this.route(), this.store.resourceName())
276
- .pipe(
277
- tap(() => {
278
- this.form().markAsPristine();
279
- this.setEditMode('view');
280
- this.formState.decrementDirtyForms();
281
- this.store.reloadResourceView();
282
- }),
283
- )
284
- .subscribe();
285
- }
286
-
287
- resetForm(): void {
288
- this.form().reset();
289
- this.form().patchValue(this.pristineFormValues);
290
- this.setEditMode('view');
291
- if (this.form().dirty) {
292
- this.formState.decrementDirtyForms();
293
- }
294
- }
295
-
296
- deleteResource(): void {
297
- const deletePatch: DeleteOperation = {
298
- op: 'remove',
299
- value: {},
300
- path: this.primaryKeyPath(),
301
- };
302
-
303
- this.cache
304
- .makePatches([deletePatch], this.route(), this.store.resourceName())
305
- .pipe(
306
- tap(() => {
307
- this.cache.updateResourceInCache(this.store.resourceName(), 'list');
308
- this.deleted.emit(true);
309
- }),
310
- filter(() => this.compoundResourceView()),
311
- tap(() => {
312
- this.location.back();
313
- }),
314
- )
315
- .subscribe();
316
- }
317
-
318
- relatedId(): string {
319
- const relatedData = this.relatedData();
320
- const config = this.config();
321
- if (config.parentRelation?.parentKey) {
322
- return String(relatedData[config.parentRelation.parentKey]);
323
- }
324
- return this.uuid();
325
- }
326
-
327
- constructor() {
328
- effect(() => {
329
- console.debug('USAGE | New FormGroup subscription for: ', this.config().title);
330
-
331
- this.form()
332
- .valueChanges.pipe(
333
- tap(() => {
334
- const dirty = this.form().dirty;
335
- if (dirty !== this.isDirty()) {
336
- this.isDirty.set(dirty);
337
- if (dirty) {
338
- this.formState.incrementDirtyForms();
339
- } else {
340
- this.formState.decrementDirtyForms();
341
- }
342
- }
343
- }),
344
- takeUntilDestroyed(this.destroyRef),
345
- )
346
- .subscribe();
347
- });
348
-
349
- effect(() => {
350
- this.uuid();
351
- this.store.uuid.set(this.relatedId());
352
- });
353
- }
354
- }
@@ -1,262 +0,0 @@
1
- import { inject, ModelSignal } from '@angular/core';
2
- import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
3
- import { Route } from '@angular/router';
4
- import type { Resource } from '@cccteam/ccc-lib/src/internal-types';
5
- import { RESOURCE_META } from '@cccteam/ccc-lib/src/internal-types';
6
- import {
7
- ConfigElement,
8
- DataType,
9
- FieldElement,
10
- MenuItem,
11
- MethodMeta,
12
- PristineData,
13
- RecordData,
14
- ResourceMeta,
15
- RootConfig,
16
- RouteResourceData,
17
- RPCRecordData,
18
- ViewConfig,
19
- } from '@cccteam/ccc-lib/src/types';
20
- import { format, isValid } from 'date-fns';
21
- import { dirtyFormDeactivateGuard } from './can-deactivate.guard';
22
- import { civildateCoercion, flattenElements } from './gui-constants';
23
- import { ResourceBaseComponent } from './resource-base/resource-base.component';
24
-
25
- /**
26
- * Recursively cleans a FormGroup or FormArray, removing controls with empty string values.
27
- * Similar to sparseFormData, but doesn't compare to an initial state
28
- * @param control - The FormGroup or FormArray to clean.
29
- * @returns A cleaned object with non-empty values.
30
- */
31
- export function cleanStringForm<T>(control: AbstractControl): T | undefined {
32
- if (control instanceof FormGroup) {
33
- const cleanedGroup: Record<string, unknown> = {};
34
- for (const key of Object.keys(control.controls)) {
35
- const childControl = control.get(key);
36
- if (childControl) {
37
- const cleanedValue = cleanStringForm(childControl);
38
- if (cleanedValue !== undefined && cleanedValue !== null && cleanedValue !== '') {
39
- cleanedGroup[key] = cleanedValue;
40
- }
41
- }
42
- }
43
- return cleanedGroup as T;
44
- } else if (control instanceof FormArray) {
45
- const cleanedArray = control.controls
46
- .map((childControl) => cleanStringForm(childControl))
47
- .filter((item) => item !== undefined && item !== null && item !== '');
48
- return cleanedArray as unknown as T;
49
- } else {
50
- return control.value !== '' ? control.value : undefined;
51
- }
52
- }
53
-
54
- export const createFormGroup = (
55
- meta: ResourceMeta,
56
- resourceData: RecordData,
57
- config: ViewConfig,
58
- formDataState?: ModelSignal<RecordData>,
59
- ): {
60
- formGroup: FormGroup;
61
- pristineFormValues: PristineData;
62
- } => {
63
- const fg = new FormGroup({});
64
- const pristineValues: Record<string, DataType | null> = {};
65
- const allElements = flattenElements(config.elements);
66
-
67
- for (const field of meta.fields || []) {
68
- const isFieldNameRegistered = fg.get(field.fieldName) !== null;
69
- if (isFieldNameRegistered) {
70
- continue;
71
- }
72
-
73
- const findConfig = allElements.find((element) => element.type === 'field' && element.name === field.fieldName);
74
- const fieldConfig = findConfig as FieldElement | undefined;
75
- if (!fieldConfig) {
76
- continue;
77
- }
78
-
79
- let value: DataType | null = null;
80
- const stringValue = resourceData?.[field.fieldName] ? String(resourceData[field.fieldName]) : '';
81
-
82
- if (field.displayType === 'civildate' && stringValue) {
83
- value = civildateCoercion(stringValue);
84
- } else if (resourceData[field.fieldName] !== undefined) {
85
- value = resourceData[field.fieldName];
86
- }
87
-
88
- const control = new FormControl(value);
89
-
90
- if (fieldConfig.validators.length > 0) {
91
- control.setValidators(fieldConfig.validators);
92
- }
93
-
94
- fg.addControl(field.fieldName, control);
95
- pristineValues[field.fieldName] = value;
96
- }
97
- // todo: swap this with a manual subscription where the form data is subscribed to and
98
- // is dstroyed once the form is destroyed, similar to gui/src/app/components/Resource/resource-view/resource-view.component.ts
99
- // constructor effect
100
- console.log(formDataState);
101
- // formDataState && formDataState.set(pristineValues);
102
-
103
- return {
104
- formGroup: fg,
105
- pristineFormValues: pristineValues,
106
- };
107
- };
108
-
109
- export const resourceRoutes = (config: RootConfig): Route => {
110
- const resourceMeta = inject(RESOURCE_META);
111
- const meta = resourceMeta(config.parentConfig.primaryResource as Resource);
112
- if (!meta) {
113
- return {} as Route;
114
- }
115
-
116
- if (config.nav) {
117
- if (config.routeData.route) {
118
- addToNavItems(config.nav, config.routeData.route);
119
- } else {
120
- addToNavItems(config.nav, meta.route);
121
- }
122
- }
123
-
124
- if (config.routeData.route) {
125
- const baseRoute: Route = {
126
- path: config.routeData.route,
127
- data: { config: config } satisfies RouteResourceData,
128
- component: ResourceBaseComponent,
129
- children: [
130
- {
131
- path: '',
132
- loadComponent: () =>
133
- import(`./resource-list-create/resource-list-create.component`).then(
134
- (mod) => mod.ResourceListCreateComponent,
135
- ),
136
- canDeactivate: [dirtyFormDeactivateGuard],
137
- },
138
- ],
139
- };
140
- if (config.routeData.hasViewRoute !== false) {
141
- baseRoute.children?.push({
142
- path: ':uuid',
143
- loadComponent: () =>
144
- import(`./compound-resource/compound-resource.component`).then((mod) => mod.CompoundResourceComponent),
145
- canDeactivate: [dirtyFormDeactivateGuard],
146
- });
147
- return baseRoute;
148
- }
149
- }
150
-
151
- return {
152
- path: meta.route,
153
- data: { config: config } as RouteResourceData,
154
- component: ResourceBaseComponent,
155
- children: [
156
- {
157
- path: ':uuid',
158
- loadComponent: () =>
159
- import(`./compound-resource/compound-resource.component`).then((mod) => mod.CompoundResourceComponent),
160
- canDeactivate: [dirtyFormDeactivateGuard],
161
- },
162
- {
163
- path: '',
164
- loadComponent: () =>
165
- import(`./resource-list-create/resource-list-create.component`).then(
166
- (mod) => mod.ResourceListCreateComponent,
167
- ),
168
- canDeactivate: [dirtyFormDeactivateGuard],
169
- },
170
- ],
171
- } satisfies Route;
172
- };
173
-
174
- export const generatedNavItems = [] as MenuItem[];
175
- export const generatedNavGroups = [] as string[];
176
-
177
- function addToNavItems(
178
- nav: {
179
- navItem: MenuItem;
180
- group?: string;
181
- },
182
- route: string,
183
- ): void {
184
- nav.navItem.route = [route];
185
-
186
- if (!nav.group) {
187
- generatedNavItems.push(nav.navItem);
188
- return;
189
- }
190
-
191
- if (!generatedNavGroups.includes(nav.group)) {
192
- generatedNavGroups.push(nav.group);
193
- }
194
-
195
- let groupItem = generatedNavItems.find((item) => item.label === nav.group);
196
-
197
- if (!groupItem) {
198
- groupItem = { label: nav.group, children: [] };
199
- generatedNavItems.push(groupItem);
200
- }
201
-
202
- groupItem.children = groupItem.children || [];
203
- groupItem.children.push(nav.navItem);
204
-
205
- generatedNavItems.sort((a, b) => (a.label > b.label ? -1 : 1));
206
- }
207
-
208
- /**
209
- * Recursive function to extract nested field names from a config.
210
- * @param elements - The elements to extract field names from.
211
- * @returns - An array of field names.
212
- */
213
- export function extractFieldNames(elements: ConfigElement[]): string[] {
214
- const fields: string[] = [];
215
- for (const element of elements) {
216
- if (element.type === 'section') {
217
- fields.push(...extractFieldNames(element.children));
218
- } else if (element.type === 'field') {
219
- fields.push(element.name as string);
220
- }
221
- }
222
- return fields;
223
- }
224
-
225
- /**
226
- * Checks if a string is a valid UUID (versions 1-5) according to RFC 4122.
227
- *
228
- * @param str - The string to validate.
229
- * @returns `true` if the string is a valid UUID, otherwise `false`.
230
- */
231
- export function isUUID(str: string): boolean {
232
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
233
- return uuidRegex.test(str);
234
- }
235
-
236
- /**
237
- * Coerces metadata types in a record according to the metadata.
238
- *
239
- * @param record - The record to coerce.
240
- * @param meta - The metadata (resource or method).
241
- * @returns The coerced record.
242
- */
243
- export function metadataTypeCoercion(record: RecordData, meta: ResourceMeta): RecordData;
244
- export function metadataTypeCoercion(record: RPCRecordData, meta: MethodMeta): RPCRecordData;
245
- export function metadataTypeCoercion(
246
- record: RecordData | RPCRecordData,
247
- meta: ResourceMeta | MethodMeta,
248
- ): RecordData | RPCRecordData {
249
- if (!meta?.fields) return record;
250
-
251
- const displayTypeByField = new Map(meta.fields.map((f) => [f.fieldName, f.displayType]));
252
-
253
- for (const [key, value] of Object.entries(record)) {
254
- const displayType = displayTypeByField.get(key);
255
- if (displayType === 'civildate' && value && isValid(value)) {
256
- const date = value as Date;
257
- record[key] = format(date, 'yyyy-MM-dd');
258
- }
259
- }
260
-
261
- return record;
262
- }
@@ -1,6 +0,0 @@
1
- import { ValidatorFn } from '@angular/forms';
2
- import { ResourceValidatorFn } from '@cccteam/ccc-lib/src/types';
3
-
4
- export function createResourceValidator(validator: ValidatorFn): ResourceValidatorFn {
5
- return validator as ResourceValidatorFn;
6
- }
package/src/index.ts DELETED
@@ -1,44 +0,0 @@
1
- /*
2
- * Public API Surface of ccc-lib
3
- */
4
-
5
- // Auth service
6
- export * from '@cccteam/ccc-lib/src/auth-service';
7
-
8
- // UI Core service
9
- export * from '@cccteam/ccc-lib/src/ui-core-service';
10
-
11
- // Auth directives
12
- export * from '@cccteam/ccc-lib/src/auth-has-permission';
13
-
14
- // Auth forms
15
- export * from '@cccteam/ccc-lib/src/auth-forms';
16
-
17
- // Auth guards
18
- export * from '@cccteam/ccc-lib/src/auth-authentication-guard';
19
- export * from '@cccteam/ccc-lib/src/auth-authorization-guard';
20
-
21
- // Util
22
- export * from '@cccteam/ccc-lib/src/util-request-options';
23
-
24
- // Types
25
- export * from '@cccteam/ccc-lib/src/types';
26
-
27
- // Ui components
28
- export * from '@cccteam/ccc-lib/src/ui-alert';
29
- export * from '@cccteam/ccc-lib/src/ui-sidenav';
30
-
31
- // Ui interceptor
32
- export * from '@cccteam/ccc-lib/src/ui-interceptor';
33
-
34
- // Ui services
35
- export * from '@cccteam/ccc-lib/src/ui-notification-service';
36
-
37
- // Resources
38
- export * from '@cccteam/ccc-lib/src/ccc-resource';
39
-
40
- // Camel case pipe
41
- export * from '@cccteam/ccc-lib/src/ccc-camel-case-to-title';
42
-
43
- // Grid
44
- export * from '@cccteam/ccc-lib/src/ccc-grid';
@@ -1,6 +0,0 @@
1
- {
2
- "$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json",
3
- "lib": {
4
- "entryFile": "./index.ts"
5
- }
6
- }