// to expire on the server.
let pollTime = this.authtime() * 1000 + 5000;
+ console.debug('polling with timeout ' + pollTime);
+
this.pollTimeout = setTimeout(() => {
this.net.request(
'open-ils.auth',
// EgNetService intercepts NO_SESSION events.
// If the promise resolves, the session is valid.
- ).toPromise().then(user => this.sessionPoll())
+ ).subscribe(
+ user => this.sessionPoll(),
+ err => console.warn('auth poll error: ' + err)
+ );
}, pollTime);
}
--- /dev/null
+<ng-template #dialogContent>
+ <div class="modal-header bg-info">
+ <h4 class="modal-title" i18n>Grid Columns Configuration</h4>
+ <button type="button" class="close"
+ i18n-aria-label aria-label="Close"
+ (click)="dismiss('cross_click')">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body eg-grid-column-config-dialog">
+
+ <div class="row">
+ <div class="col-lg-1 eg-grid-header-cell">Visible</div>
+ <div class="col-lg-3 eg-grid-header-cell">Column Name</div>
+ <div class="col-lg-1 eg-grid-header-cell">Move Up</div>
+ <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-3 eg-grid-header-cell">
+ <button class="btn btn-info" ng-click="elevateVisible()">
+ 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>
+ <div class="col-lg-3" (click)="col.hidden=!col.hidden">{{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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </div>
+ -->
+
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-success"
+ (click)="close('confirmed')" i18n>Close</button>
+ </div>
+</ng-template>
--- /dev/null
+import {Component, Input, ViewChild, TemplateRef} from '@angular/core';
+import {EgDialogComponent} from '@eg/share/dialog/dialog.component';
+import {EgGridService, EgGridColumn, EgGridColumnSet} from './grid.service';
+
+@Component({
+ selector: 'eg-grid-column-config',
+ templateUrl: './grid-column-config.component.html'
+})
+
+/**
+ */
+export class EgGridColumnConfigComponent extends EgDialogComponent {
+ @Input() columnSet: EgGridColumnSet;
+
+}
+
+
<div class="eg-grid-cell eg-grid-header-cell eg-grid-number-cell eg-grid-cell-skinny">
<span i18n="number|Row Number Header">#</span>
</div>
- <div *ngFor="let col of columnSet.displayColumns()"
- class="eg-grid-cell eg-grid-header-cell" [ngStyle]="{flex:col.flex}">
- {{col.label}}
- </div>
+ <div *ngFor="let col of columnSet.displayColumns()"
+ draggable="true"
+ (dragstart)="dragColumn = col"
+ (drop)="onColumnDrop(col)"
+ (dragover)="onColumnDragEnter($event, col)"
+ (dragleave)="onColumnDragLeave($event, col)"
+ [ngClass]="{'eg-grid-header-cell dragover' : col.isDragTarget}"
+ class="eg-grid-cell eg-grid-header-cell" [ngStyle]="{flex:col.flex}">
+ {{col.label}}
+ </div>
</div>
-import {Component, Input, OnInit} from '@angular/core';
+import {Component, Input, OnInit, HostListener} from '@angular/core';
import {EgGridService, EgGridColumn, EgGridColumnSet} from './grid.service';
@Component({
@Input() columnSet: EgGridColumnSet;
@Input() selected: {[idx:number] : boolean};
+ dragColumn: EgGridColumn;
constructor(private gridSvc: EgGridService) { }
ngOnInit() {
}
+
+ onColumnDragEnter($event: any, col: any) {
+ if (this.dragColumn && this.dragColumn.name != col.name)
+ col.isDragTarget = true;
+ $event.preventDefault();
+ }
+
+ onColumnDragLeave($event: any, col: any) {
+ col.isDragTarget = false;
+ $event.preventDefault();
+ }
+
+ onColumnDrop(col: EgGridColumn) {
+ this.columnSet.insertBefore(this.dragColumn, col);
+ this.columnSet.columns.forEach(c => c.isDragTarget = false);
+ }
}
--- /dev/null
+import {Component, Input, OnInit, Host, TemplateRef} from '@angular/core';
+import {EgGridService, EgGridToolbarButton} from './grid.service';
+import {EgGridComponent} from './grid.component';
+
+@Component({
+ selector: 'eg-grid-toolbar-button',
+ template: '<ng-template></ng-template>'
+})
+
+export class EgGridToolbarButtonComponent implements OnInit {
+
+ // Note most input fields should match class fields for EgGridColumn
+ @Input() label: string;
+ @Input() action: () => any;
+
+ // get a reference to our container grid.
+ constructor(
+ private gridSvc: EgGridService,
+ @Host() private grid: EgGridComponent) {
+ }
+
+ ngOnInit() {
+
+ if (!this.grid) {
+ console.warn('EgGridToolbarButtonComponent needs a [grid]');
+ return;
+ }
+
+ let btn = new EgGridToolbarButton();
+ btn.label = this.label;
+ btn.action = this.action;
+
+ this.grid.toolbarButtons.push(btn);
+ }
+}
+
</div>
</div>
+ <eg-grid-column-config #columnConfDialog [columnSet]="columnSet">
+ </eg-grid-column-config>
+ <div ngbDropdown class="ml-1" placement="bottom-right">
+ <button ngbDropdownToggle class="btn btn-light no-dropdown-caret">
+ <span title="Show Grid Options" i18n-title class="material-icons">arrow_drop_down</span>
+ </button>
+ <div class="dropdown-menu" ngbDropdownMenu>
+ <a class="dropdown-item" (click)="columnConfDialog.open({size:'lg'})">
+ <span class="material-icons">build</span>
+ <span i18n>Manage Columns</span>
+ </a>
+ </div>
+ </div>
+
<div>
+
+
import {Pager} from '@eg/share/util/pager';
import {EgGridService, EgGridColumn, EgGridColumnSet, EgGridToolbarButton}
from '@eg/share/grid/grid.service';
+import {EgDialogComponent} from '@eg/share/dialog/dialog.component';
@Component({
selector: 'eg-grid-toolbar',
@Input() dataSource: EgGridDataSource;
@Input() pager: Pager;
@Input() toolbarButtons: EgGridToolbarButton[];
+ @Input() columnSet: EgGridColumnSet;
ngOnInit() {
font-weight: bold;
}
+.eg-grid-header-cell.dragover {
+ background-color: #cce5ff;
+ border-color: #b8daff;
+}
+
.eg-grid-cell {
flex: 1; /* applied per column */
padding: 6px;
flex: none;
}
+.eg-grid-column-config-dialog.visible {
+ color: #000;
+ background-color: rgb(201, 221, 225);
+ border-bottom: 1px solid #888;
+}
+
<div class="eg-grid">
<eg-grid-toolbar [dataSource]="dataSource" [pager]="pager"
- [toolbarButtons]="toolbarButtons"></eg-grid-toolbar>
+ [toolbarButtons]="toolbarButtons" [columnSet]="columnSet"></eg-grid-toolbar>
<eg-grid-header [columnSet]="columnSet"></eg-grid-header>
<div class="eg-grid-row eg-grid-body-row"
import {NgModule} from '@angular/core';
-import {CommonModule} from '@angular/common';
-import {FormsModule} from '@angular/forms';
+import {EgCommonModule} from '@eg/common.module';
+//import {EgDialogComponent} from '@eg/share/dialog/dialog.component';
import {EgGridComponent} from './grid.component';
import {EgGridColumnComponent} from './grid-column.component';
import {EgGridHeaderComponent} from './grid-header.component';
import {EgGridToolbarComponent} from './grid-toolbar.component';
import {EgGridService} from './grid.service';
import {EgGridToolbarButtonComponent} from './grid-toolbar-button.component';
+import {EgGridColumnConfigComponent} from './grid-column-config.component';
+
@NgModule({
declarations: [
EgGridColumnComponent,
EgGridHeaderComponent,
EgGridToolbarComponent,
- EgGridToolbarButtonComponent
+ EgGridToolbarButtonComponent,
+ EgGridColumnConfigComponent
],
imports: [
- CommonModule,
- FormsModule
+ EgCommonModule
],
exports: [
// public components
idlFieldDef: any;
cellTemplate: TemplateRef<any>;
isPkey: boolean;
+ isDragTarget: boolean;
}
displayColumns(): EgGridColumn[] {
return this.columns.filter(c => !c.hidden);
}
+
+ insertBefore(source: EgGridColumn, target: EgGridColumn) {
+ let targetIdx = 0;
+ let sourceIdx = 0;
+ this.columns.forEach((col, idx) => {
+ if (col.name == target.name) targetIdx = idx; });
+
+ this.columns.forEach((col, idx) => {
+ if (col.name == source.name) sourceIdx = idx; });
+
+ if (sourceIdx)
+ this.columns.splice(sourceIdx, 1);
+
+ this.columns.splice(targetIdx, 0, source);
+ }
+
}
export class EgGridToolbarButton {
align-items: center;
}
+/* dropdown menu link/button with no downward carrot icon */
+.no-dropdown-caret::after {
+ display: none;
+}
+
/* Default .card padding is extreme */
.tight-card .card-body,
.tight-card .list-group-item {