mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
More ViewModel cleanup (#116)
This commit is contained in:
@@ -27,9 +27,10 @@ import { TextField, ITextFieldProps, ITextField } from "office-ui-fabric-react/l
|
||||
import TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
import SaveQueryBannerIcon from "../../../../images/save_query_banner.png";
|
||||
import { QueriesClient } from "../../../Common/QueriesClient";
|
||||
|
||||
export interface QueriesGridComponentProps {
|
||||
queriesClient: ViewModels.QueriesClient;
|
||||
queriesClient: QueriesClient;
|
||||
onQuerySelect: (query: DataModels.Query) => void;
|
||||
containerVisible: boolean;
|
||||
saveQueryEnabled: boolean;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import IToolbarDisplayable from "./IToolbarDisplayable";
|
||||
|
||||
interface IToolbarAction extends IToolbarDisplayable {
|
||||
type: "action";
|
||||
action: () => void;
|
||||
}
|
||||
|
||||
export default IToolbarAction;
|
||||
@@ -1,18 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
interface IToolbarDisplayable {
|
||||
id: string;
|
||||
title: ko.Subscribable<string>;
|
||||
displayName: ko.Subscribable<string>;
|
||||
enabled: ko.Subscribable<boolean>;
|
||||
visible: ko.Observable<boolean>;
|
||||
focused: ko.Observable<boolean>;
|
||||
icon: string;
|
||||
mouseDown: (data: any, event: MouseEvent) => any;
|
||||
keyUp: (data: any, event: KeyboardEvent) => any;
|
||||
keyDown: (data: any, event: KeyboardEvent) => any;
|
||||
}
|
||||
|
||||
export default IToolbarDisplayable;
|
||||
@@ -1,56 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import IToolbarDisplayable from "./IToolbarDisplayable";
|
||||
|
||||
interface IToolbarDropDown extends IToolbarDisplayable {
|
||||
type: "dropdown";
|
||||
subgroup: IActionConfigItem[];
|
||||
expanded: ko.Observable<boolean>;
|
||||
open: () => void;
|
||||
}
|
||||
|
||||
export interface IDropdown {
|
||||
type: "dropdown";
|
||||
title: string;
|
||||
displayName: string;
|
||||
id: string;
|
||||
enabled: ko.Observable<boolean>;
|
||||
visible?: ko.Observable<boolean>;
|
||||
icon?: string;
|
||||
subgroup?: IActionConfigItem[];
|
||||
}
|
||||
|
||||
export interface ISeperator {
|
||||
type: "separator";
|
||||
visible?: ko.Observable<boolean>;
|
||||
}
|
||||
|
||||
export interface IToggle {
|
||||
type: "toggle";
|
||||
title: string;
|
||||
displayName: string;
|
||||
checkedTitle: string;
|
||||
checkedDisplayName: string;
|
||||
id: string;
|
||||
checked: ko.Observable<boolean>;
|
||||
enabled: ko.Observable<boolean>;
|
||||
visible?: ko.Observable<boolean>;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export interface IAction {
|
||||
type: "action";
|
||||
title: string;
|
||||
displayName: string;
|
||||
id: string;
|
||||
action: () => any;
|
||||
enabled: ko.Subscribable<boolean>;
|
||||
visible?: ko.Observable<boolean>;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export type IActionConfigItem = ISeperator | IAction | IToggle | IDropdown;
|
||||
|
||||
export default IToolbarDropDown;
|
||||
@@ -1,12 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import IToolbarAction from "./IToolbarAction";
|
||||
import IToolbarToggle from "./IToolbarToggle";
|
||||
import IToolbarSeperator from "./IToolbarSeperator";
|
||||
import IToolbarDropDown from "./IToolbarDropDown";
|
||||
|
||||
type IToolbarItem = IToolbarAction | IToolbarToggle | IToolbarSeperator | IToolbarDropDown;
|
||||
|
||||
export default IToolbarItem;
|
||||
@@ -1,10 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
interface IToolbarSeperator {
|
||||
type: "separator";
|
||||
visible: ko.Observable<boolean>;
|
||||
}
|
||||
|
||||
export default IToolbarSeperator;
|
||||
@@ -1,12 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import IToolbarDisplayable from "./IToolbarDisplayable";
|
||||
|
||||
interface IToolbarToggle extends IToolbarDisplayable {
|
||||
type: "toggle";
|
||||
checked: ko.Observable<boolean>;
|
||||
toggle: () => void;
|
||||
}
|
||||
export default IToolbarToggle;
|
||||
@@ -1,58 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
var keyCodes = {
|
||||
RightClick: 3,
|
||||
Enter: 13,
|
||||
Esc: 27,
|
||||
Tab: 9,
|
||||
LeftArrow: 37,
|
||||
UpArrow: 38,
|
||||
RightArrow: 39,
|
||||
DownArrow: 40,
|
||||
Delete: 46,
|
||||
A: 65,
|
||||
B: 66,
|
||||
C: 67,
|
||||
D: 68,
|
||||
E: 69,
|
||||
F: 70,
|
||||
G: 71,
|
||||
H: 72,
|
||||
I: 73,
|
||||
J: 74,
|
||||
K: 75,
|
||||
L: 76,
|
||||
M: 77,
|
||||
N: 78,
|
||||
O: 79,
|
||||
P: 80,
|
||||
Q: 81,
|
||||
R: 82,
|
||||
S: 83,
|
||||
T: 84,
|
||||
U: 85,
|
||||
V: 86,
|
||||
W: 87,
|
||||
X: 88,
|
||||
Y: 89,
|
||||
Z: 90,
|
||||
Period: 190,
|
||||
DecimalPoint: 110,
|
||||
F1: 112,
|
||||
F2: 113,
|
||||
F3: 114,
|
||||
F4: 115,
|
||||
F5: 116,
|
||||
F6: 117,
|
||||
F7: 118,
|
||||
F8: 119,
|
||||
F9: 120,
|
||||
F10: 121,
|
||||
F11: 122,
|
||||
F12: 123,
|
||||
Dash: 189
|
||||
};
|
||||
|
||||
export default keyCodes;
|
||||
@@ -1,145 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
import { IDropdown } from "./IToolbarDropDown";
|
||||
import { IActionConfigItem } from "./IToolbarDropDown";
|
||||
import IToolbarItem from "./IToolbarItem";
|
||||
|
||||
import * as ko from "knockout";
|
||||
import ToolbarDropDown from "./ToolbarDropDown";
|
||||
import ToolbarAction from "./ToolbarAction";
|
||||
import ToolbarToggle from "./ToolbarToggle";
|
||||
import template from "./toolbar.html";
|
||||
|
||||
export default class Toolbar {
|
||||
private _toolbarWidth = ko.observable<number>();
|
||||
private _actionConfigs: IActionConfigItem[];
|
||||
private _afterExecute: (id: string) => void;
|
||||
|
||||
private _hasFocus: boolean = false;
|
||||
private _focusedSubscription: ko.Subscription;
|
||||
|
||||
constructor(actionItems: IActionConfigItem[], afterExecute?: (id: string) => void) {
|
||||
this._actionConfigs = actionItems;
|
||||
this._afterExecute = afterExecute;
|
||||
this.toolbarItems.subscribe(this._focusFirstEnabledItem);
|
||||
|
||||
$(window).resize(() => {
|
||||
this._toolbarWidth($(".toolbar").width());
|
||||
});
|
||||
setTimeout(() => {
|
||||
this._toolbarWidth($(".toolbar").width());
|
||||
}, 500);
|
||||
}
|
||||
|
||||
public toolbarItems: ko.PureComputed<IToolbarItem[]> = ko.pureComputed(() => {
|
||||
var remainingToolbarSpace = this._toolbarWidth();
|
||||
var toolbarItems: IToolbarItem[] = [];
|
||||
|
||||
var moreItem: IDropdown = {
|
||||
type: "dropdown",
|
||||
title: "More",
|
||||
displayName: "More",
|
||||
id: "more-actions-toggle",
|
||||
enabled: ko.observable(true),
|
||||
visible: ko.observable(true),
|
||||
icon: "images/ASX_More.svg",
|
||||
subgroup: []
|
||||
};
|
||||
|
||||
var showHasMoreItem = false;
|
||||
var addSeparator = false;
|
||||
this._actionConfigs.forEach(actionConfig => {
|
||||
if (actionConfig.type === "separator") {
|
||||
addSeparator = true;
|
||||
} else if (remainingToolbarSpace / 60 > 2) {
|
||||
if (addSeparator) {
|
||||
addSeparator = false;
|
||||
toolbarItems.push(Toolbar._createToolbarItemFromConfig({ type: "separator" }));
|
||||
remainingToolbarSpace -= 10;
|
||||
}
|
||||
|
||||
toolbarItems.push(Toolbar._createToolbarItemFromConfig(actionConfig));
|
||||
remainingToolbarSpace -= 60;
|
||||
} else {
|
||||
showHasMoreItem = true;
|
||||
if (addSeparator) {
|
||||
addSeparator = false;
|
||||
moreItem.subgroup.push({
|
||||
type: "separator"
|
||||
});
|
||||
}
|
||||
|
||||
if (!!actionConfig) {
|
||||
moreItem.subgroup.push(actionConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (showHasMoreItem) {
|
||||
toolbarItems.push(
|
||||
Toolbar._createToolbarItemFromConfig({ type: "separator" }),
|
||||
Toolbar._createToolbarItemFromConfig(moreItem)
|
||||
);
|
||||
}
|
||||
|
||||
return toolbarItems;
|
||||
});
|
||||
|
||||
public focus() {
|
||||
this._hasFocus = true;
|
||||
this._focusFirstEnabledItem(this.toolbarItems());
|
||||
}
|
||||
|
||||
private _focusFirstEnabledItem = (items: IToolbarItem[]) => {
|
||||
if (!!this._focusedSubscription) {
|
||||
// no memory leaks! :D
|
||||
this._focusedSubscription.dispose();
|
||||
}
|
||||
if (this._hasFocus) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].type !== "separator" && (<any>items[i]).enabled()) {
|
||||
(<any>items[i]).focused(true);
|
||||
this._focusedSubscription = (<any>items[i]).focused.subscribe((newValue: any) => {
|
||||
if (!newValue) {
|
||||
this._hasFocus = false;
|
||||
this._focusedSubscription.dispose();
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static _createToolbarItemFromConfig(
|
||||
configItem: IActionConfigItem,
|
||||
afterExecute?: (id: string) => void
|
||||
): IToolbarItem {
|
||||
switch (configItem.type) {
|
||||
case "dropdown":
|
||||
return new ToolbarDropDown(configItem, afterExecute);
|
||||
case "action":
|
||||
return new ToolbarAction(configItem, afterExecute);
|
||||
case "toggle":
|
||||
return new ToolbarToggle(configItem, afterExecute);
|
||||
case "separator":
|
||||
return {
|
||||
type: "separator",
|
||||
visible: ko.observable(true)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for ko component registration
|
||||
*/
|
||||
export class ToolbarComponent {
|
||||
constructor() {
|
||||
return {
|
||||
viewModel: Toolbar,
|
||||
template
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import * as ko from "knockout";
|
||||
import { IAction } from "./IToolbarDropDown";
|
||||
import IToolbarAction from "./IToolbarAction";
|
||||
import KeyCodes from "./KeyCodes";
|
||||
import Utilities from "./Utilities";
|
||||
|
||||
export default class ToolbarAction implements IToolbarAction {
|
||||
public type: "action" = "action";
|
||||
public id: string;
|
||||
public icon: string;
|
||||
public title: ko.Observable<string>;
|
||||
public displayName: ko.Observable<string>;
|
||||
public enabled: ko.Subscribable<boolean>;
|
||||
public visible: ko.Observable<boolean>;
|
||||
public focused: ko.Observable<boolean>;
|
||||
public action: () => void;
|
||||
private _afterExecute: (id: string) => void;
|
||||
|
||||
constructor(actionItem: IAction, afterExecute?: (id: string) => void) {
|
||||
this.action = actionItem.action;
|
||||
this.title = ko.observable(actionItem.title);
|
||||
this.displayName = ko.observable(actionItem.displayName);
|
||||
this.id = actionItem.id;
|
||||
this.enabled = actionItem.enabled;
|
||||
this.visible = actionItem.visible ? actionItem.visible : ko.observable(true);
|
||||
this.focused = ko.observable(false);
|
||||
this.icon = actionItem.icon;
|
||||
this._afterExecute = afterExecute;
|
||||
}
|
||||
|
||||
private _executeAction = () => {
|
||||
this.action();
|
||||
if (!!this._afterExecute) {
|
||||
this._afterExecute(this.id);
|
||||
}
|
||||
};
|
||||
|
||||
public mouseDown = (data: any, event: MouseEvent): boolean => {
|
||||
this._executeAction();
|
||||
return false;
|
||||
};
|
||||
|
||||
public keyUp = (data: any, event: KeyboardEvent): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
||||
this._executeAction();
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return !handled;
|
||||
};
|
||||
|
||||
public keyDown = (data: any, event: KeyboardEvent): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!handled) {
|
||||
// Reset color if [shift-] tabbing, 'up/down arrowing', or 'esc'-aping away from button while holding down 'enter'
|
||||
Utilities.onKeys(
|
||||
event,
|
||||
[KeyCodes.Tab, KeyCodes.UpArrow, KeyCodes.DownArrow, KeyCodes.Esc],
|
||||
($sourceElement: JQuery) => {
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return !handled;
|
||||
};
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import * as ko from "knockout";
|
||||
import { IDropdown } from "./IToolbarDropDown";
|
||||
import { IActionConfigItem } from "./IToolbarDropDown";
|
||||
import IToolbarDropDown from "./IToolbarDropDown";
|
||||
import KeyCodes from "./KeyCodes";
|
||||
import Utilities from "./Utilities";
|
||||
|
||||
interface IMenuItem {
|
||||
id?: string;
|
||||
type: "normal" | "separator" | "submenu";
|
||||
label?: string;
|
||||
enabled?: boolean;
|
||||
visible?: boolean;
|
||||
submenu?: IMenuItem[];
|
||||
}
|
||||
|
||||
export default class ToolbarDropDown implements IToolbarDropDown {
|
||||
public type: "dropdown" = "dropdown";
|
||||
public title: ko.Observable<string>;
|
||||
public displayName: ko.Observable<string>;
|
||||
public id: string;
|
||||
public enabled: ko.Observable<boolean>;
|
||||
public visible: ko.Observable<boolean>;
|
||||
public focused: ko.Observable<boolean>;
|
||||
public icon: string;
|
||||
public subgroup: IActionConfigItem[] = [];
|
||||
public expanded: ko.Observable<boolean> = ko.observable(false);
|
||||
private _afterExecute: (id: string) => void;
|
||||
|
||||
constructor(dropdown: IDropdown, afterExecute?: (id: string) => void) {
|
||||
this.subgroup = dropdown.subgroup;
|
||||
this.title = ko.observable(dropdown.title);
|
||||
this.displayName = ko.observable(dropdown.displayName);
|
||||
this.id = dropdown.id;
|
||||
this.enabled = dropdown.enabled;
|
||||
this.visible = dropdown.visible ? dropdown.visible : ko.observable(true);
|
||||
this.focused = ko.observable(false);
|
||||
this.icon = dropdown.icon;
|
||||
this._afterExecute = afterExecute;
|
||||
}
|
||||
|
||||
private static _convertToMenuItem = (
|
||||
actionConfigs: IActionConfigItem[],
|
||||
actionMap: { [id: string]: () => void } = {}
|
||||
): { menuItems: IMenuItem[]; actionMap: { [id: string]: () => void } } => {
|
||||
var returnValue = {
|
||||
menuItems: actionConfigs.map<IMenuItem>((actionConfig: IActionConfigItem, index, array) => {
|
||||
var menuItem: IMenuItem;
|
||||
switch (actionConfig.type) {
|
||||
case "action":
|
||||
menuItem = <IMenuItem>{
|
||||
id: actionConfig.id,
|
||||
type: "normal",
|
||||
label: actionConfig.displayName,
|
||||
enabled: actionConfig.enabled(),
|
||||
visible: actionConfig.visible ? actionConfig.visible() : true
|
||||
};
|
||||
actionMap[actionConfig.id] = actionConfig.action;
|
||||
break;
|
||||
case "dropdown":
|
||||
menuItem = <IMenuItem>{
|
||||
id: actionConfig.id,
|
||||
type: "submenu",
|
||||
label: actionConfig.displayName,
|
||||
enabled: actionConfig.enabled(),
|
||||
visible: actionConfig.visible ? actionConfig.visible() : true,
|
||||
submenu: ToolbarDropDown._convertToMenuItem(actionConfig.subgroup, actionMap).menuItems
|
||||
};
|
||||
break;
|
||||
case "toggle":
|
||||
menuItem = <IMenuItem>{
|
||||
id: actionConfig.id,
|
||||
type: "normal",
|
||||
label: actionConfig.checked() ? actionConfig.checkedDisplayName : actionConfig.displayName,
|
||||
enabled: actionConfig.enabled(),
|
||||
visible: actionConfig.visible ? actionConfig.visible() : true
|
||||
};
|
||||
actionMap[actionConfig.id] = () => {
|
||||
actionConfig.checked(!actionConfig.checked());
|
||||
};
|
||||
break;
|
||||
case "separator":
|
||||
menuItem = <IMenuItem>{
|
||||
type: "separator",
|
||||
visible: true
|
||||
};
|
||||
break;
|
||||
}
|
||||
return menuItem;
|
||||
}),
|
||||
actionMap: actionMap
|
||||
};
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
public open = () => {
|
||||
if (!!(<any>window).host) {
|
||||
var convertedMenuItem = ToolbarDropDown._convertToMenuItem(this.subgroup);
|
||||
|
||||
(<any>window).host
|
||||
.executeProviderOperation("MenuManager.showMenu", {
|
||||
iFrameStack: [`#${window.frameElement.id}`],
|
||||
anchor: `#${this.id}`,
|
||||
menuItems: convertedMenuItem.menuItems
|
||||
})
|
||||
.then((id?: string) => {
|
||||
if (!!id && !!convertedMenuItem.actionMap[id]) {
|
||||
convertedMenuItem.actionMap[id]();
|
||||
}
|
||||
});
|
||||
|
||||
if (!!this._afterExecute) {
|
||||
this._afterExecute(this.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public mouseDown = (data: any, event: MouseEvent): boolean => {
|
||||
this.open();
|
||||
return false;
|
||||
};
|
||||
|
||||
public keyUp = (data: any, event: KeyboardEvent): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
||||
this.open();
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return !handled;
|
||||
};
|
||||
|
||||
public keyDown = (data: any, event: KeyboardEvent): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!handled) {
|
||||
// Reset color if [shift-] tabbing, 'up/down arrowing', or 'esc'-aping away from button while holding down 'enter'
|
||||
Utilities.onKeys(
|
||||
event,
|
||||
[KeyCodes.Tab, KeyCodes.UpArrow, KeyCodes.DownArrow, KeyCodes.Esc],
|
||||
($sourceElement: JQuery) => {
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return !handled;
|
||||
};
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import * as ko from "knockout";
|
||||
import { IToggle } from "./IToolbarDropDown";
|
||||
import IToolbarToggle from "./IToolbarToggle";
|
||||
import KeyCodes from "./KeyCodes";
|
||||
import Utilities from "./Utilities";
|
||||
|
||||
export default class ToolbarToggle implements IToolbarToggle {
|
||||
public type: "toggle" = "toggle";
|
||||
public checked: ko.Observable<boolean>;
|
||||
public id: string;
|
||||
public enabled: ko.Observable<boolean>;
|
||||
public visible: ko.Observable<boolean>;
|
||||
public focused: ko.Observable<boolean>;
|
||||
public icon: string;
|
||||
|
||||
private _title: string;
|
||||
private _displayName: string;
|
||||
private _checkedTitle: string;
|
||||
private _checkedDisplayName: string;
|
||||
|
||||
private _afterExecute: (id: string) => void;
|
||||
|
||||
constructor(toggleItem: IToggle, afterExecute?: (id: string) => void) {
|
||||
this._title = toggleItem.title;
|
||||
this._displayName = toggleItem.displayName;
|
||||
this.id = toggleItem.id;
|
||||
this.enabled = toggleItem.enabled;
|
||||
this.visible = toggleItem.visible ? toggleItem.visible : ko.observable(true);
|
||||
this.focused = ko.observable(false);
|
||||
this.icon = toggleItem.icon;
|
||||
this.checked = toggleItem.checked;
|
||||
this._checkedTitle = toggleItem.checkedTitle;
|
||||
this._checkedDisplayName = toggleItem.checkedDisplayName;
|
||||
this._afterExecute = afterExecute;
|
||||
}
|
||||
|
||||
public title = ko.pureComputed(() => {
|
||||
if (this.checked()) {
|
||||
return this._checkedTitle;
|
||||
} else {
|
||||
return this._title;
|
||||
}
|
||||
});
|
||||
|
||||
public displayName = ko.pureComputed(() => {
|
||||
if (this.checked()) {
|
||||
return this._checkedDisplayName;
|
||||
} else {
|
||||
return this._displayName;
|
||||
}
|
||||
});
|
||||
|
||||
public toggle = () => {
|
||||
this.checked(!this.checked());
|
||||
|
||||
if (this.checked() && !!this._afterExecute) {
|
||||
this._afterExecute(this.id);
|
||||
}
|
||||
};
|
||||
|
||||
public mouseDown = (data: any, event: MouseEvent): boolean => {
|
||||
this.toggle();
|
||||
return false;
|
||||
};
|
||||
|
||||
public keyUp = (data: any, event: KeyboardEvent): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
||||
this.toggle();
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return !handled;
|
||||
};
|
||||
|
||||
public keyDown = (data: any, event: KeyboardEvent): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!handled) {
|
||||
// Reset color if [shift-] tabbing, 'up/down arrowing', or 'esc'-aping away from button while holding down 'enter'
|
||||
Utilities.onKeys(
|
||||
event,
|
||||
[KeyCodes.Tab, KeyCodes.UpArrow, KeyCodes.DownArrow, KeyCodes.Esc],
|
||||
($sourceElement: JQuery) => {
|
||||
if ($sourceElement.hasClass("active")) {
|
||||
$sourceElement.removeClass("active");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return !handled;
|
||||
};
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*!---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
import KeyCodes from "./KeyCodes";
|
||||
|
||||
export default class Utilities {
|
||||
/**
|
||||
* Executes an action on a keyboard event.
|
||||
* Modifiers: ctrlKey - control/command key, shiftKey - shift key, altKey - alt/option key;
|
||||
* pass on 'null' to ignore the modifier (default).
|
||||
*/
|
||||
public static onKey(
|
||||
event: any,
|
||||
eventKeyCode: number,
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
var source: any = event.target || event.srcElement,
|
||||
keyCode: number = event.keyCode,
|
||||
$sourceElement = $(source),
|
||||
handled: boolean = false;
|
||||
|
||||
if (
|
||||
$sourceElement.length &&
|
||||
keyCode === eventKeyCode &&
|
||||
$.isFunction(action) &&
|
||||
(metaKey === null || metaKey === event.metaKey) &&
|
||||
(shiftKey === null || shiftKey === event.shiftKey) &&
|
||||
(altKey === null || altKey === event.altKey)
|
||||
) {
|
||||
action($sourceElement);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on the first matched keyboard event.
|
||||
*/
|
||||
public static onKeys(
|
||||
event: any,
|
||||
eventKeyCodes: number[],
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
var handled: boolean = false,
|
||||
keyCount: number,
|
||||
i: number;
|
||||
|
||||
if ($.isArray(eventKeyCodes)) {
|
||||
keyCount = eventKeyCodes.length;
|
||||
|
||||
for (i = 0; i < keyCount; ++i) {
|
||||
handled = Utilities.onKey(event, eventKeyCodes[i], action, metaKey, shiftKey, altKey);
|
||||
|
||||
if (handled) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on an 'enter' keyboard event.
|
||||
*/
|
||||
public static onEnter(
|
||||
event: any,
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
return Utilities.onKey(event, KeyCodes.Enter, action, metaKey, shiftKey, altKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on a 'tab' keyboard event.
|
||||
*/
|
||||
public static onTab(
|
||||
event: any,
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
return Utilities.onKey(event, KeyCodes.Tab, action, metaKey, shiftKey, altKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on an 'Esc' keyboard event.
|
||||
*/
|
||||
public static onEsc(
|
||||
event: any,
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
return Utilities.onKey(event, KeyCodes.Esc, action, metaKey, shiftKey, altKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on an 'UpArrow' keyboard event.
|
||||
*/
|
||||
public static onUpArrow(
|
||||
event: any,
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
return Utilities.onKey(event, KeyCodes.UpArrow, action, metaKey, shiftKey, altKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on a 'DownArrow' keyboard event.
|
||||
*/
|
||||
public static onDownArrow(
|
||||
event: any,
|
||||
action: ($sourceElement: JQuery) => void,
|
||||
metaKey: boolean = null,
|
||||
shiftKey: boolean = null,
|
||||
altKey: boolean = null
|
||||
): boolean {
|
||||
return Utilities.onKey(event, KeyCodes.DownArrow, action, metaKey, shiftKey, altKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on a mouse event.
|
||||
*/
|
||||
public static onButton(event: any, eventButtonCode: number, action: ($sourceElement: JQuery) => void): boolean {
|
||||
var source: any = event.currentTarget;
|
||||
var buttonCode: number = event.button;
|
||||
var $sourceElement = $(source);
|
||||
var handled: boolean = false;
|
||||
|
||||
if ($sourceElement.length && buttonCode === eventButtonCode && $.isFunction(action)) {
|
||||
action($sourceElement);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action on a 'left' mouse event.
|
||||
*/
|
||||
public static onLeftButton(event: any, action: ($sourceElement: JQuery) => void): boolean {
|
||||
return Utilities.onButton(event, buttonCodes.Left, action);
|
||||
}
|
||||
}
|
||||
|
||||
var buttonCodes = {
|
||||
None: -1,
|
||||
Left: 0,
|
||||
Middle: 1,
|
||||
Right: 2
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
<div class="toolbar">
|
||||
<!-- ko template: { name: 'toolbarItemTemplate', foreach: toolbarItems } -->
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbarItemTemplate">
|
||||
<!-- ko if: type === "action" -->
|
||||
<div class="toolbar-group" data-bind="visible: visible">
|
||||
<button class="toolbar-group-button" data-bind="hasFocus: focused, attr: {id: id, title: title, 'aria-label': displayName}, event: { mousedown: mouseDown, keydown: keyDown, keyup: keyUp }, enable: enabled">
|
||||
<div class="toolbar-group-button-icon">
|
||||
<div class="toolbar_icon" data-bind="icon: icon"></div>
|
||||
</div>
|
||||
<span data-bind="text: displayName"></span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: type === "toggle" -->
|
||||
<div class="toolbar-group" data-bind="visible: visible">
|
||||
<button class="toolbar-group-button toggle-button" data-bind="hasFocus: focused, attr: {id: id, title: title}, event: { mousedown: mouseDown, keydown: keyDown, keyup: keyUp }, enable: enabled">
|
||||
<div class="toolbar-group-button-icon" data-bind="css: { 'toggle-checked': checked }">
|
||||
<div class="toolbar_icon" data-bind="icon: icon"></div>
|
||||
</div>
|
||||
<span data-bind="text: displayName"></span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: type === "dropdown" -->
|
||||
<div class="toolbar-group" data-bind="visible: visible">
|
||||
<div class="dropdown" data-bind="attr: {id: (id + '-dropdown')}">
|
||||
<button role="menu" class="toolbar-group-button" data-bind="hasFocus: focused, attr: {id: id, title: title, 'aria-label': displayName}, event: { mousedown: mouseDown, keydown: keyDown, keyup: keyUp }, enable: enabled">
|
||||
<div class="toolbar-group-button-icon">
|
||||
<div class="toolbar_icon" data-bind="icon: icon"></div>
|
||||
</div>
|
||||
<span data-bind="text: displayName"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: type === "separator" -->
|
||||
<div class="toolbar-group vertical-separator" data-bind="visible: visible"></div>
|
||||
<!-- /ko -->
|
||||
</script>
|
||||
Reference in New Issue
Block a user