@memberjunction/ng-action-gallery 2.55.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 +237 -0
- package/dist/lib/action-gallery-dialog.service.d.ts +53 -0
- package/dist/lib/action-gallery-dialog.service.d.ts.map +1 -0
- package/dist/lib/action-gallery-dialog.service.js +149 -0
- package/dist/lib/action-gallery-dialog.service.js.map +1 -0
- package/dist/lib/action-gallery.component.d.ts +73 -0
- package/dist/lib/action-gallery.component.d.ts.map +1 -0
- package/dist/lib/action-gallery.component.js +817 -0
- package/dist/lib/action-gallery.component.js.map +1 -0
- package/dist/module.d.ts +21 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +92 -0
- package/dist/module.js.map +1 -0
- package/dist/public-api.d.ts +5 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +7 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# @memberjunction/ng-action-gallery
|
|
2
|
+
|
|
3
|
+
A beautiful, filterable gallery component for browsing and selecting actions in MemberJunction applications.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Action Gallery provides an exceptional user experience for discovering, browsing, and selecting actions. It features both grid and list views, category navigation, and powerful search capabilities.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🎨 Beautiful grid and list view modes
|
|
12
|
+
- 🌳 Hierarchical category navigation with counts
|
|
13
|
+
- 🔍 Real-time search filtering
|
|
14
|
+
- ✅ Single and multi-selection support
|
|
15
|
+
- 📇 Expandable action cards with details
|
|
16
|
+
- ⚡ Quick test integration
|
|
17
|
+
- 🎯 TypeScript support with full type safety
|
|
18
|
+
- 🌓 Light and dark theme support
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @memberjunction/ng-action-gallery
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Module Import
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { ActionGalleryModule } from '@memberjunction/ng-action-gallery';
|
|
32
|
+
|
|
33
|
+
@NgModule({
|
|
34
|
+
imports: [
|
|
35
|
+
ActionGalleryModule,
|
|
36
|
+
// ... other imports
|
|
37
|
+
]
|
|
38
|
+
})
|
|
39
|
+
export class YourModule { }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Component Usage
|
|
43
|
+
|
|
44
|
+
#### Standalone Gallery
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<mj-action-gallery
|
|
48
|
+
[config]="galleryConfig"
|
|
49
|
+
[preSelectedActions]="selectedIds"
|
|
50
|
+
(actionSelected)="onActionSelected($event)"
|
|
51
|
+
(actionsSelected)="onActionsSelected($event)"
|
|
52
|
+
(actionTestRequested)="onTestRequested($event)">
|
|
53
|
+
</mj-action-gallery>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
galleryConfig: ActionGalleryConfig = {
|
|
58
|
+
selectionMode: true,
|
|
59
|
+
multiSelect: true,
|
|
60
|
+
showCategories: true,
|
|
61
|
+
showSearch: true,
|
|
62
|
+
defaultView: 'grid',
|
|
63
|
+
gridColumns: 3,
|
|
64
|
+
enableQuickTest: true,
|
|
65
|
+
theme: 'light'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
selectedIds = ['action-id-1', 'action-id-2'];
|
|
69
|
+
|
|
70
|
+
onActionSelected(action: ActionEntity) {
|
|
71
|
+
console.log('Selected action:', action);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
onActionsSelected(actions: ActionEntity[]) {
|
|
75
|
+
console.log('Selected actions:', actions);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Dialog Mode
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { ActionGalleryDialogService } from '@memberjunction/ng-action-gallery';
|
|
83
|
+
|
|
84
|
+
constructor(private actionGallery: ActionGalleryDialogService) {}
|
|
85
|
+
|
|
86
|
+
// Single selection
|
|
87
|
+
selectSingleAction() {
|
|
88
|
+
this.actionGallery.openForSingleSelection({
|
|
89
|
+
title: 'Select an Action',
|
|
90
|
+
showCategories: true,
|
|
91
|
+
enableQuickTest: true
|
|
92
|
+
}).subscribe(action => {
|
|
93
|
+
if (action) {
|
|
94
|
+
console.log('Selected:', action);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Multi-selection
|
|
100
|
+
selectMultipleActions() {
|
|
101
|
+
this.actionGallery.openForMultiSelection({
|
|
102
|
+
title: 'Select Actions',
|
|
103
|
+
preSelectedActions: ['id1', 'id2'],
|
|
104
|
+
showCategories: true,
|
|
105
|
+
submitButtonText: 'Add Selected Actions'
|
|
106
|
+
}).subscribe(actions => {
|
|
107
|
+
console.log('Selected actions:', actions);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Browse only (no selection)
|
|
112
|
+
browseActions() {
|
|
113
|
+
this.actionGallery.openForBrowsing({
|
|
114
|
+
title: 'Action Browser',
|
|
115
|
+
enableQuickTest: true
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
### ActionGalleryConfig
|
|
123
|
+
|
|
124
|
+
| Property | Type | Default | Description |
|
|
125
|
+
|----------|------|---------|-------------|
|
|
126
|
+
| selectionMode | `boolean` | `false` | Enable selection mode |
|
|
127
|
+
| multiSelect | `boolean` | `false` | Allow multiple selections |
|
|
128
|
+
| showCategories | `boolean` | `true` | Show category sidebar |
|
|
129
|
+
| showSearch | `boolean` | `true` | Show search bar |
|
|
130
|
+
| defaultView | `'grid' \| 'list'` | `'grid'` | Default view mode |
|
|
131
|
+
| gridColumns | `number` | `3` | Number of grid columns |
|
|
132
|
+
| enableQuickTest | `boolean` | `true` | Show test buttons |
|
|
133
|
+
| theme | `'light' \| 'dark'` | `'light'` | Visual theme |
|
|
134
|
+
|
|
135
|
+
### ActionGalleryDialogConfig
|
|
136
|
+
|
|
137
|
+
Extends `ActionGalleryConfig` with:
|
|
138
|
+
|
|
139
|
+
| Property | Type | Default | Description |
|
|
140
|
+
|----------|------|---------|-------------|
|
|
141
|
+
| title | `string` | `'Select Actions'` | Dialog title |
|
|
142
|
+
| width | `number` | `1200` | Dialog width |
|
|
143
|
+
| height | `number` | `800` | Dialog height |
|
|
144
|
+
| submitButtonText | `string` | `'Select'` | Submit button text |
|
|
145
|
+
| cancelButtonText | `string` | `'Cancel'` | Cancel button text |
|
|
146
|
+
| preSelectedActions | `string[]` | `[]` | Pre-selected action IDs |
|
|
147
|
+
|
|
148
|
+
## Features in Detail
|
|
149
|
+
|
|
150
|
+
### Category Navigation
|
|
151
|
+
|
|
152
|
+
The gallery displays a hierarchical category tree on the left side:
|
|
153
|
+
- Shows action counts per category
|
|
154
|
+
- Supports nested categories
|
|
155
|
+
- Collapsible/expandable nodes
|
|
156
|
+
- "All Actions" and "Uncategorized" special categories
|
|
157
|
+
|
|
158
|
+
### Action Cards
|
|
159
|
+
|
|
160
|
+
Each action is displayed as an expandable card showing:
|
|
161
|
+
- Action name and icon
|
|
162
|
+
- Category badge
|
|
163
|
+
- Description
|
|
164
|
+
- Quick test button (if enabled)
|
|
165
|
+
- Expanded details:
|
|
166
|
+
- Parameters with types and required status
|
|
167
|
+
- Result codes with descriptions
|
|
168
|
+
|
|
169
|
+
### Search and Filtering
|
|
170
|
+
|
|
171
|
+
Real-time search across:
|
|
172
|
+
- Action names
|
|
173
|
+
- Descriptions
|
|
174
|
+
- Categories
|
|
175
|
+
|
|
176
|
+
### View Modes
|
|
177
|
+
|
|
178
|
+
**Grid View**: Visual cards in a responsive grid layout
|
|
179
|
+
**List View**: Compact table format for scanning many actions
|
|
180
|
+
|
|
181
|
+
## Styling
|
|
182
|
+
|
|
183
|
+
The component uses CSS custom properties for theming:
|
|
184
|
+
|
|
185
|
+
```scss
|
|
186
|
+
:root {
|
|
187
|
+
--gallery-primary: #007bff;
|
|
188
|
+
--gallery-hover: #0056b3;
|
|
189
|
+
--gallery-selected: #e3f2fd;
|
|
190
|
+
--gallery-background: #ffffff;
|
|
191
|
+
--gallery-text: #212529;
|
|
192
|
+
--gallery-border: #dee2e6;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Integration with AI Test Harness
|
|
197
|
+
|
|
198
|
+
The Action Gallery integrates seamlessly with the AI Test Harness:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// In gallery configuration
|
|
202
|
+
enableQuickTest: true
|
|
203
|
+
|
|
204
|
+
// Handle test requests
|
|
205
|
+
onTestRequested(action: ActionEntity) {
|
|
206
|
+
this.testHarness.openForAction(action.ID).subscribe(result => {
|
|
207
|
+
console.log('Test result:', result);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Performance
|
|
213
|
+
|
|
214
|
+
- Lazy loads action details on expansion
|
|
215
|
+
- Debounced search for smooth filtering
|
|
216
|
+
- Virtual scrolling ready for large datasets
|
|
217
|
+
- Efficient category tree rendering
|
|
218
|
+
|
|
219
|
+
## Dependencies
|
|
220
|
+
|
|
221
|
+
- Angular 18.0.2+
|
|
222
|
+
- @memberjunction/core
|
|
223
|
+
- @memberjunction/core-entities
|
|
224
|
+
- @memberjunction/ng-ai-test-harness
|
|
225
|
+
- Kendo UI for Angular
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
ISC
|
|
230
|
+
|
|
231
|
+
## Contributing
|
|
232
|
+
|
|
233
|
+
Contributions are welcome! Please submit pull requests to the MemberJunction repository.
|
|
234
|
+
|
|
235
|
+
## Support
|
|
236
|
+
|
|
237
|
+
For issues and questions, please use the MemberJunction GitHub repository.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ViewContainerRef } from '@angular/core';
|
|
2
|
+
import { DialogService } from '@progress/kendo-angular-dialog';
|
|
3
|
+
import { ActionGalleryConfig } from './action-gallery.component';
|
|
4
|
+
import { ActionEntity } from '@memberjunction/core-entities';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export interface ActionGalleryDialogConfig extends ActionGalleryConfig {
|
|
8
|
+
title?: string;
|
|
9
|
+
width?: number;
|
|
10
|
+
height?: number;
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
minHeight?: number;
|
|
13
|
+
submitButtonText?: string;
|
|
14
|
+
cancelButtonText?: string;
|
|
15
|
+
preSelectedActions?: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare class ActionGalleryDialogService {
|
|
18
|
+
private dialogService;
|
|
19
|
+
private dialogRef;
|
|
20
|
+
constructor(dialogService: DialogService);
|
|
21
|
+
/**
|
|
22
|
+
* Opens the Action Gallery in a dialog for single selection
|
|
23
|
+
* @param config Configuration for the gallery
|
|
24
|
+
* @param viewContainerRef Optional ViewContainerRef for proper positioning
|
|
25
|
+
* @returns Observable that emits the selected action when confirmed
|
|
26
|
+
*/
|
|
27
|
+
openForSingleSelection(config?: ActionGalleryDialogConfig, viewContainerRef?: ViewContainerRef): Observable<ActionEntity | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Opens the Action Gallery in a dialog for multiple selection
|
|
30
|
+
* @param config Configuration for the gallery
|
|
31
|
+
* @param viewContainerRef Optional ViewContainerRef for proper positioning
|
|
32
|
+
* @returns Observable that emits the selected actions when confirmed
|
|
33
|
+
*/
|
|
34
|
+
openForMultiSelection(config?: ActionGalleryDialogConfig, viewContainerRef?: ViewContainerRef): Observable<ActionEntity[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Opens the Action Gallery in a dialog for browsing only (no selection)
|
|
37
|
+
* @param config Configuration for the gallery
|
|
38
|
+
* @param viewContainerRef Optional ViewContainerRef for proper positioning
|
|
39
|
+
*/
|
|
40
|
+
openForBrowsing(config?: ActionGalleryDialogConfig, viewContainerRef?: ViewContainerRef): void;
|
|
41
|
+
/**
|
|
42
|
+
* Closes the currently open dialog
|
|
43
|
+
*/
|
|
44
|
+
close(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a dialog is currently open
|
|
47
|
+
*/
|
|
48
|
+
isOpen(): boolean;
|
|
49
|
+
private openDialog;
|
|
50
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ActionGalleryDialogService, never>;
|
|
51
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ActionGalleryDialogService>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=action-gallery-dialog.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-gallery-dialog.service.d.ts","sourceRoot":"","sources":["../../src/lib/action-gallery-dialog.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAA6B,MAAM,gCAAgC,CAAC;AAC1F,OAAO,EAA0B,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;;AAE3C,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,qBAGa,0BAA0B;IAGzB,OAAO,CAAC,aAAa;IAFjC,OAAO,CAAC,SAAS,CAA0B;gBAEvB,aAAa,EAAE,aAAa;IAEhD;;;;;OAKG;IACH,sBAAsB,CACpB,MAAM,GAAE,yBAA8B,EACtC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC;IA2BlC;;;;;OAKG;IACH,qBAAqB,CACnB,MAAM,GAAE,yBAA8B,EACtC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,UAAU,CAAC,YAAY,EAAE,CAAC;IA2B7B;;;;OAIG;IACH,eAAe,CACb,MAAM,GAAE,yBAA8B,EACtC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,IAAI;IAgCP;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB,OAAO,CAAC,UAAU;yCAtIP,0BAA0B;6CAA1B,0BAA0B;CAmKtC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { ActionGalleryComponent } from './action-gallery.component';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@progress/kendo-angular-dialog";
|
|
6
|
+
export class ActionGalleryDialogService {
|
|
7
|
+
constructor(dialogService) {
|
|
8
|
+
this.dialogService = dialogService;
|
|
9
|
+
this.dialogRef = null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Opens the Action Gallery in a dialog for single selection
|
|
13
|
+
* @param config Configuration for the gallery
|
|
14
|
+
* @param viewContainerRef Optional ViewContainerRef for proper positioning
|
|
15
|
+
* @returns Observable that emits the selected action when confirmed
|
|
16
|
+
*/
|
|
17
|
+
openForSingleSelection(config = {}, viewContainerRef) {
|
|
18
|
+
const resultSubject = new Subject();
|
|
19
|
+
// Configure for single selection
|
|
20
|
+
const galleryConfig = {
|
|
21
|
+
...config,
|
|
22
|
+
selectionMode: true,
|
|
23
|
+
multiSelect: false
|
|
24
|
+
};
|
|
25
|
+
this.openDialog(galleryConfig, viewContainerRef, (component) => {
|
|
26
|
+
// Handle dialog result
|
|
27
|
+
this.dialogRef.result.subscribe((result) => {
|
|
28
|
+
if (result && result.action === 'submit') {
|
|
29
|
+
const selectedActions = component.getSelectedActions();
|
|
30
|
+
resultSubject.next(selectedActions[0] || null);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
resultSubject.next(null);
|
|
34
|
+
}
|
|
35
|
+
resultSubject.complete();
|
|
36
|
+
this.dialogRef = null;
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return resultSubject.asObservable();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Opens the Action Gallery in a dialog for multiple selection
|
|
43
|
+
* @param config Configuration for the gallery
|
|
44
|
+
* @param viewContainerRef Optional ViewContainerRef for proper positioning
|
|
45
|
+
* @returns Observable that emits the selected actions when confirmed
|
|
46
|
+
*/
|
|
47
|
+
openForMultiSelection(config = {}, viewContainerRef) {
|
|
48
|
+
const resultSubject = new Subject();
|
|
49
|
+
// Configure for multi selection
|
|
50
|
+
const galleryConfig = {
|
|
51
|
+
...config,
|
|
52
|
+
selectionMode: true,
|
|
53
|
+
multiSelect: true
|
|
54
|
+
};
|
|
55
|
+
this.openDialog(galleryConfig, viewContainerRef, (component) => {
|
|
56
|
+
// Handle dialog result
|
|
57
|
+
this.dialogRef.result.subscribe((result) => {
|
|
58
|
+
if (result && result.action === 'submit') {
|
|
59
|
+
const selectedActions = component.getSelectedActions();
|
|
60
|
+
resultSubject.next(selectedActions);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
resultSubject.next([]);
|
|
64
|
+
}
|
|
65
|
+
resultSubject.complete();
|
|
66
|
+
this.dialogRef = null;
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
return resultSubject.asObservable();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Opens the Action Gallery in a dialog for browsing only (no selection)
|
|
73
|
+
* @param config Configuration for the gallery
|
|
74
|
+
* @param viewContainerRef Optional ViewContainerRef for proper positioning
|
|
75
|
+
*/
|
|
76
|
+
openForBrowsing(config = {}, viewContainerRef) {
|
|
77
|
+
const galleryConfig = {
|
|
78
|
+
...config,
|
|
79
|
+
selectionMode: false,
|
|
80
|
+
enableQuickTest: true
|
|
81
|
+
};
|
|
82
|
+
const dialogSettings = {
|
|
83
|
+
title: config.title || 'Action Gallery',
|
|
84
|
+
width: config.width || 1200,
|
|
85
|
+
height: config.height || 800,
|
|
86
|
+
minWidth: config.minWidth || 800,
|
|
87
|
+
minHeight: config.minHeight || 600,
|
|
88
|
+
content: ActionGalleryComponent,
|
|
89
|
+
actions: [
|
|
90
|
+
{ text: 'Close', themeColor: 'base' }
|
|
91
|
+
],
|
|
92
|
+
preventAction: () => false
|
|
93
|
+
};
|
|
94
|
+
this.dialogRef = this.dialogService.open(dialogSettings);
|
|
95
|
+
// Configure the component
|
|
96
|
+
const component = this.dialogRef.content.instance;
|
|
97
|
+
component.config = galleryConfig;
|
|
98
|
+
// Handle dialog close
|
|
99
|
+
this.dialogRef.result.subscribe(() => {
|
|
100
|
+
this.dialogRef = null;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Closes the currently open dialog
|
|
105
|
+
*/
|
|
106
|
+
close() {
|
|
107
|
+
if (this.dialogRef) {
|
|
108
|
+
this.dialogRef.close();
|
|
109
|
+
this.dialogRef = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Checks if a dialog is currently open
|
|
114
|
+
*/
|
|
115
|
+
isOpen() {
|
|
116
|
+
return this.dialogRef !== null;
|
|
117
|
+
}
|
|
118
|
+
openDialog(config, viewContainerRef, resultHandler) {
|
|
119
|
+
const dialogSettings = {
|
|
120
|
+
title: config.title || 'Select Actions',
|
|
121
|
+
width: config.width || 1200,
|
|
122
|
+
height: config.height || 800,
|
|
123
|
+
minWidth: config.minWidth || 800,
|
|
124
|
+
minHeight: config.minHeight || 600,
|
|
125
|
+
content: ActionGalleryComponent,
|
|
126
|
+
actions: [
|
|
127
|
+
{ text: config.cancelButtonText || 'Cancel' },
|
|
128
|
+
{ text: config.submitButtonText || 'Select', themeColor: 'primary', action: 'submit' }
|
|
129
|
+
],
|
|
130
|
+
preventAction: () => false
|
|
131
|
+
};
|
|
132
|
+
this.dialogRef = this.dialogService.open(dialogSettings);
|
|
133
|
+
// Configure the component
|
|
134
|
+
const component = this.dialogRef.content.instance;
|
|
135
|
+
component.config = config;
|
|
136
|
+
component.preSelectedActions = config.preSelectedActions || [];
|
|
137
|
+
// Handle result
|
|
138
|
+
resultHandler(component);
|
|
139
|
+
}
|
|
140
|
+
static { this.ɵfac = function ActionGalleryDialogService_Factory(t) { return new (t || ActionGalleryDialogService)(i0.ɵɵinject(i1.DialogService)); }; }
|
|
141
|
+
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ActionGalleryDialogService, factory: ActionGalleryDialogService.ɵfac, providedIn: 'root' }); }
|
|
142
|
+
}
|
|
143
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActionGalleryDialogService, [{
|
|
144
|
+
type: Injectable,
|
|
145
|
+
args: [{
|
|
146
|
+
providedIn: 'root'
|
|
147
|
+
}]
|
|
148
|
+
}], () => [{ type: i1.DialogService }], null); })();
|
|
149
|
+
//# sourceMappingURL=action-gallery-dialog.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-gallery-dialog.service.js","sourceRoot":"","sources":["../../src/lib/action-gallery-dialog.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { EventEmitter, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
|
2
|
+
import { FormControl } from '@angular/forms';
|
|
3
|
+
import { BehaviorSubject } from 'rxjs';
|
|
4
|
+
import { ActionEntity, ActionCategoryEntity, ActionParamEntity, ActionResultCodeEntity } from '@memberjunction/core-entities';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export interface ActionGalleryConfig {
|
|
7
|
+
selectionMode?: boolean;
|
|
8
|
+
multiSelect?: boolean;
|
|
9
|
+
showCategories?: boolean;
|
|
10
|
+
showSearch?: boolean;
|
|
11
|
+
defaultView?: 'grid' | 'list';
|
|
12
|
+
gridColumns?: number;
|
|
13
|
+
enableQuickTest?: boolean;
|
|
14
|
+
theme?: 'light' | 'dark';
|
|
15
|
+
}
|
|
16
|
+
export interface CategoryNode {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
parent?: string;
|
|
20
|
+
children?: CategoryNode[];
|
|
21
|
+
count?: number;
|
|
22
|
+
icon?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ActionWithDetails extends ActionEntity {
|
|
25
|
+
parameters?: ActionParamEntity[];
|
|
26
|
+
resultCodes?: ActionResultCodeEntity[];
|
|
27
|
+
expanded?: boolean;
|
|
28
|
+
selected?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare class ActionGalleryComponent implements OnInit, OnDestroy {
|
|
31
|
+
config: ActionGalleryConfig;
|
|
32
|
+
preSelectedActions: string[];
|
|
33
|
+
actionSelected: EventEmitter<ActionEntity>;
|
|
34
|
+
actionsSelected: EventEmitter<ActionEntity[]>;
|
|
35
|
+
actionTestRequested: EventEmitter<ActionEntity>;
|
|
36
|
+
searchInput: ElementRef<HTMLInputElement>;
|
|
37
|
+
private destroy$;
|
|
38
|
+
actions$: BehaviorSubject<ActionWithDetails[]>;
|
|
39
|
+
categories$: BehaviorSubject<ActionCategoryEntity[]>;
|
|
40
|
+
filteredActions$: BehaviorSubject<ActionWithDetails[]>;
|
|
41
|
+
categoryTree$: BehaviorSubject<CategoryNode[]>;
|
|
42
|
+
selectedCategory$: BehaviorSubject<string>;
|
|
43
|
+
viewMode$: BehaviorSubject<"grid" | "list">;
|
|
44
|
+
isLoading$: BehaviorSubject<boolean>;
|
|
45
|
+
selectedActions$: BehaviorSubject<Set<string>>;
|
|
46
|
+
searchControl: FormControl<string | null>;
|
|
47
|
+
expandedCategories: Set<string>;
|
|
48
|
+
hoveredAction: string | null;
|
|
49
|
+
animateCards: boolean;
|
|
50
|
+
totalActions: number;
|
|
51
|
+
categoryCounts: Map<string, number>;
|
|
52
|
+
constructor();
|
|
53
|
+
ngOnInit(): void;
|
|
54
|
+
ngOnDestroy(): void;
|
|
55
|
+
loadData(): Promise<void>;
|
|
56
|
+
private buildCategoryTree;
|
|
57
|
+
private getCategoryIcon;
|
|
58
|
+
private filterActions;
|
|
59
|
+
private getCategoryName;
|
|
60
|
+
selectCategory(categoryId: string): void;
|
|
61
|
+
toggleCategoryExpanded(categoryId: string): void;
|
|
62
|
+
toggleViewMode(): void;
|
|
63
|
+
toggleActionExpanded(action: ActionWithDetails): Promise<void>;
|
|
64
|
+
loadActionDetails(action: ActionWithDetails): Promise<void>;
|
|
65
|
+
toggleActionSelection(action: ActionWithDetails): void;
|
|
66
|
+
testAction(action: ActionEntity, event: Event): void;
|
|
67
|
+
clearSearch(): void;
|
|
68
|
+
getSelectedActions(): ActionEntity[];
|
|
69
|
+
getActionIcon(action: ActionEntity): string;
|
|
70
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ActionGalleryComponent, never>;
|
|
71
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ActionGalleryComponent, "mj-action-gallery", never, { "config": { "alias": "config"; "required": false; }; "preSelectedActions": { "alias": "preSelectedActions"; "required": false; }; }, { "actionSelected": "actionSelected"; "actionsSelected": "actionsSelected"; "actionTestRequested": "actionTestRequested"; }, never, never, false, never>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=action-gallery.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-gallery.component.d.ts","sourceRoot":"","sources":["../../src/lib/action-gallery.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAa,UAAU,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAW,eAAe,EAAgE,MAAM,MAAM,CAAC;AAE9G,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;;AAE9H,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAKa,sBAAuB,YAAW,MAAM,EAAE,SAAS;IACrD,MAAM,EAAE,mBAAmB,CASlC;IAEO,kBAAkB,EAAE,MAAM,EAAE,CAAM;IACjC,cAAc,6BAAoC;IAClD,eAAe,+BAAsC;IACrD,mBAAmB,6BAAoC;IAEpB,WAAW,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAGvF,OAAO,CAAC,QAAQ,CAAuB;IACvC,QAAQ,uCAAgD;IACxD,WAAW,0CAAmD;IAC9D,gBAAgB,uCAAgD;IAChE,aAAa,kCAA2C;IACxD,iBAAiB,0BAAsC;IACvD,SAAS,mCAAgD;IACzD,UAAU,2BAAuC;IACjD,gBAAgB,+BAA+C;IAG/D,aAAa,6BAAuB;IAGpC,kBAAkB,cAAqB;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,YAAY,UAAS;IAGrB,YAAY,SAAK;IACjB,cAAc,sBAA6B;;IAI3C,QAAQ;IAgCR,WAAW;IAKL,QAAQ;IAkDd,OAAO,CAAC,iBAAiB;IA4DzB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,eAAe;IAKvB,cAAc,CAAC,UAAU,EAAE,MAAM;IAIjC,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAQzC,cAAc;IAKR,oBAAoB,CAAC,MAAM,EAAE,iBAAiB;IAS9C,iBAAiB,CAAC,MAAM,EAAE,iBAAiB;IAiCjD,qBAAqB,CAAC,MAAM,EAAE,iBAAiB;IAgC/C,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK;IAW7C,WAAW;IAOX,kBAAkB,IAAI,YAAY,EAAE;IAKpC,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;yCAjWhC,sBAAsB;2CAAtB,sBAAsB;CAyXlC"}
|