2.48.0 • Published 8 months ago

@memberjunction/ng-timeline v2.48.0

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

@memberjunction/ng-timeline

The @memberjunction/ng-timeline package provides a comprehensive Angular component for displaying chronological data from MemberJunction entities in a timeline format. Built on top of Kendo UI's Timeline component, it offers a flexible and intuitive way to visualize time-based data from multiple entity sources.

Features

  • Multiple Data Sources: Display data from multiple MemberJunction entities on a unified timeline
  • Flexible Orientation: Support for both vertical and horizontal timeline layouts
  • Data Source Options: Load data via entity views with filters or provide pre-loaded entity arrays
  • Customizable Display: Configure title, date, and summary fields for each timeline item
  • Visual Customization: Support for custom icons and colors for different event groups
  • Interactive UI: Collapsible event details with alternating layout mode
  • Dynamic Content: Custom summary generation via callback functions
  • Refresh Control: Manual control over data loading and refresh operations

Installation

npm install @memberjunction/ng-timeline

Requirements

  • Angular 18.0.2 or higher
  • @memberjunction/core and related MemberJunction packages
  • Kendo UI Angular components:
    • @progress/kendo-angular-layout (v16.2.0)
    • @progress/kendo-angular-buttons (v16.2.0)
    • @progress/kendo-angular-indicators (v16.2.0)

Usage

Basic Usage

First, import the TimelineModule in your module:

import { TimelineModule } from '@memberjunction/ng-timeline';

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

Then, use the component in your template:

<mj-timeline [Groups]="timelineGroups" [DisplayOrientation]="'vertical'"></mj-timeline>

In your component file:

import { TimelineGroup } from '@memberjunction/ng-timeline';

export class YourComponent {
  timelineGroups: TimelineGroup[] = [];

  constructor() {
    // Create a timeline group using entity data
    const tasksGroup = new TimelineGroup();
    tasksGroup.EntityName = 'Tasks';
    tasksGroup.DataSourceType = 'entity';
    tasksGroup.TitleFieldName = 'Title';
    tasksGroup.DateFieldName = 'DueDate';
    tasksGroup.Filter = "Status = 'Open'";
    
    // Add the group to the array
    this.timelineGroups.push(tasksGroup);
  }
}

Advanced Usage

Using Multiple Data Sources

Display data from multiple entity types on the same timeline with different visual treatments:

import { TimelineGroup } from '@memberjunction/ng-timeline';
import { BaseEntity } from '@memberjunction/core';

export class YourComponent implements OnInit {
  timelineGroups: TimelineGroup[] = [];

  async ngOnInit() {
    // First group - Tasks with custom icon and color
    const tasksGroup = new TimelineGroup();
    tasksGroup.EntityName = 'Tasks';
    tasksGroup.DataSourceType = 'entity';
    tasksGroup.TitleFieldName = 'Title';
    tasksGroup.DateFieldName = 'DueDate';
    tasksGroup.Filter = "Status = 'Active'"; // Optional filter
    tasksGroup.DisplayIconMode = 'custom';
    tasksGroup.DisplayIcon = 'fa fa-tasks';
    tasksGroup.DisplayColorMode = 'manual';
    tasksGroup.DisplayColor = '#4287f5';
    
    // Second group - Meetings with custom summary
    const meetingsGroup = new TimelineGroup();
    meetingsGroup.EntityName = 'Meetings';
    meetingsGroup.DataSourceType = 'entity';
    meetingsGroup.TitleFieldName = 'Subject';
    meetingsGroup.DateFieldName = 'StartTime';
    meetingsGroup.SummaryMode = 'custom';
    meetingsGroup.SummaryFunction = (record: BaseEntity) => {
      return `<strong>Location:</strong> ${record.Get('Location')}<br/>
              <strong>Duration:</strong> ${record.Get('DurationMinutes')} minutes`;
    };
    
    // Add groups to array
    this.timelineGroups.push(tasksGroup, meetingsGroup);
  }
}

Using RunView Parameters

Create a TimelineGroup using pre-configured RunViewParams:

import { TimelineGroup } from '@memberjunction/ng-timeline';
import { RunViewParams } from '@memberjunction/core';

export class YourComponent implements OnInit {
  timelineGroups: TimelineGroup[] = [];

  async ngOnInit() {
    // Configure RunViewParams for data retrieval
    const params: RunViewParams = {
      EntityName: 'Tasks',
      ExtraFilter: "Status = 'Open' AND Priority = 'High'",
      Skip: 0,
      Take: 50,
      OrderBy: 'DueDate DESC'
    };
    
    // Create TimelineGroup from view parameters
    const tasksGroup = await TimelineGroup.FromView(params);
    tasksGroup.TitleFieldName = 'Title';
    tasksGroup.DateFieldName = 'DueDate';
    tasksGroup.DisplayIconMode = 'custom';
    tasksGroup.DisplayIcon = 'fa fa-exclamation-circle';
    
    this.timelineGroups.push(tasksGroup);
  }
}

Using Pre-loaded Entity Arrays

For scenarios where you already have entity data loaded:

import { TimelineGroup } from '@memberjunction/ng-timeline';
import { BaseEntity } from '@memberjunction/core';

export class YourComponent {
  timelineGroups: TimelineGroup[] = [];

  displayLoadedData(entities: BaseEntity[]) {
    const group = new TimelineGroup();
    group.EntityName = 'Custom Events';
    group.DataSourceType = 'array'; // Use provided array instead of loading
    group.EntityObjects = entities;
    group.TitleFieldName = 'EventName';
    group.DateFieldName = 'EventDate';
    group.SummaryMode = 'field';
    
    this.timelineGroups = [group];
  }
}

Deferred Loading

Control when the timeline loads data using the AllowLoad property:

import { Component, ViewChild } from '@angular/core';
import { TimelineComponent, TimelineGroup } from '@memberjunction/ng-timeline';

@Component({
  template: `
    <mj-timeline 
      #timeline
      [Groups]="timelineGroups" 
      [AllowLoad]="false">
    </mj-timeline>
    <button (click)="loadTimeline()">Load Timeline Data</button>
  `
})
export class YourComponent {
  @ViewChild('timeline') timeline!: TimelineComponent;
  timelineGroups: TimelineGroup[] = [];

  constructor() {
    // Configure groups but don't load yet
    const group = new TimelineGroup();
    group.EntityName = 'Events';
    group.TitleFieldName = 'Name';
    group.DateFieldName = 'EventDate';
    this.timelineGroups = [group];
  }

  async loadTimeline() {
    // Manually trigger data loading
    await this.timeline.Refresh();
  }
}

## API Reference

### TimelineComponent

#### Inputs

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `DisplayOrientation` | `'horizontal' \| 'vertical'` | `'vertical'` | Orientation of the timeline |
| `Groups` | `TimelineGroup[]` | `[]` | Array of groups to display on the timeline |
| `AllowLoad` | `boolean` | `true` | Whether to load data automatically |

#### Methods

| Name | Parameters | Return Type | Description |
|------|------------|-------------|-------------|
| `Refresh` | None | `Promise<void>` | Refreshes the timeline with current group data |

### TimelineGroup Class

#### Properties

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `EntityName` | `string` | (required) | Entity name for the records to display |
| `DataSourceType` | `'array' \| 'entity'` | `'entity'` | Specifies data source type |
| `Filter` | `string` | (optional) | Filter to apply when loading entity data |
| `EntityObjects` | `BaseEntity[]` | `[]` | Array of entities when using 'array' data source |
| `TitleFieldName` | `string` | (required) | Field name for event titles |
| `DateFieldName` | `string` | (required) | Field name for event dates |
| `DisplayIconMode` | `'standard' \| 'custom'` | `'standard'` | Icon display mode |
| `DisplayIcon` | `string` | (optional) | Custom icon class for events |
| `DisplayColorMode` | `'auto' \| 'manual'` | `'auto'` | Color selection mode |
| `DisplayColor` | `string` | (optional) | Manual color for events |
| `SummaryMode` | `'field' \| 'custom' \| 'none'` | `'field'` | Mode for summary display |
| `SummaryFieldName` | `string` | (optional) | Field name for summary when using 'field' mode (Note: Currently uses TitleFieldName) |
| `SummaryFunction` | `(record: BaseEntity) => string` | (optional) | Function for custom summary generation |

#### Static Methods

| Name | Parameters | Return Type | Description |
|------|------------|-------------|-------------|
| `FromView` | `RunViewParams` | `Promise<TimelineGroup>` | Creates a TimelineGroup from RunViewParams |

## Styling

The component uses Kendo UI's Timeline styling with additional customization options:

- The timeline component automatically applies alternating layout mode for better visual separation
- Events are displayed with collapsible details for better space utilization
- Custom CSS can be applied by targeting the `.wrapper` class or Kendo UI elements
- Icon and color customization per group allows for visual categorization

### CSS Example

```css
/* Custom timeline styling */
mj-timeline .wrapper {
  height: 100%;
  padding: 20px;
}

/* Custom event styling */
mj-timeline .k-timeline-event {
  /* Your custom styles */
}

Integration with MemberJunction

This component is designed to work seamlessly with the MemberJunction framework:

  • Entity System: Automatically loads and displays data from any MemberJunction entity
  • Metadata Integration: Leverages MJ's metadata system for entity field access
  • View System: Supports RunView parameters for flexible data retrieval
  • Container Directives: Uses mjFillContainer directive for responsive layouts
  • Entity Form Dialog: Can integrate with entity form dialogs for detailed views (future enhancement)

Performance Considerations

  • Data Loading: The component loads all data at once. For large datasets, consider using filters or pagination
  • Multiple Groups: Each group triggers a separate data query. Consolidate groups when possible
  • Refresh Operations: The Refresh() method reloads all groups. Use judiciously for performance

Dependencies

Production Dependencies

  • @memberjunction/core (^2.43.0)
  • @memberjunction/core-entities (^2.43.0)
  • @memberjunction/global (^2.43.0)
  • @memberjunction/ng-container-directives (^2.43.0)
  • @memberjunction/ng-entity-form-dialog (^2.43.0)
  • @memberjunction/ng-shared (^2.43.0)
  • @progress/kendo-angular-buttons (^16.2.0)
  • @progress/kendo-angular-layout (^16.2.0)
  • @progress/kendo-angular-indicators (^16.2.0)
  • @progress/kendo-angular-scheduler (^16.2.0)
  • tslib (^2.3.0)

Peer Dependencies

  • @angular/common (^18.0.2)
  • @angular/core (^18.0.2)
  • @angular/forms (^18.0.2)
  • @angular/router (^18.0.2)

Building

This package is part of the MemberJunction monorepo. To build:

# From the package directory
npm run build

# From the monorepo root
turbo build --filter="@memberjunction/ng-timeline"

Future Enhancements

  • Support for pagination and virtual scrolling for large datasets
  • Integration with entity form dialogs for inline editing
  • Custom event templates for advanced display scenarios
  • Export functionality for timeline data
  • Real-time updates via entity change notifications

License

ISC

2.27.1

11 months ago

2.23.2

12 months ago

2.46.0

8 months ago

2.23.1

12 months ago

2.27.0

11 months ago

2.34.0

9 months ago

2.30.0

11 months ago

2.19.4

1 year ago

2.19.5

1 year ago

2.19.2

1 year ago

2.19.3

1 year ago

2.19.0

1 year ago

2.19.1

1 year ago

2.15.2

1 year ago

2.34.2

9 months ago

2.34.1

9 months ago

2.15.1

1 year ago

2.38.0

9 months ago

2.45.0

8 months ago

2.22.1

12 months ago

2.22.0

12 months ago

2.41.0

9 months ago

2.22.2

12 months ago

2.26.1

12 months ago

2.26.0

12 months ago

2.33.0

10 months ago

2.18.3

1 year ago

2.18.1

1 year ago

2.18.2

1 year ago

2.18.0

1 year ago

2.37.1

9 months ago

2.37.0

9 months ago

2.14.0

1 year ago

2.21.0

12 months ago

2.44.0

8 months ago

2.40.0

9 months ago

2.29.0

11 months ago

2.29.2

11 months ago

2.29.1

11 months ago

2.25.0

12 months ago

2.48.0

8 months ago

2.32.0

10 months ago

2.32.2

10 months ago

2.32.1

10 months ago

2.17.0

1 year ago

2.13.4

1 year ago

2.36.0

9 months ago

2.13.2

1 year ago

2.13.3

1 year ago

2.13.0

1 year ago

2.36.1

9 months ago

2.13.1

1 year ago

2.43.0

8 months ago

2.20.2

12 months ago

2.20.3

12 months ago

2.20.0

1 year ago

2.20.1

1 year ago

2.28.0

11 months ago

2.47.0

8 months ago

2.24.1

12 months ago

2.24.0

12 months ago

2.31.0

10 months ago

2.12.0

1 year ago

2.39.0

9 months ago

2.16.1

1 year ago

2.35.1

9 months ago

2.35.0

9 months ago

2.16.0

1 year ago

2.42.1

8 months ago

2.42.0

8 months ago

2.23.0

12 months ago

2.11.0

1 year ago

2.10.0

1 year ago

2.9.0

1 year ago

2.8.0

1 year ago

2.7.0

1 year ago

2.6.1

1 year ago

2.5.2

1 year ago

2.6.0

1 year ago

2.7.1

1 year ago

2.5.1

1 year ago

2.5.0

1 year ago

2.4.1

1 year ago

2.4.0

1 year ago

2.3.3

1 year ago

2.3.2

1 year ago

2.3.1

1 year ago

2.3.0

1 year ago

2.2.1

1 year ago

2.2.0

1 year ago

2.1.5

2 years ago

2.1.4

2 years ago

2.1.3

2 years ago

2.1.2

2 years ago

2.1.1

2 years ago

2.0.0

2 years ago

1.8.1

2 years ago

1.8.0

2 years ago

1.7.1

2 years ago

1.7.0

2 years ago

1.6.1

2 years ago

1.6.0

2 years ago

1.5.3

2 years ago

1.5.2

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

1.4.1

2 years ago