2.48.0 • Published 4 months ago

@memberjunction/ng-user-view-grid v2.48.0

Weekly downloads
-
License
ISC
Repository
-
Last release
4 months ago

@memberjunction/ng-user-view-grid

The @memberjunction/ng-user-view-grid package provides a powerful Angular grid component for displaying both saved and dynamic views of MemberJunction entity data. It offers a comprehensive set of features for viewing, editing, exporting, comparing, and merging entity records with full integration into the MemberJunction ecosystem.

Features

  • View Management

    • Display entities using saved user views or dynamic configurations
    • Support for both stored views (by ID) and dynamic views (by entity/filter)
    • Virtual scrolling for optimal performance with large datasets
    • Customizable columns with reordering, resizing, and sorting
    • Column formatting based on entity field types
  • Data Operations

    • Inline record editing with validation
    • Create new records directly from the grid (dialog or tab mode)
    • Export to Excel with formatted data
    • Record comparison and merging capabilities
    • Duplicate detection functionality
    • Add records to lists for organization
  • Integration Features

    • Entity action execution from the grid
    • Communication capabilities (send emails related to records)
    • Role-based permission controls for all operations
    • Auto-save and queue-based editing modes
    • Navigation to record details on row click

Installation

npm install @memberjunction/ng-user-view-grid

Requirements

Angular Version

  • Angular 18.0.2 or higher

Peer Dependencies

  • @angular/common: ^18.0.2
  • @angular/core: ^18.0.2
  • @angular/forms: ^18.0.2
  • @angular/router: ^18.0.2

MemberJunction Dependencies

  • @memberjunction/global: ^2.43.0
  • @memberjunction/core: ^2.43.0
  • @memberjunction/core-entities: ^2.43.0
  • @memberjunction/entity-communications-client: ^2.43.0
  • @memberjunction/communication-types: ^2.43.0
  • @memberjunction/templates-base-types: ^2.43.0
  • @memberjunction/actions-base: ^2.43.0
  • @memberjunction/ng-shared: ^2.43.0
  • @memberjunction/ng-entity-form-dialog: ^2.43.0
  • @memberjunction/ng-compare-records: ^2.43.0
  • @memberjunction/ng-container-directives: ^2.43.0
  • @memberjunction/ng-entity-communications: ^2.43.0
  • @memberjunction/ng-base-types: ^2.43.0

Kendo UI Dependencies

  • @progress/kendo-angular-grid: ^16.2.0
  • @progress/kendo-angular-layout: ^16.2.0
  • @progress/kendo-angular-inputs: ^16.2.0
  • @progress/kendo-angular-buttons: ^16.2.0

Usage

Module Setup

Import the UserViewGridModule in your Angular module:

import { UserViewGridModule } from '@memberjunction/ng-user-view-grid';

@NgModule({
  imports: [
    // other imports...
    UserViewGridModule
  ],
})
export class YourModule { }

Basic Example

Use the component in your template:

<mj-user-view-grid
  [Params]="viewParams"
  [BottomMargin]="15"
  [AutoNavigate]="true"
  (rowClicked)="onRowClicked($event)"
  (rowEdited)="onRowEdited($event)">
</mj-user-view-grid>

Component implementation:

import { Component } from '@angular/core';
import { RunViewParams } from '@memberjunction/core';
import { GridRowClickedEvent, GridRowEditedEvent } from '@memberjunction/ng-user-view-grid';

@Component({
  selector: 'app-my-view',
  templateUrl: './my-view.component.html',
})
export class MyViewComponent {
  // Option 1: Using a saved view by ID
  viewParams: RunViewParams = {
    ViewID: 'view-id-here'
  };
  
  // Option 2: Using a dynamic view with entity and filter
  dynamicViewParams: RunViewParams = {
    EntityName: 'Customer',
    ExtraFilter: "Status = 'Active'",
    OrderBy: 'Name ASC',
    Skip: 0,
    Take: 40
  };
  
  onRowClicked(event: GridRowClickedEvent) {
    console.log('Row clicked:', event);
    // Access event.entityName, event.entityId, event.CompositeKey
  }
  
  onRowEdited(event: GridRowEditedEvent) {
    console.log('Row edited:', event);
    // Access event.record, event.row, event.saved
  }
}

Editing Records

Enable inline editing with different save modes:

<mj-user-view-grid
  [Params]="viewParams"
  [InEditMode]="false"
  [EditMode]="'Save'"
  (rowEdited)="onRowEdited($event)">
</mj-user-view-grid>
// Component
export class MyViewComponent {
  editMode: "None" | "Save" | "Queue" = "Save";
  
  onRowEdited(event: GridRowEditedEvent) {
    if (event.saved) {
      console.log('Record saved successfully:', event.record);
    } else {
      console.log('Record queued for saving:', event.record);
    }
  }
}

The EditMode property supports three values:

  • "None" - Editing is disabled
  • "Save" - Changes are saved immediately to the database
  • "Queue" - Changes are queued locally for batch saving later

Creating New Records

Configure new record creation behavior:

<mj-user-view-grid
  [Params]="viewParams"
  [ShowCreateNewRecordButton]="true"
  [CreateRecordMode]="'Dialog'"
  [NewRecordValues]="initialValues">
</mj-user-view-grid>
// Component
export class MyViewComponent {
  // Pre-populate new records with default values
  initialValues = {
    Status: 'Active',
    CreatedDate: new Date(),
    DepartmentID: 123
  };
}

The CreateRecordMode property supports:

  • "Dialog" - Opens a modal dialog to create a new record
  • "Tab" - Opens a new browser tab to create a new record

Entity Actions and Communication

Enable entity-specific actions and communication features:

<mj-user-view-grid
  [Params]="viewParams"
  [ShowEntityActionButtons]="true"
  [ShowCommunicationButton]="true">
</mj-user-view-grid>

These features integrate with:

  • Entity Actions: Execute custom actions defined in entity metadata
  • Communications: Send emails or other communications related to selected records

API Reference

UserViewGridComponent

The main component for displaying entity data in a grid format.

Inputs

NameTypeDefaultDescription
ParamsRunViewParamsundefinedParameters defining which view to display (either ViewID for saved views or EntityName with filters for dynamic views)
BottomMarginnumber0Bottom margin in pixels to apply to the grid container
InEditModebooleanfalseControls whether the grid is currently in edit mode
EditMode"None" \| "Save" \| "Queue""None"Determines how edits are handled: None (no editing), Save (immediate), or Queue (batch)
AutoNavigatebooleantrueWhether to automatically navigate to a record's detail view when clicked
NewRecordValuesanyundefinedDefault values to populate when creating new records
ShowCreateNewRecordButtonbooleantrueWhether to display the Create New Record button (if user has permission)
ShowEntityActionButtonsbooleantrueWhether to display entity action buttons for the current entity
ShowCommunicationButtonbooleantrueWhether to display the communication button (if entity supports it)
CreateRecordMode"Dialog" \| "Tab""Tab"How to open the new record form: Dialog (modal) or Tab (new browser tab)
AllowLoadbooleantrueControls whether the grid loads data. Set to false to defer loading until ready

Outputs

NameTypeDescription
rowClickedEventEmitter<GridRowClickedEvent>Fired when a user clicks on a grid row
rowEditedEventEmitter<GridRowEditedEvent>Fired when a row edit is completed (saved or queued)

Public Methods

NameParametersReturn TypeDescription
Refreshparams: RunViewParamsPromise<void>Refreshes the grid with new view parameters
RefreshFromSavedParamsNonePromise<void>Refreshes the grid using the currently stored parameters
EditingCompleteNonePromise<boolean>Completes any in-progress editing and returns true when done
RevertPendingChangesNonevoidReverts all pending changes in Queue mode
enableMergeOrComparecancel: boolean, type: 'merge' \| 'compare'voidEnables or disables merge/compare selection mode
enableCheckboxcancel: boolean, type: 'merge' \| 'compare' \| 'duplicate' \| 'addToList' \| ''voidEnables checkbox selection for various operations
doExcelExportNonePromise<void>Exports the current view data to Excel format

Public Properties

NameTypeDescription
PendingRecordsGridPendingRecordItem[]Array of records with pending changes (readonly)
ViewIDstringThe ID of the current view being displayed (readonly)
UserCanCreateNewRecordbooleanWhether the current user can create new records (readonly)
UserCanEditbooleanWhether the current user can edit the view (readonly)

Type Definitions

GridRowClickedEvent

Emitted when a user clicks on a grid row:

type GridRowClickedEvent = {
  entityId: string;        // The ID of the clicked entity
  entityName: string;      // The name of the entity type
  CompositeKey: CompositeKey; // Composite key object for multi-key entities
}

GridRowEditedEvent

Emitted when a row edit is completed:

type GridRowEditedEvent = {
  record: BaseEntity;      // The edited entity record
  row: number;            // The row index in the grid
  saved: boolean;         // Whether the record was saved (true) or queued (false)
}

GridPendingRecordItem

Represents a record with pending changes:

type GridPendingRecordItem = {
  record: BaseEntity;     // The entity record with changes
  row: number;           // The row index in the grid
  dataItem: any;         // The raw data item from the view
}

Advanced Features

Record Operations

The grid provides powerful multi-record operations:

Compare Records

Select multiple records to view their differences side-by-side:

// Enable compare mode programmatically
@ViewChild(UserViewGridComponent) grid!: UserViewGridComponent;

startCompare() {
  this.grid.enableCheckbox(false, 'compare');
}

Merge Records

Combine multiple records into a single record: 1. Select records to merge 2. Choose which field values to keep 3. Confirm the merge operation

Duplicate Detection

Find potential duplicate records based on field similarity: 1. Select records to check 2. System analyzes field similarities 3. Results are saved to a list for review

List Management

Add selected records to lists for organization:

// Enable add to list mode
addToLists() {
  this.grid.enableCheckbox(false, 'addToList');
}

Excel Export

Export grid data with formatting:

async exportToExcel() {
  await this.grid.doExcelExport();
  // Notification will appear when complete
}

Deferred Loading

Control when the grid loads data:

<mj-user-view-grid
  [Params]="viewParams"
  [AllowLoad]="false"
  #gridRef>
</mj-user-view-grid>
// Load when ready
ngAfterViewInit() {
  // Do some initialization...
  setTimeout(() => {
    this.gridRef.AllowLoad = true; // Grid will now load
  }, 1000);
}

Working with Pending Changes

In Queue mode, manage pending changes:

// Access pending records
const pending = this.grid.PendingRecords;
console.log(`${pending.length} records have pending changes`);

// Revert all pending changes
this.grid.RevertPendingChanges();

// Complete editing and get status
const completed = await this.grid.EditingComplete();
if (completed) {
  // All edits are complete
}

Integration with MemberJunction

Entity Permissions

The grid automatically respects entity-level permissions:

  • Create button only shows if user has create permission
  • Edit capabilities respect user's update permissions
  • All operations check appropriate permissions

Entity Actions

Entity actions defined in metadata appear automatically:

  • Actions with 'View' invocation context are displayed
  • Actions are filtered by status (only 'Active' shown)
  • Custom action handlers can be implemented

Communication Integration

For entities with communication support:

  • Send emails to related contacts
  • Use template-based communications
  • Track communication history

Best Practices

  1. Use ViewID for Saved Views: When displaying user-created views, use the ViewID parameter for better performance and consistency

  2. Implement Error Handling: Always handle errors in row edit events:

    onRowEdited(event: GridRowEditedEvent) {
      if (!event.saved && this.editMode === 'Save') {
        // Handle save failure
        console.error('Failed to save record:', event.record);
      }
    }
  3. Optimize Dynamic Views: For dynamic views, use appropriate filters and pagination:

    dynamicParams: RunViewParams = {
      EntityName: 'LargeTable',
      ExtraFilter: 'IsActive = 1',
      OrderBy: 'ModifiedDate DESC',
      Take: 50 // Limit initial load
    };
  4. Defer Loading for Complex Scenarios: Use AllowLoad=false when you need to prepare data or configuration before loading

  5. Column Customization: Customize columns after the grid loads to ensure proper initialization

Module Exports

The package exports:

  • UserViewGridModule - The Angular module to import
  • UserViewGridComponent - The grid component
  • GridRowClickedEvent - Type for row click events
  • GridRowEditedEvent - Type for row edit events
  • GridPendingRecordItem - Type for pending records

Support

For issues or questions:

2.23.2

8 months ago

2.46.0

4 months ago

2.23.1

8 months ago

2.34.0

6 months ago

2.19.4

9 months ago

2.19.5

9 months ago

2.19.2

9 months ago

2.19.3

9 months ago

2.19.0

9 months ago

2.19.1

9 months ago

2.34.2

6 months ago

2.34.1

6 months ago

2.45.0

4 months ago

2.22.1

8 months ago

2.22.0

8 months ago

2.22.2

8 months ago

2.33.0

6 months ago

2.18.3

9 months ago

2.18.1

9 months ago

2.18.2

9 months ago

2.18.0

9 months ago

2.21.0

8 months ago

2.44.0

5 months ago

2.29.0

7 months ago

2.29.2

7 months ago

2.29.1

7 months ago

2.32.0

7 months ago

2.32.2

7 months ago

2.32.1

7 months ago

2.17.0

9 months ago

2.43.0

5 months ago

2.20.2

9 months ago

2.20.3

8 months ago

2.20.0

9 months ago

2.20.1

9 months ago

2.28.0

8 months ago

2.31.0

7 months ago

2.39.0

5 months ago

2.16.1

9 months ago

2.16.0

9 months ago

2.42.1

5 months ago

2.42.0

5 months ago

2.27.1

8 months ago

2.27.0

8 months ago

2.30.0

7 months ago

2.15.2

9 months ago

2.15.1

9 months ago

2.38.0

5 months ago

2.41.0

5 months ago

2.26.1

8 months ago

2.26.0

8 months ago

2.37.1

5 months ago

2.37.0

5 months ago

2.14.0

9 months ago

2.40.0

5 months ago

2.25.0

8 months ago

2.48.0

4 months ago

2.13.4

10 months ago

2.36.0

6 months ago

2.13.2

11 months ago

2.13.3

10 months ago

2.13.0

11 months ago

2.36.1

6 months ago

2.13.1

11 months ago

2.47.0

4 months ago

2.24.1

8 months ago

2.24.0

8 months ago

2.12.0

12 months ago

2.35.1

6 months ago

2.35.0

6 months ago

2.23.0

8 months ago

2.11.0

12 months ago

2.10.0

12 months ago

2.9.0

12 months ago

2.8.0

1 year ago

2.7.0

1 year ago

2.7.1

1 year ago

2.6.1

1 year ago

2.6.0

1 year ago

2.5.2

1 year ago

1.6.1

1 year ago

2.4.1

1 year ago

2.4.0

1 year ago

1.5.4

1 year ago

1.5.3

1 year ago

1.5.2

1 year ago

1.5.1

1 year ago

1.5.0

1 year ago

2.3.0

1 year ago

2.3.2

1 year ago

2.3.1

1 year ago

2.3.3

1 year ago

1.4.1

1 year ago

1.4.0

1 year ago

2.2.1

1 year ago

2.2.0

1 year ago

1.3.3

1 year ago

1.3.2

1 year ago

1.3.1

1 year ago

1.3.0

1 year ago

2.1.2

1 year ago

2.1.1

1 year ago

2.1.4

1 year ago

2.1.3

1 year ago

2.1.5

1 year ago

2.0.0

1 year ago

1.8.1

1 year ago

1.8.0

1 year ago

1.7.1

1 year ago

1.7.0

1 year ago

2.5.0

1 year ago

2.5.1

1 year ago

1.2.2

1 year ago

1.2.1

1 year ago

1.2.0

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.1.3

1 year ago

1.1.2

1 year ago

1.0.11

1 year ago

1.0.9

2 years ago

1.0.7-next.0

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.8-next.6

2 years ago

1.0.8-next.5

2 years ago

1.0.8-next.4

2 years ago

1.0.8-next.3

2 years ago

1.0.8-next.2

2 years ago

1.0.8-next.1

2 years ago

1.0.8-next.0

2 years ago

1.0.8-beta.0

2 years ago

1.0.6

2 years ago

1.0.4

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.9.237

2 years ago

0.9.232

2 years ago

0.9.235

2 years ago

0.9.234

2 years ago

0.9.236

2 years ago

0.9.231

2 years ago

0.9.230

2 years ago

0.9.228

2 years ago

0.9.227

2 years ago

0.9.229

2 years ago

0.9.226

2 years ago

0.9.225

2 years ago

0.9.222

2 years ago

0.9.224

2 years ago

0.9.223

2 years ago

0.9.221

2 years ago

0.9.219

2 years ago

0.9.217

2 years ago

0.9.216

2 years ago

0.9.218

2 years ago

0.9.215

2 years ago

0.9.214

2 years ago

0.9.211

2 years ago

0.9.212

2 years ago

0.9.213

2 years ago

0.9.209

2 years ago

0.9.208

2 years ago

0.9.206

2 years ago

0.9.205

2 years ago

0.9.207

2 years ago

0.9.204

2 years ago

0.9.202

2 years ago

0.9.203

2 years ago

0.9.201

2 years ago

0.9.200

2 years ago

0.9.199

2 years ago

0.9.198

2 years ago

0.9.197

2 years ago

0.9.196

2 years ago

0.9.187

2 years ago

0.9.186

2 years ago

0.9.189

2 years ago

0.9.188

2 years ago

0.9.185

2 years ago

0.9.184

2 years ago

0.9.194

2 years ago

0.9.193

2 years ago

0.9.195

2 years ago

0.9.190

2 years ago

0.9.191

2 years ago

0.9.183

2 years ago

0.9.181

2 years ago

0.9.180

2 years ago

0.9.179

2 years ago

0.9.154

2 years ago

0.9.153

2 years ago

0.9.156

2 years ago

0.9.155

2 years ago

0.9.150

2 years ago

0.9.152

2 years ago

0.9.151

2 years ago

0.9.148

2 years ago

0.9.165

2 years ago

0.9.164

2 years ago

0.9.167

2 years ago

0.9.166

2 years ago

0.9.161

2 years ago

0.9.160

2 years ago

0.9.163

2 years ago

0.9.162

2 years ago

0.9.158

2 years ago

0.9.157

2 years ago

0.9.159

2 years ago

0.9.176

2 years ago

0.9.175

2 years ago

0.9.178

2 years ago

0.9.177

2 years ago

0.9.172

2 years ago

0.9.171

2 years ago

0.9.174

2 years ago

0.9.173

2 years ago

0.9.170

2 years ago

0.9.169

2 years ago

0.9.168

2 years ago

0.9.147

2 years ago

0.9.146

2 years ago

0.9.143

2 years ago

0.9.145

2 years ago

0.9.144

2 years ago

0.9.142

2 years ago

0.9.141

2 years ago

0.9.140

2 years ago

0.9.139

2 years ago

0.9.136

2 years ago

0.9.138

2 years ago

0.9.137

2 years ago

0.9.135

2 years ago

0.9.134

2 years ago

0.9.133

2 years ago

0.9.132

2 years ago

0.9.131

2 years ago

0.9.120

2 years ago

0.9.111

2 years ago

0.9.110

2 years ago

0.9.109

2 years ago

0.9.108

2 years ago

0.9.97

2 years ago

0.9.98

2 years ago

0.9.99

2 years ago

0.9.102

2 years ago

0.9.101

2 years ago

0.9.96

2 years ago

0.9.92

2 years ago

0.9.93

2 years ago

0.9.94

2 years ago

0.9.95

2 years ago

0.9.90

2 years ago

0.9.91

2 years ago

0.9.89

2 years ago

0.9.85

2 years ago

0.9.86

2 years ago

0.9.87

2 years ago

0.9.88

2 years ago

0.9.83

2 years ago

0.9.84

2 years ago

0.9.78

2 years ago

0.9.76

2 years ago

0.9.77

2 years ago

0.9.74

2 years ago

0.9.75

2 years ago

0.9.70

2 years ago

0.9.71

2 years ago

0.9.72

2 years ago

0.9.73

2 years ago

0.9.69

2 years ago

0.9.68

2 years ago

0.9.67

2 years ago

0.9.66

2 years ago

0.9.63

2 years ago

0.9.64

2 years ago

0.9.65

2 years ago

0.9.61

2 years ago

0.9.62

2 years ago

0.9.60

2 years ago

0.9.59

2 years ago

0.9.57

2 years ago

0.9.58

2 years ago

0.9.56

2 years ago

0.9.55

2 years ago

0.9.54

2 years ago

0.9.53

2 years ago

0.9.52

2 years ago

0.9.51

2 years ago

0.9.50

2 years ago

0.9.49

2 years ago

0.9.48

2 years ago

0.9.47

2 years ago

0.9.46

2 years ago

0.9.45

2 years ago

0.9.44

2 years ago

0.9.43

2 years ago

0.9.42

2 years ago

0.9.41

2 years ago

0.9.40

2 years ago

0.9.39

2 years ago

0.9.38

2 years ago

0.9.37

2 years ago

0.9.36

2 years ago

0.9.35

2 years ago

0.9.34

2 years ago

0.9.31

2 years ago

0.9.30

2 years ago

0.9.29

2 years ago

0.9.28

2 years ago

0.9.25

2 years ago

0.9.24

2 years ago

0.9.23

2 years ago

0.9.22

2 years ago

0.9.21

2 years ago

0.9.20

2 years ago

0.9.19

2 years ago

0.9.18

2 years ago

0.9.17

2 years ago

0.9.16

2 years ago

0.9.15

2 years ago

0.9.14

2 years ago

0.9.13

2 years ago

0.9.12

2 years ago

0.9.11

2 years ago

0.9.10

2 years ago

0.9.9

2 years ago

0.9.8

2 years ago

0.9.7

2 years ago

0.9.6

2 years ago

0.9.5

2 years ago

0.9.4

2 years ago

0.9.2

2 years ago

0.9.1

2 years ago