mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 17:23:10 -05:00
initial PR for table designer feature (#17200)
* wip * wire up e2e * hook up styler and add as dataprotocal feature * designer child component rendering * table component updates * styler and selectbox column editor * fix editor size and dupe component creation issue * fix checkbox column and add more testing data * properties pane * only rerender when needed * properties pane update * update commands * cleanup for PR * revert unwanted changes * Adding a few tests for Add SQL binding (#17079) * initial changes * add a couple more tests * LEGO: check in for main to temporary branch. (#17089) * LEGO: check in for main to temporary branch. (#17091) Co-authored-by: kburtram <karlb@microsoft.com> * Adds autorest-based SQL Project generation to SQL Database Projects extension (#17078) * Initial changes * checkpoint * Constructing project with post deployment script * Correcting to intentionally read from cached list of projects * Adding activation event, fixing fresh workspace bug * Convert netcoreTool and autorestHelper to share a helper class for streamed command * Include npm package version to force update * test checkpoint * Unit tests * Added contextual quickpicks for autorest dialogs * Adding projectController test * Added projectController test, some refactoring for testability * Merge branch 'main' into benjin/autorest * Fixing 'which' import * PR feedback * Fixing tests * Adding additional information for when project provider tests fail * Hopefully fixing failing tests (unable to repro locally) * Adding Generate Project item to workspace menu * PR feedback * LEGO: check in for main to temporary branch. (#17097) * added sql database projects strings (#17100) * Set kernelAlias in startSession when isValidConnection is truthy (#17102) * PR follow-up comments (#17113) * Change recompare message after changing options to modal (#17103) * Change recompare message to modal * change options to yes and no * Remove commented code block in git extension (#17116) * Remove commented code block in git extension * Add SQL CARBON EDIT tag * [Loc] Small change to generatingProjectFailed (#17118) * Add Null Shortcut and added NULL text for default NULL value. (#17085) * added test key event * added null function to tryHandleKeyEvent * added null formatting * added working null insert. * added editDataGridPanel string null support * Bump nth-check from 2.0.0 to 2.0.1 in /build (#17115) Bumps [nth-check](https://github.com/fb55/nth-check) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/fb55/nth-check/releases) - [Commits](https://github.com/fb55/nth-check/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: nth-check dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add excludeFlags to extenson marketplace query (#17121) * Add excludeFlags to extenson marketplace query * Remove dead code * Remove extraneous blank line * Address code review feedback * Adding Derived Columns to ADS Flatfile Import (#16795) * Adding derived column boilerplate * brandan preliminary frontend changes * empty commit * added new param * updating contracts, dialogue changes * utils changes, saving timeout attempt * pushing for aasim * Cleaning up code and fixing the issue in theory * changing button, did not solve independent scroll * Fixing the scroll bar issue * updating flat file service * adding override keyword to overrriden method * improving UI * pushing changes associated with resolved comments * localizing strings, editing comments * all comments resolved * Fixing a test * updating import package Updating azure MFA bug * Clearing navigation validator Fixing broken table name change * fixed prose test * removing unused code from tests * Fixed PR comments * Fixing some PR comments * WIP * Fixing transformation code and create derived column dialog styling * removing unused code * Adding comment for console log * fixed table styling * Adding some aria labels * Fixed some code cleanup issues * update import service Co-authored-by: Aasim Khan <aasimkhan30@gmail.com> Co-authored-by: bnhoule <t-bhoule@microsoft.com> * Change keybindings for copying query with Results (#17127) Co-authored-by: Monica Gupta <mogupt@microsoft.com> * sql proj - publish to docker improvements (#17124) * Add AAD token expiration handling for query runner (#17117) * Add AAD token refresh for notebook * move token refresh to query management and remove previous refresh calls * Add guids to RunAll and RunCell events (#17123) Add guids to RunAll and RunCell events * add error banner for failed migration cutover and cancel migration (#17106) * [Loc] update to sql migration, database projects and import extension strings (#17130) * Apply optional storage class settings in sql mi create command (#17129) * Make storage classes optional * Fix notebook to use storage class options Co-authored-by: Charmaine Chan <chachan@microsoft.com> * Add support for adding new setting in local.settings.json in add SQL binding quickpick (#17093) * be able to add new setting in local.settings.json * cleanup * addressing comments * remove todo comment * addressing comments * update some strings to uris * bump version of sqltoolsservice (#17133) * mark schema compare tests as unstable (#17140) * [Loc] Update for arc and sql-database-projects (#17148) * ML extension vbump (#17143) * Configure docker image and web smoke tests for ADSWeb. (#17136) * Adjusts timeout period * Revert "Adjusts timeout period" This reverts commit 0f372eae2a4611554093b6c09f1ff6c451132e19. * Adds firefox as browser option * Corrects yaml smoke test script * Resets args array to original values * Corrects build path * Resolves ignoring browser option error * continue even after writing to stderr * Adjusts smoke test (browser) script * More adjustments to smoke test script * Corrects server path * Uses build variable directly in build path * Specifies browser type since cannot be ignored error * Adds browser option * Updates web build image and corrects smoke test exe command * Removes commented out task * Updates dockerfile to support web smoketests * Removes failOnStderr flag * Use curl instead of wget in Dockerfile * Fixed a bug with cancling publish (#17160) * Save And Close Functionality (#17000) * save and close * wip * working save and close * cleanup * pr changes * pr changes * fix capitalization * fix build * pr fix * Added dynamic options for SQL MIAA Deployment Wizard and updated checkbox field (#17119) * Dynamic enablement * Added new package.json field for dynamic options and corresponding functions and classes. * Enabled dynamic options non-generalized and changed formatting of checkbox to have label on the left. * Added setOptions under InputComponentInfo for generalization, comments under checkbox component, and changed Replicas to High Availability to reflect parity in portal. * fix unit test Co-authored-by: Candice Ye <canye@microsoft.com> Co-authored-by: Alan Ren <alanren@microsoft.com> * LEGO: check in for main to temporary branch. (#17168) * [Loc] added new arc strings and fix for sql-database-projects lcl file for Japanese (#17171) * [Loc] added new arc strings and fix for sql-database-projects xlf * removed newline * Port of Vscode fix for colors too close (#17146) * default light colors list.focusHighlightForeground too close to list.activeSelectionBackground. Fixes #127597 * remove activeSelectionBackground from theme-carbon as it conflicts with vscode. * remove dark carbon background Co-authored-by: Martin Aeschlimann <martinae@microsoft.com> * Markdown Horizontal Scrollbar Fix (#17083) * dynamically change horizontal scrollbar * working horizontal scrollbar * created new event to handle both scrollbar and mouse wheel * only show scrollbar when needed * LEGO: check in for main to temporary branch. (#17181) * Bump axios to 0.21.4 (#17161) * Kusto version bump to 0.5.6 (#17114) * Bumped Kusto toolsservice version to 125 and bumped version to 0.5.6 * Changed netcoreapp3.1 to net5.0 in Kusto config.json * AzureMonitor bump ToolService version and extension version. (#17174) * Bump concat-with-sourcemaps from 1.0.4 to 1.1.0 (#17158) Bumps [concat-with-sourcemaps](https://github.com/floridoo/concat-with-sourcemaps) from 1.0.4 to 1.1.0. - [Release notes](https://github.com/floridoo/concat-with-sourcemaps/releases) - [Commits](https://github.com/floridoo/concat-with-sourcemaps/commits) --- updated-dependencies: - dependency-name: concat-with-sourcemaps dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update service downloader to 0.2.3 (#17186) * Notebook Views grid fixes (#17170) * update data workspace restart ADS to open workspace message (#17188) * update message * update string * Add back "Remove Project" (#17178) * remove project working with full paths * use relative paths * const * addressing comments * Bump github-auth axios to 0.21.4 (#17189) * LEGO: check in for main to temporary branch. (#17192) * LEGO: check in for main to temporary branch. (#17190) Co-authored-by: kburtram <karlb@microsoft.com> * [Loc] Add a small change to dataworkspace (#17194) * added bump to sqltoolsservice version (#17195) * Check if file is dirty before adding sql binding (#17175) * check if file is dirty before adding sql binding * Addressing comments * Add vertical scroll bar to Preview in Split View (#17164) * reset max height * add editor height * set md editor height * Split up NotebookProvider into separate providers for handling file serialization and cell execution. (#17176) * fix floating promises * pr comments * reuse component definition * comments * fix error Co-authored-by: Kim Santiago <31145923+kisantia@users.noreply.github.com> Co-authored-by: csigs <csigs@users.noreply.github.com> Co-authored-by: kburtram <karlb@microsoft.com> Co-authored-by: Benjin Dubishar <benjin.dubishar@gmail.com> Co-authored-by: Alex Ma <alma1@microsoft.com> Co-authored-by: Justin M <63619224+JustinMDotNet@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: bnhoule <52506119+bnhoule@users.noreply.github.com> Co-authored-by: Aasim Khan <aasimkhan30@gmail.com> Co-authored-by: bnhoule <t-bhoule@microsoft.com> Co-authored-by: Monica Gupta <scorpio90m@gmail.com> Co-authored-by: Monica Gupta <mogupt@microsoft.com> Co-authored-by: Leila Lali <llali@microsoft.com> Co-authored-by: Hai Cao <hacao@microsoft.com> Co-authored-by: Daniel Grajeda <dagrajed@microsoft.com> Co-authored-by: brian-harris <61598682+brian-harris@users.noreply.github.com> Co-authored-by: Charmaine Chan <69230572+charmainewkchan@users.noreply.github.com> Co-authored-by: Charmaine Chan <chachan@microsoft.com> Co-authored-by: Lewis Sanchez <87730006+lewis-sanchez@users.noreply.github.com> Co-authored-by: Christopher Suh <chsuh@microsoft.com> Co-authored-by: Candice Ye <candiceye@berkeley.edu> Co-authored-by: Candice Ye <canye@microsoft.com> Co-authored-by: Martin Aeschlimann <martinae@microsoft.com> Co-authored-by: Vasu Bhog <vabhog@microsoft.com> Co-authored-by: Charles Gagnon <chgagnon@microsoft.com> Co-authored-by: Barbara Valdez <34872381+barbaravaldez@users.noreply.github.com> Co-authored-by: Cory Rivera <corivera@microsoft.com>
This commit is contained in:
110
src/sql/base/browser/ui/table/plugins/checkboxColumn.plugin.ts
Normal file
110
src/sql/base/browser/ui/table/plugins/checkboxColumn.plugin.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/checkboxColumn.plugin';
|
||||
import { BaseTableColumnOptions, TableColumn } from 'sql/base/browser/ui/table/plugins/tableColumn';
|
||||
import { escape } from 'sql/base/common/strings';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
|
||||
export interface CheckBoxCellValue {
|
||||
enabled?: boolean;
|
||||
checked: boolean;
|
||||
}
|
||||
|
||||
export interface CheckBoxChangedEventArgs<T extends Slick.SlickData> {
|
||||
item: T;
|
||||
row: number;
|
||||
column: number;
|
||||
value: boolean;
|
||||
}
|
||||
|
||||
export interface CheckBoxColumnOptions extends BaseTableColumnOptions {
|
||||
}
|
||||
|
||||
export class CheckBoxColumn<T extends Slick.SlickData> implements Slick.Plugin<T>, TableColumn<T> {
|
||||
private _handler = new Slick.EventHandler();
|
||||
private _grid!: Slick.Grid<T>;
|
||||
private _onChange = new Emitter<CheckBoxChangedEventArgs<T>>();
|
||||
public onChange = this._onChange.event;
|
||||
|
||||
constructor(private options: CheckBoxColumnOptions) {
|
||||
|
||||
}
|
||||
|
||||
public init(grid: Slick.Grid<T>): void {
|
||||
this._grid = grid;
|
||||
this._handler.subscribe(grid.onClick, (e: DOMEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(args));
|
||||
this._handler.subscribe(grid.onKeyDown, (e: DOMEvent, args: Slick.OnKeyDownEventArgs<T>) => this.handleKeyboardEvent(e as KeyboardEvent, args));
|
||||
this._handler.subscribe(grid.onActiveCellChanged, (e: DOMEvent, args: Slick.OnActiveCellChangedEventArgs<T>) => { this.handleActiveCellChanged(args); });
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this._handler.unsubscribeAll();
|
||||
}
|
||||
|
||||
public get definition(): Slick.Column<T> {
|
||||
return {
|
||||
id: this.options.field,
|
||||
formatter: (row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string => {
|
||||
const cellValue = dataContext[columnDef.field] as CheckBoxCellValue;
|
||||
const escapedTitle = escape(columnDef.name ?? '');
|
||||
const disabledAttribute = cellValue.enabled === false ? 'disabled' : '';
|
||||
const checkedAttribute = cellValue.checked ? 'checked' : '';
|
||||
return `<input type="checkbox" tabindex=-1 title="${escapedTitle}" aria-label="${escapedTitle}" ${checkedAttribute} ${disabledAttribute}/>`;
|
||||
},
|
||||
field: this.options.field,
|
||||
name: this.options.name,
|
||||
resizable: this.options.resizable,
|
||||
cssClass: 'slick-plugin-checkbox-column'
|
||||
};
|
||||
}
|
||||
|
||||
private getCheckbox(): HTMLInputElement {
|
||||
const cellElement = this._grid.getActiveCellNode();
|
||||
return cellElement.children[0] as HTMLInputElement;
|
||||
}
|
||||
|
||||
private handleActiveCellChanged(args: Slick.OnActiveCellChangedEventArgs<T>): void {
|
||||
if (this.isCurrentColumn(args.cell)) {
|
||||
this.getCheckbox().focus();
|
||||
}
|
||||
}
|
||||
|
||||
private handleClick(args: Slick.OnClickEventArgs<T>): void {
|
||||
if (this.isCurrentColumn(args.cell)) {
|
||||
setTimeout(() => {
|
||||
this.fireOnChangeEvent();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private handleKeyboardEvent(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.Space) && this.isCurrentColumn(args.cell)) {
|
||||
this.fireOnChangeEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private fireOnChangeEvent(): void {
|
||||
const cell = this._grid.getActiveCell();
|
||||
const checked = this.getCheckbox().checked;
|
||||
const item = this._grid.getDataItem(cell.row);
|
||||
const cellValue = item[this.options.field] as CheckBoxCellValue;
|
||||
if (checked !== cellValue.checked) {
|
||||
this._onChange.fire({
|
||||
row: cell.row,
|
||||
column: cell.cell,
|
||||
value: checked,
|
||||
item: item
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private isCurrentColumn(columnIndex: number): boolean {
|
||||
return this._grid.getColumns()[columnIndex]?.id === this.definition.id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.slick-plugin-checkbox-column {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.slick-plugin-checkbox-column > input{
|
||||
margin: 0px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
172
src/sql/base/browser/ui/table/tableCellEditorFactory.ts
Normal file
172
src/sql/base/browser/ui/table/tableCellEditorFactory.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
|
||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { getCodeForKeyCode } from 'vs/base/browser/keyboardEvent';
|
||||
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
|
||||
export interface ITableCellEditorOptions {
|
||||
valueGetter?: (item: Slick.SlickData, column: Slick.Column<Slick.SlickData>) => string,
|
||||
valueSetter?: (context: any, row: number, item: Slick.SlickData, column: Slick.Column<Slick.SlickData>, value: string) => Promise<void>,
|
||||
optionsGetter?: (item: Slick.SlickData, column: Slick.Column<Slick.SlickData>) => string[],
|
||||
editorStyler: (component: InputBox | SelectBox) => void
|
||||
}
|
||||
|
||||
export class TableCellEditorFactory {
|
||||
private _options: ITableCellEditorOptions;
|
||||
|
||||
constructor(options: ITableCellEditorOptions, private _contextViewProvider: IContextViewProvider) {
|
||||
this._options = {
|
||||
valueGetter: options.valueGetter ?? function (item, column) {
|
||||
return item[column.field];
|
||||
},
|
||||
valueSetter: options.valueSetter ?? async function (context, row, item, column, value): Promise<void> {
|
||||
item[column.field] = value;
|
||||
},
|
||||
optionsGetter: options.optionsGetter ?? function (item, column) {
|
||||
return [];
|
||||
},
|
||||
editorStyler: options.editorStyler
|
||||
};
|
||||
}
|
||||
|
||||
public getTextEditorClass(context: any, inputType: 'text' | 'number' = 'text'): any {
|
||||
const self = this;
|
||||
class TextEditor {
|
||||
private _originalValue: string;
|
||||
private _input: InputBox;
|
||||
private _keyCaptureList: number[];
|
||||
|
||||
constructor(private _args: Slick.Editors.EditorOptions<Slick.SlickData>) {
|
||||
this.init();
|
||||
const keycodesToCapture = [KeyCode.Home, KeyCode.End, KeyCode.UpArrow, KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow];
|
||||
this._keyCaptureList = keycodesToCapture.map(keycode => getCodeForKeyCode(keycode));
|
||||
}
|
||||
|
||||
/**
|
||||
* The text editor should handle these key press events to avoid event bubble up
|
||||
*/
|
||||
public get keyCaptureList(): number[] {
|
||||
return this._keyCaptureList;
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
this._input = new InputBox(this._args.container, self._contextViewProvider, {
|
||||
type: inputType
|
||||
});
|
||||
self._options.editorStyler(this._input);
|
||||
this._input.element.style.height = '100%';
|
||||
this._input.focus();
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this._input.dispose();
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
this._input.focus();
|
||||
}
|
||||
|
||||
public loadValue(item: Slick.SlickData): void {
|
||||
this._originalValue = self._options.valueGetter(item, this._args.column) ?? '';
|
||||
this._input.value = this._originalValue;
|
||||
}
|
||||
|
||||
public async applyValue(item: Slick.SlickData, state: string): Promise<void> {
|
||||
const activeCell = this._args.grid.getActiveCell();
|
||||
await self._options.valueSetter(context, activeCell.row, item, this._args.column, state);
|
||||
}
|
||||
|
||||
public isValueChanged(): boolean {
|
||||
return this._input.value !== this._originalValue.toString();
|
||||
|
||||
}
|
||||
|
||||
public serializeValue(): any {
|
||||
return this._input.value;
|
||||
}
|
||||
|
||||
public validate(): Slick.ValidateResults {
|
||||
return {
|
||||
valid: true,
|
||||
msg: undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
return TextEditor;
|
||||
}
|
||||
|
||||
public getSelectBoxEditorClass(context: any, defaultOptions: string[]): any {
|
||||
const self = this;
|
||||
class TextEditor {
|
||||
private _originalValue: string;
|
||||
private _selectBox: SelectBox;
|
||||
private _keyCaptureList: number[];
|
||||
|
||||
constructor(private _args: Slick.Editors.EditorOptions<Slick.SlickData>) {
|
||||
this.init();
|
||||
const keycodesToCapture = [KeyCode.Home, KeyCode.End, KeyCode.UpArrow, KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow];
|
||||
this._keyCaptureList = keycodesToCapture.map(keycode => getCodeForKeyCode(keycode));
|
||||
}
|
||||
|
||||
/**
|
||||
* The text editor should handle these key press events to avoid event bubble up
|
||||
*/
|
||||
public get keyCaptureList(): number[] {
|
||||
return this._keyCaptureList;
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
const container = DOM.$('');
|
||||
this._args.container.appendChild(container);
|
||||
this._selectBox = new SelectBox([], undefined, self._contextViewProvider);
|
||||
container.style.height = '100%';
|
||||
container.style.width = '100%';
|
||||
this._selectBox.render(container);
|
||||
this._selectBox.selectElem.style.height = '100%';
|
||||
self._options.editorStyler(this._selectBox);
|
||||
this._selectBox.focus();
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this._selectBox.dispose();
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
this._selectBox.focus();
|
||||
}
|
||||
|
||||
public loadValue(item: Slick.SlickData): void {
|
||||
this._originalValue = self._options.valueGetter(item, this._args.column) ?? '';
|
||||
const options = self._options.optionsGetter(item, this._args.column) ?? defaultOptions;
|
||||
const idx = options?.indexOf(this._originalValue);
|
||||
if (idx > -1) {
|
||||
this._selectBox.setOptions(options);
|
||||
this._selectBox.select(idx);
|
||||
}
|
||||
}
|
||||
|
||||
public async applyValue(item: Slick.SlickData, state: string): Promise<void> {
|
||||
const activeCell = this._args.grid.getActiveCell();
|
||||
await self._options.valueSetter(context, activeCell.row, item, this._args.column, state);
|
||||
}
|
||||
|
||||
public isValueChanged(): boolean {
|
||||
return this._selectBox.value !== this._originalValue.toString();
|
||||
|
||||
}
|
||||
|
||||
public serializeValue(): any {
|
||||
return this._selectBox.value;
|
||||
}
|
||||
|
||||
public validate(): Slick.ValidateResults {
|
||||
return {
|
||||
valid: true,
|
||||
msg: undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
return TextEditor;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user