@memberjunction/ng-link-directives 2.43.0 → 2.44.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.
Files changed (2) hide show
  1. package/README.md +228 -42
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -4,13 +4,15 @@ The `@memberjunction/ng-link-directives` package provides a set of Angular direc
4
4
 
5
5
  ## Features
6
6
 
7
- - Email link directive for fields with "email" extended type
8
- - Web link directive for fields with "url" extended type
9
- - Field link directive for related entity fields that navigates to the related record
10
- - Automatic value resolution for field links (displays the related entity's name)
11
- - Target control for web links (opens in new tab)
12
- - Styling options for all link types
13
- - Leverages MemberJunction's metadata system
7
+ - **Email link directive** (`mjEmailLink`) - Converts fields with "email" extended type to mailto: links
8
+ - **Web link directive** (`mjWebLink`) - Converts fields with "url" extended type to external links
9
+ - **Field link directive** (`mjFieldLink`) - Creates navigable links to related entity records
10
+ - **Automatic value resolution** - Field links can display the related entity's name instead of ID
11
+ - **Smart navigation** - Field links use Angular Router for seamless in-app navigation
12
+ - **Target control** - Web and email links open in new tabs by default
13
+ - **CSS styling** - All links use the `link-text` class for consistent styling
14
+ - **Type safety** - Full TypeScript support with strict typing
15
+ - **Metadata integration** - Leverages MemberJunction's metadata system for field information
14
16
 
15
17
  ## Installation
16
18
 
@@ -20,16 +22,18 @@ npm install @memberjunction/ng-link-directives
20
22
 
21
23
  ## Requirements
22
24
 
23
- - Angular 18+
24
- - @memberjunction/core
25
+ - Angular 18.0.2 or higher
26
+ - @memberjunction/core 2.43.0 or higher
27
+ - TypeScript 4.0 or higher
25
28
 
26
29
  ## Usage
27
30
 
28
31
  ### Basic Setup
29
32
 
30
- First, import the LinkDirectivesModule in your module:
33
+ Import the LinkDirectivesModule in your Angular module:
31
34
 
32
35
  ```typescript
36
+ import { NgModule } from '@angular/core';
33
37
  import { LinkDirectivesModule } from '@memberjunction/ng-link-directives';
34
38
 
35
39
  @NgModule({
@@ -49,7 +53,16 @@ The email link directive converts text into a mailto: link when the field has an
49
53
  <span [mjEmailLink]="field">{{ field.Value }}</span>
50
54
  ```
51
55
 
52
- Where `field` is an EntityField object from a MemberJunction entity with ExtendedType of "email".
56
+ ```typescript
57
+ // In your component
58
+ import { EntityField } from '@memberjunction/core';
59
+
60
+ export class YourComponent {
61
+ field: EntityField; // EntityField with ExtendedType = "email"
62
+ }
63
+ ```
64
+
65
+ **Note**: The directive will log an error if the field's ExtendedType is not "email". There is a known issue where the error message incorrectly references "mjWebLink" instead of "mjEmailLink".
53
66
 
54
67
  ### Web Link Directive
55
68
 
@@ -59,74 +72,134 @@ The web link directive converts text into an external URL link when the field ha
59
72
  <span [mjWebLink]="field">{{ field.Value }}</span>
60
73
  ```
61
74
 
62
- Where `field` is an EntityField object from a MemberJunction entity with ExtendedType of "url".
75
+ ```typescript
76
+ // In your component
77
+ import { EntityField } from '@memberjunction/core';
78
+
79
+ export class YourComponent {
80
+ field: EntityField; // EntityField with ExtendedType = "url"
81
+ }
82
+ ```
83
+
84
+ **Note**: The directive will log an error if the field's ExtendedType is not "url". Links open in a new tab by default.
63
85
 
64
86
  ### Field Link Directive
65
87
 
66
88
  The field link directive creates a link to another entity record when the field is a foreign key to another entity.
67
89
 
68
90
  ```html
91
+ <!-- Basic usage -->
69
92
  <span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'">
70
93
  {{ customerRecord.Get('AssignedUserID') }}
71
94
  </span>
95
+
96
+ <!-- With text replacement disabled -->
97
+ <span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'" [replaceText]="false">
98
+ {{ customerRecord.Get('AssignedUserID') }}
99
+ </span>
100
+ ```
101
+
102
+ ```typescript
103
+ // In your component
104
+ import { BaseEntity } from '@memberjunction/core';
105
+
106
+ export class YourComponent {
107
+ customerRecord: BaseEntity; // Entity record containing the foreign key field
108
+ }
72
109
  ```
73
110
 
74
- This will display the AssignedUserID field value but link to the User entity record. The directive will attempt to replace the ID with the related entity's name when [replaceText]="true" is set.
111
+ The directive:
112
+ - Navigates to `/resource/record/{primaryKey}?Entity={EntityName}` when clicked
113
+ - Automatically replaces the ID with the related entity's name (when `replaceText=true`)
114
+ - Uses `RelatedEntityNameFieldMap` metadata for efficient name resolution
115
+ - Falls back to server lookup if name mapping is not available
75
116
 
76
117
  ## API Reference
77
118
 
78
119
  ### EmailLink Directive
79
120
 
80
- | Input | Type | Description |
81
- |-------|------|-------------|
82
- | `field` | `EntityField` | The entity field object containing email data |
121
+ **Selector**: `[mjEmailLink]`
122
+
123
+ | Input | Type | Required | Description |
124
+ |-------|------|----------|-------------|
125
+ | `field` | `EntityField` | Yes | The entity field object containing email data. Must have ExtendedType = "email" |
83
126
 
84
127
  ### WebLink Directive
85
128
 
86
- | Input | Type | Description |
87
- |-------|------|-------------|
88
- | `field` | `EntityField` | The entity field object containing URL data |
129
+ **Selector**: `[mjWebLink]`
130
+
131
+ | Input | Type | Required | Description |
132
+ |-------|------|----------|-------------|
133
+ | `field` | `EntityField` | Yes | The entity field object containing URL data. Must have ExtendedType = "url" |
89
134
 
90
135
  ### FieldLink Directive
91
136
 
92
- | Input | Type | Default | Description |
93
- |-------|------|---------|-------------|
94
- | `record` | `BaseEntity` | (required) | The entity record object |
95
- | `fieldName` | `string` | (required) | The name of the field that contains the foreign key |
96
- | `replaceText` | `boolean` | `true` | Whether to replace the field value with the related entity's name |
137
+ **Selector**: `[mjFieldLink]`
138
+
139
+ | Input | Type | Default | Required | Description |
140
+ |-------|------|---------|----------|-------------|
141
+ | `mjFieldLink` | `boolean` | - | Yes | Enable the directive (must be set to true) |
142
+ | `record` | `BaseEntity` | - | Yes | The entity record object containing the field |
143
+ | `fieldName` | `string` | - | Yes | The name of the field that contains the foreign key |
144
+ | `replaceText` | `boolean` | `true` | No | Whether to replace the field value with the related entity's name |
97
145
 
98
- ## How It Works
146
+ **Events**: The directive handles click events internally to navigate using Angular Router.
147
+
148
+ ## Implementation Details
99
149
 
100
150
  ### Base Link Class
101
151
 
102
- All directives extend the BaseLink abstract class, which provides a common CreateLink method:
152
+ All directives extend the `BaseLink` abstract class, which provides a common `CreateLink` method:
103
153
 
104
154
  ```typescript
105
- protected CreateLink(el: ElementRef, field: EntityField, renderer: Renderer2, href: string, newTab: boolean = false) {
106
- // Creates an <a> element and wraps the original element
107
- }
155
+ protected CreateLink(
156
+ el: ElementRef,
157
+ field: EntityField,
158
+ renderer: Renderer2,
159
+ href: string,
160
+ newTab: boolean = false
161
+ ): void
108
162
  ```
109
163
 
164
+ This method:
165
+ - Creates an `<a>` element using Angular's Renderer2
166
+ - Wraps the original element with the link
167
+ - Adds the `link-text` CSS class
168
+ - Sets `target="_blank"` for new tab behavior
169
+
110
170
  ### Email Links
111
171
 
112
- The EmailLink directive prepends "mailto:" to the field value and creates a link that opens the user's email client when clicked.
172
+ The `EmailLink` directive:
173
+ 1. Validates that the field has ExtendedType = "email"
174
+ 2. Prepends "mailto:" to the field value
175
+ 3. Creates a link that opens the user's default email client
176
+ 4. Always opens in a new tab
113
177
 
114
178
  ### Web Links
115
179
 
116
- The WebLink directive uses the field value as the URL and creates a link that opens in a new tab when clicked.
180
+ The `WebLink` directive:
181
+ 1. Validates that the field has ExtendedType = "url"
182
+ 2. Uses the field value directly as the href
183
+ 3. Creates an external link that opens in a new tab
184
+ 4. Logs an error if the ExtendedType validation fails
117
185
 
118
186
  ### Field Links
119
187
 
120
- The FieldLink directive:
121
- 1. Identifies the related entity from the field metadata
122
- 2. Gets the primary key of the related record
123
- 3. Creates a link to navigate to that record in the application
124
- 4. Optionally replaces the ID with the related record's name
125
- 5. Intercepts click events to handle navigation within the Angular app
188
+ The `FieldLink` directive provides the most complex functionality:
189
+
190
+ 1. **Metadata Resolution**: Uses MemberJunction's metadata to find the related entity
191
+ 2. **Navigation Setup**: Constructs the route as `/resource/record/{primaryKey}?Entity={EntityName}`
192
+ 3. **Name Resolution**:
193
+ - First checks `RelatedEntityNameFieldMap` for local field mapping
194
+ - Falls back to `GetEntityRecordName()` API call if needed
195
+ 4. **Click Handling**: Intercepts clicks and uses Angular Router for navigation
196
+ 5. **Error Handling**: Includes navigation event monitoring for debugging
197
+
198
+ **Note**: Currently supports only single-value primary keys for foreign key relationships.
126
199
 
127
200
  ## Styling
128
201
 
129
- All links use the CSS class `link-text`, which you can style in your application:
202
+ All generated links include the CSS class `link-text` for consistent styling across your application:
130
203
 
131
204
  ```css
132
205
  .link-text {
@@ -134,11 +207,124 @@ All links use the CSS class `link-text`, which you can style in your application
134
207
  text-decoration: underline;
135
208
  cursor: pointer;
136
209
  }
210
+
211
+ .link-text:hover {
212
+ color: #0052a3;
213
+ text-decoration: none;
214
+ }
215
+
216
+ .link-text:visited {
217
+ color: #551a8b;
218
+ }
219
+ ```
220
+
221
+ ## Complete Example
222
+
223
+ Here's a complete example showing all three directives in action:
224
+
225
+ ```typescript
226
+ // component.ts
227
+ import { Component, OnInit } from '@angular/core';
228
+ import { BaseEntity, Metadata } from '@memberjunction/core';
229
+
230
+ @Component({
231
+ selector: 'app-contact-details',
232
+ template: `
233
+ <div class="contact-info">
234
+ <!-- Email link -->
235
+ <div>
236
+ Email: <span [mjEmailLink]="emailField">{{ contact.Get('Email') }}</span>
237
+ </div>
238
+
239
+ <!-- Web link -->
240
+ <div>
241
+ Website: <span [mjWebLink]="websiteField">{{ contact.Get('Website') }}</span>
242
+ </div>
243
+
244
+ <!-- Field link with name replacement -->
245
+ <div>
246
+ Account Manager:
247
+ <span [mjFieldLink]="true" [record]="contact" [fieldName]="'AccountManagerID'">
248
+ {{ contact.Get('AccountManagerID') }}
249
+ </span>
250
+ </div>
251
+ </div>
252
+ `
253
+ })
254
+ export class ContactDetailsComponent implements OnInit {
255
+ contact: BaseEntity;
256
+
257
+ get emailField() {
258
+ return this.contact.Fields.find(f => f.Name === 'Email');
259
+ }
260
+
261
+ get websiteField() {
262
+ return this.contact.Fields.find(f => f.Name === 'Website');
263
+ }
264
+
265
+ async ngOnInit() {
266
+ const md = new Metadata();
267
+ this.contact = await md.GetEntityObject('Contacts');
268
+ await this.contact.Load(123); // Load specific contact
269
+ }
270
+ }
271
+ ```
272
+
273
+ ## Build and Development
274
+
275
+ This package uses the Angular CLI compiler (`ngc`) for building:
276
+
277
+ ```bash
278
+ # Build the package
279
+ npm run build
280
+
281
+ # The compiled output will be in the ./dist directory
137
282
  ```
138
283
 
284
+ The package is configured with:
285
+ - TypeScript strict mode
286
+ - ES2015 target with ES2020 modules
287
+ - Source maps and declaration files
288
+ - Angular compiler optimizations
289
+
290
+ ## Integration with MemberJunction
291
+
292
+ This package is designed to work seamlessly with the MemberJunction framework:
293
+
294
+ - **Metadata Integration**: Leverages EntityField metadata for field type detection
295
+ - **Navigation**: Integrates with MJ's standard routing patterns (`/resource/record/...`)
296
+ - **Entity System**: Works with BaseEntity and EntityField objects
297
+ - **Name Resolution**: Uses MJ's entity relationship mapping for efficient data display
298
+
299
+ ## Troubleshooting
300
+
301
+ ### Common Issues
302
+
303
+ 1. **"Entity Field must have ExtendedType of URL"** - Ensure your entity field metadata has the correct ExtendedType set
304
+ 2. **Links not appearing** - Verify the directive is properly applied and the field has a value
305
+ 3. **Navigation errors** - Check that the related entity exists in metadata and the route is configured
306
+
307
+ ### Debugging Tips
308
+
309
+ - The FieldLink directive logs navigation events to the console
310
+ - Use browser DevTools to inspect the generated link structure
311
+ - Check that RelatedEntity metadata is properly configured for field links
312
+
313
+ ## License
314
+
315
+ ISC
316
+
139
317
  ## Dependencies
140
318
 
141
- - @angular/common
142
- - @angular/core
143
- - @angular/router
144
- - @memberjunction/core
319
+ - **Runtime Dependencies:**
320
+ - @memberjunction/core: ^2.43.0
321
+ - tslib: ^2.3.0
322
+
323
+ - **Peer Dependencies:**
324
+ - @angular/common: ^18.0.2
325
+ - @angular/core: ^18.0.2
326
+ - @angular/router: ^18.0.2
327
+
328
+ - **Development Dependencies:**
329
+ - @angular/compiler: ^18.0.2
330
+ - @angular/compiler-cli: ^18.0.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-link-directives",
3
- "version": "2.43.0",
3
+ "version": "2.44.0",
4
4
  "description": "MemberJunction: Angular Link Directives for turning an element in an angular app into an email, web, or record link",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "tslib": "^2.3.0",
33
- "@memberjunction/core": "2.43.0"
33
+ "@memberjunction/core": "2.44.0"
34
34
  },
35
35
  "sideEffects": false
36
36
  }