@memberjunction/ng-link-directives 4.0.0 → 4.2.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 +54 -285
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,18 +1,37 @@
1
1
  # @memberjunction/ng-link-directives
2
2
 
3
- The `@memberjunction/ng-link-directives` package provides a set of Angular directives that transform text elements into different types of links based on MemberJunction entity field metadata. This makes it easy to display email addresses, URLs, and entity relationships as clickable links in your application.
3
+ Angular directives for transforming elements into clickable email, web, or entity record links. Used throughout MemberJunction forms to make field values interactive.
4
+
5
+ ## Overview
6
+
7
+ This package provides three directives that wrap elements in anchor tags based on the type of data they represent. A `BaseLink` abstract class handles the shared DOM manipulation logic. These directives are used automatically by MemberJunction's form system to make email addresses, URLs, and foreign key values clickable.
8
+
9
+ ```mermaid
10
+ graph TD
11
+ BL["BaseLink\n(Abstract)"] --> EL["EmailLinkDirective\n[mjEmailLink]"]
12
+ BL --> WL["WebLinkDirective\n[mjWebLink]"]
13
+ BL --> FL["FieldLinkDirective\n[mjFieldLink]"]
14
+
15
+ EL --> MA["mailto: link"]
16
+ WL --> HA["http(s): link"]
17
+ FL --> RN["Router navigation\n(entity record)"]
18
+
19
+ style BL fill:#7c5295,stroke:#563a6b,color:#fff
20
+ style EL fill:#2d6a9f,stroke:#1a4971,color:#fff
21
+ style WL fill:#2d6a9f,stroke:#1a4971,color:#fff
22
+ style FL fill:#2d6a9f,stroke:#1a4971,color:#fff
23
+ style MA fill:#2d8659,stroke:#1a5c3a,color:#fff
24
+ style HA fill:#2d8659,stroke:#1a5c3a,color:#fff
25
+ style RN fill:#2d8659,stroke:#1a5c3a,color:#fff
26
+ ```
4
27
 
5
28
  ## Features
6
29
 
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
30
+ - **Email links**: Wraps text in a `mailto:` anchor tag
31
+ - **Web links**: Wraps text in an `http(s):` anchor tag (opens in new tab)
32
+ - **Field/Record links**: Wraps entity foreign key values as router links to navigate to the referenced record
33
+ - **Automatic styling**: Adds `link-text` CSS class with consistent font sizing
34
+ - **Lightweight**: Minimal DOM manipulation using Angular `Renderer2`
16
35
 
17
36
  ## Installation
18
37
 
@@ -20,311 +39,61 @@ The `@memberjunction/ng-link-directives` package provides a set of Angular direc
20
39
  npm install @memberjunction/ng-link-directives
21
40
  ```
22
41
 
23
- ## Requirements
42
+ ## Key Dependencies
24
43
 
25
- - Angular 21 or higher
26
- - @memberjunction/core 2.43.0 or higher
27
- - TypeScript 4.0 or higher
44
+ | Dependency | Purpose |
45
+ |---|---|
46
+ | `@memberjunction/core` | EntityField metadata |
47
+ | `@memberjunction/ng-shared` | SharedService, navigation |
48
+ | `@angular/router` | Router for record navigation |
28
49
 
29
50
  ## Usage
30
51
 
31
- ### Basic Setup
32
-
33
- Import the LinkDirectivesModule in your Angular module:
52
+ ### Import the Module
34
53
 
35
54
  ```typescript
36
- import { NgModule } from '@angular/core';
37
55
  import { LinkDirectivesModule } from '@memberjunction/ng-link-directives';
38
56
 
39
57
  @NgModule({
40
- imports: [
41
- // other imports...
42
- LinkDirectivesModule
43
- ],
58
+ imports: [LinkDirectivesModule]
44
59
  })
45
- export class YourModule { }
60
+ export class AppModule {}
46
61
  ```
47
62
 
48
- ### Email Link Directive
49
-
50
- The email link directive converts text into a mailto: link when the field has an extended type of "email".
63
+ ### Email Link
51
64
 
52
65
  ```html
53
- <span [mjEmailLink]="field">{{ field.Value }}</span>
54
- ```
55
-
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
- }
66
+ <span [mjEmailLink]="emailField">user@example.com</span>
63
67
  ```
64
68
 
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".
66
-
67
- ### Web Link Directive
68
-
69
- The web link directive converts text into an external URL link when the field has an extended type of "url".
69
+ ### Web Link
70
70
 
71
71
  ```html
72
- <span [mjWebLink]="field">{{ field.Value }}</span>
73
- ```
74
-
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
- }
72
+ <span [mjWebLink]="urlField">https://example.com</span>
82
73
  ```
83
74
 
84
- **Note**: The directive will log an error if the field's ExtendedType is not "url". Links open in a new tab by default.
85
-
86
- ### Field Link Directive
87
-
88
- The field link directive creates a link to another entity record when the field is a foreign key to another entity.
75
+ ### Field/Record Link
89
76
 
90
77
  ```html
91
- <!-- Basic usage -->
92
- <span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'">
93
- {{ customerRecord.Get('AssignedUserID') }}
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
- }
109
- ```
110
-
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
116
-
117
- ## API Reference
118
-
119
- ### EmailLink Directive
120
-
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" |
126
-
127
- ### WebLink Directive
128
-
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" |
134
-
135
- ### FieldLink Directive
136
-
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 |
145
-
146
- **Events**: The directive handles click events internally to navigate using Angular Router.
147
-
148
- ## Implementation Details
149
-
150
- ### Base Link Class
151
-
152
- All directives extend the `BaseLink` abstract class, which provides a common `CreateLink` method:
153
-
154
- ```typescript
155
- protected CreateLink(
156
- el: ElementRef,
157
- field: EntityField,
158
- renderer: Renderer2,
159
- href: string,
160
- newTab: boolean = false
161
- ): void
162
- ```
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
-
170
- ### Email Links
171
-
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
177
-
178
- ### Web Links
179
-
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
185
-
186
- ### Field Links
187
-
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.
199
-
200
- ## Styling
201
-
202
- All generated links include the CSS class `link-text` for consistent styling across your application:
203
-
204
- ```css
205
- .link-text {
206
- color: #0066cc;
207
- text-decoration: underline;
208
- cursor: pointer;
209
- }
210
-
211
- .link-text:hover {
212
- color: #0052a3;
213
- text-decoration: none;
214
- }
215
-
216
- .link-text:visited {
217
- color: #551a8b;
218
- }
78
+ <span [mjFieldLink]="foreignKeyField" [record]="entityRecord">Related Record</span>
219
79
  ```
220
80
 
221
- ## Complete Example
81
+ ## Exported API
222
82
 
223
- Here's a complete example showing all three directives in action:
83
+ | Export | Type | Description |
84
+ |---|---|---|
85
+ | `LinkDirectivesModule` | NgModule | Module with all directive declarations |
86
+ | `BaseLink` | Abstract Class | Shared link creation logic |
87
+ | `EmailLinkDirective` | Directive | `[mjEmailLink]` - creates mailto links |
88
+ | `WebLinkDirective` | Directive | `[mjWebLink]` - creates web links |
89
+ | `FieldLinkDirective` | Directive | `[mjFieldLink]` - creates record navigation links |
224
90
 
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:
91
+ ## Build
276
92
 
277
93
  ```bash
278
- # Build the package
279
- npm run build
280
-
281
- # The compiled output will be in the ./dist directory
94
+ cd packages/Angular/Explorer/link-directives && npm run build
282
95
  ```
283
96
 
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
97
  ## License
314
98
 
315
99
  ISC
316
-
317
- ## Dependencies
318
-
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": "4.0.0",
3
+ "version": "4.2.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,8 +30,8 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "tslib": "^2.8.1",
33
- "@memberjunction/core": "4.0.0",
34
- "@memberjunction/ng-shared": "4.0.0"
33
+ "@memberjunction/core": "4.2.0",
34
+ "@memberjunction/ng-shared": "4.2.0"
35
35
  },
36
36
  "sideEffects": false,
37
37
  "repository": {