Add no implicit any to the strict null check (#5635)

* wip

* working through adding no implicit any
This commit is contained in:
Anthony Dresser
2019-06-04 09:29:40 -07:00
committed by GitHub
parent 50242b2c35
commit 4ad226570a
26 changed files with 296 additions and 306 deletions

View File

@@ -222,4 +222,8 @@ export class AsyncDataProvider<T extends Slick.SlickData> implements IDisposable
dispose() { dispose() {
this.dataRows.dispose(); this.dataRows.dispose();
} }
getItems(): T[] {
throw new Error('Method not supported.');
}
} }

View File

@@ -15,7 +15,7 @@ export class AdditionalKeyBindings<T> implements Slick.Plugin<T> {
public init(grid: Slick.Grid<T>) { public init(grid: Slick.Grid<T>) {
this.grid = grid; this.grid = grid;
this.handler.subscribe(this.grid.onKeyDown, (e, args) => this.handleKeyDown(e, args)); this.handler.subscribe(this.grid.onKeyDown, (e: KeyboardEvent, args) => this.handleKeyDown(e, args));
} }
public destroy() { public destroy() {

View File

@@ -49,7 +49,7 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
// since data can be async we want to only do this if we have the data to actual // since data can be async we want to only do this if we have the data to actual
// work on since we are measuring the physical length of data // work on since we are measuring the physical length of data
let data = this._grid.getData(); let data = this._grid.getData() as Slick.DataProvider<T>;
let item = data.getItem(0); let item = data.getItem(0);
if (item && Object.keys(item).length > 0) { if (item && Object.keys(item).length > 0) {
let hasValue = false; let hasValue = false;
@@ -134,15 +134,15 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
} }
} }
private getMaxColumnTextWidth(columnDef, colIndex: number): number { private getMaxColumnTextWidth(columnDef: Slick.Column<T>, colIndex: number): number {
let texts: Array<string> = []; let texts: Array<string> = [];
let rowEl = this.createRow(columnDef); let rowEl = this.createRow();
let data = this._grid.getData(); let data = this._grid.getData() as Slick.DataProvider<T>;
let viewPort = this._grid.getViewport(); let viewPort = this._grid.getViewport();
let start = Math.max(0, viewPort.top); let start = Math.max(0, viewPort.top);
let end = Math.min(data.getLength(), viewPort.bottom); let end = Math.min(data.getLength(), viewPort.bottom);
for (let i = start; i < end; i++) { for (let i = start; i < end; i++) {
texts.push(data.getItem(i)[columnDef.field]); texts.push(data.getItem(i)[columnDef.field!]);
} }
let template = this.getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl); let template = this.getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl);
let width = this.getTemplateWidth(rowEl, template); let width = this.getTemplateWidth(rowEl, template);
@@ -150,21 +150,21 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
return width > this._options.maxWidth! ? this._options.maxWidth! : width; return width > this._options.maxWidth! ? this._options.maxWidth! : width;
} }
private getTemplateWidth(rowEl: JQuery, template: JQuery | HTMLElement): number { private getTemplateWidth(rowEl: JQuery, template: JQuery | HTMLElement | string): number {
let cell = jQuery(rowEl.find('.slick-cell')); let cell = jQuery(rowEl.find('.slick-cell'));
cell.append(template); cell.append(template);
jQuery(cell).find('*').css('position', 'relative'); jQuery(cell).find('*').css('position', 'relative');
return cell.outerWidth() + 1; return cell.outerWidth() + 1;
} }
private getMaxTextTemplate(texts: string[], columnDef, colIndex: number, data, rowEl: JQuery): JQuery | HTMLElement { private getMaxTextTemplate(texts: string[], columnDef: Slick.Column<T>, colIndex: number, data: Slick.DataProvider<T>, rowEl: JQuery): JQuery | HTMLElement | string {
let max = 0, let max = 0,
maxTemplate = null; maxTemplate: JQuery | HTMLElement | string | undefined;
let formatFun = columnDef.formatter; let formatFun = columnDef.formatter;
texts.forEach((text, index) => { texts.forEach((text, index) => {
let template; let template;
if (formatFun) { if (formatFun) {
template = jQuery('<span>' + formatFun(index, colIndex, text, columnDef, data[index]) + '</span>'); template = jQuery('<span>' + formatFun(index, colIndex, text, columnDef, data.getItem(index)) + '</span>');
text = template.text() || text; text = template.text() || text;
} }
let length = text ? this.getElementWidthUsingCanvas(rowEl, text) : 0; let length = text ? this.getElementWidthUsingCanvas(rowEl, text) : 0;
@@ -176,7 +176,7 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
return maxTemplate!; return maxTemplate!;
} }
private createRow(columnDef): JQuery { private createRow(): JQuery {
let rowEl = jQuery('<div class="slick-row"><div class="slick-cell"></div></div>'); let rowEl = jQuery('<div class="slick-row"><div class="slick-cell"></div></div>');
rowEl.find('.slick-cell').css({ rowEl.find('.slick-cell').css({
'visibility': 'hidden', 'visibility': 'hidden',

View File

@@ -26,13 +26,13 @@ export interface ICellRangeSelectorOptions {
} }
export interface ICellRangeSelector<T> extends Slick.Plugin<T> { export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>; onCellRangeSelected: Slick.Event<Slick.Range>;
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>; onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
} }
export interface ICellRangeDecorator { export interface ICellRangeDecorator {
show(range: Slick.Range); show(range: Slick.Range): void;
hide(); hide(): void;
} }
export class CellRangeSelector<T> implements ICellRangeSelector<T> { export class CellRangeSelector<T> implements ICellRangeSelector<T> {
@@ -44,7 +44,7 @@ export class CellRangeSelector<T> implements ICellRangeSelector<T> {
private currentlySelectedRange: { start: Slick.Cell, end?: Slick.Cell }; private currentlySelectedRange: { start: Slick.Cell, end?: Slick.Cell };
public onBeforeCellRangeSelected = new Slick.Event<Slick.Cell>(); public onBeforeCellRangeSelected = new Slick.Event<Slick.Cell>();
public onCellRangeSelected = new Slick.Event<{ range: Slick.Range }>(); public onCellRangeSelected = new Slick.Event<Slick.Range>();
constructor(private options: ICellRangeSelectorOptions) { constructor(private options: ICellRangeSelectorOptions) {
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator'); require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
@@ -58,9 +58,9 @@ export class CellRangeSelector<T> implements ICellRangeSelector<T> {
this.canvas = this.grid.getCanvasNode(); this.canvas = this.grid.getCanvasNode();
this.handler this.handler
.subscribe(this.grid.onDragInit, e => this.handleDragInit(e)) .subscribe(this.grid.onDragInit, e => this.handleDragInit(e))
.subscribe(this.grid.onDragStart, (e, dd) => this.handleDragStart(e, dd)) .subscribe(this.grid.onDragStart, (e: MouseEvent, dd) => this.handleDragStart(e, dd))
.subscribe(this.grid.onDrag, (e, dd) => this.handleDrag(e, dd)) .subscribe(this.grid.onDrag, (e: MouseEvent, dd) => this.handleDrag(e, dd))
.subscribe(this.grid.onDragEnd, (e, dd) => this.handleDragEnd(e, dd)); .subscribe(this.grid.onDragEnd, (e: MouseEvent, dd) => this.handleDragEnd(e, dd));
} }
public destroy() { public destroy() {
@@ -138,13 +138,11 @@ export class CellRangeSelector<T> implements ICellRangeSelector<T> {
if (!dd || !dd.range || !dd.range.start || !dd.range.end) { if (!dd || !dd.range || !dd.range.start || !dd.range.end) {
return; return;
} }
this.onCellRangeSelected.notify({ this.onCellRangeSelected.notify(new Slick.Range(
range: new Slick.Range( dd.range.start.row,
dd.range.start.row, dd.range.start.cell,
dd.range.start.cell, dd.range.end.row,
dd.range.end.row, dd.range.end.cell
dd.range.end.cell ));
)
});
} }
} }

View File

@@ -19,6 +19,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
private grid: Slick.Grid<T>; private grid: Slick.Grid<T>;
private selector: ICellRangeSelector<T>; private selector: ICellRangeSelector<T>;
private ranges: Array<Slick.Range> = []; private ranges: Array<Slick.Range> = [];
private _handler = new Slick.EventHandler();
public onSelectedRangesChanged = new Slick.Event<Array<Slick.Range>>(); public onSelectedRangesChanged = new Slick.Event<Array<Slick.Range>>();
@@ -35,19 +36,16 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
public init(grid: Slick.Grid<T>) { public init(grid: Slick.Grid<T>) {
this.grid = grid; this.grid = grid;
this.grid.onActiveCellChanged.subscribe((e, args) => this.handleActiveCellChange(e, args)); this._handler.subscribe(this.grid.onActiveCellChanged, (e: Event, args: Slick.OnActiveCellChangedEventArgs<T>) => this.handleActiveCellChange(e, args));
this.grid.onKeyDown.subscribe(e => this.handleKeyDown(e)); this._handler.subscribe(this.grid.onKeyDown, (e: KeyboardEvent) => this.handleKeyDown(e));
this.grid.onHeaderClick.subscribe((e: MouseEvent, args) => this.handleHeaderClick(e, args)); this._handler.subscribe(this.grid.onHeaderClick, (e: MouseEvent, args: Slick.OnHeaderClickEventArgs<T>) => this.handleHeaderClick(e, args));
this.grid.registerPlugin(this.selector); this.grid.registerPlugin(this.selector);
this.selector.onCellRangeSelected.subscribe((e, args) => this.handleCellRangeSelected(e, args)); this._handler.subscribe(this.selector.onCellRangeSelected, (e: Event, range: Slick.Range) => this.handleCellRangeSelected(e, range));
this.selector.onBeforeCellRangeSelected.subscribe((e, args) => this.handleBeforeCellRangeSelected(e, args)); this._handler.subscribe(this.selector.onBeforeCellRangeSelected, (e: Event, cell: Slick.Cell) => this.handleBeforeCellRangeSelected(e, cell));
} }
public destroy() { public destroy() {
this.grid.onActiveCellChanged.unsubscribe((e, args) => this.handleActiveCellChange(e, args)); this._handler.unsubscribeAll();
this.grid.onKeyDown.unsubscribe(e => this.handleKeyDown(e));
this.selector.onCellRangeSelected.unsubscribe((e, args) => this.handleCellRangeSelected(e, args));
this.selector.onBeforeCellRangeSelected.unsubscribe((e, args) => this.handleBeforeCellRangeSelected(e, args));
this.grid.unregisterPlugin(this.selector); this.grid.unregisterPlugin(this.selector);
} }
@@ -81,7 +79,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
return this.ranges; return this.ranges;
} }
private handleBeforeCellRangeSelected(e, args: Slick.Cell) { private handleBeforeCellRangeSelected(e: Event, args: Slick.Cell) {
if (this.grid.getEditorLock().isActive()) { if (this.grid.getEditorLock().isActive()) {
e.stopPropagation(); e.stopPropagation();
return false; return false;
@@ -89,12 +87,12 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
return true; return true;
} }
private handleCellRangeSelected(e, args: { range: Slick.Range }) { private handleCellRangeSelected(e: Event, range: Slick.Range) {
this.grid.setActiveCell(args.range.fromRow, args.range.fromCell, false, false, true); this.grid.setActiveCell(range.fromRow, range.fromCell, false, false, true);
this.setSelectedRanges([args.range]); this.setSelectedRanges([range]);
} }
private handleActiveCellChange(e, args) { private handleActiveCellChange(e: Event, args: Slick.OnActiveCellChangedEventArgs<T>) {
if (this.options.selectActiveCell && !isUndefinedOrNull(args.row) && !isUndefinedOrNull(args.cell)) { if (this.options.selectActiveCell && !isUndefinedOrNull(args.row) && !isUndefinedOrNull(args.cell)) {
this.setSelectedRanges([new Slick.Range(args.row, args.cell)]); this.setSelectedRanges([new Slick.Range(args.row, args.cell)]);
} else if (!this.options.selectActiveCell) { } else if (!this.options.selectActiveCell) {
@@ -120,7 +118,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
} }
} }
private handleKeyDown(e) { private handleKeyDown(e: KeyboardEvent) {
/*** /***
* Кey codes * Кey codes
* 37 left * 37 left
@@ -128,12 +126,12 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
* 39 right * 39 right
* 40 down * 40 down
*/ */
let ranges, last;
let active = this.grid.getActiveCell(); let active = this.grid.getActiveCell();
let metaKey = e.ctrlKey || e.metaKey; let metaKey = e.ctrlKey || e.metaKey;
if (active && e.shiftKey && !metaKey && !e.altKey && if (active && e.shiftKey && !metaKey && !e.altKey &&
(e.which === 37 || e.which === 39 || e.which === 38 || e.which === 40)) { (e.which === 37 || e.which === 39 || e.which === 38 || e.which === 40)) {
let ranges = this.getSelectedRanges(), last: Slick.Range;
ranges = this.getSelectedRanges(); ranges = this.getSelectedRanges();
if (!ranges.length) { if (!ranges.length) {
@@ -141,7 +139,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
} }
// keyboard can work with last range only // keyboard can work with last range only
last = ranges.pop(); last = ranges.pop()!; // this is guarenteed since if ranges is empty we add one
// can't handle selection out of active cell // can't handle selection out of active cell
if (!last.contains(active.row, active.cell)) { if (!last.contains(active.row, active.cell)) {

View File

@@ -8,6 +8,7 @@ import * as strings from 'vs/base/common/strings';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes'; import { KeyCode } from 'vs/base/common/keyCodes';
import { range } from 'vs/base/common/arrays'; import { range } from 'vs/base/common/arrays';
import * as dict from 'vs/base/common/collections';
export interface ICheckboxSelectColumnOptions extends Slick.PluginOptions, ICheckboxStyles { export interface ICheckboxSelectColumnOptions extends Slick.PluginOptions, ICheckboxStyles {
columnId?: string; columnId?: string;
@@ -44,11 +45,11 @@ const checkboxTemplate = `<div style="display: flex; align-items: center; flex-d
<input type="checkbox" {0}> <input type="checkbox" {0}>
</div>`; </div>`;
export class CheckboxSelectColumn<T> implements Slick.Plugin<T> { export class CheckboxSelectColumn<T extends Slick.SlickData> implements Slick.Plugin<T> {
private _options: ICheckboxSelectColumnOptions; private _options: ICheckboxSelectColumnOptions;
private _grid: Slick.Grid<T>; private _grid: Slick.Grid<T>;
private _handler = new Slick.EventHandler(); private _handler = new Slick.EventHandler();
private _selectedRowsLookup = {}; private _selectedRowsLookup: dict.INumberDictionary<boolean> = {};
private _selectedCheckBoxLookup = {}; private _selectedCheckBoxLookup = {};
private _useState = false; private _useState = false;
@@ -64,10 +65,10 @@ export class CheckboxSelectColumn<T> implements Slick.Plugin<T> {
public init(grid: Slick.Grid<T>): void { public init(grid: Slick.Grid<T>): void {
this._grid = grid; this._grid = grid;
this._handler this._handler
.subscribe(this._grid.onSelectedRowsChanged, (e, args) => this.handleSelectedRowsChanged(e, args)) .subscribe(this._grid.onSelectedRowsChanged, (e: Event, args: Slick.OnSelectedRowsChangedEventArgs<T>) => this.handleSelectedRowsChanged(e, args))
.subscribe(this._grid.onClick, (e, args) => this.handleClick(e, args)) .subscribe(this._grid.onClick, (e: MouseEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(e, args))
.subscribe(this._grid.onHeaderClick, (e, args) => this.handleHeaderClick(e, args)) .subscribe(this._grid.onHeaderClick, (e: MouseEvent, args: Slick.OnHeaderClickEventArgs<T>) => this.handleHeaderClick(e, args))
.subscribe(this._grid.onKeyDown, (e, args) => this.handleKeyDown(e, args)); .subscribe(this._grid.onKeyDown, (e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>) => this.handleKeyDown(e, args));
} }
public destroy(): void { public destroy(): void {
@@ -82,7 +83,7 @@ export class CheckboxSelectColumn<T> implements Slick.Plugin<T> {
} }
const selectedRows = this._grid.getSelectedRows(); const selectedRows = this._grid.getSelectedRows();
let lookup = {}, row, i; let lookup: dict.INumberDictionary<boolean> = {}, row: number, i: number;
for (i = 0; i < selectedRows.length; i++) { for (i = 0; i < selectedRows.length; i++) {
row = selectedRows[i]; row = selectedRows[i];
lookup[row] = true; lookup[row] = true;
@@ -91,9 +92,7 @@ export class CheckboxSelectColumn<T> implements Slick.Plugin<T> {
delete this._selectedRowsLookup[row]; delete this._selectedRowsLookup[row];
} }
} }
for (i in this._selectedRowsLookup) { dict.forEach(this._selectedRowsLookup, (e) => this._grid.invalidateRow(e.key));
this._grid.invalidateRow(i);
}
this._selectedRowsLookup = lookup; this._selectedRowsLookup = lookup;
this._grid.render(); this._grid.render();
@@ -231,11 +230,11 @@ export class CheckboxSelectColumn<T> implements Slick.Plugin<T> {
sortable: false, sortable: false,
cssClass: this._options.cssClass, cssClass: this._options.cssClass,
headerCssClass: this._options.headerCssClass, headerCssClass: this._options.headerCssClass,
formatter: (r, c, v, cd, dc) => this.checkboxSelectionFormatter(r, c, v, cd, dc) formatter: (r, c, v, cd, dc) => this.checkboxSelectionFormatter(r, c, v, cd, dc as T)
}; };
} }
private checkboxSelectionFormatter(row, cell, value, columnDef: Slick.Column<T>, dataContext): string { private checkboxSelectionFormatter(row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string {
if (this.isCustomActionRequested()) { if (this.isCustomActionRequested()) {
return this.checkboxTemplateCustom(row); return this.checkboxTemplateCustom(row);
} }

View File

@@ -20,7 +20,7 @@ export class CopyKeybind<T> implements Slick.Plugin<T> {
public init(grid: Slick.Grid<T>) { public init(grid: Slick.Grid<T>) {
this.grid = grid; this.grid = grid;
this.handler.subscribe(this.grid.onKeyDown, (e, args) => this.handleKeyDown(e, args)); this.handler.subscribe(this.grid.onKeyDown, (e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>) => this.handleKeyDown(e, args));
} }
public destroy() { public destroy() {

View File

@@ -1,46 +1,39 @@
// Adopted and converted to typescript from https://github.com/danny-sg/slickgrid-spreadsheet-plugins/blob/master/ext.headerfilter.js // Adopted and converted to typescript from https://github.com/danny-sg/slickgrid-spreadsheet-plugins/blob/master/ext.headerfilter.js
// heavily modified // heavily modified
import { mixin } from 'vs/base/common/objects';
import { IButtonStyles } from 'vs/base/browser/ui/button/button'; import { IButtonStyles } from 'vs/base/browser/ui/button/button';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { Button } from 'sql/base/browser/ui/button/button'; import { Button } from 'sql/base/browser/ui/button/button';
import { escape } from 'sql/base/common/strings'; import { escape } from 'sql/base/common/strings';
export class HeaderFilter { interface IExtendedColumn<T> extends Slick.Column<T> {
filterValues?: Array<string>;
}
export class HeaderFilter<T extends Slick.SlickData> {
public onFilterApplied = new Slick.Event(); public onFilterApplied = new Slick.Event();
public onCommand = new Slick.Event(); public onCommand = new Slick.Event();
private grid: Slick.Grid<any>; private grid: Slick.Grid<T>;
private handler = new Slick.EventHandler(); private handler = new Slick.EventHandler();
private defaults = {
filterImage: 'src/sql/media/icons/filter.svg',
sortAscImage: 'sort-asc.gif',
sortDescImage: 'sort-desc.gif'
};
private $menu?: JQuery<HTMLElement>; private $menu?: JQuery<HTMLElement>;
private options: any;
private okButton: Button; private okButton: Button;
private clearButton: Button; private clearButton: Button;
private cancelButton: Button; private cancelButton: Button;
private workingFilters: any; private workingFilters: Array<string>;
private columnDef: any; private columnDef: IExtendedColumn<T>;
private buttonStyles: IButtonStyles; private buttonStyles: IButtonStyles;
constructor(options: any) { public init(grid: Slick.Grid<T>): void {
this.options = mixin(options, this.defaults, false);
}
public init(grid: Slick.Grid<any>): void {
this.grid = grid; this.grid = grid;
this.handler.subscribe(this.grid.onHeaderCellRendered, (e, args) => this.handleHeaderCellRendered(e, args)) this.handler.subscribe(this.grid.onHeaderCellRendered, (e: Event, args: Slick.OnHeaderCellRenderedEventArgs<T>) => this.handleHeaderCellRendered(e, args))
.subscribe(this.grid.onBeforeHeaderCellDestroy, (e, args) => this.handleBeforeHeaderCellDestroy(e, args)) .subscribe(this.grid.onBeforeHeaderCellDestroy, (e: Event, args: Slick.OnBeforeHeaderCellDestroyEventArgs<T>) => this.handleBeforeHeaderCellDestroy(e, args))
.subscribe(this.grid.onClick, (e) => this.handleBodyMouseDown) .subscribe(this.grid.onClick, (e: MouseEvent) => this.handleBodyMouseDown(e))
.subscribe(this.grid.onColumnsResized, () => this.columnsResized()) .subscribe(this.grid.onColumnsResized, () => this.columnsResized())
.subscribe(this.grid.onKeyDown, (e) => this.handleKeyDown); .subscribe(this.grid.onKeyDown, (e: KeyboardEvent) => this.handleKeyDown(e));
this.grid.setColumns(this.grid.getColumns()); this.grid.setColumns(this.grid.getColumns());
jQuery(document.body).bind('mousedown', this.handleBodyMouseDown); jQuery(document.body).bind('mousedown', this.handleBodyMouseDown);
@@ -53,7 +46,7 @@ export class HeaderFilter {
jQuery(document.body).unbind('keydown', this.handleKeyDown); jQuery(document.body).unbind('keydown', this.handleKeyDown);
} }
private handleKeyDown = (e) => { private handleKeyDown(e: KeyboardEvent | JQuery.Event<HTMLElement, null>): void {
if (this.$menu && (e.key === 'Escape' || e.keyCode === 27)) { if (this.$menu && (e.key === 'Escape' || e.keyCode === 27)) {
this.hideMenu(); this.hideMenu();
e.preventDefault(); e.preventDefault();
@@ -61,8 +54,8 @@ export class HeaderFilter {
} }
} }
private handleBodyMouseDown = (e) => { private handleBodyMouseDown(e: MouseEvent | JQuery.Event<HTMLElement, null>): void {
if (this.$menu && this.$menu[0] !== e.target && !jQuery.contains(this.$menu[0], e.target)) { if (this.$menu && this.$menu[0] !== e.target && !jQuery.contains(this.$menu[0], e.target as Element)) {
this.hideMenu(); this.hideMenu();
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@@ -76,7 +69,7 @@ export class HeaderFilter {
} }
} }
private handleHeaderCellRendered(e, args) { private handleHeaderCellRendered(e: Event, args: Slick.OnHeaderCellRenderedEventArgs<T>) {
const column = args.column; const column = args.column;
if (column.id === '_detail_selector') { if (column.id === '_detail_selector') {
return; return;
@@ -88,13 +81,13 @@ export class HeaderFilter {
$el.bind('click', (e) => this.showFilter(e)).appendTo(args.node); $el.bind('click', (e) => this.showFilter(e)).appendTo(args.node);
} }
private handleBeforeHeaderCellDestroy(e, args) { private handleBeforeHeaderCellDestroy(e: Event, args: Slick.OnBeforeHeaderCellDestroyEventArgs<T>) {
jQuery(args.node) jQuery(args.node)
.find('.slick-header-menubutton') .find('.slick-header-menubutton')
.remove(); .remove();
} }
private addMenuItem(menu, columnDef, title, command, image) { private addMenuItem(menu: JQuery<HTMLElement>, columnDef: Slick.Column<T>, title: string, command: string) {
const $item = jQuery('<div class="slick-header-menuitem">') const $item = jQuery('<div class="slick-header-menuitem">')
.data('command', command) .data('command', command)
.data('column', columnDef) .data('column', columnDef)
@@ -115,7 +108,7 @@ export class HeaderFilter {
.appendTo($item); .appendTo($item);
} }
private addMenuInput(menu, columnDef) { private addMenuInput(menu: JQuery<HTMLElement>, columnDef: Slick.Column<T>) {
const self = this; const self = this;
jQuery('<input class="input" placeholder="Search" style="margin-top: 5px; width: 206px">') jQuery('<input class="input" placeholder="Search" style="margin-top: 5px; width: 206px">')
.data('column', columnDef) .data('column', columnDef)
@@ -126,7 +119,7 @@ export class HeaderFilter {
.appendTo(menu); .appendTo(menu);
} }
private updateFilterInputs(menu, columnDef, filterItems) { private updateFilterInputs(menu: JQuery<HTMLElement>, columnDef: IExtendedColumn<T>, filterItems: Array<string>) {
let filterOptions = '<label><input type="checkbox" value="-1" />(Select All)</label>'; let filterOptions = '<label><input type="checkbox" value="-1" />(Select All)</label>';
columnDef.filterValues = columnDef.filterValues || []; columnDef.filterValues = columnDef.filterValues || [];
@@ -148,7 +141,7 @@ export class HeaderFilter {
}); });
} }
private showFilter(e) { private showFilter(e: JQuery.Event<HTMLElement, null>) {
const $menuButton = jQuery(e.target); const $menuButton = jQuery(e.target);
this.columnDef = $menuButton.data('column'); this.columnDef = $menuButton.data('column');
@@ -157,15 +150,15 @@ export class HeaderFilter {
// WorkingFilters is a copy of the filters to enable apply/cancel behaviour // WorkingFilters is a copy of the filters to enable apply/cancel behaviour
this.workingFilters = this.columnDef.filterValues.slice(0); this.workingFilters = this.columnDef.filterValues.slice(0);
let filterItems; let filterItems: Array<string>;
if (this.workingFilters.length === 0) { if (this.workingFilters.length === 0) {
// Filter based all available values // Filter based all available values
filterItems = this.getFilterValues(this.grid.getData(), this.columnDef); filterItems = this.getFilterValues(this.grid.getData() as Slick.DataProvider<T>, this.columnDef);
} }
else { else {
// Filter based on current dataView subset // Filter based on current dataView subset
filterItems = this.getAllFilterValues(this.grid.getData().getItems(), this.columnDef); filterItems = this.getAllFilterValues((this.grid.getData() as Slick.DataProvider<T>).getItems(), this.columnDef);
} }
if (!this.$menu) { if (!this.$menu) {
@@ -174,8 +167,8 @@ export class HeaderFilter {
this.$menu.empty(); this.$menu.empty();
this.addMenuItem(this.$menu, this.columnDef, 'Sort Ascending', 'sort-asc', this.options.sortAscImage); this.addMenuItem(this.$menu, this.columnDef, 'Sort Ascending', 'sort-asc');
this.addMenuItem(this.$menu, this.columnDef, 'Sort Descending', 'sort-desc', this.options.sortDescImage); this.addMenuItem(this.$menu, this.columnDef, 'Sort Descending', 'sort-desc');
this.addMenuInput(this.$menu, this.columnDef); this.addMenuInput(this.$menu, this.columnDef);
let filterOptions = '<label><input type="checkbox" value="-1" />(Select All)</label>'; let filterOptions = '<label><input type="checkbox" value="-1" />(Select All)</label>';
@@ -209,7 +202,7 @@ export class HeaderFilter {
this.clearButton.element.id = 'filter-clear-button'; this.clearButton.element.id = 'filter-clear-button';
const clearElement = jQuery('#filter-clear-button'); const clearElement = jQuery('#filter-clear-button');
clearElement.bind('click', (ev) => { clearElement.bind('click', (ev) => {
this.columnDef.filterValues.length = 0; this.columnDef.filterValues!.length = 0;
this.setButtonImage($menuButton, false); this.setButtonImage($menuButton, false);
this.handleApply(ev, this.columnDef); this.handleApply(ev, this.columnDef);
}); });
@@ -265,11 +258,11 @@ export class HeaderFilter {
this.hideMenu(); this.hideMenu();
} }
private changeWorkingFilter(filterItems, workingFilters, $checkbox) { private changeWorkingFilter(filterItems: Array<string>, workingFilters: Array<string>, $checkbox: JQuery<HTMLElement>) {
const value = $checkbox.val(); const value = $checkbox.val() as number;
const $filter = $checkbox.parent().parent(); const $filter = $checkbox.parent().parent();
if ($checkbox.val() < 0) { if ($checkbox.val() as number < 0) {
// Select All // Select All
if ($checkbox.prop('checked')) { if ($checkbox.prop('checked')) {
jQuery(':checkbox', $filter).prop('checked', true); jQuery(':checkbox', $filter).prop('checked', true);
@@ -283,7 +276,7 @@ export class HeaderFilter {
if ($checkbox.prop('checked') && index < 0) { if ($checkbox.prop('checked') && index < 0) {
workingFilters.push(filterItems[value]); workingFilters.push(filterItems[value]);
const nextRow = filterItems[(parseInt(value) + 1).toString()]; const nextRow = filterItems[(parseInt(<string><any>value) + 1).toString()]; // for some reason parseInt is defined as only supporting strings even though it works fine for numbers
if (nextRow && nextRow.indexOf('Error:') >= 0) { if (nextRow && nextRow.indexOf('Error:') >= 0) {
workingFilters.push(nextRow); workingFilters.push(nextRow);
} }
@@ -298,7 +291,7 @@ export class HeaderFilter {
return workingFilters; return workingFilters;
} }
private setButtonImage($el, filtered) { private setButtonImage($el: JQuery<HTMLElement>, filtered: boolean) {
const element: HTMLElement = $el.get(0); const element: HTMLElement = $el.get(0);
if (filtered) { if (filtered) {
element.className += ' filtered'; element.className += ' filtered';
@@ -310,7 +303,7 @@ export class HeaderFilter {
} }
} }
private handleApply(e, columnDef) { private handleApply(e: JQuery.Event<HTMLElement, null>, columnDef: Slick.Column<T>) {
this.hideMenu(); this.hideMenu();
this.onFilterApplied.notify({ 'grid': this.grid, 'column': columnDef }, e, self); this.onFilterApplied.notify({ 'grid': this.grid, 'column': columnDef }, e, self);
@@ -318,10 +311,10 @@ export class HeaderFilter {
e.stopPropagation(); e.stopPropagation();
} }
private getFilterValues(dataView, column) { private getFilterValues(dataView: Slick.DataProvider<T>, column: Slick.Column<T>): Array<any> {
const seen: Array<any> = []; const seen: Array<string> = [];
for (let i = 0; i < dataView.getLength(); i++) { for (let i = 0; i < dataView.getLength(); i++) {
const value = dataView.getItem(i)[column.field]; const value = dataView.getItem(i)[column.field!];
if (!_.contains(seen, value)) { if (!_.contains(seen, value)) {
seen.push(value); seen.push(value);
@@ -330,10 +323,10 @@ export class HeaderFilter {
return seen; return seen;
} }
private getFilterValuesByInput($input) { private getFilterValuesByInput($input: JQuery<HTMLElement>): Array<string> {
const column = $input.data('column'), const column = $input.data('column'),
filter = $input.val(), filter = $input.val() as string,
dataView = this.grid.getData(), dataView = this.grid.getData() as Slick.DataProvider<T>,
seen: Array<any> = []; seen: Array<any> = [];
for (let i = 0; i < dataView.getLength(); i++) { for (let i = 0; i < dataView.getLength(); i++) {
@@ -357,10 +350,10 @@ export class HeaderFilter {
return _.sortBy(seen, (v) => { return v; }); return _.sortBy(seen, (v) => { return v; });
} }
private getAllFilterValues(data, column) { private getAllFilterValues(data: Array<Slick.SlickData>, column: Slick.Column<T>) {
const seen: Array<any> = []; const seen: Array<any> = [];
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const value = data[i][column.field]; const value = data[i][column.field!];
if (!_.contains(seen, value)) { if (!_.contains(seen, value)) {
seen.push(value); seen.push(value);
@@ -370,7 +363,7 @@ export class HeaderFilter {
return _.sortBy(seen, (v) => { return v; }); return _.sortBy(seen, (v) => { return v; });
} }
private handleMenuItemClick(e, command, columnDef) { private handleMenuItemClick(e: JQuery.Event<HTMLElement, null>, command: string, columnDef: Slick.Column<T>) {
this.hideMenu(); this.hideMenu();
this.onCommand.notify({ this.onCommand.notify({

View File

@@ -4,44 +4,79 @@ import { escape } from 'sql/base/common/strings';
import { mixin } from 'vs/base/common/objects'; import { mixin } from 'vs/base/common/objects';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
export class RowDetailView { export interface IRowDetailViewOptions<T> {
columnId?: string;
cssClass?: string;
toolTip?: string;
width?: number;
panelRows: number;
useRowClick?: boolean;
loadOnce?: boolean;
preTemplate: (item: ExtendedItem<T>) => string;
process: (item: ExtendedItem<T>) => void;
postTemplate: (item: ExtendedItem<T>) => string;
}
public onAsyncResponse = new Slick.Event<any>(); const defaultOptions = {
public onAsyncEndUpdate = new Slick.Event<any>(); columnId: '_detail_selector',
public onAfterRowDetailToggle = new Slick.Event<any>(); toolTip: '',
public onBeforeRowDetailToggle = new Slick.Event<any>(); width: 30
};
private _grid: any; export interface IExtendedItem<T extends Slick.SlickData> {
private _expandedRows: any = []; _collapsed?: boolean;
_parent?: IExtendedItem<T> & T;
_detailContent?: string;
_detailViewLoaded?: boolean;
_sizePadding?: number;
id?: string;
_height?: number;
_isPadding?: boolean;
name?: string;
_child?: IExtendedItem<T>;
message?: string;
}
export type ExtendedItem<T extends Slick.SlickData> = T & IExtendedItem<T>;
interface AugmentedDataView<T extends Slick.SlickData> extends Slick.Data.DataView<T> {
getItem(row: number): ExtendedItem<T>;
getItemByIdx(row: number): ExtendedItem<T>;
}
export class RowDetailView<T extends Slick.SlickData> {
public readonly onAsyncResponse = new Slick.Event<{ itemDetail: ExtendedItem<T>, detailView: string }>();
public readonly onAsyncEndUpdate = new Slick.Event<{ grid: Slick.Grid<T>, itemDetail: T }>();
public readonly onAfterRowDetailToggle = new Slick.Event<{ grid: Slick.Grid<T>, item: T }>();
public readonly onBeforeRowDetailToggle = new Slick.Event<{ grid: Slick.Grid<T>, item: T }>();
private _grid: Slick.Grid<T>;
private _expandedRows: Array<ExtendedItem<T>> = [];
private _handler = new Slick.EventHandler(); private _handler = new Slick.EventHandler();
private _defaults: any = {
columnId: '_detail_selector',
cssClass: null,
toolTip: '',
width: 30
};
private _dataView: any; private _dataView: AugmentedDataView<T>;
private _options: any; private _options: IRowDetailViewOptions<T>;
constructor(options) { constructor(options: IRowDetailViewOptions<T>) {
this._options = mixin(options, this._defaults, false); this._options = options || Object.create(null);
mixin(this._options, defaultOptions, false);
} }
public init(grid: any): void { public init(grid: Slick.Grid<T>): void {
this._grid = grid; this._grid = grid;
this._dataView = this._grid.getData(); this._dataView = this._grid.getData() as AugmentedDataView<T>; // this is a bad assumption but the code is written with this assumption
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3 // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
this._grid.getOptions().minRowBuffer = this._options.panelRows + 3; this._grid.getOptions().minRowBuffer = this._options.panelRows + 3;
this._handler this._handler
.subscribe(this._grid.onClick, (e, args) => this.handleClick(e, args)) .subscribe(this._grid.onClick, (e: MouseEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(e, args))
.subscribe(this._grid.onSort, (e, args) => this.handleSort(e, args)) .subscribe(this._grid.onSort, () => this.handleSort())
.subscribe(this._grid.onScroll, (e, args) => this.handleScroll(e, args)); .subscribe(this._grid.onScroll, () => this.handleScroll());
this._grid.getData().onRowCountChanged.subscribe(() => { this._grid.updateRowCount(); this._grid.render(); }); this._dataView.onRowCountChanged.subscribe(() => { this._grid.updateRowCount(); this._grid.render(); });
this._grid.getData().onRowsChanged.subscribe((e, a) => { this._grid.invalidateRows(a.rows); this._grid.render(); }); this._dataView.onRowsChanged.subscribe((e, a) => { this._grid.invalidateRows(a.rows); this._grid.render(); });
// subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished // subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished
this.subscribeToOnAsyncResponse(); this.subscribeToOnAsyncResponse();
@@ -55,17 +90,17 @@ export class RowDetailView {
this.onBeforeRowDetailToggle.unsubscribe(); this.onBeforeRowDetailToggle.unsubscribe();
} }
public getOptions(options: any) { public getOptions() {
return this._options; return this._options;
} }
public setOptions(options: any) { public setOptions(options: IRowDetailViewOptions<T>) {
this._options = jQuery.extend(true, {}, this._options, options); this._options = jQuery.extend(true, {}, this._options, options);
} }
public handleClick(e: any, args: any): void { public handleClick(e: MouseEvent, args: Slick.OnClickEventArgs<T>): void {
// clicking on a row select checkbox // clicking on a row select checkbox
if (this._options.useRowClick || this._grid.getColumns()[args.cell].id === this._options.columnId && jQuery(e.target).hasClass('detailView-toggle')) { if (this._options.useRowClick || this._grid.getColumns()[args.cell].id === this._options.columnId && jQuery(e.target!).hasClass('detailView-toggle')) {
// if editing, try to commit // if editing, try to commit
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) { if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
e.preventDefault(); e.preventDefault();
@@ -95,12 +130,12 @@ export class RowDetailView {
} }
// Sort will just collapse all of the open items // Sort will just collapse all of the open items
public handleSort(e, args) { public handleSort() {
this.collapseAll(); this.collapseAll();
} }
// If we scroll save detail views that go out of cache range // If we scroll save detail views that go out of cache range
public handleScroll(e, args) { public handleScroll() {
const range = this._grid.getRenderedRange(); const range = this._grid.getRenderedRange();
@@ -136,10 +171,10 @@ export class RowDetailView {
} }
// Toggle between showing and hiding a row // Toggle between showing and hiding a row
public toggleRowSelection(row) { public toggleRowSelection(row: T) {
this._grid.getData().beginUpdate(); this._dataView.beginUpdate();
this.handleAccordionShowHide(row); this.handleAccordionShowHide(row);
this._grid.getData().endUpdate(); this._dataView.endUpdate();
} }
// Collapse all of the open items // Collapse all of the open items
@@ -150,7 +185,7 @@ export class RowDetailView {
} }
// Saves the current state of the detail view // Saves the current state of the detail view
public saveDetailView(item) { public saveDetailView(item: ExtendedItem<T>) {
const view = jQuery('#innerDetailView_' + item.id); const view = jQuery('#innerDetailView_' + item.id);
if (view) { if (view) {
const html = jQuery('#innerDetailView_' + item.id).html(); const html = jQuery('#innerDetailView_' + item.id).html();
@@ -161,7 +196,7 @@ export class RowDetailView {
} }
// Colapse an Item so it is notlonger seen // Colapse an Item so it is notlonger seen
public collapseItem(item) { public collapseItem(item: ExtendedItem<T>) {
// Save the details on the collapse assuming onetime loading // Save the details on the collapse assuming onetime loading
if (this._options.loadOnce) { if (this._options.loadOnce) {
@@ -169,11 +204,11 @@ export class RowDetailView {
} }
item._collapsed = true; item._collapsed = true;
for (let idx = 1; idx <= item._sizePadding; idx++) { for (let idx = 1; idx <= item._sizePadding!; idx++) {
this._dataView.deleteItem(item.id + '.' + idx); this._dataView.deleteItem(item.id + '.' + idx);
} }
item._sizePadding = 0; item._sizePadding = 0;
this._dataView.updateItem(item.id, item); this._dataView.updateItem(item.id!, item);
// Remove the item from the expandedRows // Remove the item from the expandedRows
this._expandedRows = this._expandedRows.filter((r) => { this._expandedRows = this._expandedRows.filter((r) => {
@@ -182,7 +217,7 @@ export class RowDetailView {
} }
// Expand a row given the dataview item that is to be expanded // Expand a row given the dataview item that is to be expanded
public expandItem(item) { public expandItem(item: ExtendedItem<T>) {
item._collapsed = false; item._collapsed = false;
this._expandedRows.push(item); this._expandedRows.push(item);
@@ -197,16 +232,16 @@ export class RowDetailView {
} else { } else {
this.onAsyncResponse.notify({ this.onAsyncResponse.notify({
itemDetail: item, itemDetail: item,
detailView: item._detailContent detailView: item._detailContent!
}, undefined, this); }, undefined, this);
this.applyTemplateNewLineHeight(item); this.applyTemplateNewLineHeight(item);
this._dataView.updateItem(item.id, item); this._dataView.updateItem(item.id!, item);
return; return;
} }
this.applyTemplateNewLineHeight(item); this.applyTemplateNewLineHeight(item);
this._dataView.updateItem(item.id, item); this._dataView.updateItem(item.id!, item);
// async server call // async server call
this._options.process(item); this._options.process(item);
@@ -231,7 +266,7 @@ export class RowDetailView {
args.itemDetail._detailViewLoaded = true; args.itemDetail._detailViewLoaded = true;
this._dataView.updateItem(args.itemDetail.id, args.itemDetail); this._dataView.updateItem(args.itemDetail.id!, args.itemDetail);
// trigger an event once the post template is finished loading // trigger an event once the post template is finished loading
this.onAsyncEndUpdate.notify({ this.onAsyncEndUpdate.notify({
@@ -241,7 +276,7 @@ export class RowDetailView {
}); });
} }
public handleAccordionShowHide(item) { public handleAccordionShowHide(item?: ExtendedItem<T>) {
if (item) { if (item) {
if (!item._collapsed) { if (!item._collapsed) {
this.collapseItem(item); this.collapseItem(item);
@@ -253,7 +288,7 @@ export class RowDetailView {
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
public getPaddingItem(parent, offset) { public getPaddingItem(parent: ExtendedItem<T>, offset: number | string) {
const item: any = {}; const item: any = {};
for (const prop in this._grid.getData()) { for (const prop in this._grid.getData()) {
@@ -265,18 +300,16 @@ export class RowDetailView {
item._collapsed = true; item._collapsed = true;
item._isPadding = true; item._isPadding = true;
item._parent = parent; item._parent = parent;
item._offset = offset;
return item; return item;
} }
public getErrorItem(parent, offset) { public getErrorItem(parent: ExtendedItem<T>, offset: number | string) {
const item: any = {}; const item: ExtendedItem<T> = Object.create(null);
item.id = parent.id + '.' + offset; item.id = parent.id + '.' + offset;
item._collapsed = true; item._collapsed = true;
item._isPadding = false; item._isPadding = false;
item._parent = parent; item._parent = parent;
item._offset = offset;
item.name = parent.message ? parent.message : nls.localize('rowDetailView.loadError', 'Loading Error...'); item.name = parent.message ? parent.message : nls.localize('rowDetailView.loadError', 'Loading Error...');
parent._child = item; parent._child = item;
return item; return item;
@@ -285,17 +318,17 @@ export class RowDetailView {
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
//create the detail ctr node. this belongs to the dev & can be custom-styled as per //create the detail ctr node. this belongs to the dev & can be custom-styled as per
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
public applyTemplateNewLineHeight(item, showError = false) { public applyTemplateNewLineHeight(item: ExtendedItem<T>, showError = false) {
// the height seems to be calculated by the template row count (how many line of items does the template have) // the height seems to be calculated by the template row count (how many line of items does the template have)
const rowCount = this._options.panelRows; const rowCount = this._options.panelRows;
//calculate padding requirements based on detail-content.. //calculate padding requirements based on detail-content..
//ie. worst-case: create an invisible dom node now &find it's height. //ie. worst-case: create an invisible dom node now &find it's height.
const lineHeight = 13; //we know cuz we wrote the custom css innit ;) const lineHeight = 13; //we know cuz we wrote the custom css innit ;)
item._sizePadding = Math.ceil(((rowCount * 2) * lineHeight) / this._grid.getOptions().rowHeight); item._sizePadding = Math.ceil(((rowCount * 2) * lineHeight) / this._grid.getOptions().rowHeight!);
item._height = (item._sizePadding * this._grid.getOptions().rowHeight); item._height = (item._sizePadding * this._grid.getOptions().rowHeight!);
const idxParent = this._dataView.getIdxById(item.id); const idxParent = this._dataView.getIdxById(item.id!);
for (let idx = 1; idx <= item._sizePadding; idx++) { for (let idx = 1; idx <= item._sizePadding; idx++) {
if (showError) { if (showError) {
this._dataView.insertItem(idxParent + idx, this.getErrorItem(item, 'error')); this._dataView.insertItem(idxParent + idx, this.getErrorItem(item, 'error'));
@@ -305,7 +338,7 @@ export class RowDetailView {
} }
} }
public getColumnDefinition() { public getColumnDefinition(): Slick.Column<T> {
return { return {
id: this._options.columnId, id: this._options.columnId,
name: '', name: '',
@@ -315,11 +348,11 @@ export class RowDetailView {
resizable: false, resizable: false,
sortable: false, sortable: false,
cssClass: this._options.cssClass, cssClass: this._options.cssClass,
formatter: (row, cell, value, columnDef, dataContext) => this.detailSelectionFormatter(row, cell, value, columnDef, dataContext) formatter: (row, cell, value, columnDef, dataContext) => this.detailSelectionFormatter(row, cell, value, columnDef, dataContext as ExtendedItem<T>)
}; };
} }
public detailSelectionFormatter(row, cell, value, columnDef, dataContext) { public detailSelectionFormatter(row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: ExtendedItem<T>): string | undefined {
if (dataContext._collapsed === undefined) { if (dataContext._collapsed === undefined) {
dataContext._collapsed = true; dataContext._collapsed = true;
@@ -327,7 +360,6 @@ export class RowDetailView {
dataContext._height = 0; //the actual height in pixels of the detail field dataContext._height = 0; //the actual height in pixels of the detail field
dataContext._isPadding = false; dataContext._isPadding = false;
dataContext._parent = undefined; dataContext._parent = undefined;
dataContext._offset = 0;
} }
if (dataContext._isPadding === true) { if (dataContext._isPadding === true) {
@@ -336,7 +368,7 @@ export class RowDetailView {
return '<div class=\'detailView-toggle expand\'></div>'; return '<div class=\'detailView-toggle expand\'></div>';
} else { } else {
const html: Array<string> = []; const html: Array<string> = [];
const rowHeight = this._grid.getOptions().rowHeight; const rowHeight = this._grid.getOptions().rowHeight!;
const bottomMargin = 5; const bottomMargin = 5;
//V313HAX: //V313HAX:
@@ -353,59 +385,12 @@ export class RowDetailView {
html.push(`<div id='cellDetailView_${dataContext.id}' class='dynamic-cell-detail' `); //apply custom css to detail html.push(`<div id='cellDetailView_${dataContext.id}' class='dynamic-cell-detail' `); //apply custom css to detail
html.push(`style=\'height:${dataContext._height}px;`); //set total height of padding html.push(`style=\'height:${dataContext._height}px;`); //set total height of padding
html.push(`top:${rowHeight}px'>`); //shift detail below 1st row html.push(`top:${rowHeight}px'>`); //shift detail below 1st row
html.push(`<div id='detailViewContainer_${dataContext.id}"' class='detail-container' style='max-height:${(dataContext._height - rowHeight + bottomMargin)}px'>`); //sub ctr for custom styling html.push(`<div id='detailViewContainer_${dataContext.id}"' class='detail-container' style='max-height:${(dataContext._height! - rowHeight + bottomMargin)}px'>`); //sub ctr for custom styling
html.push(`<div id='innerDetailView_${dataContext.id}'>${escape(dataContext._detailContent)}</div></div>`); html.push(`<div id='innerDetailView_${dataContext.id}'>${escape(dataContext._detailContent!)}</div></div>`);
//&omit a final closing detail container </div> that would come next //&omit a final closing detail container </div> that would come next
return html.join(''); return html.join('');
} }
return null; return undefined;
}
public resizeDetailView(item) {
if (!item) {
return;
}
// Grad each of the dom items
const mainContainer = document.getElementById('detailViewContainer_' + item.id);
const cellItem = document.getElementById('cellDetailView_' + item.id);
const inner = document.getElementById('innerDetailView_' + item.id);
if (!mainContainer || !cellItem || !inner) {
return;
}
for (let idx = 1; idx <= item._sizePadding; idx++) {
this._dataView.deleteItem(item.id + '.' + idx);
}
const rowHeight = this._grid.getOptions().rowHeight; // height of a row
const lineHeight = 13; //we know cuz we wrote the custom css innit ;)
// Get the inner Item height as this will be the actual size
const itemHeight = inner.clientHeight;
// Now work out how many rows
const rowCount = Math.ceil(itemHeight / rowHeight) + 1;
item._sizePadding = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight);
item._height = (item._sizePadding * rowHeight);
// If the padding is now more than the original minRowBuff we need to increase it
if (this._grid.getOptions().minRowBuffer < item._sizePadding) {
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
this._grid.getOptions().minRowBuffer = item._sizePadding + 3;
}
mainContainer.setAttribute('style', `max-height: ${item._height}px`);
if (cellItem) {
cellItem.setAttribute('style', `height: ${item._height}px;top:${rowHeight}px`);
}
const idxParent = this._dataView.getIdxById(item.id);
for (let idx = 1; idx <= item._sizePadding; idx++) {
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
}
} }
} }

View File

@@ -18,8 +18,8 @@ export class RowNumberColumn<T> implements Slick.Plugin<T> {
public init(grid: Slick.Grid<T>) { public init(grid: Slick.Grid<T>) {
this.grid = grid; this.grid = grid;
this.handler this.handler
.subscribe(this.grid.onClick, (e, args) => this.handleClick(e, args)) .subscribe(this.grid.onClick, (e: MouseEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(e, args))
.subscribe(this.grid.onHeaderClick, (e, args) => this.handleHeaderClick(e, args)); .subscribe(this.grid.onHeaderClick, (e: MouseEvent, args: Slick.OnHeaderClickEventArgs<T>) => this.handleHeaderClick(e, args));
} }
public destroy() { public destroy() {
@@ -56,11 +56,11 @@ export class RowNumberColumn<T> implements Slick.Plugin<T> {
cssClass: this.options.cssClass, cssClass: this.options.cssClass,
focusable: false, focusable: false,
selectable: false, selectable: false,
formatter: (r, c, v, cd, dc) => this.formatter(r, c, v, cd, dc) formatter: r => this.formatter(r)
}; };
} }
private formatter(row, cell, value, columnDef: Slick.Column<T>, dataContext): string { private formatter(row: number): string {
// row is zero-based, we need make it 1 based for display in the result grid // row is zero-based, we need make it 1 based for display in the result grid
return `<span>${row + 1}</span>`; return `<span>${row + 1}</span>`;
} }

View File

@@ -25,9 +25,9 @@ export class RowSelectionModel<T extends Slick.SlickData> implements Slick.Selec
public init(grid: Slick.Grid<T>) { public init(grid: Slick.Grid<T>) {
this._grid = grid; this._grid = grid;
this._handler this._handler
.subscribe(this._grid.onActiveCellChanged, (e, data) => this.handleActiveCellChange(e, data)) .subscribe(this._grid.onActiveCellChanged, (e: Event, data: Slick.OnActiveCellChangedEventArgs<T>) => this.handleActiveCellChange(e, data))
.subscribe(this._grid.onKeyDown, e => this.handleKeyDown(e)) .subscribe(this._grid.onKeyDown, (e: KeyboardEvent) => this.handleKeyDown(e))
.subscribe(this._grid.onClick, e => this.handleClick(e)); .subscribe(this._grid.onClick, (e: MouseEvent) => this.handleClick(e));
} }
private rangesToRows(ranges: Slick.Range[]): number[] { private rangesToRows(ranges: Slick.Range[]): number[] {
@@ -116,7 +116,7 @@ export class RowSelectionModel<T extends Slick.SlickData> implements Slick.Selec
} }
} }
private handleClick(e: KeyboardEvent): boolean { private handleClick(e: MouseEvent): boolean {
const cell = this._grid.getCellFromEvent(e); const cell = this._grid.getCellFromEvent(e);
if (!cell || !this._grid.canCellBeActive(cell.row, cell.cell)) { if (!cell || !this._grid.canCellBeActive(cell.row, cell.cell)) {
return false; return false;

View File

@@ -117,6 +117,10 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
return this._data[index]; return this._data[index];
} }
getItems(): T[] {
return this._data.slice();
}
getLengthNonFiltered(): number { getLengthNonFiltered(): number {
return this.filterEnabled ? this._allData.length : this._data.length; return this.filterEnabled ? this._allData.length : this._data.length;
} }

View File

@@ -19,7 +19,7 @@ suite('TableDataView', () => {
let rowCountEventInvokeCount = 0; let rowCountEventInvokeCount = 0;
let filterStateChangeEventInvokeCount = 0; let filterStateChangeEventInvokeCount = 0;
let rowCountEventParameter; let rowCountEventParameter: number;
obj.onRowCountChange((count) => { obj.onRowCountChange((count) => {
rowCountEventInvokeCount++; rowCountEventInvokeCount++;
rowCountEventParameter = count; rowCountEventParameter = count;

View File

@@ -134,7 +134,10 @@ export class AlertsViewComponent extends JobManagementView implements OnInit, On
let rowDetail = new RowDetailView({ let rowDetail = new RowDetailView({
cssClass: '_detail_selector', cssClass: '_detail_selector',
useRowClick: false, useRowClick: false,
panelRows: 1 panelRows: 1,
postTemplate: () => '', // I'm assuming these code paths are just never hit...
preTemplate: () => '',
process: () => { }
}); });
columns.unshift(rowDetail.getColumnDefinition()); columns.unshift(rowDetail.getColumnDefinition());
jQuery(this._gridEl.nativeElement).empty(); jQuery(this._gridEl.nativeElement).empty();

View File

@@ -37,6 +37,11 @@ export const JOBSVIEW_SELECTOR: string = 'jobsview-component';
export const ROW_HEIGHT: number = 45; export const ROW_HEIGHT: number = 45;
export const ACTIONBAR_PADDING: number = 10; export const ACTIONBAR_PADDING: number = 10;
interface IItem extends Slick.SlickData {
jobId?: string;
id: string;
}
@Component({ @Component({
selector: JOBSVIEW_SELECTOR, selector: JOBSVIEW_SELECTOR,
templateUrl: decodeURI(require.toUrl('./jobsView.component.html')), templateUrl: decodeURI(require.toUrl('./jobsView.component.html')),
@@ -71,7 +76,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
]; ];
private _jobCacheObject: JobCacheObject; private _jobCacheObject: JobCacheObject;
private rowDetail: RowDetailView; private rowDetail: RowDetailView<IItem>;
private filterPlugin: any; private filterPlugin: any;
private dataView: any; private dataView: any;
private _isCloud: boolean; private _isCloud: boolean;
@@ -161,7 +166,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
this.dataView = new Slick.Data.DataView({ inlineFilters: false }); this.dataView = new Slick.Data.DataView({ inlineFilters: false });
let rowDetail = new RowDetailView({ let rowDetail = new RowDetailView<IItem>({
cssClass: '_detail_selector', cssClass: '_detail_selector',
process: (job) => { process: (job) => {
(<any>rowDetail).onAsyncResponse.notify({ (<any>rowDetail).onAsyncResponse.notify({
@@ -169,11 +174,13 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
}, undefined, this); }, undefined, this);
}, },
useRowClick: false, useRowClick: false,
panelRows: 1 panelRows: 1,
postTemplate: () => '', // I'm assuming these code paths are just never hit...
preTemplate: () => '',
}); });
this.rowDetail = rowDetail; this.rowDetail = rowDetail;
columns.unshift(this.rowDetail.getColumnDefinition()); columns.unshift(this.rowDetail.getColumnDefinition());
let filterPlugin = new HeaderFilter({}); let filterPlugin = new HeaderFilter<{ inlineFilters: false }>();
this._register(attachButtonStyler(filterPlugin, this._themeService)); this._register(attachButtonStyler(filterPlugin, this._themeService));
this.filterPlugin = filterPlugin; this.filterPlugin = filterPlugin;
jQuery(this._gridEl.nativeElement).empty(); jQuery(this._gridEl.nativeElement).empty();
@@ -337,7 +344,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
this.filterPlugin.onCommand.subscribe((e, args: any) => { this.filterPlugin.onCommand.subscribe((e, args: any) => {
this.columnSort(args.column.name, args.command === 'sort-asc'); this.columnSort(args.column.name, args.command === 'sort-asc');
}); });
this._table.registerPlugin(<HeaderFilter>this.filterPlugin); this._table.registerPlugin(this.filterPlugin);
this.dataView.beginUpdate(); this.dataView.beginUpdate();
this.dataView.setItems(jobViews); this.dataView.setItems(jobViews);
@@ -900,7 +907,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
} }
protected getCurrentTableObject(rowIndex: number): JobActionContext { protected getCurrentTableObject(rowIndex: number): JobActionContext {
let data = this._table.grid.getData(); let data = this._table.grid.getData() as Slick.DataProvider<IItem>;
if (!data || rowIndex >= data.getLength()) { if (!data || rowIndex >= data.getLength()) {
return undefined; return undefined;
} }

View File

@@ -134,7 +134,10 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit,
let rowDetail = new RowDetailView({ let rowDetail = new RowDetailView({
cssClass: '_detail_selector', cssClass: '_detail_selector',
useRowClick: false, useRowClick: false,
panelRows: 1 panelRows: 1,
postTemplate: () => '', // I'm assuming these code paths are just never hit...
preTemplate: () => '',
process: () => { }
}); });
columns.unshift(rowDetail.getColumnDefinition()); columns.unshift(rowDetail.getColumnDefinition());

View File

@@ -137,7 +137,10 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit, O
let rowDetail = new RowDetailView({ let rowDetail = new RowDetailView({
cssClass: '_detail_selector', cssClass: '_detail_selector',
useRowClick: false, useRowClick: false,
panelRows: 1 panelRows: 1,
postTemplate: () => '', // I'm assuming these code paths are just never hit...
preTemplate: () => '',
process: () => { }
}); });
columns.unshift(rowDetail.getColumnDefinition()); columns.unshift(rowDetail.getColumnDefinition());

View File

@@ -423,7 +423,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
// Check extensions to create ActionItem; otherwise, return undefined // Check extensions to create ActionItem; otherwise, return undefined
// This is similar behavior that exists in MenuItemActionItem // This is similar behavior that exists in MenuItemActionItem
if (action instanceof MenuItemAction) { if (action instanceof MenuItemAction) {
return new LabeledMenuItemActionItem(action, this.keybindingService, this.notificationService, this.contextMenuService, 'notebook-button'); return new LabeledMenuItemActionItem(action, this.keybindingService, this.contextMenuService, this.notificationService, 'notebook-button');
} }
return undefined; return undefined;
} }

View File

@@ -1,8 +1,10 @@
{ {
"extends": "./tsconfig.base.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"noEmit": true, "noEmit": true,
"strictNullChecks": true, "strictNullChecks": true,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"moduleResolution": "classic" "moduleResolution": "classic"
}, },
"include": [ "include": [
@@ -11,6 +13,8 @@
"./vs/vscode.proposed.d.ts", "./vs/vscode.proposed.d.ts",
"./sql/azdata.d.ts", "./sql/azdata.d.ts",
"./sql/azdata.proposed.d.ts", "./sql/azdata.proposed.d.ts",
"./vs/base/**/*.ts",
"./vs/platform/**/*.ts",
"./sql/base/**/*.ts", "./sql/base/**/*.ts",
"./sql/platform/angularEventing/**/*.ts", "./sql/platform/angularEventing/**/*.ts",
"./sql/platform/clipboard/**/*.ts", "./sql/platform/clipboard/**/*.ts",

View File

@@ -96,8 +96,8 @@ declare namespace Slick {
export class EventHandler { export class EventHandler {
constructor(); constructor();
public subscribe<T>(event: Event<T>, handler: Function): EventHandler; public subscribe<T>(event: Event<T>, handler: (event: DOMEvent, args: T) => void): EventHandler;
public unsubscribe<T>(event: Event<T>, handler: Function): EventHandler; public unsubscribe<T>(event: Event<T>, handler: (event: DOMEvent, args: T) => void): EventHandler;
public unsubscribeAll(): EventHandler; public unsubscribeAll(): EventHandler;
} }
@@ -668,6 +668,11 @@ declare namespace Slick {
* Page grid when navigating * Page grid when navigating
*/ */
emulatePagingWhenScrolling?: boolean; emulatePagingWhenScrolling?: boolean;
/**
*
*/
minRowBuffer?: number;
} }
export interface DataProvider<T extends SlickData> { export interface DataProvider<T extends SlickData> {
@@ -687,10 +692,14 @@ declare namespace Slick {
* @param index * @param index
*/ */
getItemMetadata?(index: number): RowMetadata<T>; getItemMetadata?(index: number): RowMetadata<T>;
/**
*
*/
getItems(): Array<T>;
} }
export interface SlickData { export interface SlickData extends Object {
// todo ? might be able to leave as empty
} }
export interface RowMetadata<T> { export interface RowMetadata<T> {
@@ -772,7 +781,7 @@ declare namespace Slick {
/** /**
* Sets selected ranges for the grid * Sets selected ranges for the grid
*/ */
setSelectedRanges(ranges: Slick.Range[]); setSelectedRanges(ranges: Slick.Range[]): void;
/** /**
* Gets selected ranges for the grid * Gets selected ranges for the grid
@@ -818,10 +827,7 @@ declare namespace Slick {
* Returns an array of every data object, unless you're using DataView in which case it returns a DataView object. * Returns an array of every data object, unless you're using DataView in which case it returns a DataView object.
* @return * @return
**/ **/
public getData(): any; public getData(): T[] | DataProvider<T>;
//public getData(): T[];
// Issue: typescript limitation, cannot differentiate calls by return type only, so need to cast to DataView or T[].
//public getData(): DataView;
/** /**
* Returns the databinding item at a given position. * Returns the databinding item at a given position.
@@ -1228,7 +1234,7 @@ declare namespace Slick {
public render(): void; public render(): void;
public invalidate(): void; public invalidate(): void;
public invalidateRow(row: number): void; public invalidateRow(row: number): void;
public invalidateRows(rows: number[], keepEditor: boolean): void; public invalidateRows(rows: number[], keepEditor?: boolean): void;
public invalidateAllRows(): void; public invalidateAllRows(): void;
public updateCell(row: number, cell: number): void; public updateCell(row: number, cell: number): void;
public updateRow(row: number): void; public updateRow(row: number): void;
@@ -1543,7 +1549,7 @@ declare namespace Slick {
} }
export interface Formatter<T extends SlickData> { export interface Formatter<T extends SlickData> {
(row: number, cell: number, value: any, columnDef: Column<T>, dataContext: SlickData): string; (row: number, cell: number, value: any, columnDef: Column<T>, dataContext: SlickData): string | undefined;
} }
export module Formatters { export module Formatters {

View File

@@ -1,5 +1,5 @@
// Generated by typings // Generated by typings
// Source: node_modules/angular2-slickgrid/out/js/interfaces.d.ts // Source: ../node_modules/angular2-slickgrid/out/js/interfaces.d.ts
declare module '~angular2-slickgrid/out/js/interfaces' { declare module '~angular2-slickgrid/out/js/interfaces' {
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
export enum NotificationType { export enum NotificationType {
@@ -21,6 +21,7 @@ export interface IObservableCollection<T> {
at(index: number): T; at(index: number): T;
getRange(start: number, end: number): T[]; getRange(start: number, end: number): T[];
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void; setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void;
resetWindowsAroundIndex(index: number): void;
} }
export class CancellationToken { export class CancellationToken {
private _isCanceled; private _isCanceled;
@@ -33,10 +34,6 @@ export interface IGridColumnDefinition {
id: string; id: string;
type: number; type: number;
} }
export interface IGridDataRow {
row?: number;
values: any[];
}
export interface ISlickColumn<T> extends Slick.Column<T> { export interface ISlickColumn<T> extends Slick.Column<T> {
isEditable?: boolean; isEditable?: boolean;
} }
@@ -46,7 +43,7 @@ export * from '~angular2-slickgrid/out/js/interfaces';
} }
// Generated by typings // Generated by typings
// Source: node_modules/angular2-slickgrid/out/js/selectionModel.d.ts // Source: ../node_modules/angular2-slickgrid/out/js/selectionModel.d.ts
declare module '~angular2-slickgrid/out/js/selectionModel' { declare module '~angular2-slickgrid/out/js/selectionModel' {
import { ISelectionRange } from '~angular2-slickgrid/out/js/interfaces'; import { ISelectionRange } from '~angular2-slickgrid/out/js/interfaces';
export class SelectionModel implements ISlickSelectionModel { export class SelectionModel implements ISlickSelectionModel {
@@ -106,20 +103,16 @@ export * from '~angular2-slickgrid/out/js/selectionModel';
} }
// Generated by typings // Generated by typings
// Source: node_modules/angular2-slickgrid/out/js/slickGrid.d.ts // Source: ../node_modules/angular2-slickgrid/out/js/slickGrid.d.ts
declare module '~angular2-slickgrid/out/js/slickGrid' { declare module '~angular2-slickgrid/out/js/slickGrid' {
import { OnChanges, OnInit, OnDestroy, SimpleChange, EventEmitter, AfterViewInit } from '@angular/core'; import { OnChanges, OnInit, OnDestroy, SimpleChange, EventEmitter, AfterViewInit } from '@angular/core';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { IObservableCollection, IGridDataRow, ISlickColumn } from '~angular2-slickgrid/out/js/interfaces'; import { IObservableCollection, ISlickColumn } from '~angular2-slickgrid/out/js/interfaces';
export class OnRangeRenderCompletedEventArgs {
startRow: number;
endRow: number;
}
export function getOverridableTextEditorClass(grid: SlickGrid): any; export function getOverridableTextEditorClass(grid: SlickGrid): any;
export class SlickGrid implements OnChanges, OnInit, OnDestroy, AfterViewInit { export class SlickGrid implements OnChanges, OnInit, OnDestroy, AfterViewInit {
private _el; private _el;
columnDefinitions: ISlickColumn<any>[]; columnDefinitions: ISlickColumn<any>[];
dataRows: IObservableCollection<IGridDataRow>; dataRows: IObservableCollection<{}>;
resized: Observable<any>; resized: Observable<any>;
highlightedCells: { highlightedCells: {
row: number; row: number;
@@ -135,23 +128,18 @@ export class SlickGrid implements OnChanges, OnInit, OnDestroy, AfterViewInit {
plugins: Array<string | Slick.Plugin<any>>; plugins: Array<string | Slick.Plugin<any>>;
enableEditing: boolean; enableEditing: boolean;
topRowNumber: number; topRowNumber: number;
overrideCellFn: (rowNumber, columnId, value?, data?) => string; overrideCellFn: (rowNumber: number, columnId: number, value?: any, data?: any) => string;
isCellEditValid: (row: number, column: number, newValue: any) => boolean; isCellEditValid: (row: number, column: number, newValue: any) => boolean;
onBeforeAppendCell: (row: number, column: number) => string;
loadFinished: EventEmitter<void>; loadFinished: EventEmitter<void>;
onContextMenu: EventEmitter<Slick.OnContextMenuEventArgs<any>>; onContextMenu: EventEmitter<Slick.EventData>;
onScroll: EventEmitter<Slick.OnScrollEventArgs<any>>; onScroll: EventEmitter<Slick.OnScrollEventArgs<any>>;
onActiveCellChanged: EventEmitter<Slick.OnActiveCellChangedEventArgs<any>>; onActiveCellChanged: EventEmitter<Slick.OnActiveCellChangedEventArgs<any>>;
onBeforeEditCell: EventEmitter<Slick.OnBeforeEditCellEventArgs<any>>; onBeforeEditCell: EventEmitter<Slick.OnBeforeEditCellEventArgs<any>>;
onCellChange: EventEmitter<Slick.OnCellChangeEventArgs<any>>; onCellChange: EventEmitter<Slick.OnCellChangeEventArgs<any>>;
onRendered: EventEmitter<Slick.OnRenderedEventArgs<any>>;
onFocus(): void; onFocus(): void;
rowHeight: number; rowHeight: number;
private _rowHeight;
private _grid;
private _gridColumns;
private _columnNameToIndex;
private _gridData;
private _resizeSubscription;
private _gridSyncSubscription;
constructor(_el: any); constructor(_el: any);
ngOnChanges(changes: { ngOnChanges(changes: {
[propName: string]: SimpleChange; [propName: string]: SimpleChange;
@@ -168,17 +156,7 @@ export class SlickGrid implements OnChanges, OnInit, OnDestroy, AfterViewInit {
registerPlugin(plugin: Slick.Plugin<any> | string): void; registerPlugin(plugin: Slick.Plugin<any> | string): void;
setActive(): void; setActive(): void;
selection: Slick.Range[] | boolean; selection: Slick.Range[] | boolean;
private initGrid();
private changeEditSession(enabled);
private onResize();
private invalidateRange(start, end);
private getColumnEditor(column);
private getFormatter;
private setupEvents();
private updateSchema();
private setCallbackOnDataRowsChanged();
readonly activeCell: Slick.Cell; readonly activeCell: Slick.Cell;
private renderGridDataRowsRange(startIndex, count);
} }
} }
declare module 'angular2-slickgrid/out/js/slickGrid' { declare module 'angular2-slickgrid/out/js/slickGrid' {
@@ -186,25 +164,16 @@ export * from '~angular2-slickgrid/out/js/slickGrid';
} }
// Generated by typings // Generated by typings
// Source: node_modules/angular2-slickgrid/out/js/virtualizedCollection.d.ts // Source: ../node_modules/angular2-slickgrid/out/js/virtualizedCollection.d.ts
declare module '~angular2-slickgrid/out/js/virtualizedCollection' { declare module '~angular2-slickgrid/out/js/virtualizedCollection' {
import { IObservableCollection, CollectionChange } from '~angular2-slickgrid/out/js/interfaces'; import { IObservableCollection, CollectionChange } from '~angular2-slickgrid/out/js/interfaces';
export class VirtualizedCollection<TData> implements IObservableCollection<TData> { export class VirtualizedCollection<TData> implements IObservableCollection<TData> {
private _placeHolderGenerator;
private _length;
private _windowSize;
private _bufferWindowBefore;
private _window;
private _bufferWindowAfter;
private collectionChangedCallback;
constructor(windowSize: number, length: number, loadFn: (offset: number, count: number) => Promise<TData[]>, _placeHolderGenerator: (index: number) => TData); constructor(windowSize: number, length: number, loadFn: (offset: number, count: number) => Promise<TData[]>, _placeHolderGenerator: (index: number) => TData);
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void; setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void;
getLength(): number; getLength(): number;
at(index: number): TData; at(index: number): TData;
getRange(start: number, end: number): TData[]; getRange(start: number, end: number): TData[];
private getRangeFromCurrent(start, end); resetWindowsAroundIndex(index: number): void;
private getDataFromCurrent(index);
resetWindowsAroundIndex(index);
} }
} }
declare module 'angular2-slickgrid/out/js/virtualizedCollection' { declare module 'angular2-slickgrid/out/js/virtualizedCollection' {
@@ -212,7 +181,7 @@ export * from '~angular2-slickgrid/out/js/virtualizedCollection';
} }
// Generated by typings // Generated by typings
// Source: node_modules/angular2-slickgrid/out/index.d.ts // Source: ../node_modules/angular2-slickgrid/out/index.d.ts
declare module '~angular2-slickgrid/out/index' { declare module '~angular2-slickgrid/out/index' {
export * from '~angular2-slickgrid/out/js/interfaces'; export * from '~angular2-slickgrid/out/js/interfaces';
export * from '~angular2-slickgrid/out/js/selectionModel'; export * from '~angular2-slickgrid/out/js/selectionModel';

View File

@@ -58,6 +58,8 @@ export function first<T>(from: IStringDictionary<T> | INumberDictionary<T>): T |
* Iterates over each entry in the provided set. The iterator allows * Iterates over each entry in the provided set. The iterator allows
* to remove elements and will stop when the callback returns {{false}}. * to remove elements and will stop when the callback returns {{false}}.
*/ */
export function forEach<T>(from: IStringDictionary<T>, callback: (entry: { key: string; value: T; }, remove: () => void) => any): void; // {{SQL CARBON EDIT}} @anthonydresser add hard typings
export function forEach<T>(from: INumberDictionary<T>, callback: (entry: { key: number; value: T; }, remove: () => void) => any): void;
export function forEach<T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any): void { export function forEach<T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any): void {
for (let key in from) { for (let key in from) {
if (hasOwnProperty.call(from, key)) { if (hasOwnProperty.call(from, key)) {
@@ -96,4 +98,4 @@ export function fromMap<T>(original: Map<string, T>): IStringDictionary<T> {
}); });
} }
return result; return result;
} }

View File

@@ -274,16 +274,16 @@ export class ContextAwareMenuEntryActionViewItem extends MenuEntryActionViewItem
// an icon/CSS class. Useful for some toolbar scenarios in particular with // an icon/CSS class. Useful for some toolbar scenarios in particular with
// contributed actions from other extensions // contributed actions from other extensions
export class LabeledMenuItemActionItem extends MenuEntryActionViewItem { export class LabeledMenuItemActionItem extends MenuEntryActionViewItem {
private _labeledItemClassDispose: IDisposable; private _labeledItemClassDispose?: IDisposable;
constructor( constructor(
public _action: MenuItemAction, public _action: MenuItemAction,
@IKeybindingService private readonly _labeledkeybindingService: IKeybindingService, @IKeybindingService labeledkeybindingService: IKeybindingService,
@IContextMenuService labeledcontextMenuService: IContextMenuService,
@INotificationService protected _notificationService: INotificationService, @INotificationService protected _notificationService: INotificationService,
@IContextMenuService private readonly _labeledcontextMenuService: IContextMenuService,
private readonly _defaultCSSClassToAdd: string = '' private readonly _defaultCSSClassToAdd: string = ''
) { ) {
super(_action, _labeledkeybindingService, _notificationService, _labeledcontextMenuService); super(_action, labeledkeybindingService, _notificationService, labeledcontextMenuService);
} }
updateLabel(): void { updateLabel(): void {
@@ -302,7 +302,7 @@ export class LabeledMenuItemActionItem extends MenuEntryActionViewItem {
const iconPathMapKey = item.iconLocation.dark.toString(); const iconPathMapKey = item.iconLocation.dark.toString();
if (MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.has(iconPathMapKey)) { if (MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.has(iconPathMapKey)) {
iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey); iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey)!;
} else { } else {
iconClass = ids.nextId(); iconClass = ids.nextId();
createCSSRule(`.icon.${iconClass}`, `background-image: url("${(item.iconLocation.light || item.iconLocation.dark).toString()}")`); createCSSRule(`.icon.${iconClass}`, `background-image: url("${(item.iconLocation.light || item.iconLocation.dark).toString()}")`);

View File

@@ -259,7 +259,7 @@ function getVersionAsset(version: IRawGalleryExtensionVersion, type: string): IG
const result = version.files.filter(f => f.assetType === type)[0]; const result = version.files.filter(f => f.assetType === type)[0];
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
let uriFromSource: string = undefined; let uriFromSource: string | undefined;
if (result) { if (result) {
uriFromSource = result.source; uriFromSource = result.source;
} }
@@ -275,7 +275,7 @@ function getVersionAsset(version: IRawGalleryExtensionVersion, type: string): IG
fallbackUri: `${version.fallbackAssetUri}/${type}` fallbackUri: `${version.fallbackAssetUri}/${type}`
}; };
} else { } else {
return result ? { uri: uriFromSource, fallbackUri: `${version.fallbackAssetUri}/${type}` } : null; return result ? { uri: uriFromSource!, fallbackUri: `${version.fallbackAssetUri}/${type}` } : null;
} }
// return result ? { uri: `${version.assetUri}/${type}`, fallbackUri: `${version.fallbackAssetUri}/${type}` } : null; // return result ? { uri: `${version.assetUri}/${type}`, fallbackUri: `${version.fallbackAssetUri}/${type}` } : null;
// {{SQL CARBON EDIT}} - End // {{SQL CARBON EDIT}} - End
@@ -410,7 +410,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
if (extension) { if (extension) {
return Promise.resolve(extension); return Promise.resolve(extension);
} }
const { id, uuid } = extension ? extension.identifier : <IExtensionIdentifier>arg1; const { id, uuid } = <IExtensionIdentifier>arg1; // {{SQL CARBON EDIT}} @anthonydresser remove extension ? extension.identifier
let query = new Query() let query = new Query()
.withFlags(Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties, Flags.ExcludeNonValidated) .withFlags(Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties, Flags.ExcludeNonValidated)
.withPage(1, 1) .withPage(1, 1)
@@ -542,15 +542,15 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
// Filtering // Filtering
let filteredExtensions = galleryExtensions; let filteredExtensions = galleryExtensions;
if (query.criteria) { if (query.criteria) {
const ids = query.criteria.filter(x => x.filterType === FilterType.ExtensionId).map(v => v.value.toLocaleLowerCase()); const ids = query.criteria.filter(x => x.filterType === FilterType.ExtensionId).map(v => v.value ? v.value.toLocaleLowerCase() : undefined);
if (ids && ids.length > 0) { if (ids && ids.length > 0) {
filteredExtensions = filteredExtensions.filter(e => e.extensionId && ids.includes(e.extensionId.toLocaleLowerCase())); filteredExtensions = filteredExtensions.filter(e => e.extensionId && ids.includes(e.extensionId.toLocaleLowerCase()));
} }
const names = query.criteria.filter(x => x.filterType === FilterType.ExtensionName).map(v => v.value.toLocaleLowerCase()); const names = query.criteria.filter(x => x.filterType === FilterType.ExtensionName).map(v => v.value ? v.value.toLocaleLowerCase() : undefined);
if (names && names.length > 0) { if (names && names.length > 0) {
filteredExtensions = filteredExtensions.filter(e => e.extensionName && e.publisher.publisherName && names.includes(`${e.publisher.publisherName.toLocaleLowerCase()}.${e.extensionName.toLocaleLowerCase()}`)); filteredExtensions = filteredExtensions.filter(e => e.extensionName && e.publisher.publisherName && names.includes(`${e.publisher.publisherName.toLocaleLowerCase()}.${e.extensionName.toLocaleLowerCase()}`));
} }
const searchTexts = query.criteria.filter(x => x.filterType === FilterType.SearchText).map(v => v.value.toLocaleLowerCase()); const searchTexts = query.criteria.filter(x => x.filterType === FilterType.SearchText).map(v => v.value ? v.value.toLocaleLowerCase() : undefined);
if (searchTexts && searchTexts.length > 0) { if (searchTexts && searchTexts.length > 0) {
searchTexts.forEach(searchText => { searchTexts.forEach(searchText => {
if (searchText !== '@allmarketplace') { if (searchText !== '@allmarketplace') {
@@ -585,13 +585,13 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
/* /*
* Checks whether the extension matches the search text * Checks whether the extension matches the search text
*/ */
public static isMatchingExtension(extension: IRawGalleryExtension, searchText: string): boolean { public static isMatchingExtension(extension?: IRawGalleryExtension, searchText?: string): boolean {
if (!searchText) { if (!searchText) {
return true; return true;
} }
let text = searchText.toLocaleLowerCase(); let text = searchText.toLocaleLowerCase();
return extension return !!extension
&& (extension.extensionName && extension.extensionName.toLocaleLowerCase().includes(text) || && !!(extension.extensionName && extension.extensionName.toLocaleLowerCase().includes(text) ||
extension.publisher && extension.publisher.publisherName && extension.publisher.publisherName.toLocaleLowerCase().includes(text) || extension.publisher && extension.publisher.publisherName && extension.publisher.publisherName.toLocaleLowerCase().includes(text) ||
extension.publisher && extension.publisher.displayName && extension.publisher.displayName.toLocaleLowerCase().includes(text) || extension.publisher && extension.publisher.displayName && extension.publisher.displayName.toLocaleLowerCase().includes(text) ||
extension.displayName && extension.displayName.toLocaleLowerCase().includes(text) || extension.displayName && extension.displayName.toLocaleLowerCase().includes(text) ||

View File

@@ -47,14 +47,26 @@ suite('Extension Gallery Service', () => {
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
test('sortByField', () => { test('sortByField', () => {
let a = { let a: {
extensionId: string | undefined;
extensionName: string | undefined;
displayName: string | undefined;
shortDescription: string | undefined;
publisher: { displayName: string | undefined, publisherId: string | undefined, publisherName: string | undefined; } | undefined;
} = {
extensionId: undefined, extensionId: undefined,
extensionName: undefined, extensionName: undefined,
displayName: undefined, displayName: undefined,
shortDescription: undefined, shortDescription: undefined,
publisher: undefined publisher: undefined
}; };
let b = { let b: {
extensionId: string | undefined;
extensionName: string | undefined;
displayName: string | undefined;
shortDescription: string | undefined;
publisher: { displayName: string | undefined, publisherId: string | undefined, publisherName: string | undefined; } | undefined;
} = {
extensionId: undefined, extensionId: undefined,
extensionName: undefined, extensionName: undefined,
displayName: undefined, displayName: undefined,

View File

@@ -222,7 +222,7 @@ export function isValidExtensionVersion(version: string, extensionDesc: IReduced
} }
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
return (extensionDesc.engines.azdata && extensionDesc.engines.azdata === '*') || isVersionValid(version, extensionDesc.engines.azdata, notices); return extensionDesc.engines.azdata ? extensionDesc.engines.azdata === '*' || isVersionValid(version, extensionDesc.engines.azdata, notices) : true;
} }
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}