UNPKG

novo-elements

Version:

Bullhorn's NOVO Element Repository for Angular 2

477 lines (447 loc) 17.8 kB
// NG2 import { Component, OnInit } from '@angular/core'; // APP // import { MovieDataProvider } from './MovieDataProvider'; import { TableData } from './TableData'; import { ArrayCollection } from './../../../../src/services/data-provider/ArrayCollection'; let TableDemoTpl = require('./templates/TableDemo.html'); let EditableTableDemoTpl = require('./templates/EditableTableDemo.html'); let DetailsTableDemoTpl = require('./templates/DetailsTableDemo.html'); let SelectAllTableDemoTpl = require('./templates/SelectAllTableDemo.html'); let MovieTableDemoTpl = require('./templates/MovieTableDemo.html'); let TotalFooterTableDemoTpl = require('./templates/TotalFooterTableDemo.html'); // Vendor import { DateCell, PercentageCell, BaseRenderer, NovoTableElement, NovoTableConfig, TextBoxControl, TablePickerControl, SelectControl, NovoDropdownCell } from './../../../../index'; const template = ` <div class="container"> <h1>Table <small><a target="_blank" href="https://bullhorn.github.io/novo-elements/blob/master/src/elements/table">(source)</a></small></h1> <p>Tables allow users to view date in a tabular format and perform actions such as Sorting and Filtering. Different configuration are possible for pagination or infinite scroll. Feature to be added include: Custom Item Renderers, etc...</p> <h2>Types</h2> <h5>Basic Table</h5> <p>This is the most basic table.</p> <div class="example table-demo">${TableDemoTpl}</div> <code-snippet [code]="TableDemoTpl"></code-snippet> <h5>Details Table</h5> <p>This has a row renderer to show a new details row that is expanded when you click on the action column.</p> <div class="example table-demo">${DetailsTableDemoTpl}</div> <code-snippet [code]="DetailsTableDemoTpl"></code-snippet> <h5>Select All Table w/ Custom Actions</h5> <p>This has checkboxes for selection with custom actions.</p> <div class="example table-demo">${SelectAllTableDemoTpl}</div> <code-snippet [code]="SelectAllTableDemoTpl"></code-snippet> <h5>Remote Table Provider</h5> <p>This has connects to the OMDB service.</p> <div class="example table-demo">${MovieTableDemoTpl}</div> <code-snippet [code]="MovieTableDemoTpl"></code-snippet> <h5>Editable Table</h5> <p>Can be put into edit mode and use editors that are set on the column to modify the data.</p> <div class="example table-demo">${EditableTableDemoTpl}</div> <code-snippet [code]="EditableTableDemoTpl"></code-snippet> <h5>Total/Average Footer</h5> <p>Easily configure a footer to sum or average up columns.</p> <div class="example table-demo">${TotalFooterTableDemoTpl}</div> <code-snippet [code]="TotalFooterTableDemoTpl"></code-snippet> </div> `; const HEADER_COLORS = ['aqua', 'ocean', 'mint', 'grass', 'sunflower', 'company', 'lead', 'positive', 'black']; @Component({ selector: 'status-cell', template: ` <div class="status-cell"> <i class="bhi-info"></i> <label>{{ value }}</label> </div> ` }) export class StatusCell extends BaseRenderer { } @Component({ selector: 'extra-details', template: ` <div class="extra-data"> <label><i class="bhi-info"></i>Description</label> <p>{{ data.description }}</p> <label><i class="bhi-info"></i>Categories</label> <p>{{ data.categories }}</p> </div> ` }) export class ExtraDetails extends BaseRenderer { } @Component({ selector: 'image-cell', template: ` <div class="image-cell"> <img src="{{value}}"/> </div> ` }) export class ImageCell extends BaseRenderer { } @Component({ selector: 'actions-cell', template: ` <novo-dropdown appendToBody="true" parentScrollSelector=".table-container"> <button type="button" theme="dialogue" icon="collapse">Actions!</button> <list> <item>Item 1</item> <item>Item 2</item> <item>Item 3</item> <item>Item 4</item> <item>Item 5</item> <item>Item 6</item> <item>Item 7</item> <item>Item 8</item> <item>Item 9</item> </list> </novo-dropdown> ` }) export class ActionsCell extends BaseRenderer { constructor() { super(); } getActionContext(data, meta) { return { item: data, meta }; } } interface TableDemoConfig { rows?: any; dataProvider?: any; columns: any[]; config: NovoTableConfig; } @Component({ selector: 'table-demo', template: template }) export class TableDemoComponent implements OnInit { public TableDemoTpl: string = TableDemoTpl; public DetailsTableDemoTpl: string = DetailsTableDemoTpl; public SelectAllTableDemoTpl: string = SelectAllTableDemoTpl; public MovieTableDemoTpl: string = MovieTableDemoTpl; public EditableTableDemoTpl: string = EditableTableDemoTpl; public TotalFooterTableDemoTpl: string = TotalFooterTableDemoTpl; public customRowOptions: Array<any> = [ { label: '10', value: 10 }, { label: '20', value: 20 }, { label: '30', value: 30 }, { label: '40', value: 40 } ]; public theme: string; public basic: TableDemoConfig; public details: TableDemoConfig; private selectAll: TableDemoConfig; public remote: TableDemoConfig; public totalFooter: TableDemoConfig; public editable: TableDemoConfig; public editableNewRowDefault: any = { name: 'Default', jobType: 'Contract' }; constructor() { let columns = [ { title: 'Actions', renderer: ActionsCell }, { title: 'Name', name: 'name', ordering: true, type: 'link', filtering: true }, { title: 'Position', name: 'position', ordering: true, filtering: true }, { title: 'Extn.', name: 'ext', ordering: true, renderer: object => { return object.ext.obj; }, compare: (sort, previous, current) => { let first = previous.obj, second = current.obj; if (first > second) { return sort === 'desc' ? -1 : 1; } if (first < second) { return sort === 'asc' ? -1 : 1; } return 0; } }, { title: 'Start date', type: 'date', name: 'startDate', renderer: DateCell, ordering: true, filtering: true, range: true }, { title: '%', name: 'percent', ordering: true, renderer: PercentageCell }, { title: 'Salary', name: 'salary', ordering: true, renderer: (object) => { return `$ ${Number(object.salary).toFixed(2)}`; } }, { title: 'Status', name: 'status', renderer: NovoDropdownCell, dropdownCellConfig: [ { category: 'Update Status', callback: this.updateStatus.bind(this), options: [ { label: 'New Lead', value: 'New Lead' }, { label: 'Active', value: 'Active' }, { label: 'Archived', value: 'Archived', } ] }, { category: 'Move', callback: this.move.bind(this), options: ['Kitten', 'Kitty'] }, { callback: this.move.bind(this), options: ['Meow', 'Kitty'] } ] } ]; this.basic = { columns: columns.slice(), rows: [], config: { paging: { current: 1, itemsPerPage: 10, onPageChange: event => { this.basic.config.paging.current = event.page; this.basic.config.paging.itemsPerPage = event.itemsPerPage; } }, filtering: true, sorting: true, ordering: true, resizing: true } }; this.details = { columns: columns.slice(), rows: TableData.slice(), config: { paging: { current: 1, itemsPerPage: 10, onPageChange: event => { this.details.config.paging.current = event.page; this.details.config.paging.itemsPerPage = event.itemsPerPage; } }, sorting: true, filtering: true, ordering: true, resizing: true, hasDetails: true, detailsRenderer: ExtraDetails } }; this.selectAll = { columns: columns.slice(), rows: TableData.slice(), config: { paging: { current: 1, itemsPerPage: 10, onPageChange: event => { this.selectAll.config.paging.current = event.page; this.selectAll.config.paging.itemsPerPage = event.itemsPerPage; } }, sorting: true, filtering: true, ordering: true, resizing: true, selectAllEnabled: true, rowSelectionStyle: 'checkbox' } }; let imdbColumns = [ { title: 'Title', name: 'Title', ordering: true, filtering: true }, { title: 'Year', name: 'Year', ordering: true, filtering: true }, { title: 'Type', name: 'Type', ordering: true, filtering: true, options: ['movie', 'series', 'episode'], multiple: true }, { title: 'Poster', name: 'Poster', ordering: false, filtering: false, renderer: ImageCell } ]; // this.remote = { // columns: imdbColumns.slice(), // dataProvider: new MovieDataProvider(), // config: { // paging: { // current: 1, // itemsPerPage: 10, // onPageChange: event => { // this.basic.config.paging.current = event.page; // this.basic.config.paging.itemsPerPage = event.itemsPerPage; // } // }, // filtering: true, // sorting: true, // ordering: true, // resizing: true // } // }; // For columns that can be edited, pass an editor property let names = [ 'Joshua Godi', 'Kameron Sween', 'Brian Kimball', 'Sweeney Todd', 'Tom Cruise', 'Ed Bailey', 'Bo Jackson', 'Ernie McDudson' ]; this.editable = { columns: [ { title: 'Name', name: 'name', ordering: true, filtering: true, editorType: 'TablePickerControl', editorConfig: { key: 'name', config: { options: names } } }, { title: 'Job Type', name: 'jobType', ordering: true, filtering: true, editorType: 'SelectControl', editorConfig: { key: 'jobType', options: ['Freelance', 'Contract', 'Billable'] } }, { title: 'Rate', name: 'rate', ordering: true, filtering: true, renderer: PercentageCell, editorType: 'TextBoxControl', editorConfig: { key: 'rate', type: 'percentage', required: true, interactions: [ { event: 'change', script: (form) => { console.log('Form Interaction Called!', form); // tslint:disable-line if (form.value.rate) { if (Number(form.value.rate) >= .75) { form.controls.rating.setValue('High'); } else if (Number(form.value.rate) >= .50) { form.controls.rating.setValue('Medium'); } else { form.controls.rating.setValue('Low'); } } } } ] } }, { title: 'Rating', name: 'rating' } ], rows: new ArrayCollection([ { id: 1, name: 'Joshua Godi', jobType: 'Freelance', rate: null, rating: 'Low' }, { id: 2, name: 'Brian Kimball', jobType: 'Contact', rate: .50, rating: 'Medium' }, { id: 3, name: 'Kameron Sween', jobType: 'Billable', rate: 1.00, rating: 'High' } ]), config: { paging: { current: 1, itemsPerPage: 10, onPageChange: event => { this.basic.config.paging.current = event.page; this.basic.config.paging.itemsPerPage = event.itemsPerPage; } }, filtering: true, sorting: true, ordering: true, resizing: true } }; this.totalFooter = { columns: [ { title: 'Name', name: 'name', ordering: true, filtering: true }, { title: 'Count 1', name: 'count1', ordering: true, filtering: true }, { title: 'Count 2', name: 'count2', ordering: true, filtering: true }, { title: 'Count 3', name: 'count3', ordering: true, filtering: true } ], rows: [ { id: 1, name: 'Name 1', count1: 1, count2: 2, count3: 3 }, { id: 2, name: 'Name 2', count1: 1, count2: 2, count3: 3 }, { id: 3, name: 'Name 3', count1: 1, count2: 2, count3: 3 }, { id: 4, name: 'Name 4', count1: 1, count2: 2, count3: 3 }, { id: 5, name: 'Name 5', count1: 1, count2: 2, count3: 3 }, ], config: { paging: { current: 1, itemsPerPage: 10, onPageChange: event => { this.basic.config.paging.current = event.page; this.basic.config.paging.itemsPerPage = event.itemsPerPage; } }, footers: [{ columns: ['count1', 'count2', 'count3'], method: 'SUM', labelColumn: 'name', label: 'Mega Total' }, { columns: ['count1', 'count2', 'count3'], method: 'AVG', labelColumn: 'name', label: 'Yep, Average!' }], filtering: true, sorting: true, ordering: true, resizing: true } }; } ngOnInit() { this.theme = HEADER_COLORS[0]; } reload() { this.basic.rows = TableData.slice(); } changeTheme() { let idx = HEADER_COLORS.indexOf(this.theme); if (idx === HEADER_COLORS.length - 1) { idx = -1; } this.theme = HEADER_COLORS[idx + 1]; } singleAction() { window.alert('HI!'); } selectedAction(action) { window.alert(`You clicked ${action}!`); } save(table: NovoTableElement) { // Save updated data and get fresh data for the table to reflect the changes! let errorsOrData = table.validateAndGetUpdatedData(); if (!errorsOrData.errors) { table.toggleLoading(true); console.log('SAVING', errorsOrData); // tslint:disable-line // TODO - save data - fetch the data setTimeout(() => { table.displayToastMessage({ icon: 'check', theme: 'success', message: 'Saved!' }, 2000); table.saveChanges(); }, 2000); } else { console.log('ERRORS!', errorsOrData); // tslint:disable-line table.displayToastMessage({ icon: 'caution', theme: 'danger', message: 'Errors!!' }); } } public updateStatus(data: any, status: string): void { console.log('Update Status', data, status); // tslint:disable-line } public move(data: any, status: string): void { console.log('Move', data, status); // tslint:disable-line } }