@memberjunction/ng-base-types 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -222
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
# @memberjunction/ng-base-types
|
|
2
2
|
|
|
3
|
-
Foundational types and base classes for Angular components in the MemberJunction ecosystem, providing
|
|
3
|
+
Foundational types and base classes for Angular components in the MemberJunction ecosystem, providing standardized provider management and form event coordination.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This package provides essential building blocks
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
This package provides essential building blocks that other MemberJunction Angular packages depend on. It exports `BaseAngularComponent`, an abstract base class that standardizes data provider access across the component tree, and a set of form event types used for coordinating save/delete operations across form sub-components.
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
graph TD
|
|
11
|
+
A["@memberjunction/ng-base-types"] --> B[BaseAngularComponent]
|
|
12
|
+
A --> C[Form Event System]
|
|
13
|
+
|
|
14
|
+
B --> B1["ProviderToUse
|
|
15
|
+
(IMetadataProvider)"]
|
|
16
|
+
B --> B2["RunViewToUse
|
|
17
|
+
(IRunViewProvider)"]
|
|
18
|
+
B --> B3["RunQueryToUse
|
|
19
|
+
(IRunQueryProvider)"]
|
|
20
|
+
B --> B4["RunReportToUse
|
|
21
|
+
(IRunReportProvider)"]
|
|
22
|
+
|
|
23
|
+
C --> C1[BaseFormComponentEvent]
|
|
24
|
+
C --> C2[FormEditingCompleteEvent]
|
|
25
|
+
C --> C3[PendingRecordItem]
|
|
26
|
+
C --> C4[BaseFormComponentEventCodes]
|
|
27
|
+
|
|
28
|
+
style A fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
29
|
+
style B fill:#7c5295,stroke:#563a6b,color:#fff
|
|
30
|
+
style C fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
31
|
+
```
|
|
11
32
|
|
|
12
33
|
## Installation
|
|
13
34
|
|
|
@@ -15,48 +36,30 @@ This package provides essential building blocks for Angular applications using M
|
|
|
15
36
|
npm install @memberjunction/ng-base-types
|
|
16
37
|
```
|
|
17
38
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
### Abstract Base Component
|
|
21
|
-
- Centralized provider management for data access
|
|
22
|
-
- Automatic provider inheritance throughout component trees
|
|
23
|
-
- Support for multiple concurrent API connections
|
|
24
|
-
|
|
25
|
-
### Form Event System
|
|
26
|
-
- Standardized event types for form component communication
|
|
27
|
-
- Support for save/delete operations coordination
|
|
28
|
-
- Pending changes management
|
|
29
|
-
|
|
30
|
-
### TypeScript Support
|
|
31
|
-
- Full type definitions for all exports
|
|
32
|
-
- Strict mode compatible
|
|
33
|
-
- Enhanced IDE intellisense
|
|
34
|
-
|
|
35
|
-
## API Documentation
|
|
39
|
+
## Usage
|
|
36
40
|
|
|
37
41
|
### BaseAngularComponent
|
|
38
42
|
|
|
39
|
-
Abstract base class that all MemberJunction Angular components should extend:
|
|
43
|
+
Abstract base class that all MemberJunction Angular components should extend for standardized provider management:
|
|
40
44
|
|
|
41
45
|
```typescript
|
|
42
46
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
43
|
-
import { Component, OnInit } from '@angular/core';
|
|
44
47
|
|
|
45
48
|
@Component({
|
|
46
49
|
selector: 'my-component',
|
|
47
50
|
templateUrl: './my-component.html'
|
|
48
51
|
})
|
|
49
|
-
export class MyComponent extends BaseAngularComponent
|
|
50
|
-
|
|
52
|
+
export class MyComponent extends BaseAngularComponent {
|
|
53
|
+
async loadData() {
|
|
51
54
|
// Access the metadata provider
|
|
52
55
|
const metadata = this.ProviderToUse;
|
|
53
|
-
|
|
56
|
+
|
|
54
57
|
// Use RunView functionality
|
|
55
58
|
const viewProvider = this.RunViewToUse;
|
|
56
|
-
|
|
59
|
+
|
|
57
60
|
// Execute queries
|
|
58
61
|
const queryProvider = this.RunQueryToUse;
|
|
59
|
-
|
|
62
|
+
|
|
60
63
|
// Run reports
|
|
61
64
|
const reportProvider = this.RunReportToUse;
|
|
62
65
|
}
|
|
@@ -73,12 +76,12 @@ export class MyComponent extends BaseAngularComponent implements OnInit {
|
|
|
73
76
|
|
|
74
77
|
| Method | Return Type | Description |
|
|
75
78
|
|--------|-------------|-------------|
|
|
76
|
-
| `ProviderToUse` | `IMetadataProvider` | Returns the Provider if specified, otherwise returns
|
|
77
|
-
| `RunViewToUse` | `IRunViewProvider` |
|
|
78
|
-
| `RunQueryToUse` | `IRunQueryProvider` |
|
|
79
|
-
| `RunReportToUse` | `IRunReportProvider` |
|
|
79
|
+
| `ProviderToUse` | `IMetadataProvider` | Returns the Provider if specified, otherwise returns Metadata.Provider |
|
|
80
|
+
| `RunViewToUse` | `IRunViewProvider` | Provider cast as IRunViewProvider for running views |
|
|
81
|
+
| `RunQueryToUse` | `IRunQueryProvider` | Provider cast as IRunQueryProvider for executing queries |
|
|
82
|
+
| `RunReportToUse` | `IRunReportProvider` | Provider cast as IRunReportProvider for running reports |
|
|
80
83
|
|
|
81
|
-
### Form
|
|
84
|
+
### Form Event System
|
|
82
85
|
|
|
83
86
|
#### BaseFormComponentEventCodes
|
|
84
87
|
|
|
@@ -95,229 +98,74 @@ const BaseFormComponentEventCodes = {
|
|
|
95
98
|
|
|
96
99
|
#### Event Classes
|
|
97
100
|
|
|
98
|
-
##### BaseFormComponentEvent
|
|
99
|
-
|
|
100
|
-
Base class for all form component events:
|
|
101
|
-
|
|
102
101
|
```typescript
|
|
102
|
+
// Base event for form component communication
|
|
103
103
|
class BaseFormComponentEvent {
|
|
104
|
-
subEventCode: string;
|
|
105
|
-
elementRef:
|
|
106
|
-
returnValue:
|
|
104
|
+
subEventCode: string;
|
|
105
|
+
elementRef: unknown;
|
|
106
|
+
returnValue: unknown;
|
|
107
107
|
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
##### FormEditingCompleteEvent
|
|
111
|
-
|
|
112
|
-
Specialized event emitted when form editing is complete:
|
|
113
108
|
|
|
114
|
-
|
|
109
|
+
// Emitted when form editing is complete, carrying pending changes
|
|
115
110
|
class FormEditingCompleteEvent extends BaseFormComponentEvent {
|
|
116
111
|
subEventCode: string = BaseFormComponentEventCodes.EDITING_COMPLETE;
|
|
117
112
|
pendingChanges: PendingRecordItem[] = [];
|
|
118
113
|
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
##### PendingRecordItem
|
|
122
|
-
|
|
123
|
-
Represents a record pending save or delete:
|
|
124
114
|
|
|
125
|
-
|
|
115
|
+
// Represents a record pending save or delete
|
|
126
116
|
class PendingRecordItem {
|
|
127
|
-
entityObject: BaseEntity;
|
|
128
|
-
action: 'save' | 'delete' = 'save';
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Usage Examples
|
|
133
|
-
|
|
134
|
-
### Implementing a Component with Custom Provider
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
import { Component, OnInit } from '@angular/core';
|
|
138
|
-
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
139
|
-
import { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';
|
|
140
|
-
|
|
141
|
-
@Component({
|
|
142
|
-
selector: 'app-custom-provider',
|
|
143
|
-
template: `
|
|
144
|
-
<div>
|
|
145
|
-
<child-component [Provider]="customProvider"></child-component>
|
|
146
|
-
</div>
|
|
147
|
-
`
|
|
148
|
-
})
|
|
149
|
-
export class CustomProviderComponent extends BaseAngularComponent implements OnInit {
|
|
150
|
-
customProvider: GraphQLDataProvider;
|
|
151
|
-
|
|
152
|
-
ngOnInit() {
|
|
153
|
-
// Create a custom provider for a different API endpoint
|
|
154
|
-
this.customProvider = new GraphQLDataProvider({
|
|
155
|
-
endpoint: 'https://api.example.com/graphql',
|
|
156
|
-
headers: {
|
|
157
|
-
'Authorization': 'Bearer YOUR_TOKEN'
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
}
|
|
117
|
+
entityObject: BaseEntity;
|
|
118
|
+
action: 'save' | 'delete' = 'save';
|
|
161
119
|
}
|
|
162
120
|
```
|
|
163
121
|
|
|
164
122
|
### Handling Form Events
|
|
165
123
|
|
|
166
124
|
```typescript
|
|
167
|
-
import {
|
|
168
|
-
import {
|
|
169
|
-
BaseAngularComponent,
|
|
125
|
+
import {
|
|
170
126
|
BaseFormComponentEvent,
|
|
171
127
|
BaseFormComponentEventCodes,
|
|
172
128
|
FormEditingCompleteEvent,
|
|
173
129
|
PendingRecordItem
|
|
174
130
|
} from '@memberjunction/ng-base-types';
|
|
175
131
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
event.pendingChanges = entities.map(entity => ({
|
|
189
|
-
entityObject: entity,
|
|
190
|
-
action: 'save' as const
|
|
191
|
-
}));
|
|
192
|
-
|
|
193
|
-
// Emit the event
|
|
194
|
-
this.formEvent.emit(event);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
onFormEvent(event: BaseFormComponentEvent) {
|
|
198
|
-
switch (event.subEventCode) {
|
|
199
|
-
case BaseFormComponentEventCodes.EDITING_COMPLETE:
|
|
200
|
-
const editEvent = event as FormEditingCompleteEvent;
|
|
201
|
-
this.processPendingChanges(editEvent.pendingChanges);
|
|
202
|
-
break;
|
|
203
|
-
|
|
204
|
-
case BaseFormComponentEventCodes.REVERT_PENDING_CHANGES:
|
|
205
|
-
this.revertChanges();
|
|
206
|
-
break;
|
|
207
|
-
|
|
208
|
-
case BaseFormComponentEventCodes.POPULATE_PENDING_RECORDS:
|
|
209
|
-
this.populateRecords();
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
private async processPendingChanges(changes: PendingRecordItem[]) {
|
|
215
|
-
for (const item of changes) {
|
|
216
|
-
try {
|
|
217
|
-
if (item.action === 'save') {
|
|
218
|
-
await item.entityObject.Save();
|
|
219
|
-
} else if (item.action === 'delete') {
|
|
220
|
-
await item.entityObject.Delete();
|
|
221
|
-
}
|
|
222
|
-
} catch (error) {
|
|
223
|
-
console.error(`Failed to ${item.action} entity:`, error);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
132
|
+
onFormEvent(event: BaseFormComponentEvent) {
|
|
133
|
+
switch (event.subEventCode) {
|
|
134
|
+
case BaseFormComponentEventCodes.EDITING_COMPLETE:
|
|
135
|
+
const editEvent = event as FormEditingCompleteEvent;
|
|
136
|
+
this.processPendingChanges(editEvent.pendingChanges);
|
|
137
|
+
break;
|
|
138
|
+
case BaseFormComponentEventCodes.REVERT_PENDING_CHANGES:
|
|
139
|
+
this.revertChanges();
|
|
140
|
+
break;
|
|
141
|
+
case BaseFormComponentEventCodes.POPULATE_PENDING_RECORDS:
|
|
142
|
+
this.populateRecords();
|
|
143
|
+
break;
|
|
226
144
|
}
|
|
227
145
|
}
|
|
228
146
|
```
|
|
229
147
|
|
|
230
|
-
### Using Multiple Providers in an Application
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
import { Component } from '@angular/core';
|
|
234
|
-
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
235
|
-
import { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';
|
|
236
|
-
|
|
237
|
-
@Component({
|
|
238
|
-
selector: 'app-multi-tenant',
|
|
239
|
-
template: `
|
|
240
|
-
<div class="tenant-a">
|
|
241
|
-
<user-list [Provider]="tenantAProvider"></user-list>
|
|
242
|
-
</div>
|
|
243
|
-
<div class="tenant-b">
|
|
244
|
-
<user-list [Provider]="tenantBProvider"></user-list>
|
|
245
|
-
</div>
|
|
246
|
-
`
|
|
247
|
-
})
|
|
248
|
-
export class MultiTenantComponent extends BaseAngularComponent {
|
|
249
|
-
tenantAProvider = new GraphQLDataProvider({
|
|
250
|
-
endpoint: 'https://tenant-a.example.com/graphql'
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
tenantBProvider = new GraphQLDataProvider({
|
|
254
|
-
endpoint: 'https://tenant-b.example.com/graphql'
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
```
|
|
258
|
-
|
|
259
148
|
## Dependencies
|
|
260
149
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
150
|
+
| Package | Description |
|
|
151
|
+
|---------|-------------|
|
|
152
|
+
| `@memberjunction/core` | Core MemberJunction framework |
|
|
153
|
+
| `@memberjunction/core-entities` | Entity definitions |
|
|
154
|
+
| `@memberjunction/global` | Global utilities |
|
|
155
|
+
| `tslib` | TypeScript runtime helpers |
|
|
266
156
|
|
|
267
157
|
### Peer Dependencies
|
|
268
|
-
- `@angular/common`: ^18.0.2
|
|
269
|
-
- `@angular/core`: ^18.0.2
|
|
270
158
|
|
|
271
|
-
|
|
159
|
+
- `@angular/common` ^21.x
|
|
160
|
+
- `@angular/core` ^21.x
|
|
272
161
|
|
|
273
|
-
|
|
162
|
+
## Build
|
|
274
163
|
|
|
275
164
|
```bash
|
|
165
|
+
cd packages/Angular/Generic/base-types
|
|
276
166
|
npm run build
|
|
277
167
|
```
|
|
278
168
|
|
|
279
|
-
The package is configured with:
|
|
280
|
-
- No side effects for better tree-shaking
|
|
281
|
-
- Full TypeScript declarations
|
|
282
|
-
- Angular Ivy compatibility
|
|
283
|
-
|
|
284
|
-
## Integration with MemberJunction
|
|
285
|
-
|
|
286
|
-
This package is designed to work seamlessly with other MemberJunction packages:
|
|
287
|
-
|
|
288
|
-
- **@memberjunction/core**: Provides the entity and provider interfaces
|
|
289
|
-
- **@memberjunction/graphql-dataprovider**: Default data provider implementation
|
|
290
|
-
- **@memberjunction/ng-\***: Other Angular-specific packages that extend BaseAngularComponent
|
|
291
|
-
|
|
292
|
-
## Best Practices
|
|
293
|
-
|
|
294
|
-
1. **Always extend BaseAngularComponent** for MemberJunction Angular components
|
|
295
|
-
2. **Use the provider getters** instead of directly accessing Metadata or RunView classes
|
|
296
|
-
3. **Emit standardized events** using the provided event classes for better interoperability
|
|
297
|
-
4. **Handle errors appropriately** when processing pending changes
|
|
298
|
-
5. **Pass providers down the component tree** when working with multiple API endpoints
|
|
299
|
-
|
|
300
|
-
## Migration Guide
|
|
301
|
-
|
|
302
|
-
If upgrading from a previous version:
|
|
303
|
-
|
|
304
|
-
1. Update all components to extend `BaseAngularComponent`
|
|
305
|
-
2. Replace direct `Metadata` usage with `this.ProviderToUse`
|
|
306
|
-
3. Update event handling to use the standardized event types
|
|
307
|
-
4. Remove any custom provider management code in favor of the built-in system
|
|
308
|
-
|
|
309
|
-
## Known Issues
|
|
310
|
-
|
|
311
|
-
- The `RunQueryToUse` and `RunReportToUse` getters in the current implementation have incomplete type casting. Ensure your provider implements all required interfaces.
|
|
312
|
-
|
|
313
|
-
## Contributing
|
|
314
|
-
|
|
315
|
-
When contributing to this package:
|
|
316
|
-
1. Maintain backward compatibility
|
|
317
|
-
2. Add tests for new functionality
|
|
318
|
-
3. Update this README with new features
|
|
319
|
-
4. Follow the MemberJunction coding standards
|
|
320
|
-
|
|
321
169
|
## License
|
|
322
170
|
|
|
323
|
-
ISC
|
|
171
|
+
ISC
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-base-types",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "MemberJunction: Simple types that are used across many generic Angular UI components for coordination",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"@angular/core": "21.1.3"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@memberjunction/core-entities": "4.
|
|
27
|
-
"@memberjunction/global": "4.
|
|
28
|
-
"@memberjunction/core": "4.
|
|
26
|
+
"@memberjunction/core-entities": "4.1.0",
|
|
27
|
+
"@memberjunction/global": "4.1.0",
|
|
28
|
+
"@memberjunction/core": "4.1.0",
|
|
29
29
|
"tslib": "^2.8.1"
|
|
30
30
|
},
|
|
31
31
|
"sideEffects": false,
|