diff --git a/.eslintrc.json b/.eslintrc.json index 3d59b9b..26378c9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,9 +18,8 @@ "plugin:@angular-eslint/recommended", "plugin:@angular-eslint/template/process-inline-templates", // "plugin:@angular-eslint/all", // more pedantic tests =) - "plugin:@typescript-eslint/recommended", - // "plugin:@typescript-eslint/recommended-type-checked", - // "plugin:@typescript-eslint/stylistic", + "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/stylistic", // "plugin:@typescript-eslint/stylistic-type-checked", // "plugin:@stylistic/recommended-extends", "plugin:import/recommended" @@ -31,7 +30,6 @@ "rules": { "quotes": ["error", "single"], "@typescript-eslint/explicit-function-return-type": "warn", - "@typescript-eslint/no-explicit-any": "off", "import/order": [ "error", { diff --git a/README.md b/README.md index 4ffe6d8..96db7a7 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,6 @@ Running the following command to install the library ``` npm install @frxjs/ngx-timeline ``` -

- - ## Examples of Usage @@ -31,38 +28,37 @@ After installing the library and including NgxTimelineModule in your imports mod ``` -

## Configuration ### Input -Input name | Explanation | Mandatory | Type/Supported Values | Default value ---- | --- | --- |---------------------------------------------------------------------------------------------------------------------------------------------| --- -events | list of events to be displayed | yes | NgxTimelineEvent | no default -langCode | language code use to format dates | no | | 'en' -enableAnimation | Boolean used to enable or disable the animations | no | boolean | true -reverseOrder | Boolean used to reverse sort order (default older first) | no | boolean | false -groupEvent | Logic to be applied in order to group events | no | enum NgxTimelineEventGroup | NgxTimelineEventGroup.MONTH_YEAR -orientation | Orientation of the timeline | no | enum NgxTimelineOrientation | NgxTimelineOrientation.VERTICAL -changeSide | Logic to be applied in order to put events on LEFT or RIGHT | no | enum NgxTimelineEventChangeSide | NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP -periodCustomTemplate | Custom Template displayed before a group of events | no | TemplateRef | no default -eventCustomTemplate | Custom Template displayed to show a single event | no | TemplateRef | no default -centerIconCustomTemplate | Custom Template displayed to show an separator icon | no | TemplateRef | no default -dateInstantCustomTemplate | Custom Template displayed to show the side date | no | TemplateRef | no default -innerEventCustomTemplate | Custom Template displayed to show the inner event | no | TemplateRef | no default -eventDescriptionCustomTemplate| Custom Template displayed to show the description | no | TemplateRef | no default -
+ +| Input name | Explanation | Mandatory | Type/Supported Values | Default value | +|--------------------------------|-------------------------------------------------------------|-----------|---------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------| +| events | list of events to be displayed | yes | NgxTimelineEvent | no default | +| langCode | language code use to format dates | no |
  • 'en'
  • 'it'
  • 'fr'
  • 'de'
  • 'es'
  • 'sl'
  • 'tr'
  • 'pl'
  • 'pt'
  • 'ru'
| 'en' | +| enableAnimation | Boolean used to enable or disable the animations | no | boolean | true | +| reverseOrder | Boolean used to reverse sort order (default older first) | no | boolean | false | +| groupEvent | Logic to be applied in order to group events | no | enum NgxTimelineEventGroup | NgxTimelineEventGroup.MONTH_YEAR | +| orientation | Orientation of the timeline | no | enum NgxTimelineOrientation | NgxTimelineOrientation.VERTICAL | +| changeSide | Logic to be applied in order to put events on LEFT or RIGHT | no | enum NgxTimelineEventChangeSide | NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP | +| periodCustomTemplate | Custom Template displayed before a group of events | no | `TemplateRef` | no default | +| eventCustomTemplate | Custom Template displayed to show a single event | no | `TemplateRef` | no default | +| centerIconCustomTemplate | Custom Template displayed to show an separator icon | no | `TemplateRef` | no default | +| dateInstantCustomTemplate | Custom Template displayed to show the side date | no | `TemplateRef` | no default | +| innerEventCustomTemplate | Custom Template displayed to show the inner event | no | `TemplateRef` | no default | +| eventDescriptionCustomTemplate | Custom Template displayed to show the description | no | `TemplateRef` | no default | ### Output -Output name | Explanation | Mandatory | Type/Supported Values | Default value ---- | --- | --- | --- | --- -clickEmitter | Output click event emitter | no | BehaviorSubject | no default -
+ +| Output name | Explanation | Mandatory | Type/Supported Values | Default value | +|--------------|----------------------------|-----------|-------------------------------------|---------------| +| clickEmitter | Output click event emitter | no | `OutputEmitterRef` | no default | ### Types and Enums ```typescript interface NgxTimelineEvent { - timestamp?: Date; + timestamp: Date; title?: string; description?: string; id?: any; @@ -91,7 +87,6 @@ enum NgxTimelineEventChangeSide { ON_DIFFERENT_MONTH_IN_GROUP = 'ON_DIFFERENT_MONTH_IN_GROUP' } ``` -
### Custom Theme supported @@ -110,7 +105,7 @@ This is an example of custom-theme that can be applied for instance via an ng-cl

- {{index}} - {{period | json }} + {{index}} - {{period | json}}

@@ -148,9 +143,9 @@ This is an example of custom-theme that can be applied for instance via an ng-cl {{item | json}} -``` +```

- + ## How to contribute First of all, in order to track everything, open an issue describing the problem or a missing functionality you would like to add to the lib. diff --git a/projects/demo-app/src/app/app.component.html b/projects/demo-app/src/app/app.component.html index 23180a0..22d0872 100644 --- a/projects/demo-app/src/app/app.component.html +++ b/projects/demo-app/src/app/app.component.html @@ -30,24 +30,24 @@

Ngx-Timeline

-
+
@@ -56,13 +56,13 @@

Ngx-Timeline

- {{index}} - {{period?.firstDate | ngxdate }} + {{index}} - {{period?.firstDate | ngxdate}}
- + custom icon
@@ -85,11 +85,8 @@

Ngx-Timeline

- {{item?.timestamp | ngxdate : ngxDateFormat.FULL_DATE }} + {{item?.timestamp | ngxdate : ngxDateFormat.FULL_DATE}} -
- - diff --git a/projects/demo-app/src/app/app.component.ts b/projects/demo-app/src/app/app.component.ts index 5e3ec63..9b6c9a5 100644 --- a/projects/demo-app/src/app/app.component.ts +++ b/projects/demo-app/src/app/app.component.ts @@ -2,22 +2,24 @@ import {JsonPipe, NgClass} from '@angular/common'; import {Component} from '@angular/core'; import {UntypedFormGroup, UntypedFormControl, ReactiveFormsModule} from '@angular/forms'; +import {NgxTimelineItem} from '../../../ngx-timeline/src/lib/models'; import {NgxDateFormat, NgxTimelineEvent, NgxTimelineEventChangeSide, NgxTimelineEventGroup, NgxTimelineModule, NgxTimelineOrientation} from 'ngx-timeline'; + @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrl: './app.component.scss', - imports: [ - JsonPipe, - NgClass, - NgxTimelineModule, - ReactiveFormsModule, - ] + selector: 'app-root', + templateUrl: './app.component.html', + styleUrl: './app.component.scss', + imports: [ + JsonPipe, + NgClass, + NgxTimelineModule, + ReactiveFormsModule, + ], }) export class AppComponent { title = 'demo-app'; - events: NgxTimelineEvent[]; + events: NgxTimelineEvent[] = []; form: UntypedFormGroup; ngxDateFormat = NgxDateFormat; @@ -184,9 +186,7 @@ export class AppComponent { ]; } - handleClick(event: any): void { - if (event) { - window.console.log('', event); - } + handleClick(event: NgxTimelineItem): void { + window.console.log('', event); } } diff --git a/projects/demo-app/tsconfig.app.json b/projects/demo-app/tsconfig.app.json index 66b7263..009f6cc 100644 --- a/projects/demo-app/tsconfig.app.json +++ b/projects/demo-app/tsconfig.app.json @@ -14,9 +14,10 @@ } }, "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, - "strictTemplates": false + "strictTemplates": true }, "files": [ "src/main.ts" diff --git a/projects/ngx-timeline/README.md b/projects/ngx-timeline/README.md index 4ffe6d8..96db7a7 100644 --- a/projects/ngx-timeline/README.md +++ b/projects/ngx-timeline/README.md @@ -18,9 +18,6 @@ Running the following command to install the library ``` npm install @frxjs/ngx-timeline ``` -

- - ## Examples of Usage @@ -31,38 +28,37 @@ After installing the library and including NgxTimelineModule in your imports mod ``` -

## Configuration ### Input -Input name | Explanation | Mandatory | Type/Supported Values | Default value ---- | --- | --- |---------------------------------------------------------------------------------------------------------------------------------------------| --- -events | list of events to be displayed | yes | NgxTimelineEvent | no default -langCode | language code use to format dates | no |
  • 'en'
  • 'it'
  • 'fr'
  • 'de'
  • 'es'
  • 'sl'
  • 'tr'
  • 'pl'
  • 'pt'
  • 'ru'
| 'en' -enableAnimation | Boolean used to enable or disable the animations | no | boolean | true -reverseOrder | Boolean used to reverse sort order (default older first) | no | boolean | false -groupEvent | Logic to be applied in order to group events | no | enum NgxTimelineEventGroup | NgxTimelineEventGroup.MONTH_YEAR -orientation | Orientation of the timeline | no | enum NgxTimelineOrientation | NgxTimelineOrientation.VERTICAL -changeSide | Logic to be applied in order to put events on LEFT or RIGHT | no | enum NgxTimelineEventChangeSide | NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP -periodCustomTemplate | Custom Template displayed before a group of events | no | TemplateRef | no default -eventCustomTemplate | Custom Template displayed to show a single event | no | TemplateRef | no default -centerIconCustomTemplate | Custom Template displayed to show an separator icon | no | TemplateRef | no default -dateInstantCustomTemplate | Custom Template displayed to show the side date | no | TemplateRef | no default -innerEventCustomTemplate | Custom Template displayed to show the inner event | no | TemplateRef | no default -eventDescriptionCustomTemplate| Custom Template displayed to show the description | no | TemplateRef | no default -
+ +| Input name | Explanation | Mandatory | Type/Supported Values | Default value | +|--------------------------------|-------------------------------------------------------------|-----------|---------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------| +| events | list of events to be displayed | yes | NgxTimelineEvent | no default | +| langCode | language code use to format dates | no |
  • 'en'
  • 'it'
  • 'fr'
  • 'de'
  • 'es'
  • 'sl'
  • 'tr'
  • 'pl'
  • 'pt'
  • 'ru'
| 'en' | +| enableAnimation | Boolean used to enable or disable the animations | no | boolean | true | +| reverseOrder | Boolean used to reverse sort order (default older first) | no | boolean | false | +| groupEvent | Logic to be applied in order to group events | no | enum NgxTimelineEventGroup | NgxTimelineEventGroup.MONTH_YEAR | +| orientation | Orientation of the timeline | no | enum NgxTimelineOrientation | NgxTimelineOrientation.VERTICAL | +| changeSide | Logic to be applied in order to put events on LEFT or RIGHT | no | enum NgxTimelineEventChangeSide | NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP | +| periodCustomTemplate | Custom Template displayed before a group of events | no | `TemplateRef` | no default | +| eventCustomTemplate | Custom Template displayed to show a single event | no | `TemplateRef` | no default | +| centerIconCustomTemplate | Custom Template displayed to show an separator icon | no | `TemplateRef` | no default | +| dateInstantCustomTemplate | Custom Template displayed to show the side date | no | `TemplateRef` | no default | +| innerEventCustomTemplate | Custom Template displayed to show the inner event | no | `TemplateRef` | no default | +| eventDescriptionCustomTemplate | Custom Template displayed to show the description | no | `TemplateRef` | no default | ### Output -Output name | Explanation | Mandatory | Type/Supported Values | Default value ---- | --- | --- | --- | --- -clickEmitter | Output click event emitter | no | BehaviorSubject | no default -
+ +| Output name | Explanation | Mandatory | Type/Supported Values | Default value | +|--------------|----------------------------|-----------|-------------------------------------|---------------| +| clickEmitter | Output click event emitter | no | `OutputEmitterRef` | no default | ### Types and Enums ```typescript interface NgxTimelineEvent { - timestamp?: Date; + timestamp: Date; title?: string; description?: string; id?: any; @@ -91,7 +87,6 @@ enum NgxTimelineEventChangeSide { ON_DIFFERENT_MONTH_IN_GROUP = 'ON_DIFFERENT_MONTH_IN_GROUP' } ``` -
### Custom Theme supported @@ -110,7 +105,7 @@ This is an example of custom-theme that can be applied for instance via an ng-cl

- {{index}} - {{period | json }} + {{index}} - {{period | json}}

@@ -148,9 +143,9 @@ This is an example of custom-theme that can be applied for instance via an ng-cl {{item | json}} -``` +```

- + ## How to contribute First of all, in order to track everything, open an issue describing the problem or a missing functionality you would like to add to the lib. diff --git a/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.html b/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.html index b04ddfa..ecc9bef 100644 --- a/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.html +++ b/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.html @@ -1,23 +1,23 @@ -
- @if (colSidePosition===ngxTimelineItemPosition.ON_RIGHT) { +
+ @if (colSidePosition()===ngxTimelineItemPosition.ON_RIGHT) {
} -
- +
+
- @if (colSidePosition === ngxTimelineItemPosition.ON_LEFT) { + @if (colSidePosition() === ngxTimelineItemPosition.ON_LEFT) {
}
-
+
{{event?.eventInfo?.title | titlecase}}
- +
diff --git a/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.spec.ts b/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.spec.ts index fd7139d..35fb79e 100644 --- a/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.spec.ts +++ b/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.spec.ts @@ -1,10 +1,13 @@ import {registerLocaleData} from '@angular/common'; import localeIt from '@angular/common/locales/it'; +import {ComponentRef} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {NgxTimelineEventComponent} from './ngx-timeline-event.component'; import {NgxTimelineItemPosition} from '../../models'; + + registerLocaleData(localeIt); const year = 2021; @@ -29,8 +32,8 @@ const event = { }; describe('NgxTimelineEventComponent', () => { let component: NgxTimelineEventComponent; + let componentRef: ComponentRef; let fixture: ComponentFixture; - beforeEach(async () => { await TestBed.configureTestingModule({ imports: [NgxTimelineEventComponent], @@ -40,27 +43,17 @@ describe('NgxTimelineEventComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(NgxTimelineEventComponent); component = fixture.componentInstance; - component.event = event; + componentRef = fixture.componentRef; + componentRef.setInput('event', event); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); - describe('should getDateObj', () => { - it('without event', () => { - component.event = null; - const res = component.getDateObj(); - expect(res).toEqual({day: undefined, month: undefined, year: undefined}); - }); it('without event info', () => { - component.event = {}; - const res = component.getDateObj(); - expect(res).toEqual({day: undefined, month: undefined, year: undefined}); - }); - it('without event info timestamp', () => { - component.event = {eventInfo: null}; + componentRef.setInput('event', {}); const res = component.getDateObj(); expect(res).toEqual({day: undefined, month: undefined, year: undefined}); }); @@ -69,14 +62,28 @@ describe('NgxTimelineEventComponent', () => { expect(res).toEqual({day: '19', month: 'Aug', year: 2021}); }); it('should getDateObj with supported langCode', () => { - component.langCode = 'en'; + componentRef.setInput('langCode', 'en'); const res = component.getDateObj(); expect(res).toEqual({day: '19', month: 'Aug', year: 2021}); }); it('should getDateObj with another supported langCode', () => { - component.langCode = 'it'; + componentRef.setInput('langCode', 'it'); const res = component.getDateObj(); expect(res).toEqual({day: '19', month: 'ago', year: 2021}); }); }); + describe('should type error', () => { + it('without event', () => { + componentRef.setInput('event', null); + expect(() => { + component.getDateObj(); + }).toThrowError(TypeError); + }); + it('without event info timestamp', () => { + componentRef.setInput('event', undefined); + expect(() => { + component.getDateObj(); + }).toThrowError(TypeError); + }); + }); }); diff --git a/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.ts b/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.ts index 0c9b3a1..a44e0ed 100644 --- a/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.ts +++ b/projects/ngx-timeline/src/lib/components/ngx-timeline-event/ngx-timeline-event.component.ts @@ -1,53 +1,52 @@ import {DatePipe, NgClass, NgTemplateOutlet, TitleCasePipe} from '@angular/common'; -import {Component, Input, Output, TemplateRef} from '@angular/core'; -import {BehaviorSubject} from 'rxjs'; +import {Component, output, TemplateRef, input} from '@angular/core'; import {defaultSupportedLanguageCode, NgxTimelineOrientation, SupportedLanguageCode} from '../../models'; import {NgxTimelineItem, NgxTimelineItemPosition} from '../../models/NgxTimelineEvent'; @Component({ - selector: 'ngx-timeline-event', - templateUrl: './ngx-timeline-event.component.html', - styleUrl: './ngx-timeline-event.component.scss', - imports: [ - NgClass, - NgTemplateOutlet, - TitleCasePipe, - ] + selector: 'ngx-timeline-event', + templateUrl: './ngx-timeline-event.component.html', + styleUrl: './ngx-timeline-event.component.scss', + imports: [ + NgClass, + NgTemplateOutlet, + TitleCasePipe, + ], }) export class NgxTimelineEventComponent { /** - * Event to be displayed + * Event to be displayed. */ - @Input() event!: NgxTimelineItem; + readonly event = input.required(); /** - * Event position respect to the vertical line (LEFT or RIGHT) + * Event position respect to the vertical line (LEFT or RIGHT). */ - @Input() colSidePosition?: NgxTimelineItemPosition; + readonly colSidePosition = input(); /** - * Language code used to format the dates + * Language code used to format the dates. */ - @Input() langCode: SupportedLanguageCode = defaultSupportedLanguageCode; + readonly langCode = input(defaultSupportedLanguageCode); /** - * Inner custom template used to display the event detail + * Inner custom template used to display the event detail. */ - @Input() innerEventCustomTemplate?: TemplateRef; + readonly innerEventCustomTemplate = input>(); /** - * Inner custom template used to display the event description + * Inner custom template used to display the event description. */ - @Input() eventDescriptionCustomTemplate?: TemplateRef; + readonly eventDescriptionCustomTemplate = input>(); /** - * Boolean used to enable or disable the animations + * Boolean used to enable or disable the animations. */ - @Input() enableAnimation = true; + readonly enableAnimation = input(true); /** - * Orientation of the timeline + * Orientation of the timeline. */ - @Input() orientation: NgxTimelineOrientation = NgxTimelineOrientation.VERTICAL; + readonly orientation = input(NgxTimelineOrientation.VERTICAL); /** - * Output click event emitter + * Output click event emitter. */ - @Output() clickEmitter: BehaviorSubject = new BehaviorSubject(null); + readonly clickEmitter = output(); ngxTimelineItemPosition = NgxTimelineItemPosition; ngxTimelineOrientation = NgxTimelineOrientation; @@ -55,13 +54,11 @@ export class NgxTimelineEventComponent { private readonly monthAbbr = 'MMM'; private readonly dayFormat = 'dd'; - constructor() { } - - getDateObj(): any { - let day; - let month; - let year; - const dateTimestamp = this.event?.eventInfo?.timestamp; + getDateObj(): { day: unknown, month: unknown, year: unknown } { + let day = undefined; + let month = undefined; + let year = undefined; + const dateTimestamp = this.event().eventInfo?.timestamp; if (dateTimestamp) { const timestamp = new Date(dateTimestamp); const langCode = this.getLangCode(); @@ -74,6 +71,6 @@ export class NgxTimelineEventComponent { } protected getLangCode(): SupportedLanguageCode { - return this.langCode; + return this.langCode(); } } diff --git a/projects/ngx-timeline/src/lib/components/ngx-timeline.component.html b/projects/ngx-timeline/src/lib/components/ngx-timeline.component.html index 62a4df5..bafce9e 100644 --- a/projects/ngx-timeline/src/lib/components/ngx-timeline.component.html +++ b/projects/ngx-timeline/src/lib/components/ngx-timeline.component.html @@ -1,17 +1,17 @@
-
+
@for (item of items; track item; let index = $index) {
@if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_LEFT) {
- +
} @if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_RIGHT) {
- +
}
@@ -30,12 +30,12 @@
@if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_RIGHT) {
- +
} @if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_LEFT) {
- +
}
@@ -44,18 +44,18 @@ @if (item.eventInfo) {
- +
}
- @if (item.periodInfo; ) { + @if (item.periodInfo) {
} - @if (!item.periodInfo; ) { + @if (!item.periodInfo) {
@@ -64,7 +64,7 @@
@if (item.eventInfo) {
- +
}
@@ -76,7 +76,7 @@
- +
@@ -88,19 +88,19 @@ - {{item?.timestamp | ngxdate : ngxDateFormat.HOURS_MINUTES : langCode}} + {{item?.timestamp | ngxdate : ngxDateFormat.HOURS_MINUTES : langCode()}}
- +
- {{period?.firstDate | ngxdate : getPeriodKeyDateFormat() : langCode}} + {{period?.firstDate | ngxdate : getPeriodKeyDateFormat() : langCode()}}
@@ -108,13 +108,13 @@ + (clickEmitter)="clickEmitter.emit($event)"> diff --git a/projects/ngx-timeline/src/lib/components/ngx-timeline.component.spec.ts b/projects/ngx-timeline/src/lib/components/ngx-timeline.component.spec.ts index f547ab8..d7e2f1b 100644 --- a/projects/ngx-timeline/src/lib/components/ngx-timeline.component.spec.ts +++ b/projects/ngx-timeline/src/lib/components/ngx-timeline.component.spec.ts @@ -1,10 +1,13 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import {ComponentRef} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; -import {NgxTimelineComponent} from './ngx-timeline.component'; import {NgxDateFormat, NgxTimelineEventChangeSide, NgxTimelineEventGroup, NgxTimelineItemPosition} from '../models'; +import {NgxTimelineComponent} from './ngx-timeline.component'; describe('NgxTimelineComponent', () => { let component: NgxTimelineComponent; + let componentRef: ComponentRef; let fixture: ComponentFixture; beforeEach(async () => { @@ -16,7 +19,8 @@ describe('NgxTimelineComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(NgxTimelineComponent); component = fixture.componentInstance; - component.events = null; + componentRef = fixture.componentRef; + componentRef.setInput('events', []); fixture.detectChanges(); }); @@ -31,9 +35,9 @@ describe('NgxTimelineComponent', () => { }); it('should call the groupEvents when ngDoCheck and iterable diff find some changes', () => { - component.events = []; + componentRef.setInput('event', []); const spy = spyOn(component, 'groupEvents'); - component.events.push({}); + component.events().push({timestamp: new Date()}); fixture.detectChanges(); expect(spy).toHaveBeenCalled(); }); @@ -55,24 +59,25 @@ describe('NgxTimelineComponent', () => { {groupEvent: NgxTimelineEventGroup.DAY_MONTH_YEAR, formatDate: NgxDateFormat.DAY_MONTH_YEAR}, ].forEach((elem) => { it(`when groupEvent ${elem.groupEvent} is provided`, () => { - component.groupEvent = elem.groupEvent; + componentRef.setInput('groupEvent', elem.groupEvent); expect(component.getPeriodKeyDateFormat()).toEqual(elem.formatDate); }); }); }); - describe('should groupEvents', ()=> { - it('when no events', () => { + describe('should groupEvents', () => { + it('when null as events (legacy)', () => { const spies = []; spies.push(spyOn(component, 'clear')); spies.push(spyOn(component, 'sortEvents')); spies.push(spyOn(component, 'setGroupsAndPeriods')); spies.push(spyOn(component, 'setItems')); + // @ts-expect-error legacy non-strict test component['groupEvents'](null); spies.forEach((spy) => expect(spy).not.toHaveBeenCalled()); }); - it('when events', () => { + it('when no events', () => { const spies = []; spies.push(spyOn(component, 'clear')); spies.push(spyOn(component, 'sortEvents')); @@ -96,7 +101,7 @@ describe('NgxTimelineComponent', () => { }); }); - describe('should sortEvents', ()=> { + describe('should sortEvents', () => { it('when events', () => { const event = {timestamp: new Date(2021, 11, 10)}; const event2 = {timestamp: new Date(2021, 8, 10)}; @@ -107,19 +112,19 @@ describe('NgxTimelineComponent', () => { }); }); - describe('should sortEvents in reverse order', ()=> { + describe('should sortEvents in reverse order', () => { it('when events', () => { const event = {timestamp: new Date(2021, 11, 10)}; const event2 = {timestamp: new Date(2021, 8, 10)}; const events = [event, event2]; - component.reverseOrder = true; + componentRef.setInput('reverseOrder', true); component['sortEvents'](events); expect(events[0]).toEqual(event); expect(events[1]).toEqual(event2); }); }); - describe('should setGroupsAndPeriodsAndPeriods', ()=> { + describe('should setGroupsAndPeriodsAndPeriods', () => { it('when events', () => { const date = new Date(2021, 11, 10); const date2 = new Date(2021, 8, 10); @@ -136,7 +141,7 @@ describe('NgxTimelineComponent', () => { }); }); - describe('should setItems', ()=> { + describe('should setItems', () => { it('when events', () => { const period = {periodInfo: {periodKey: '2021/7'}}; const period2 = {periodInfo: {periodKey: '2021/8'}}; @@ -158,7 +163,7 @@ describe('NgxTimelineComponent', () => { const event3 = {timestamp: new Date(2021, 8, 11)}; component.groups['2021/7'] = [event]; component.groups['2021/8'] = [event2, event3]; - component.changeSide = NgxTimelineEventChangeSide.ALL; + componentRef.setInput('changeSide', NgxTimelineEventChangeSide.ALL); component['setItems'](); expect(component.items.length).toEqual(5); expect(component.items[1].position).toEqual(NgxTimelineItemPosition.ON_LEFT); @@ -167,23 +172,23 @@ describe('NgxTimelineComponent', () => { }); }); - describe('should getPeriodKeyFromEvent', ()=> { + describe('should getPeriodKeyFromEvent', () => { it('when groupEvent by year', () => { - component.groupEvent = NgxTimelineEventGroup.YEAR; + componentRef.setInput('groupEvent', NgxTimelineEventGroup.YEAR); const event = {timestamp: new Date(2021, 7, 10)}; const event2 = {timestamp: new Date(2021, 8, 9)}; expect(component['getPeriodKeyFromEvent'](event)).toBe('2021'); expect(component['getPeriodKeyFromEvent'](event2)).toBe('2021'); }); it('when groupEvent by month year', () => { - component.groupEvent = NgxTimelineEventGroup.MONTH_YEAR; + componentRef.setInput('groupEvent', NgxTimelineEventGroup.MONTH_YEAR); const event = {timestamp: new Date(2021, 7, 10)}; const event2 = {timestamp: new Date(2021, 8, 9)}; expect(component['getPeriodKeyFromEvent'](event)).toBe('2021/7'); expect(component['getPeriodKeyFromEvent'](event2)).toBe('2021/8'); }); it('when groupEvent by day month year', () => { - component.groupEvent = NgxTimelineEventGroup.DAY_MONTH_YEAR; + componentRef.setInput('groupEvent', NgxTimelineEventGroup.DAY_MONTH_YEAR); const event = {timestamp: new Date(2021, 7, 10)}; const event2 = {timestamp: new Date(2021, 8, 9)}; expect(component['getPeriodKeyFromEvent'](event)).toBe('2021/7/10'); diff --git a/projects/ngx-timeline/src/lib/components/ngx-timeline.component.ts b/projects/ngx-timeline/src/lib/components/ngx-timeline.component.ts index eab0371..49c504d 100644 --- a/projects/ngx-timeline/src/lib/components/ngx-timeline.component.ts +++ b/projects/ngx-timeline/src/lib/components/ngx-timeline.component.ts @@ -1,6 +1,5 @@ import {NgClass, NgTemplateOutlet} from '@angular/common'; -import {Component, DoCheck, inject, Input, IterableDiffer, IterableDiffers, OnChanges, OnInit, Output, TemplateRef} from '@angular/core'; -import {BehaviorSubject} from 'rxjs'; +import {Component, DoCheck, inject, IterableDiffer, IterableDiffers, OnChanges, TemplateRef, input, output} from '@angular/core'; import { NgxTimelineEvent, @@ -18,78 +17,76 @@ import { import {NgxDatePipe} from '../pipes'; import {NgxTimelineEventComponent} from './ngx-timeline-event/ngx-timeline-event.component'; - @Component({ - selector: 'ngx-timeline', - templateUrl: './ngx-timeline.component.html', - styleUrl: './ngx-timeline.component.scss', - imports: [ - NgClass, - NgTemplateOutlet, - NgxDatePipe, - NgxTimelineEventComponent, - ] + selector: 'ngx-timeline', + templateUrl: './ngx-timeline.component.html', + styleUrl: './ngx-timeline.component.scss', + imports: [ + NgClass, + NgTemplateOutlet, + NgxDatePipe, + NgxTimelineEventComponent, + ], }) -export class NgxTimelineComponent implements OnInit, OnChanges, DoCheck { +export class NgxTimelineComponent implements OnChanges, DoCheck { /** - * List of events to be displayed + * List of events to be displayed. */ - @Input() events!: NgxTimelineEvent[]; + readonly events = input.required(); /** - * Language code used to show the date formatted + * Language code used to show the date formatted. */ - @Input() langCode: SupportedLanguageCode = defaultSupportedLanguageCode; + readonly langCode = input(defaultSupportedLanguageCode); /** - * Boolean used to enable or disable the animations + * Boolean used to enable or disable the animations. */ - @Input() enableAnimation = true; + readonly enableAnimation = input(true); /** - * Boolean used to reverse sort order (default older first) + * Boolean used to reverse sort order (default older first). */ - @Input() reverseOrder = false; + readonly reverseOrder = input(false); /** - * Orientation of the timeline + * Orientation of the timeline. */ - @Input() orientation: NgxTimelineOrientation = NgxTimelineOrientation.VERTICAL; + readonly orientation = input(NgxTimelineOrientation.VERTICAL); /** - * Logic to be applied in order to group events + * Logic to be applied in order to group events. */ - @Input() groupEvent: NgxTimelineEventGroup = NgxTimelineEventGroup.MONTH_YEAR; + readonly groupEvent = input(NgxTimelineEventGroup.MONTH_YEAR); /** - * Logic to be applied in order to put events on LEFT or RIGHT + * Logic to be applied in order to put events on LEFT or RIGHT. */ - @Input() changeSide: NgxTimelineEventChangeSide = NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP; + readonly changeSide = input(NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP); /** - * Custom Template displayed before a group of events + * Custom Template displayed before a group of events. */ - @Input() periodCustomTemplate?: TemplateRef; + readonly periodCustomTemplate = input>(); /** - * Custom Template displayed to show a single event + * Custom Template displayed to show a single event. */ - @Input() eventCustomTemplate?: TemplateRef; + readonly eventCustomTemplate = input>(); /** - * Custom Template displayed to show an separator icon + * Custom Template displayed to show a separator icon. */ - @Input() centerIconCustomTemplate?: TemplateRef; + readonly centerIconCustomTemplate = input>(); /** - * Custom Template displayed to show the side date + * Custom Template displayed to show the side date. */ - @Input() dateInstantCustomTemplate?: TemplateRef; + readonly dateInstantCustomTemplate = input>(); /** - * Custom Template displayed to show the inner event + * Custom Template displayed to show the inner event. */ - @Input() innerEventCustomTemplate?: TemplateRef; + readonly innerEventCustomTemplate = input>(); /** - * Inner custom template used to display the event description + * Inner custom template used to display the event description. */ - @Input() eventDescriptionCustomTemplate?: TemplateRef; + readonly eventDescriptionCustomTemplate = input>(); /** - * Output click event emitter + * Output click event emitter. */ - @Output() - clickEmitter: BehaviorSubject = new BehaviorSubject(null); + readonly clickEmitter = output(); - groups: { [key: string]: NgxTimelineEvent[] } = {}; + groups: Record = {}; periods: NgxTimelineItem[] = []; items: NgxTimelineItem[] = []; ngxTimelineItemPosition = NgxTimelineItemPosition; @@ -97,26 +94,22 @@ export class NgxTimelineComponent implements OnInit, OnChanges, DoCheck { ngxDateFormat = NgxDateFormat; private differs: IterableDiffers = inject(IterableDiffers); - private iterableDiffer: IterableDiffer = this.differs.find([]).create(); + private iterableDiffer: IterableDiffer = this.differs.find([]).create(); private readonly separator = '/'; - ngOnInit(): void { - this.groupEvents(this.events); - } - ngOnChanges(): void { - this.groupEvents(this.events); + this.groupEvents(this.events()); } ngDoCheck(): void { - const changes = this.iterableDiffer.diff(this.events); + const changes = this.iterableDiffer.diff(this.events()); if (changes) { - this.groupEvents(this.events); + this.groupEvents(this.events()); } } getPeriodKeyDateFormat(): string { - return periodKeyDateFormat[this.groupEvent]; + return periodKeyDateFormat[this.groupEvent()]; } protected clear(): void { @@ -136,9 +129,10 @@ export class NgxTimelineComponent implements OnInit, OnChanges, DoCheck { protected sortEvents(events: NgxTimelineEvent[]): void { events.sort((a, b) => { - const aTime = a.timestamp.getTime(); - const bTime = b.timestamp.getTime(); - return this.reverseOrder ? bTime - aTime : aTime - bTime;}); + const aTime: number = a.timestamp.getTime(); + const bTime: number = b.timestamp.getTime(); + return this.reverseOrder() ? bTime - aTime : aTime - bTime; + }); } protected setGroupsAndPeriods(events: NgxTimelineEvent[]): void { @@ -149,7 +143,7 @@ export class NgxTimelineComponent implements OnInit, OnChanges, DoCheck { const periodKey = this.getPeriodKeyFromEvent(event); if (!this.groups[periodKey]) { this.groups[periodKey] = []; - this.periods.push(this.getPeriodInfoFromPeriodKey(periodKey, event)) + this.periods.push({periodInfo: this.getPeriodInfoFromPeriodKey(periodKey, event)}); } this.groups[periodKey].push(event); }); @@ -162,23 +156,29 @@ export class NgxTimelineComponent implements OnInit, OnChanges, DoCheck { this.items.push(p); // in each period putting items on left let onLeft = true; - if (this.changeSide === NgxTimelineEventChangeSide.ALL) { + if (this.changeSide() === NgxTimelineEventChangeSide.ALL) { onLeft = !isLastItemOnLeft; } - const periodInfo = p.periodInfo; - // insert then all the events in this period - isLastItemOnLeft = this.addPeriodEvents(periodInfo, onLeft); - // onLeft = this.addEventItemsAndGetIfOnLeft(periodInfo, onLeft); + const periodInfo: NgxTimelinePeriodInfo | undefined = p.periodInfo; + if (periodInfo) { + // insert then all the events in this period + isLastItemOnLeft = this.addPeriodEvents(periodInfo, onLeft); + // onLeft = this.addEventItemsAndGetIfOnLeft(periodInfo, onLeft); + } }); } protected addPeriodEvents(periodInfo: NgxTimelinePeriodInfo, onLeft: boolean): boolean { - this.groups[periodInfo.periodKey].forEach((event, index) => { - const prevEvent = this.groups[periodInfo.periodKey][index - 1]; + const periodKey = periodInfo?.periodKey; + if (periodKey == undefined) { + return onLeft; + } + this.groups[periodKey].forEach((event: NgxTimelineEvent, index: number) => { + const prevEvent = this.groups[periodKey][index - 1]; if (event.itemPosition) { onLeft = event.itemPosition && event.itemPosition === NgxTimelineItemPosition.ON_LEFT; } else if (index > 0 && this.compareEvents(prevEvent, event)) { - onLeft = !onLeft; + onLeft = !onLeft; } this.pushEventOnItems(event, onLeft); }); @@ -197,35 +197,33 @@ export class NgxTimelineComponent implements OnInit, OnChanges, DoCheck { */ protected compareEvents(prevEvent: NgxTimelineEvent, event: NgxTimelineEvent): boolean { return this.shouldChangeEventsInPeriod() || - this.compareEventsField(prevEvent, event, ...fieldsToCheckEventChangeSide[this.changeSide]); + this.compareEventsField(prevEvent, event, ...(fieldsToCheckEventChangeSide[this.changeSide()] ?? [])); } protected compareEventsField(prevEvent: NgxTimelineEvent, event: NgxTimelineEvent, ...fields: string[]): boolean { - return fields.reduce((res, field) => res = res || prevEvent.timestamp[field]() !== event.timestamp[field](), false); + return fields.reduce((res, field) => res = res || (prevEvent.timestamp[field as keyof Date] as () => number)() !== (event.timestamp[field as keyof Date] as () => number)(), false); } - protected getPeriodInfoFromPeriodKey(periodKey: string, firstGroupEvent: NgxTimelineEvent): { periodInfo: NgxTimelinePeriodInfo } { - const split = periodKey.split(this.separator); - return this.getPeriodInfo(split, periodKey, firstGroupEvent); + protected getPeriodInfoFromPeriodKey(periodKey: string, firstGroupEvent: NgxTimelineEvent): NgxTimelinePeriodInfo { + const split = periodKey.split(this.separator); + return this.getPeriodInfo(split, periodKey, firstGroupEvent); } - private getPeriodInfo(split: string[], periodKey: string, firstGroupEvent: NgxTimelineEvent): { periodInfo: NgxTimelinePeriodInfo } { + private getPeriodInfo(split: string[], periodKey: string, firstGroupEvent: NgxTimelineEvent): NgxTimelinePeriodInfo { return { - periodInfo: { - year: Number(split[0]), - month: Number(split[1]), - day: Number(split[2]), - periodKey, - firstDate: firstGroupEvent.timestamp as Date, - }, + year: Number(split[0]), + month: Number(split[1]), + day: Number(split[2]), + periodKey, + firstDate: firstGroupEvent.timestamp, }; } private shouldChangeEventsInPeriod(): boolean { - return [NgxTimelineEventChangeSide.ALL_IN_GROUP, NgxTimelineEventChangeSide.ALL].indexOf(this.changeSide) != -1; + return [NgxTimelineEventChangeSide.ALL_IN_GROUP, NgxTimelineEventChangeSide.ALL].includes(this.changeSide()); } protected getPeriodKeyFromEvent(event: NgxTimelineEvent): string { - return fieldsToAddEventGroup[this.groupEvent].map((field) => event.timestamp[field]()).join(this.separator); + return fieldsToAddEventGroup[this.groupEvent()].map((field) => (event.timestamp[field as keyof Date] as () => number)()).join(this.separator); } } diff --git a/projects/ngx-timeline/src/lib/models/NgxConfigObj.ts b/projects/ngx-timeline/src/lib/models/NgxConfigObj.ts index 0926a09..2ab9a02 100644 --- a/projects/ngx-timeline/src/lib/models/NgxConfigObj.ts +++ b/projects/ngx-timeline/src/lib/models/NgxConfigObj.ts @@ -11,11 +11,7 @@ export interface NgxConfigDate { year: string; } -export type NgxDateObjMap = { - [key in SupportedLanguageCode]: NgxConfigDate; -}; - -export const dateConfigMap: NgxDateObjMap = { +export const dateConfigMap: Record = { en: { code: 'en-US', fullDate: 'MM/dd/yyyy h:mm a', @@ -95,23 +91,23 @@ export const dateConfigMap: NgxDateObjMap = { monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', - } + }, }; export enum NgxDateFormat { DAY_MONTH_YEAR = 'DAY_MONTH_YEAR', FULL_DATE = 'FULL_DATE', - MONTH_YEAR = 'MONTH_YEAR', HOURS_MINUTES = 'HOURS_MINUTES', + MONTH_YEAR = 'MONTH_YEAR', YEAR = 'YEAR' } -export const fieldConfigDate = { +export const fieldConfigDate: Record = { + DAY_MONTH_YEAR: 'dayMonthYear', + FULL_DATE: 'fullDate', + HOURS_MINUTES: 'hoursMinutes', MONTH_YEAR: 'monthYear', YEAR: 'year', - HOURS_MINUTES: 'hoursMinutes', - FULL_DATE: 'fullDate', - DAY_MONTH_YEAR: 'dayMonthYear', }; /** @@ -123,28 +119,28 @@ export enum NgxTimelineEventGroup { DAY_MONTH_YEAR = 'DAY_MONTH_YEAR' } -/** - * Enum used to set the group event logic - */ -export enum NgxTimelineOrientation { - HORIZONTAL = 'HORIZONTAL', - VERTICAL = 'VERTICAL', -} - -export const fieldsToAddEventGroup = { +export const fieldsToAddEventGroup: Record = { YEAR: ['getFullYear'], MONTH_YEAR: ['getFullYear', 'getMonth'], DAY_MONTH_YEAR: ['getFullYear', 'getMonth', 'getDate'], }; -export const periodKeyDateFormat = { +export const periodKeyDateFormat: Record = { YEAR: NgxDateFormat.YEAR, MONTH_YEAR: NgxDateFormat.MONTH_YEAR, DAY_MONTH_YEAR: NgxDateFormat.DAY_MONTH_YEAR, }; /** - * Enum used to set the change side event logic + * Enum used to set the group event logic. + */ +export enum NgxTimelineOrientation { + HORIZONTAL = 'HORIZONTAL', + VERTICAL = 'VERTICAL', +} + +/** + * Enum used to set the change side event logic. */ export enum NgxTimelineEventChangeSide { ALL = 'ALL', @@ -154,7 +150,7 @@ export enum NgxTimelineEventChangeSide { ON_DIFFERENT_MONTH_IN_GROUP = 'ON_DIFFERENT_MONTH_IN_GROUP' } -export const fieldsToCheckEventChangeSideInGroup = { +export const fieldsToCheckEventChangeSideInGroup: Partial> = { ON_DIFFERENT_DAY_IN_GROUP: ['getFullYear', 'getMonth', 'getDate'], ON_DIFFERENT_MONTH_IN_GROUP: ['getFullYear', 'getMonth'], ON_DIFFERENT_HMS_IN_GROUP: ['getFullYear', 'getMonth', 'getDate', 'getHours', 'getMinutes', 'getSeconds'], diff --git a/projects/ngx-timeline/src/lib/models/NgxTimelineEvent.ts b/projects/ngx-timeline/src/lib/models/NgxTimelineEvent.ts index af943aa..4220cbb 100644 --- a/projects/ngx-timeline/src/lib/models/NgxTimelineEvent.ts +++ b/projects/ngx-timeline/src/lib/models/NgxTimelineEvent.ts @@ -1,11 +1,11 @@ /** - * Event to be provided from outside the timeline + * Event to be provided from outside the timeline. */ export interface NgxTimelineEvent { - timestamp?: Date; + timestamp: Date; title?: string; description?: string; - id?: any; + id?: unknown; itemPosition?: NgxTimelineItemPosition; } @@ -14,14 +14,13 @@ export interface NgxTimelinePeriodInfo { year?: number; month?: number; day?: number; - firstDate?: any; + firstDate?: Date; } /** - * Item used inside the timeline + * Item used inside the timeline. */ export interface NgxTimelineItem { - type?: string; position?: NgxTimelineItemPosition.ON_LEFT | NgxTimelineItemPosition.ON_RIGHT; periodInfo?: NgxTimelinePeriodInfo; eventInfo?: NgxTimelineEvent; diff --git a/projects/ngx-timeline/src/lib/ngx-timeline.module.ts b/projects/ngx-timeline/src/lib/ngx-timeline.module.ts index f11910b..6608939 100644 --- a/projects/ngx-timeline/src/lib/ngx-timeline.module.ts +++ b/projects/ngx-timeline/src/lib/ngx-timeline.module.ts @@ -1,4 +1,4 @@ -import {CommonModule, registerLocaleData} from '@angular/common'; +import {registerLocaleData} from '@angular/common'; import localeDe from '@angular/common/locales/de'; import localeEs from '@angular/common/locales/es'; import localeFr from '@angular/common/locales/fr'; @@ -10,7 +10,7 @@ import localeSl from '@angular/common/locales/sl'; import localeTr from '@angular/common/locales/tr'; import {NgModule} from '@angular/core'; -import {NgxTimelineEventComponent, NgxTimelineComponent} from './components'; +import {NgxTimelineComponent, NgxTimelineEventComponent} from './components'; import {NgxDatePipe} from './pipes'; registerLocaleData(localeIt); @@ -25,7 +25,7 @@ registerLocaleData(localeRu); @NgModule({ declarations: [], - imports: [CommonModule, NgxTimelineComponent, NgxTimelineEventComponent, NgxDatePipe], - exports: [NgxTimelineComponent, NgxDatePipe], + imports: [NgxDatePipe, NgxTimelineComponent, NgxTimelineEventComponent], + exports: [NgxDatePipe, NgxTimelineComponent], }) export class NgxTimelineModule { } diff --git a/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.spec.ts b/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.spec.ts index d845139..63e9763 100644 --- a/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.spec.ts +++ b/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.spec.ts @@ -1,11 +1,11 @@ import { NgxDatePipe } from './ngx-date-pipe'; import { NgxDateFormat } from '../models'; -describe('TitleCasePipe', () => { +describe('NgxDatePipe', () => { // This pipe is a pure, stateless function so no need for BeforeEach const pipe = new NgxDatePipe(); - it('transforms from date to string', () => { + it('transforms from date to string (language: it)', () => { const date = new Date('2024-07-10'); expect(pipe.transform(date, NgxDateFormat.DAY_MONTH_YEAR, 'it')).toBe('10 luglio 2024'); }); @@ -14,4 +14,4 @@ describe('TitleCasePipe', () => { const date = new Date('2024-07-10'); expect(pipe.transform(date, NgxDateFormat.DAY_MONTH_YEAR)).toBe('10 July 2024'); }); -}); \ No newline at end of file +}); diff --git a/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.ts b/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.ts index 09ac6e9..b74a3da 100644 --- a/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.ts +++ b/projects/ngx-timeline/src/lib/pipes/ngx-date-pipe.ts @@ -1,26 +1,26 @@ import {DatePipe} from '@angular/common'; import {Pipe, PipeTransform} from '@angular/core'; -import {dateConfigMap, defaultSupportedLanguageCode, fieldConfigDate, NgxConfigDate, SupportedLanguageCode} from '../models'; +import {dateConfigMap, defaultSupportedLanguageCode, fieldConfigDate, NgxConfigDate, NgxDateFormat, SupportedLanguageCode} from '../models'; @Pipe({ name: 'ngxdate', - pure: false, }) export class NgxDatePipe implements PipeTransform { - constructor() { - } - - transform(date: Date | string, dateFormat?: string, langCode?: SupportedLanguageCode): string { - let transformedDate = null; - if (date) { - const objDate = this.getDateConfig(langCode); - transformedDate = new DatePipe(objDate.code).transform(new Date(date), this.dateFormat(dateFormat, objDate)); + transform(date: Date | string, dateFormat?: NgxDateFormat | string, langCode?: SupportedLanguageCode): string | null { + const configDate = this.getDateConfig(langCode); + let dateFormatString = 'yyyy'; + if (dateFormat === undefined) { + console.warn('frxjs-ngx-timeline: no date format defined.'); + } else if (dateFormat in NgxDateFormat) { + dateFormatString = this.dateFormat(dateFormat as NgxDateFormat, configDate); + } else if (typeof dateFormat === 'string') { + dateFormatString = dateFormat; } - return transformedDate; + return new DatePipe(configDate.code).transform(new Date(date), dateFormatString); } - private dateFormat(dateFormat: string, configDate: NgxConfigDate): string { + private dateFormat(dateFormat: NgxDateFormat, configDate: NgxConfigDate): string { return configDate[fieldConfigDate[dateFormat]]; } diff --git a/tsconfig.json b/tsconfig.json index 7116219..8f7712f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "forceConsistentCasingInFileNames": true, "esModuleInterop": true, "preserveSymlinks": true, - "strict": false, + "strict": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "sourceMap": true, @@ -32,7 +32,7 @@ "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, - "strictTemplates": false + "strictTemplates": true }, "include": [ "projects/ngx-timeline/src/**/*.ts" ,