Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 6057a8f

Browse files
committed
Created a component for defining a simple card container
One of the requests for the team was to make it easier to build a simple card container with less setup that has to go into it. We can do this by having a component that inputs the data, columns, and optional options, and sets up a card container builder for you. To allow for live data changes, we'll take the data input and convert it to a behavior subject, and provide this to an observable data source for the card container. The biggest hurdle with this approach is that templates are kind of finicky. To get around this, we have to @ContentChild(ren) the templates into the simple container, then bind these into the card container as external templates. The card container then has to check to see if it needs to use external templates instead of the internal ones.
1 parent 523e861 commit 6057a8f

File tree

6 files changed

+109
-3
lines changed

6 files changed

+109
-3
lines changed

bootstrapper/cards/cardsNg2.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ <h3>Cards</h3>
2626
</div>
2727
</rlSimpleCard>
2828
</div>
29+
<div>
30+
<label>Simple card container:</label>
31+
<rlSimpleCardContainer [data]="data" [columns]="columns" [options]="{ paging: true, search: true }">
32+
<div *rlColumnHeader="let value; name 'value'">Number</div>
33+
<div *rlColumnContent="let value; name 'value'">#{{value}}</div>
34+
<div *rlCardContent="let myItem">
35+
Name: {{myItem.name}}
36+
Value: {{myItem.value}}
37+
</div>
38+
</rlSimpleCardContainer>
39+
</div>
2940
<div>
3041
<label>Card container:</label>
3142
<rlCardContainer [builder]="builder">

bootstrapper/cards/cardsNg2Bootstrapper.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import __transform = services.transform;
1010
import __timezone = services.timezone;
1111
import __object = services.object;
1212

13+
import { IColumn } from '../../source/components/cardContainer/index';
1314
import { CardContainerBuilderService, ICardContainerInstance } from '../../source/components/cardContainer/builder/index';
1415
import {
1516
IDateFilter,
@@ -19,7 +20,7 @@ import {
1920
SelectFilter,
2021
} from '../../source/components/cardContainer/filters/index';
2122

22-
interface ICardItem {
23+
export interface ICardItem {
2324
id: number;
2425
name: string;
2526
value: number;
@@ -55,12 +56,30 @@ export class CardsBootstrapper {
5556
disabledFilterGroup: IFilterGroup<any>;
5657
selectFilter: SelectFilter<any, any>;
5758

59+
columns: IColumn<ICardItem>[];
60+
data: ICardItem[] = items;
61+
5862
constructor(timezone: __timezone.TimezoneService
5963
, cardContainerBuilder: CardContainerBuilderService) {
6064
timezone.setCurrentTimezone('-05:00');
6165

6266
this.options = [1, 2, 3, 4, 5];
6367

68+
this.columns = [
69+
{
70+
name: 'name',
71+
label: 'Name',
72+
size: 6,
73+
getValue: 'name',
74+
},
75+
{
76+
name: 'value',
77+
label: 'Value',
78+
size: 6,
79+
getValue: 'value',
80+
},
81+
];
82+
6483
this.builder = this.setupCardContainer(cardContainerBuilder);
6584
this.selectBuilder = this.setupCardContainer(cardContainerBuilder);
6685
this.searchBuilder = this.setupCardContainer(cardContainerBuilder);

source/components/cardContainer/cardContainer.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Input, ContentChild, ContentChildren, ViewChildren, QueryList, OnInit, ChangeDetectionStrategy } from '@angular/core';
1+
import { Component, Input, ContentChild, ContentChildren, ViewChildren, QueryList, OnInit, AfterContentInit, ChangeDetectionStrategy } from '@angular/core';
22
import { Observable, BehaviorSubject } from 'rxjs';
33
import { isUndefined, isObject, each, map, find, take, every } from 'lodash';
44

@@ -34,7 +34,7 @@ export const defaultMaxColumnSorts: number = 2;
3434
providers: [DataPager, SearchFilter, SortManagerService],
3535
changeDetection: ChangeDetectionStrategy.OnPush,
3636
})
37-
export class CardContainerComponent<T> implements OnInit {
37+
export class CardContainerComponent<T> implements OnInit, AfterContentInit {
3838
builder: ICardContainerConstructor<T>;
3939
save: ISaveAction<any>;
4040

@@ -62,6 +62,13 @@ export class CardContainerComponent<T> implements OnInit {
6262
@ContentChildren(ColumnContentTemplate) columnTemplates: QueryList<ColumnContentTemplate>;
6363
@ContentChildren(ColumnHeaderTemplate) columnHeaders: QueryList<ColumnHeaderTemplate>;
6464

65+
@Input() externalContainerHeader: ContainerHeaderTemplate;
66+
@Input() externalContainerFooter: ContainerFooterTemplate;
67+
@Input() externalCardContent: CardContentTemplate;
68+
@Input() externalCardFooter: CardFooterTemplate;
69+
@Input() externalColumnTemplates: QueryList<ColumnContentTemplate>;
70+
@Input() externalColumnHeaders: QueryList<ColumnHeaderTemplate>;
71+
6572
@ViewChildren(CardComponent) cardChildren: QueryList<CardComponent<T>>;
6673

6774
get cards(): CardComponent<T>[] {
@@ -112,6 +119,19 @@ export class CardContainerComponent<T> implements OnInit {
112119
this.dataSource.init();
113120
}
114121

122+
ngAfterContentInit(): void {
123+
this.containerHeader = this.containerHeader || this.externalContainerHeader;
124+
this.containerFooter = this.containerFooter || this.externalContainerFooter;
125+
this.cardContent = this.cardContent || this.externalCardContent;
126+
this.cardFooter = this.cardFooter || this.externalCardFooter;
127+
if (!this.columnHeaders.length && this.externalColumnHeaders) {
128+
this.columnHeaders = this.externalColumnHeaders;
129+
}
130+
if (!this.columnTemplates.length && this.externalColumnTemplates) {
131+
this.columnTemplates = this.externalColumnTemplates;
132+
}
133+
}
134+
115135
openCard(): boolean {
116136
return every(map(this.cards, card => card.close()));
117137
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<rlCardContainer [builder]="builder"
2+
[externalContainerHeader]="containerHeader"
3+
[externalContainerFooter]="containerFooter"
4+
[externalCardContent]="cardContent"
5+
[externalCardFooter]="cardFooter"
6+
[externalColumnHeaders]="columnHeaders"
7+
[externalColumnTemplates]="columnTemplates"></rlCardContainer>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Component, Input, OnInit, ContentChild, ContentChildren, QueryList } from '@angular/core';
2+
import { BehaviorSubject, Observable } from 'rxjs';
3+
import { each } from 'lodash';
4+
5+
import { IColumn } from '../cardContainer/index';
6+
import { CardContainerBuilderService, ICardContainerInstance, ICardContainerSettings } from '../cardContainer/builder/index';
7+
import { CardContentTemplate, CardFooterTemplate } from '../cards/index';
8+
import { ContainerHeaderTemplate, ContainerFooterTemplate, ColumnContentTemplate } from '../cardContainer/templates/index';
9+
import { ColumnHeaderTemplate } from '../cardContainer/templates/columnHeader.template';
10+
11+
@Component({
12+
selector: 'rlSimpleCardContainer',
13+
template: require('./simpleCardContainer.html'),
14+
})
15+
export class SimpleCardContainer<T> implements OnInit {
16+
@Input() columns: IColumn<T>[];
17+
@Input() options: ICardContainerSettings;
18+
19+
@Input()
20+
set data(value: T[]) {
21+
this.data$.next(value);
22+
}
23+
24+
data$: BehaviorSubject<T[]>;
25+
builder: ICardContainerInstance;
26+
cardContainerBuilder: CardContainerBuilderService;
27+
28+
@ContentChild(ContainerHeaderTemplate) containerHeader: ContainerHeaderTemplate;
29+
@ContentChild(ContainerFooterTemplate) containerFooter: ContainerFooterTemplate;
30+
@ContentChild(CardContentTemplate) cardContent: CardContentTemplate;
31+
@ContentChild(CardFooterTemplate) cardFooter: CardFooterTemplate;
32+
@ContentChildren(ColumnContentTemplate) columnTemplates: QueryList<ColumnContentTemplate>;
33+
@ContentChildren(ColumnHeaderTemplate) columnHeaders: QueryList<ColumnHeaderTemplate>;
34+
35+
constructor(cardContainerBuilder: CardContainerBuilderService) {
36+
this.cardContainerBuilder = cardContainerBuilder;
37+
this.data$ = new BehaviorSubject(null);
38+
}
39+
40+
ngOnInit(): void {
41+
this.builder = this.cardContainerBuilder.getInstance(this.options || {});
42+
each(this.columns, column => {
43+
this.cardContainerBuilder.addColumn(this.builder, column);
44+
});
45+
this.cardContainerBuilder.buildObservableDataSource(this.builder, this.data$);
46+
}
47+
}

source/ui.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { FormComponent } from'./components/form/form';
1313
import { INPUT_DIRECTIVES } from'./components/inputs/index';
1414
import { MultiStepIndicatorComponent } from'./components/multiStepIndicator/multiStepIndicator';
1515
import { RatingBarComponent } from'./components/ratingBar/ratingBar';
16+
import { SimpleCardContainer } from'./components/simpleCardContainer/simpleCardContainer';
1617
import { SIMPLE_CARD_DIRECTIVES } from'./components/simpleCardList/index';
1718
import { StringWithWatermarkComponent } from'./components/stringWithWatermark/stringWithWatermark';
1819
import { TABS_COMPONENT } from'./components/tabs/index';
@@ -42,6 +43,7 @@ export const componentsList: any[] = [
4243
INPUT_DIRECTIVES,
4344
MultiStepIndicatorComponent,
4445
RatingBarComponent,
46+
SimpleCardContainer,
4547
SIMPLE_CARD_DIRECTIVES,
4648
StringWithWatermarkComponent,
4749
TABS_COMPONENT,

0 commit comments

Comments
 (0)