@memberjunction/ng-link-directives 2.43.0 → 2.45.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 +228 -42
- 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
|
|
8
|
-
- Web link directive
|
|
9
|
-
- Field link directive
|
|
10
|
-
- Automatic value resolution
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
|
95
|
-
|
|
96
|
-
| `
|
|
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
|
-
|
|
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(
|
|
106
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
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
|
-
-
|
|
142
|
-
- @
|
|
143
|
-
-
|
|
144
|
-
|
|
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.
|
|
3
|
+
"version": "2.45.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.
|
|
33
|
+
"@memberjunction/core": "2.45.0"
|
|
34
34
|
},
|
|
35
35
|
"sideEffects": false
|
|
36
36
|
}
|