mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
Remove old resource tree and cleanup (#28)
* Remove old resource tree and its various components * Fix stored procedure, udf, trigger not always deleting when context menu option chosen * Reformat and fix eslint warnings * Remove CommandButtonOptions
This commit is contained in:
@@ -1,200 +0,0 @@
|
||||
@import "../../../../less/Common/Constants";
|
||||
|
||||
@ButtonIconSize: 18px;
|
||||
|
||||
.commandBar {
|
||||
padding-left: @DefaultSpace;
|
||||
border-bottom: @ButtonBorderWidth solid @BaseMedium;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: @topcommandbarheight;
|
||||
|
||||
.staticCommands {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.overflowCommands {
|
||||
display:flex;
|
||||
flex: 1 0 auto;
|
||||
|
||||
.visibleCommands {
|
||||
display: inline-flex;
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.partialSplitterContainer {
|
||||
padding: @SmallSpace @DefaultSpace @SmallSpace @SmallSpace;
|
||||
.flex-display();
|
||||
}
|
||||
}
|
||||
|
||||
.commandExpand {
|
||||
border: none;
|
||||
padding: 0px;
|
||||
direction: rtl;
|
||||
|
||||
&:hover {
|
||||
.hover();
|
||||
cursor: pointer;
|
||||
& > .commandDropdownContainer {
|
||||
display: block !important; // TODO: Remove after reusing KO mouseover and mouseout event handlers
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
.focus();
|
||||
}
|
||||
|
||||
.commandDropdownLauncher {
|
||||
direction: ltr;
|
||||
padding-top: @SmallSpace;
|
||||
|
||||
.commandIcon {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
.commandBarEllipses {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hiddenCommandsContainer > .commandDropdownLauncher {
|
||||
padding: 0px @DefaultSpace;
|
||||
}
|
||||
|
||||
.commandDropdownContainer {
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
direction: ltr;
|
||||
position: absolute;
|
||||
width: fit-content;
|
||||
padding: 0px;
|
||||
background-color: @BaseLight;
|
||||
box-shadow: 1px 2px 6px @BaseMediumHigh, -2px 2px 6px @BaseMediumHigh;
|
||||
|
||||
.commandDropdown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.feedbackButton {
|
||||
margin-right: @LargeSpace;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
command-button,
|
||||
.commandButtonReact {
|
||||
display: inline-flex;
|
||||
.commandButtonComponent {
|
||||
width: 100%;
|
||||
color: @BaseHigh;
|
||||
background-color: transparent;
|
||||
text-decoration: none;
|
||||
border: @ButtonBorderWidth solid transparent;
|
||||
.flex-display();
|
||||
|
||||
&:hover:not(.commandDisabled) {
|
||||
cursor: pointer;
|
||||
.hover();
|
||||
}
|
||||
|
||||
&:active:not(.commandDisabled) {
|
||||
border: @ButtonBorderWidth dashed @AccentMedium;
|
||||
.active();
|
||||
}
|
||||
|
||||
&:focus:not(.commandDisabled) {
|
||||
border: @ButtonBorderWidth dashed @AccentMedium;
|
||||
}
|
||||
|
||||
.commandContent {
|
||||
padding: @DefaultSpace @DefaultSpace @DefaultSpace;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.commandIcon {
|
||||
margin: 0 @SmallSpace 0 0;
|
||||
vertical-align: text-top;
|
||||
width: @ButtonIconSize;
|
||||
height: @ButtonIconSize;
|
||||
}
|
||||
|
||||
.commandLabel {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.commandContent .hasHiddenItems {
|
||||
padding-right: @SmallSpace;
|
||||
}
|
||||
}
|
||||
|
||||
.commandButtonComponent.commandDisabled {
|
||||
color: @BaseMediumHigh;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.commandExpand {
|
||||
padding-top: @SmallSpace;
|
||||
padding-bottom: @SmallSpace;
|
||||
&:hover {
|
||||
.hover();
|
||||
& > .commandDropdownContainer {
|
||||
display: block !important; // TODO: Remove after reusing KO mouseover and mouseout event handlers
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
.focus();
|
||||
}
|
||||
|
||||
.commandDropdownLauncher {
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
|
||||
.commandButtonComponent {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.expandDropdown {
|
||||
padding: @SmallSpace;
|
||||
|
||||
img {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.partialSplitter {
|
||||
margin: @SmallSpace 0px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.commandButtonComponent[tabindex]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.selectedButton {
|
||||
background-color: @AccentLow;
|
||||
outline: none
|
||||
}
|
||||
}
|
||||
|
||||
.partialSplitter {
|
||||
border-left: @ButtonBorderWidth solid @BaseMediumHigh;
|
||||
}
|
||||
|
||||
.commandDropdown .commandButtonComponent {
|
||||
padding-left: 0px;
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
import * as ko from "knockout";
|
||||
import { CommandButtonComponent, CommandButtonOptions } from "./CommandButton";
|
||||
|
||||
const mockLabel = "Some Label";
|
||||
const id = "Some id";
|
||||
|
||||
function buildComponent(buttonOptions: any) {
|
||||
document.body.innerHTML = CommandButtonComponent.template as any;
|
||||
const vm = new CommandButtonComponent.viewModel(buttonOptions);
|
||||
ko.applyBindings(vm);
|
||||
}
|
||||
|
||||
describe("Command Button Component", () => {
|
||||
function buildButtonOptions(
|
||||
onClick: () => void,
|
||||
id?: string,
|
||||
label?: string,
|
||||
disabled?: ko.Observable<boolean>,
|
||||
visible?: ko.Observable<boolean>,
|
||||
tooltipText?: string
|
||||
): { buttonProps: CommandButtonOptions } {
|
||||
return {
|
||||
buttonProps: {
|
||||
iconSrc: "images/AddCollection.svg",
|
||||
id: id,
|
||||
commandButtonLabel: label || mockLabel,
|
||||
disabled: disabled,
|
||||
visible: visible,
|
||||
tooltipText: tooltipText,
|
||||
hasPopup: false,
|
||||
onCommandClick: onClick
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function buildSplitterButtonOptions(
|
||||
onClick: () => void,
|
||||
id?: string,
|
||||
label?: string,
|
||||
disabled?: ko.Observable<boolean>,
|
||||
visible?: ko.Observable<boolean>,
|
||||
tooltipText?: string
|
||||
): { buttonProps: CommandButtonOptions } {
|
||||
const child: CommandButtonOptions = {
|
||||
iconSrc: "images/settings_15x15.svg",
|
||||
id: id,
|
||||
commandButtonLabel: label || mockLabel,
|
||||
disabled: disabled,
|
||||
visible: visible,
|
||||
tooltipText: tooltipText,
|
||||
hasPopup: false,
|
||||
onCommandClick: onClick
|
||||
};
|
||||
|
||||
return {
|
||||
buttonProps: {
|
||||
iconSrc: "images/AddCollection.svg",
|
||||
id: id,
|
||||
commandButtonLabel: label || mockLabel,
|
||||
disabled: disabled,
|
||||
visible: visible,
|
||||
tooltipText: tooltipText,
|
||||
hasPopup: false,
|
||||
onCommandClick: onClick,
|
||||
children: [child]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
ko.cleanNode(document);
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
describe("Rendering", () => {
|
||||
it("should display button label", () => {
|
||||
const buttonOptions = buildButtonOptions(() => {
|
||||
/** do nothing **/
|
||||
}, mockLabel);
|
||||
buildComponent(buttonOptions);
|
||||
expect(document.getElementsByClassName("commandButtonComponent").item(0).textContent).toContain(mockLabel);
|
||||
});
|
||||
|
||||
it("should display button icon", () => {
|
||||
const buttonOptions = buildButtonOptions(() => {
|
||||
/** do nothing **/
|
||||
});
|
||||
buildComponent(buttonOptions);
|
||||
expect(
|
||||
document
|
||||
.getElementsByTagName("img")
|
||||
.item(0)
|
||||
.getAttribute("src")
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Behavior", () => {
|
||||
let clickSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
clickSpy = jasmine.createSpy("Command button click spy");
|
||||
});
|
||||
|
||||
it("should trigger the click handler when the command button is clicked", () => {
|
||||
const buttonOptions = buildButtonOptions(() => clickSpy());
|
||||
buildComponent(buttonOptions);
|
||||
document
|
||||
.getElementsByClassName("commandButtonComponent")
|
||||
.item(0)
|
||||
.dispatchEvent(new Event("click"));
|
||||
expect(clickSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not trigger the click handler when command button is disabled", () => {
|
||||
const buttonOptions = buildButtonOptions(() => clickSpy(), id, mockLabel, ko.observable(true));
|
||||
buildComponent(buttonOptions);
|
||||
document
|
||||
.getElementsByClassName("commandButtonComponent")
|
||||
.item(0)
|
||||
.dispatchEvent(new Event("click"));
|
||||
expect(clickSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not have a dropdown if it has no child", () => {
|
||||
const buttonOptions = buildButtonOptions(() => clickSpy(), id, mockLabel, ko.observable(true));
|
||||
buildComponent(buttonOptions);
|
||||
const dropdownSize = document.getElementsByClassName("commandExpand").length;
|
||||
expect(dropdownSize).toBe(0);
|
||||
});
|
||||
|
||||
it("should have a dropdown if it has a child", () => {
|
||||
const buttonOptions = buildSplitterButtonOptions(() => clickSpy(), id, mockLabel, ko.observable(true));
|
||||
buildComponent(buttonOptions);
|
||||
const dropdownSize = document.getElementsByClassName("commandExpand").length;
|
||||
expect(dropdownSize).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,191 +0,0 @@
|
||||
/**
|
||||
* How to use this component:
|
||||
*
|
||||
* In your html markup, use:
|
||||
* <command-button params="{
|
||||
* iconSrc: '/icon/example/src/',
|
||||
* onCommandClick: () => { doSomething },
|
||||
* commandButtonLabel: 'Some Label'
|
||||
* disabled: true/false
|
||||
* }">
|
||||
* </command-button>
|
||||
*
|
||||
*/
|
||||
|
||||
import * as ko from "knockout";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import { WaitsForTemplateViewModel } from "../../WaitsForTemplateViewModel";
|
||||
import { KeyCodes } from "../../../Common/Constants";
|
||||
|
||||
import TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import template from "./command-button.html";
|
||||
|
||||
/**
|
||||
* Options for this component
|
||||
*/
|
||||
export interface CommandButtonOptions {
|
||||
/**
|
||||
* image source for the button icon
|
||||
*/
|
||||
iconSrc: string;
|
||||
|
||||
/**
|
||||
* Id for the button icon
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Click handler for command button click
|
||||
*/
|
||||
onCommandClick: () => void;
|
||||
|
||||
/**
|
||||
* Label for the button
|
||||
*/
|
||||
commandButtonLabel: string | ko.Observable<string>;
|
||||
|
||||
/**
|
||||
* True if this button opens a tab or pane, false otherwise.
|
||||
*/
|
||||
hasPopup: boolean;
|
||||
|
||||
/**
|
||||
* Enabled/disabled state of command button
|
||||
*/
|
||||
disabled?: ko.Subscribable<boolean>;
|
||||
|
||||
/**
|
||||
* Visibility/Invisibility of the button
|
||||
*/
|
||||
visible?: ko.Subscribable<boolean>;
|
||||
|
||||
/**
|
||||
* Whether or not the button should have the 'selectedButton' styling
|
||||
*/
|
||||
isSelected?: ko.Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Text to displayed in the tooltip on hover
|
||||
*/
|
||||
tooltipText?: string | ko.Observable<string>;
|
||||
|
||||
/**
|
||||
* Callback triggered when the template is bound to the component
|
||||
*/
|
||||
onTemplateReady?: () => void;
|
||||
|
||||
/**
|
||||
* tabindex for the command button
|
||||
*/
|
||||
tabIndex?: ko.Observable<number>;
|
||||
|
||||
/**
|
||||
* Childrens command buttons to hide in the dropdown
|
||||
*/
|
||||
children?: CommandButtonOptions[];
|
||||
}
|
||||
|
||||
export class CommandButtonViewModel extends WaitsForTemplateViewModel implements ViewModels.CommandButton {
|
||||
public commandClickCallback: () => void;
|
||||
public commandButtonId: string;
|
||||
public disabled: ko.Subscribable<boolean>;
|
||||
public visible: ko.Subscribable<boolean>;
|
||||
public isSelected: ko.Observable<boolean>;
|
||||
public iconSrc: string;
|
||||
public commandButtonLabel: ko.Observable<string>;
|
||||
public tooltipText: ko.Observable<string>;
|
||||
public tabIndex: ko.Observable<number>;
|
||||
public isTemplateReady: ko.Observable<boolean>;
|
||||
public hasPopup: boolean;
|
||||
public children: ko.ObservableArray<CommandButtonOptions>;
|
||||
|
||||
public constructor(options: { buttonProps: CommandButtonOptions }) {
|
||||
super();
|
||||
const props = options.buttonProps;
|
||||
const commandButtonLabel = props.commandButtonLabel;
|
||||
const tooltipText = props.tooltipText;
|
||||
this.commandButtonLabel =
|
||||
typeof commandButtonLabel === "string" ? ko.observable<string>(commandButtonLabel) : commandButtonLabel;
|
||||
this.commandButtonId = props.id;
|
||||
this.disabled = props.disabled || ko.observable(false);
|
||||
this.visible = props.visible || ko.observable(true);
|
||||
this.isSelected = props.isSelected || ko.observable(false);
|
||||
this.iconSrc = props.iconSrc;
|
||||
this.tabIndex = props.tabIndex || ko.observable(0);
|
||||
this.hasPopup = props.hasPopup;
|
||||
this.children = ko.observableArray(props.children);
|
||||
|
||||
super.onTemplateReady((isTemplateReady: boolean) => {
|
||||
if (isTemplateReady && props.onTemplateReady) {
|
||||
props.onTemplateReady();
|
||||
}
|
||||
});
|
||||
|
||||
if (tooltipText && typeof tooltipText === "string") {
|
||||
this.tooltipText = ko.observable<string>(tooltipText);
|
||||
} else if (tooltipText && typeof tooltipText === "function") {
|
||||
this.tooltipText = tooltipText;
|
||||
} else {
|
||||
this.tooltipText = this.commandButtonLabel;
|
||||
}
|
||||
|
||||
this.commandClickCallback = () => {
|
||||
if (this.disabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const el = document.querySelector(".commandDropdownContainer") as HTMLElement;
|
||||
if (el) {
|
||||
el.style.display = "none";
|
||||
}
|
||||
props.onCommandClick();
|
||||
TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, {
|
||||
commandButtonClicked: this.commandButtonLabel
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
public onKeyPress(source: any, event: KeyboardEvent): boolean {
|
||||
if (event.keyCode === KeyCodes.Space || event.keyCode === KeyCodes.Enter) {
|
||||
this.commandClickCallback && this.commandClickCallback();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onLauncherKeyDown(source: any, event: KeyboardEvent): boolean {
|
||||
// TODO: Convert JQuery code into Knockout
|
||||
if (event.keyCode === KeyCodes.DownArrow) {
|
||||
$(event.target)
|
||||
.parent()
|
||||
.siblings()
|
||||
.children(".commandExpand")
|
||||
.children(".commandDropdownContainer")
|
||||
.hide();
|
||||
$(event.target)
|
||||
.children(".commandDropdownContainer")
|
||||
.show()
|
||||
.focus();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
if (event.keyCode === KeyCodes.UpArrow) {
|
||||
$(event.target)
|
||||
.children(".commandDropdownContainer")
|
||||
.hide();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for ko component registration
|
||||
*/
|
||||
export const CommandButtonComponent = {
|
||||
viewModel: CommandButtonViewModel,
|
||||
template
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
<span
|
||||
class="commandButtonComponent"
|
||||
role="menuitem"
|
||||
tabindex="0"
|
||||
data-bind="setTemplateReady: true,
|
||||
css: {
|
||||
commandDisabled: disabled,
|
||||
selectedButton: isSelected
|
||||
},
|
||||
event: {
|
||||
keypress: onKeyPress
|
||||
},
|
||||
attr: {
|
||||
title: tooltipText,
|
||||
id: commandButtonId,
|
||||
tabindex: tabIndex ,
|
||||
'aria-disabled': disabled,
|
||||
'aria-haspopup': hasPopup
|
||||
},
|
||||
click: commandClickCallback,
|
||||
visible: visible"
|
||||
>
|
||||
<div class="commandContent" data-bind="css: { hasHiddenItems: children().length > 0 }">
|
||||
<img class="commandIcon" data-bind="attr: {src: iconSrc, alt: commandButtonLabel}" />
|
||||
<span class="commandLabel" data-bind="text: commandButtonLabel"></span>
|
||||
</div>
|
||||
</span>
|
||||
<!-- ko if: children().length > 0 -->
|
||||
<div class="commandExpand" tabindex="0" data-bind="visible: visible, event: { keydown: onLauncherKeyDown }">
|
||||
<div class="commandDropdownLauncher">
|
||||
<span class="partialSplitter"></span>
|
||||
<span class="expandDropdown"> <img src="/QueryBuilder/CollapseChevronDown_16x.png" /> </span>
|
||||
</div>
|
||||
<div class="commandDropdownContainer">
|
||||
<div class="commandDropdown" data-bind="foreach: children">
|
||||
<command-button params="{buttonProps: $data}"></command-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
Reference in New Issue
Block a user