<div class="col-lg-1 eg-grid-header-cell">Move Down</div>
<div class="col-lg-1 eg-grid-header-cell">First Visible</div>
<div class="col-lg-1 eg-grid-header-cell">Last Visible</div>
- <div class="col-lg-1 eg-grid-header-cell" *ngIf="!disableMultiSort">Sort Priority</div>
+ <div class="col-lg-1 eg-grid-header-cell"
+ *ngIf="columnSet.isMultiSortable">Sort Priority</div>
<div class="col-lg-3 eg-grid-header-cell">
- <button class="btn btn-info" ng-click="elevateVisible()">
+ <button class="btn btn-info" (click)="columnSet.moveVisibleToFront()">
Visible Columns To Top
</button>
</div>
</div>
- <div class="row" *ngFor="let col of columnSet.columns"
- [ngClass]="{visible : !col.visible}">
- <div class="col-lg-1" (click)="col.hidden=!col.hidden">
- <span *ngIf="!col.hidden" class="badge badge-success">✓</span>
- <span *ngIf="col.hidden" class="badge badge-warning">✗</span>
+ <div class="row mt-1" *ngFor="let col of columnSet.columns"
+ [ngClass]="{visible : col.visible}">
+ <div class="col-lg-1" (click)="col.visible=!col.visible">
+ <span *ngIf="col.visible" class="badge badge-success">✓</span>
+ <span *ngIf="!col.visible" class="badge badge-warning">✗</span>
</div>
- <div class="col-lg-3" (click)="col.hidden=!col.hidden">{{col.label}}</div>
- <!--
+ <div class="col-lg-3" (click)="col.visible=!col.visible">{{col.label}}</div>
<div class="col-lg-1">
- <a href title="[% l('Move column up') %]"
- ng-click="modifyColumnPos(col, -1)">
- <span class="glyphicon glyphicon-arrow-up"></span>
+ <a class="no-href" title="Move column up" i18n-title
+ (click)="columnSet.moveColumn(col, -1)">
+ <span class="material-icons">arrow_upward</span>
</a>
</div>
<div class="col-lg-1">
- <a href title="[% l('Move column down') %]"
- ng-click="modifyColumnPos(col, 1)">
- <span class="glyphicon glyphicon-arrow-down"></span>
+ <a class="no-href" title="Move column down" i18n-title
+ (click)="columnSet.moveColumn(col, 1)">
+ <span class="material-icons">arrow_downward</span>
</a>
</div>
<div class="col-lg-1">
- <a href title="[% l('Make first visible') %]"
- ng-click="modifyColumnPos(col, -10000)">
- <span class="glyphicon glyphicon-open"></span>
+ <a class="no-href" title="Make first visible" i18n-title
+ (click)="columnSet.moveColumn(col, -10000)">
+ <span class="material-icons">vertical_align_top</span>
</a>
</div>
<div class="col-lg-1">
- <a href title="[% l('Make last visible') %]"
- ng-click="modifyColumnPos(col, 10000)">
- <span class="glyphicon glyphicon-save"></span>
+ <a class="no-href" title="Make last visible" i18n-title
+ (click)="columnSet.moveColumn(col, 10000)">
+ <span class="material-icons">vertical_align_bottom</span>
</a>
</div>
- <div class="col-lg-1" ng-if="!disableMultiSort">
- <div ng-if="col.multisortable">
- <input type='number' ng-model="col.sort"
- title="[% l('Sort Priority / Direction') %]" style='width:2.3em'/>
+ <div class="col-lg-1" *ngIf="columnSet.isMultiSortable">
+ <div *ngIf="col.isMultiSortable">
+ <input type='number' [(ngModel)]="col.sort"
+ title="Sort Priority / Direction" i18n-title style='width:2.4em'/>
</div>
</div>
- -->
</div>
</div>
@Input() path: string;
@Input() label: string;
@Input() flex: number;
- @Input() hidden: boolean = false;
+ @Input() visible: boolean;
+ @Input() hidden: boolean;
@Input() cellTemplate: TemplateRef<any>;
@Input() pkey: boolean;
@Input() dataSource: EgGridDataSource;
@Input() idlClass: string;
+ @Input() isMultiSortable: boolean;
+ @Input() persistKey: string;
pager: Pager;
columnSet: EgGridColumnSet;
constructor(private gridSvc: EgGridService) {
this.pager = new Pager();
this.selector = {};
- this.pager.limit = 10; // TODO
+ this.pager.limit = 10; // TODO config
this.onRowDblClick$ = new EventEmitter<any>();
this.toolbarButtons = [];
}
ngOnInit() {
- this.columnSet = this.gridSvc.initializeColumnSet(this.idlClass);
+ this.columnSet = new EgGridColumnSet(this.idlClass);
+ this.columnSet.isMultiSortable = this.isMultiSortable;
+ this.gridSvc.generateColumns(this.columnSet);
this.dataSource.requestPage(this.pager);
}
reload() {
- this.dataSource.data = [];
this.pager.offset = 0;
+ this.dataSource.data = [];
this.dataSource.requestPage(this.pager);
}
return val+'';
}
- initializeColumnSet(idlClass?: string): EgGridColumnSet {
- let columnSet = new EgGridColumnSet();
+ generateColumns(columnSet: EgGridColumnSet) {
// generate columns for all non-virtual fields on the IDL class
- if (idlClass) {
- this.idl.classes[idlClass].fields.forEach(field => {
+ if (columnSet.idlClass) {
+ this.idl.classes[columnSet.idlClass].fields.forEach(field => {
if (field.virtual) return;
let col = new EgGridColumn();
col.name = field.name;
col.label = field.label || field.name;
col.idlFieldDef = field;
- if (field.name == this.idl.classes[idlClass].pkey)
+ if (field.name == this.idl.classes[columnSet.idlClass].pkey)
col.isPkey = true;
columnSet.add(col);
});
label: string;
flex: number;
hidden: boolean;
+ visible: boolean;
+ sort: number;
idlClass: string;
idlFieldDef: any;
cellTemplate: TemplateRef<any>;
isPkey: boolean;
isDragTarget: boolean;
+ isMultiSortable: boolean;
}
export class EgGridColumnSet {
columns: EgGridColumn[];
+ idlClass: string;
pkeyColumn: EgGridColumn;
+ isMultiSortable: boolean;
- constructor() {
+ constructor(idlClass?: string) {
this.columns = [];
+ this.idlClass = idlClass;
}
add(col: EgGridColumn) {
if (col.isPkey) this.pkeyColumn = col;
+ col.visible = !col.hidden;
+
+ // If a column set is multisortable, all columns are multisortable
+ // by default. TODO: add isNotMultiSortable ?
+ if (col.isMultiSortable === undefined && this.isMultiSortable)
+ col.isMultiSortable = true;
+
this.columns.push(col);
}
displayColumns(): EgGridColumn[] {
- return this.columns.filter(c => !c.hidden);
+ return this.columns.filter(c => c.visible);
}
insertBefore(source: EgGridColumn, target: EgGridColumn) {
this.columns.splice(targetIdx, 0, source);
}
+ // Move visible columns to the front of the list.
+ moveVisibleToFront() {
+ let newCols = this.displayColumns();
+ this.columns.forEach(col => { if (!col.visible) newCols.push(col) });
+ this.columns = newCols;
+ }
+
+ moveColumn(col: EgGridColumn, diff: number) {
+ var srcIdx, targetIdx;
+
+ this.columns.forEach((c, i) => {
+ if (c.name == col.name) srcIdx = i
+ });
+
+ targetIdx = srcIdx + diff;
+ if (targetIdx < 0) {
+ targetIdx = 0;
+ } else if (targetIdx >= this.columns.length) {
+ // Target index follows the last visible column.
+ var lastVisible = 0;
+ this.columns.forEach((c, idx) => {
+ if (c.visible) lastVisible = idx;
+ });
+
+ // When moving a column (down) causes one or more
+ // visible columns to shuffle forward, our column
+ // moves into the slot of the last visible column.
+ // Otherwise, put it into the slot directly following
+ // the last visible column.
+ targetIdx = srcIdx <= lastVisible ? lastVisible : lastVisible + 1;
+ }
+
+ // Splice column out of old position, insert at new position.
+ this.columns.splice(srcIdx, 1);
+ this.columns.splice(targetIdx, 0, col);
+ }
+
+
}
export class EgGridToolbarButton {
<eg-staff-banner bannerText="Billing Type Configuration" i18n-bannerText>
</eg-staff-banner>
-<eg-grid #btGrid idlClass="cbt" [dataSource]="dataSource">
+<eg-grid #btGrid idlClass="cbt" [dataSource]="dataSource" [isMultiSortable]="true">
<eg-grid-toolbar-button label="New Billing Type" i18n-label [action]="createBillingType">
</eg-grid-toolbar-button>
</eg-grid>