Prettier 2.0 (#393)

This commit is contained in:
Steve Faulkner
2021-01-20 09:15:01 -06:00
committed by GitHub
parent c1937ca464
commit 4be53284b5
500 changed files with 41927 additions and 41838 deletions

View File

@@ -1,327 +1,327 @@
import QueryClauseViewModel from "./QueryClauseViewModel";
import * as Utilities from "../Utilities";
export default class ClauseGroup {
public isRootGroup: boolean;
public children = new Array();
public parentGroup: ClauseGroup;
private _id: string;
constructor(isRootGroup: boolean, parentGroup: ClauseGroup, id?: string) {
this.isRootGroup = isRootGroup;
this.parentGroup = parentGroup;
this._id = id ? id : Utilities.guid();
}
/**
* Flattens the clause tree into an array, depth-first, left to right.
*/
public flattenClauses(targetArray: ko.ObservableArray<QueryClauseViewModel>): void {
var tempArray = new Array<QueryClauseViewModel>();
this.flattenClausesImpl(this, tempArray);
targetArray.removeAll();
tempArray.forEach(element => {
targetArray.push(element);
});
}
public insertClauseBefore(newClause: QueryClauseViewModel, insertBefore?: QueryClauseViewModel): void {
if (!insertBefore) {
newClause.clauseGroup = this;
this.children.push(newClause);
} else {
var targetGroup = insertBefore.clauseGroup;
if (targetGroup) {
var insertBeforeIndex = targetGroup.children.indexOf(insertBefore);
newClause.clauseGroup = targetGroup;
targetGroup.children.splice(insertBeforeIndex, 0, newClause);
}
}
}
public deleteClause(clause: QueryClauseViewModel): void {
var targetGroup = clause.clauseGroup;
if (targetGroup) {
var index = targetGroup.children.indexOf(clause);
targetGroup.children.splice(index, 1);
clause.dispose();
if (targetGroup.children.length <= 1 && !targetGroup.isRootGroup) {
var parent = targetGroup.parentGroup;
var targetGroupIndex = parent.children.indexOf(targetGroup);
if (targetGroup.children.length === 1) {
var orphan = targetGroup.children.shift();
if (orphan instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>orphan).clauseGroup = parent;
} else if (orphan instanceof ClauseGroup) {
(<ClauseGroup>orphan).parentGroup = parent;
}
parent.children.splice(targetGroupIndex, 1, orphan);
} else {
parent.children.splice(targetGroupIndex, 1);
}
}
}
}
public removeAll(): void {
var allClauses: QueryClauseViewModel[] = new Array<QueryClauseViewModel>();
this.flattenClausesImpl(this, allClauses);
while (allClauses.length > 0) {
allClauses.shift().dispose();
}
this.children = new Array<any>();
}
/**
* Groups selected items. Returns True if a new group was created, otherwise False.
*/
public groupSelectedItems(): boolean {
// Find the selection start & end, also check for gaps between selected items (if found, cannot proceed).
var selection = this.getCheckedItemsInfo();
if (selection.canGroup) {
var newGroup = new ClauseGroup(false, this);
// Replace the selected items with the new group, and then move the selected items into the new group.
var groupedItems = this.children.splice(selection.begin, selection.end - selection.begin + 1, newGroup);
groupedItems &&
groupedItems.forEach(element => {
newGroup.children.push(element);
if (element instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>element).clauseGroup = newGroup;
} else if (element instanceof ClauseGroup) {
(<ClauseGroup>element).parentGroup = newGroup;
}
});
this.unselectAll();
return true;
}
return false;
}
public ungroup(): void {
if (this.isRootGroup) {
return;
}
var parentGroup = this.parentGroup;
var index = parentGroup.children.indexOf(this);
if (index >= 0) {
parentGroup.children.splice(index, 1);
var toPromote = this.children.splice(0, this.children.length);
// Move all children one level up.
toPromote &&
toPromote.forEach(element => {
if (element instanceof ClauseGroup) {
(<ClauseGroup>element).parentGroup = parentGroup;
} else if (element instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>element).clauseGroup = parentGroup;
}
parentGroup.children.splice(index, 0, element);
index++;
});
}
}
public canGroupSelectedItems(): boolean {
return this.getCheckedItemsInfo().canGroup;
}
public findDeepestGroupInChildren(skipIndex?: number): ClauseGroup {
var deepest: ClauseGroup = this;
var level: number = 0;
var func = (currentGroup: ClauseGroup): void => {
level++;
if (currentGroup.getCurrentGroupDepth() > deepest.getCurrentGroupDepth()) {
deepest = currentGroup;
}
for (var i = 0; i < currentGroup.children.length; i++) {
var currentItem = currentGroup.children[i];
if ((i !== skipIndex || level > 1) && currentItem instanceof ClauseGroup) {
func(currentItem);
}
}
level--;
};
func(this);
return deepest;
}
private getCheckedItemsInfo(): { canGroup: boolean; begin: number; end: number } {
var beginIndex = -1;
var endIndex = -1;
// In order to perform group, all selected items must be next to each other.
// If one or more items are not selected between the first and the last selected item, the gapFlag will be set to True, meaning cannot perform group.
var gapFlag = false;
var count = 0;
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
var subGroupSelectionState: { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean };
if (currentItem instanceof ClauseGroup) {
subGroupSelectionState = (<ClauseGroup>currentItem).getSelectionState();
if (subGroupSelectionState.partiallySelected) {
gapFlag = true;
break;
}
}
if (
beginIndex < 0 &&
endIndex < 0 &&
((currentItem instanceof QueryClauseViewModel && currentItem.checkedForGrouping.peek()) ||
(currentItem instanceof ClauseGroup && subGroupSelectionState.allSelected))
) {
beginIndex = i;
}
if (
beginIndex >= 0 &&
endIndex < 0 &&
((currentItem instanceof QueryClauseViewModel && !currentItem.checkedForGrouping.peek()) ||
(currentItem instanceof ClauseGroup && !subGroupSelectionState.allSelected))
) {
endIndex = i - 1;
}
if (beginIndex >= 0 && endIndex < 0) {
count++;
}
if (
beginIndex >= 0 &&
endIndex >= 0 &&
((currentItem instanceof QueryClauseViewModel && currentItem.checkedForGrouping.peek()) ||
(currentItem instanceof ClauseGroup && !subGroupSelectionState.nonSelected))
) {
gapFlag = true;
break;
}
}
if (!gapFlag && endIndex < 0) {
endIndex = this.children.length - 1;
}
return {
canGroup: beginIndex >= 0 && !gapFlag && count > 1,
begin: beginIndex,
end: endIndex
};
}
private getSelectionState(): { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean } {
var selectedCount = 0;
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
if (currentItem instanceof ClauseGroup && (<ClauseGroup>currentItem).getSelectionState().allSelected) {
selectedCount++;
}
if (
currentItem instanceof QueryClauseViewModel &&
(<QueryClauseViewModel>currentItem).checkedForGrouping.peek()
) {
selectedCount++;
}
}
return {
allSelected: selectedCount === this.children.length,
partiallySelected: selectedCount > 0 && selectedCount < this.children.length,
nonSelected: selectedCount === 0
};
}
private unselectAll(): void {
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
if (currentItem instanceof ClauseGroup) {
(<ClauseGroup>currentItem).unselectAll();
}
if (currentItem instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>currentItem).checkedForGrouping(false);
}
}
}
private flattenClausesImpl(queryGroup: ClauseGroup, targetArray: QueryClauseViewModel[]): void {
if (queryGroup.isRootGroup) {
targetArray.splice(0, targetArray.length);
}
for (var i = 0; i < queryGroup.children.length; i++) {
var currentItem = queryGroup.children[i];
if (currentItem instanceof ClauseGroup) {
this.flattenClausesImpl(currentItem, targetArray);
}
if (currentItem instanceof QueryClauseViewModel) {
targetArray.push(currentItem);
}
}
}
public getTreeDepth(): number {
var currentDepth = this.getCurrentGroupDepth();
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
if (currentItem instanceof ClauseGroup) {
var newDepth = (<ClauseGroup>currentItem).getTreeDepth();
if (newDepth > currentDepth) {
currentDepth = newDepth;
}
}
}
return currentDepth;
}
public getCurrentGroupDepth(): number {
var group = <ClauseGroup>this;
var depth = 0;
while (!group.isRootGroup) {
depth++;
group = group.parentGroup;
}
return depth;
}
public getId(): string {
return this._id;
}
}
import QueryClauseViewModel from "./QueryClauseViewModel";
import * as Utilities from "../Utilities";
export default class ClauseGroup {
public isRootGroup: boolean;
public children = new Array();
public parentGroup: ClauseGroup;
private _id: string;
constructor(isRootGroup: boolean, parentGroup: ClauseGroup, id?: string) {
this.isRootGroup = isRootGroup;
this.parentGroup = parentGroup;
this._id = id ? id : Utilities.guid();
}
/**
* Flattens the clause tree into an array, depth-first, left to right.
*/
public flattenClauses(targetArray: ko.ObservableArray<QueryClauseViewModel>): void {
var tempArray = new Array<QueryClauseViewModel>();
this.flattenClausesImpl(this, tempArray);
targetArray.removeAll();
tempArray.forEach((element) => {
targetArray.push(element);
});
}
public insertClauseBefore(newClause: QueryClauseViewModel, insertBefore?: QueryClauseViewModel): void {
if (!insertBefore) {
newClause.clauseGroup = this;
this.children.push(newClause);
} else {
var targetGroup = insertBefore.clauseGroup;
if (targetGroup) {
var insertBeforeIndex = targetGroup.children.indexOf(insertBefore);
newClause.clauseGroup = targetGroup;
targetGroup.children.splice(insertBeforeIndex, 0, newClause);
}
}
}
public deleteClause(clause: QueryClauseViewModel): void {
var targetGroup = clause.clauseGroup;
if (targetGroup) {
var index = targetGroup.children.indexOf(clause);
targetGroup.children.splice(index, 1);
clause.dispose();
if (targetGroup.children.length <= 1 && !targetGroup.isRootGroup) {
var parent = targetGroup.parentGroup;
var targetGroupIndex = parent.children.indexOf(targetGroup);
if (targetGroup.children.length === 1) {
var orphan = targetGroup.children.shift();
if (orphan instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>orphan).clauseGroup = parent;
} else if (orphan instanceof ClauseGroup) {
(<ClauseGroup>orphan).parentGroup = parent;
}
parent.children.splice(targetGroupIndex, 1, orphan);
} else {
parent.children.splice(targetGroupIndex, 1);
}
}
}
}
public removeAll(): void {
var allClauses: QueryClauseViewModel[] = new Array<QueryClauseViewModel>();
this.flattenClausesImpl(this, allClauses);
while (allClauses.length > 0) {
allClauses.shift().dispose();
}
this.children = new Array<any>();
}
/**
* Groups selected items. Returns True if a new group was created, otherwise False.
*/
public groupSelectedItems(): boolean {
// Find the selection start & end, also check for gaps between selected items (if found, cannot proceed).
var selection = this.getCheckedItemsInfo();
if (selection.canGroup) {
var newGroup = new ClauseGroup(false, this);
// Replace the selected items with the new group, and then move the selected items into the new group.
var groupedItems = this.children.splice(selection.begin, selection.end - selection.begin + 1, newGroup);
groupedItems &&
groupedItems.forEach((element) => {
newGroup.children.push(element);
if (element instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>element).clauseGroup = newGroup;
} else if (element instanceof ClauseGroup) {
(<ClauseGroup>element).parentGroup = newGroup;
}
});
this.unselectAll();
return true;
}
return false;
}
public ungroup(): void {
if (this.isRootGroup) {
return;
}
var parentGroup = this.parentGroup;
var index = parentGroup.children.indexOf(this);
if (index >= 0) {
parentGroup.children.splice(index, 1);
var toPromote = this.children.splice(0, this.children.length);
// Move all children one level up.
toPromote &&
toPromote.forEach((element) => {
if (element instanceof ClauseGroup) {
(<ClauseGroup>element).parentGroup = parentGroup;
} else if (element instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>element).clauseGroup = parentGroup;
}
parentGroup.children.splice(index, 0, element);
index++;
});
}
}
public canGroupSelectedItems(): boolean {
return this.getCheckedItemsInfo().canGroup;
}
public findDeepestGroupInChildren(skipIndex?: number): ClauseGroup {
var deepest: ClauseGroup = this;
var level: number = 0;
var func = (currentGroup: ClauseGroup): void => {
level++;
if (currentGroup.getCurrentGroupDepth() > deepest.getCurrentGroupDepth()) {
deepest = currentGroup;
}
for (var i = 0; i < currentGroup.children.length; i++) {
var currentItem = currentGroup.children[i];
if ((i !== skipIndex || level > 1) && currentItem instanceof ClauseGroup) {
func(currentItem);
}
}
level--;
};
func(this);
return deepest;
}
private getCheckedItemsInfo(): { canGroup: boolean; begin: number; end: number } {
var beginIndex = -1;
var endIndex = -1;
// In order to perform group, all selected items must be next to each other.
// If one or more items are not selected between the first and the last selected item, the gapFlag will be set to True, meaning cannot perform group.
var gapFlag = false;
var count = 0;
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
var subGroupSelectionState: { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean };
if (currentItem instanceof ClauseGroup) {
subGroupSelectionState = (<ClauseGroup>currentItem).getSelectionState();
if (subGroupSelectionState.partiallySelected) {
gapFlag = true;
break;
}
}
if (
beginIndex < 0 &&
endIndex < 0 &&
((currentItem instanceof QueryClauseViewModel && currentItem.checkedForGrouping.peek()) ||
(currentItem instanceof ClauseGroup && subGroupSelectionState.allSelected))
) {
beginIndex = i;
}
if (
beginIndex >= 0 &&
endIndex < 0 &&
((currentItem instanceof QueryClauseViewModel && !currentItem.checkedForGrouping.peek()) ||
(currentItem instanceof ClauseGroup && !subGroupSelectionState.allSelected))
) {
endIndex = i - 1;
}
if (beginIndex >= 0 && endIndex < 0) {
count++;
}
if (
beginIndex >= 0 &&
endIndex >= 0 &&
((currentItem instanceof QueryClauseViewModel && currentItem.checkedForGrouping.peek()) ||
(currentItem instanceof ClauseGroup && !subGroupSelectionState.nonSelected))
) {
gapFlag = true;
break;
}
}
if (!gapFlag && endIndex < 0) {
endIndex = this.children.length - 1;
}
return {
canGroup: beginIndex >= 0 && !gapFlag && count > 1,
begin: beginIndex,
end: endIndex,
};
}
private getSelectionState(): { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean } {
var selectedCount = 0;
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
if (currentItem instanceof ClauseGroup && (<ClauseGroup>currentItem).getSelectionState().allSelected) {
selectedCount++;
}
if (
currentItem instanceof QueryClauseViewModel &&
(<QueryClauseViewModel>currentItem).checkedForGrouping.peek()
) {
selectedCount++;
}
}
return {
allSelected: selectedCount === this.children.length,
partiallySelected: selectedCount > 0 && selectedCount < this.children.length,
nonSelected: selectedCount === 0,
};
}
private unselectAll(): void {
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
if (currentItem instanceof ClauseGroup) {
(<ClauseGroup>currentItem).unselectAll();
}
if (currentItem instanceof QueryClauseViewModel) {
(<QueryClauseViewModel>currentItem).checkedForGrouping(false);
}
}
}
private flattenClausesImpl(queryGroup: ClauseGroup, targetArray: QueryClauseViewModel[]): void {
if (queryGroup.isRootGroup) {
targetArray.splice(0, targetArray.length);
}
for (var i = 0; i < queryGroup.children.length; i++) {
var currentItem = queryGroup.children[i];
if (currentItem instanceof ClauseGroup) {
this.flattenClausesImpl(currentItem, targetArray);
}
if (currentItem instanceof QueryClauseViewModel) {
targetArray.push(currentItem);
}
}
}
public getTreeDepth(): number {
var currentDepth = this.getCurrentGroupDepth();
for (var i = 0; i < this.children.length; i++) {
var currentItem = this.children[i];
if (currentItem instanceof ClauseGroup) {
var newDepth = (<ClauseGroup>currentItem).getTreeDepth();
if (newDepth > currentDepth) {
currentDepth = newDepth;
}
}
}
return currentDepth;
}
public getCurrentGroupDepth(): number {
var group = <ClauseGroup>this;
var depth = 0;
while (!group.isRootGroup) {
depth++;
group = group.parentGroup;
}
return depth;
}
public getId(): string {
return this._id;
}
}

View File

@@ -1,49 +1,49 @@
import * as ko from "knockout";
import ClauseGroup from "./ClauseGroup";
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import * as Constants from "../Constants";
/**
* View model for showing group indicators on UI, contains information such as group color and border styles.
*/
export default class ClauseGroupViewModel {
public ungroupClausesLabel = "Ungroup clauses"; // localize
public backgroundColor: ko.Observable<string>;
public canUngroup: ko.Observable<boolean>;
public showTopBorder: ko.Observable<boolean>;
public showLeftBorder: ko.Observable<boolean>;
public showBottomBorder: ko.Observable<boolean>;
public depth: ko.Observable<number>; // for debugging purpose only, now showing the number on UI.
public borderBackgroundColor: ko.Observable<string>;
private _clauseGroup: ClauseGroup;
private _queryBuilderViewModel: QueryBuilderViewModel;
constructor(clauseGroup: ClauseGroup, canUngroup: boolean, queryBuilderViewModel: QueryBuilderViewModel) {
this._clauseGroup = clauseGroup;
this._queryBuilderViewModel = queryBuilderViewModel;
this.backgroundColor = ko.observable<string>(this.getGroupBackgroundColor(clauseGroup));
this.canUngroup = ko.observable<boolean>(canUngroup);
this.showTopBorder = ko.observable<boolean>(false);
this.showLeftBorder = ko.observable<boolean>(false);
this.showBottomBorder = ko.observable<boolean>(false);
this.depth = ko.observable<number>(clauseGroup.getCurrentGroupDepth());
this.borderBackgroundColor = ko.observable<string>("solid thin " + this.getGroupBackgroundColor(clauseGroup));
}
public ungroupClauses = (): void => {
this._clauseGroup.ungroup();
this._queryBuilderViewModel.updateClauseArray();
};
private getGroupBackgroundColor(group: ClauseGroup): string {
var colorCount = Constants.clauseGroupColors.length;
if (group.isRootGroup) {
return Constants.transparentColor;
} else {
return Constants.clauseGroupColors[group.getCurrentGroupDepth() % colorCount];
}
}
}
import * as ko from "knockout";
import ClauseGroup from "./ClauseGroup";
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import * as Constants from "../Constants";
/**
* View model for showing group indicators on UI, contains information such as group color and border styles.
*/
export default class ClauseGroupViewModel {
public ungroupClausesLabel = "Ungroup clauses"; // localize
public backgroundColor: ko.Observable<string>;
public canUngroup: ko.Observable<boolean>;
public showTopBorder: ko.Observable<boolean>;
public showLeftBorder: ko.Observable<boolean>;
public showBottomBorder: ko.Observable<boolean>;
public depth: ko.Observable<number>; // for debugging purpose only, now showing the number on UI.
public borderBackgroundColor: ko.Observable<string>;
private _clauseGroup: ClauseGroup;
private _queryBuilderViewModel: QueryBuilderViewModel;
constructor(clauseGroup: ClauseGroup, canUngroup: boolean, queryBuilderViewModel: QueryBuilderViewModel) {
this._clauseGroup = clauseGroup;
this._queryBuilderViewModel = queryBuilderViewModel;
this.backgroundColor = ko.observable<string>(this.getGroupBackgroundColor(clauseGroup));
this.canUngroup = ko.observable<boolean>(canUngroup);
this.showTopBorder = ko.observable<boolean>(false);
this.showLeftBorder = ko.observable<boolean>(false);
this.showBottomBorder = ko.observable<boolean>(false);
this.depth = ko.observable<number>(clauseGroup.getCurrentGroupDepth());
this.borderBackgroundColor = ko.observable<string>("solid thin " + this.getGroupBackgroundColor(clauseGroup));
}
public ungroupClauses = (): void => {
this._clauseGroup.ungroup();
this._queryBuilderViewModel.updateClauseArray();
};
private getGroupBackgroundColor(group: ClauseGroup): string {
var colorCount = Constants.clauseGroupColors.length;
if (group.isRootGroup) {
return Constants.transparentColor;
} else {
return Constants.clauseGroupColors[group.getCurrentGroupDepth() % colorCount];
}
}
}

View File

@@ -1,377 +1,377 @@
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import QueryClauseViewModel from "./QueryClauseViewModel";
import * as DateTimeUtilities from "./DateTimeUtilities";
/**
* Constants
*/
export var utc = "utc";
export var local = "local";
export interface ITimestampQuery {
queryType: string; // valid values are "last" and "range"
lastNumber: number; // number value of a custom timestamp using the last option
lastTimeUnit: string; // timeunit of a custom timestamp using the last option
startTime: string;
endTime: string;
timeZone: string; // timezone of custom range timestamp, valid values are "local" and "utc"
}
export interface ILastQuery {
lastNumber: number;
lastTimeUnit: string;
}
export enum TimeUnit {
Seconds,
Minutes,
Hours,
Days
}
/**
* Setting helpers
*/
export function addRangeTimestamp(
timestamp: ITimestampQuery,
queryBuilderViewModel: QueryBuilderViewModel,
queryClauseViewModel: QueryClauseViewModel
): void {
queryBuilderViewModel.addCustomRange(timestamp, queryClauseViewModel);
}
export function getDefaultStart(localTime: boolean, durationHours: number = 24): string {
var startTimestamp: string;
var utcNowString: string = new Date().toISOString();
var yesterday: Date = new Date(utcNowString);
yesterday.setHours(yesterday.getHours() - durationHours);
startTimestamp = yesterday.toISOString();
if (localTime) {
startTimestamp = localFromUtcDateString(startTimestamp);
}
return startTimestamp;
}
export function getDefaultEnd(localTime: boolean): string {
var endTimestamp: string;
var utcNowString: string = new Date().toISOString();
endTimestamp = utcNowString;
if (localTime) {
endTimestamp = localFromUtcDateString(endTimestamp);
}
return endTimestamp;
}
export function parseDate(dateString: string, isUTC: boolean): Date {
// TODO validate dateString
var date: Date = null;
if (dateString) {
try {
// Date string is assumed to be UTC in Storage Explorer Standalone.
// Behavior may vary in other browsers.
// Here's an example of how the string looks like "2015-10-24T21:44:12"
var millisecondTime = Date.parse(dateString),
parsed: Date = new Date(millisecondTime);
if (isUTC) {
date = parsed;
} else {
// Since we parsed in UTC, accessors are flipped - we get local time from the getUTC* group
// Reinstating, the date is parsed above as UTC, and here we are creating a new date object
// in local time.
var year = parsed.getUTCFullYear(),
month = parsed.getUTCMonth(),
day = parsed.getUTCDate(),
hours = parsed.getUTCHours(),
minutes = parsed.getUTCMinutes(),
seconds = parsed.getUTCSeconds(),
milliseconds = parsed.getUTCMilliseconds();
date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
}
} catch (error) {
//Debug.error("Error parsing date string: ", dateString, error);
}
}
return date;
}
export function utcFromLocalDateString(localDateString: string): string {
// TODO validate localDateString
var localDate = parseDate(localDateString, false),
utcDateString: string = null;
if (localDate) {
utcDateString = localDate.toISOString();
}
return utcDateString;
}
function padIfNeeded(value: number): string {
var padded: string = String(value);
if (0 <= value && value < 10) {
padded = "0" + padded;
}
return padded;
}
function toLocalDateString(date: Date): string {
var localDateString: string = null;
if (date) {
localDateString =
date.getFullYear() +
"-" +
padIfNeeded(date.getMonth() + 1) +
"-" +
padIfNeeded(date.getDate()) +
"T" +
padIfNeeded(date.getHours()) +
":" +
padIfNeeded(date.getMinutes()) +
":" +
padIfNeeded(date.getSeconds());
}
return localDateString;
}
export function localFromUtcDateString(utcDateString: string): string {
// TODO validate utcDateString
var utcDate: Date = parseDate(utcDateString, true),
localDateString: string = null;
if (utcDate) {
localDateString = toLocalDateString(utcDate);
}
return localDateString;
}
export function tryChangeTimestampTimeZone(koTimestamp: ko.Observable<string>, toUTC: boolean): void {
if (koTimestamp) {
var currentDateString: string = koTimestamp(),
newDateString: string;
if (currentDateString) {
if (toUTC) {
newDateString = utcFromLocalDateString(currentDateString);
// removing last character because cannot format it to html binding with the 'Z' at the end
newDateString = newDateString.substring(0, newDateString.length - 1);
} else {
newDateString = localFromUtcDateString(currentDateString);
}
// utcFromLocalDateString and localFromUtcDateString could return null if currentDateString is invalid.
// Hence, only set koTimestamp if newDateString is not null.
if (newDateString) {
koTimestamp(newDateString);
}
}
}
}
/**
* Input validation helpers
*/
export var noTooltip = "",
invalidStartTimeTooltip = "Please provide a valid start time.", // localize
invalidExpiryTimeRequiredTooltip = "Required field. Please provide a valid expiry time.", // localize
invalidExpiryTimeGreaterThanStartTimeTooltip = "The expiry time must be greater than the start time."; // localize
export function isDateString(dateString: string): boolean {
var success: boolean = false;
if (dateString) {
var date: number = Date.parse(dateString);
success = $.isNumeric(date);
}
return success;
}
// Is date string and earlier than expiry time; or is empty
// export function isInvalidStartTimeInput(startTimestamp: string, expiryTimestamp: string, isUTC: boolean): DialogsCommon.IValidationResult {
// var tooltip: string = noTooltip,
// isValid: boolean = isDateString(startTimestamp),
// startDate: Date,
// expiryDate: Date;
// if (!isValid) {
// isValid = (startTimestamp === "");
// }
// if (!isValid) {
// tooltip = invalidStartTimeTooltip;
// }
// if (isValid && !!startTimestamp && isDateString(expiryTimestamp)) {
// startDate = parseDate(startTimestamp, isUTC);
// expiryDate = parseDate(expiryTimestamp, isUTC);
// isValid = (startDate < expiryDate);
// if (!isValid) {
// tooltip = invalidExpiryTimeGreaterThanStartTimeTooltip;
// }
// }
// return { isInvalid: !isValid, help: tooltip };
// }
// Is date string, and later than start time (if any)
// export function isInvalidExpiryTimeInput(startTimestamp: string, expiryTimestamp: string, isUTC: boolean): DialogsCommon.IValidationResult {
// var isValid: boolean = isDateString(expiryTimestamp),
// tooltip: string = isValid ? noTooltip : invalidExpiryTimeRequiredTooltip,
// startDate: Date,
// expiryDate: Date;
// if (isValid && startTimestamp) {
// if (isDateString(startTimestamp)) {
// startDate = parseDate(startTimestamp, isUTC);
// expiryDate = parseDate(expiryTimestamp, isUTC);
// isValid = (startDate < expiryDate);
// if (!isValid) {
// tooltip = invalidExpiryTimeGreaterThanStartTimeTooltip;
// }
// }
// }
// return { isInvalid: !isValid, help: tooltip };
// }
/**
* Functions to calculate DateTime Strings
*/
function _getLocalIsoDateTimeString(time: Date): string {
// yyyy-mm-ddThh:mm:ss.sss
// Not using the timezone offset (or 'Z'), which will make the
// date/time represent local time by default.
// var formatted = _string.sprintf(
// "%sT%02d:%02d:%02d.%03d",
// _getLocalIsoDateString(time),
// time.getHours(),
// time.getMinutes(),
// time.getSeconds(),
// time.getMilliseconds()
// );
// return formatted;
return (
_getLocalIsoDateString(time) +
"T" +
DateTimeUtilities.ensureDoubleDigits(time.getHours()) +
":" +
DateTimeUtilities.ensureDoubleDigits(time.getMinutes()) +
":" +
DateTimeUtilities.ensureDoubleDigits(time.getSeconds()) +
"." +
DateTimeUtilities.ensureTripleDigits(time.getMilliseconds())
);
}
function _getLocalIsoDateString(date: Date): string {
return _getLocalIsoDateStringFromParts(date.getFullYear(), date.getMonth(), date.getDate());
}
function _getLocalIsoDateStringFromParts(
fullYear: number,
month: number /* 0..11 */,
date: number /* 1..31 */
): string {
month = month + 1;
return (
fullYear + "-" + DateTimeUtilities.ensureDoubleDigits(month) + "-" + DateTimeUtilities.ensureDoubleDigits(date)
);
// return _string.sprintf(
// "%04d-%02d-%02d",
// fullYear,
// month + 1, // JS month is 0..11
// date); // but date is 1..31
}
function _addDaysHours(time: Date, days: number, hours: number): Date {
var msPerHour = 1000 * 60 * 60;
var daysMs = days * msPerHour * 24;
var hoursMs = hours * msPerHour;
var newTimeMs = time.getTime() + daysMs + hoursMs;
return new Date(newTimeMs);
}
function _daysHoursBeforeNow(days: number, hours: number): Date {
return _addDaysHours(new Date(), -days, -hours);
}
export function _queryLastDaysHours(days: number, hours: number): string {
/* tslint:disable: no-unused-variable */
var daysHoursAgo = _getLocalIsoDateTimeString(_daysHoursBeforeNow(days, hours));
daysHoursAgo = DateTimeUtilities.getUTCDateTime(daysHoursAgo);
return daysHoursAgo;
/* tslint:enable: no-unused-variable */
}
export function _queryCurrentMonthLocal(): string {
var now = new Date();
var start = _getLocalIsoDateStringFromParts(now.getFullYear(), now.getMonth(), 1);
start = DateTimeUtilities.getUTCDateTime(start);
return start;
}
export function _queryCurrentYearLocal(): string {
var now = new Date();
var start = _getLocalIsoDateStringFromParts(now.getFullYear(), 0, 1); // Month is 0..11, date is 1..31
start = DateTimeUtilities.getUTCDateTime(start);
return start;
}
function _addTime(time: Date, lastNumber: number, timeUnit: string): Date {
var timeMS: number;
switch (TimeUnit[Number(timeUnit)]) {
case TimeUnit.Days.toString():
timeMS = lastNumber * 1000 * 60 * 60 * 24;
break;
case TimeUnit.Hours.toString():
timeMS = lastNumber * 1000 * 60 * 60;
break;
case TimeUnit.Minutes.toString():
timeMS = lastNumber * 1000 * 60;
break;
case TimeUnit.Seconds.toString():
timeMS = lastNumber * 1000;
break;
default:
//throw new Errors.ArgumentOutOfRangeError(timeUnit);
}
var newTimeMS = time.getTime() + timeMS;
return new Date(newTimeMS);
}
function _timeBeforeNow(lastNumber: number, timeUnit: string): Date {
return _addTime(new Date(), -lastNumber, timeUnit);
}
export function _queryLastTime(lastNumber: number, timeUnit: string): string {
/* tslint:disable: no-unused-variable */
var daysHoursAgo = _getLocalIsoDateTimeString(_timeBeforeNow(lastNumber, timeUnit));
daysHoursAgo = DateTimeUtilities.getUTCDateTime(daysHoursAgo);
return daysHoursAgo;
/* tslint:enable: no-unused-variable */
}
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import QueryClauseViewModel from "./QueryClauseViewModel";
import * as DateTimeUtilities from "./DateTimeUtilities";
/**
* Constants
*/
export var utc = "utc";
export var local = "local";
export interface ITimestampQuery {
queryType: string; // valid values are "last" and "range"
lastNumber: number; // number value of a custom timestamp using the last option
lastTimeUnit: string; // timeunit of a custom timestamp using the last option
startTime: string;
endTime: string;
timeZone: string; // timezone of custom range timestamp, valid values are "local" and "utc"
}
export interface ILastQuery {
lastNumber: number;
lastTimeUnit: string;
}
export enum TimeUnit {
Seconds,
Minutes,
Hours,
Days,
}
/**
* Setting helpers
*/
export function addRangeTimestamp(
timestamp: ITimestampQuery,
queryBuilderViewModel: QueryBuilderViewModel,
queryClauseViewModel: QueryClauseViewModel
): void {
queryBuilderViewModel.addCustomRange(timestamp, queryClauseViewModel);
}
export function getDefaultStart(localTime: boolean, durationHours: number = 24): string {
var startTimestamp: string;
var utcNowString: string = new Date().toISOString();
var yesterday: Date = new Date(utcNowString);
yesterday.setHours(yesterday.getHours() - durationHours);
startTimestamp = yesterday.toISOString();
if (localTime) {
startTimestamp = localFromUtcDateString(startTimestamp);
}
return startTimestamp;
}
export function getDefaultEnd(localTime: boolean): string {
var endTimestamp: string;
var utcNowString: string = new Date().toISOString();
endTimestamp = utcNowString;
if (localTime) {
endTimestamp = localFromUtcDateString(endTimestamp);
}
return endTimestamp;
}
export function parseDate(dateString: string, isUTC: boolean): Date {
// TODO validate dateString
var date: Date = null;
if (dateString) {
try {
// Date string is assumed to be UTC in Storage Explorer Standalone.
// Behavior may vary in other browsers.
// Here's an example of how the string looks like "2015-10-24T21:44:12"
var millisecondTime = Date.parse(dateString),
parsed: Date = new Date(millisecondTime);
if (isUTC) {
date = parsed;
} else {
// Since we parsed in UTC, accessors are flipped - we get local time from the getUTC* group
// Reinstating, the date is parsed above as UTC, and here we are creating a new date object
// in local time.
var year = parsed.getUTCFullYear(),
month = parsed.getUTCMonth(),
day = parsed.getUTCDate(),
hours = parsed.getUTCHours(),
minutes = parsed.getUTCMinutes(),
seconds = parsed.getUTCSeconds(),
milliseconds = parsed.getUTCMilliseconds();
date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
}
} catch (error) {
//Debug.error("Error parsing date string: ", dateString, error);
}
}
return date;
}
export function utcFromLocalDateString(localDateString: string): string {
// TODO validate localDateString
var localDate = parseDate(localDateString, false),
utcDateString: string = null;
if (localDate) {
utcDateString = localDate.toISOString();
}
return utcDateString;
}
function padIfNeeded(value: number): string {
var padded: string = String(value);
if (0 <= value && value < 10) {
padded = "0" + padded;
}
return padded;
}
function toLocalDateString(date: Date): string {
var localDateString: string = null;
if (date) {
localDateString =
date.getFullYear() +
"-" +
padIfNeeded(date.getMonth() + 1) +
"-" +
padIfNeeded(date.getDate()) +
"T" +
padIfNeeded(date.getHours()) +
":" +
padIfNeeded(date.getMinutes()) +
":" +
padIfNeeded(date.getSeconds());
}
return localDateString;
}
export function localFromUtcDateString(utcDateString: string): string {
// TODO validate utcDateString
var utcDate: Date = parseDate(utcDateString, true),
localDateString: string = null;
if (utcDate) {
localDateString = toLocalDateString(utcDate);
}
return localDateString;
}
export function tryChangeTimestampTimeZone(koTimestamp: ko.Observable<string>, toUTC: boolean): void {
if (koTimestamp) {
var currentDateString: string = koTimestamp(),
newDateString: string;
if (currentDateString) {
if (toUTC) {
newDateString = utcFromLocalDateString(currentDateString);
// removing last character because cannot format it to html binding with the 'Z' at the end
newDateString = newDateString.substring(0, newDateString.length - 1);
} else {
newDateString = localFromUtcDateString(currentDateString);
}
// utcFromLocalDateString and localFromUtcDateString could return null if currentDateString is invalid.
// Hence, only set koTimestamp if newDateString is not null.
if (newDateString) {
koTimestamp(newDateString);
}
}
}
}
/**
* Input validation helpers
*/
export var noTooltip = "",
invalidStartTimeTooltip = "Please provide a valid start time.", // localize
invalidExpiryTimeRequiredTooltip = "Required field. Please provide a valid expiry time.", // localize
invalidExpiryTimeGreaterThanStartTimeTooltip = "The expiry time must be greater than the start time."; // localize
export function isDateString(dateString: string): boolean {
var success: boolean = false;
if (dateString) {
var date: number = Date.parse(dateString);
success = $.isNumeric(date);
}
return success;
}
// Is date string and earlier than expiry time; or is empty
// export function isInvalidStartTimeInput(startTimestamp: string, expiryTimestamp: string, isUTC: boolean): DialogsCommon.IValidationResult {
// var tooltip: string = noTooltip,
// isValid: boolean = isDateString(startTimestamp),
// startDate: Date,
// expiryDate: Date;
// if (!isValid) {
// isValid = (startTimestamp === "");
// }
// if (!isValid) {
// tooltip = invalidStartTimeTooltip;
// }
// if (isValid && !!startTimestamp && isDateString(expiryTimestamp)) {
// startDate = parseDate(startTimestamp, isUTC);
// expiryDate = parseDate(expiryTimestamp, isUTC);
// isValid = (startDate < expiryDate);
// if (!isValid) {
// tooltip = invalidExpiryTimeGreaterThanStartTimeTooltip;
// }
// }
// return { isInvalid: !isValid, help: tooltip };
// }
// Is date string, and later than start time (if any)
// export function isInvalidExpiryTimeInput(startTimestamp: string, expiryTimestamp: string, isUTC: boolean): DialogsCommon.IValidationResult {
// var isValid: boolean = isDateString(expiryTimestamp),
// tooltip: string = isValid ? noTooltip : invalidExpiryTimeRequiredTooltip,
// startDate: Date,
// expiryDate: Date;
// if (isValid && startTimestamp) {
// if (isDateString(startTimestamp)) {
// startDate = parseDate(startTimestamp, isUTC);
// expiryDate = parseDate(expiryTimestamp, isUTC);
// isValid = (startDate < expiryDate);
// if (!isValid) {
// tooltip = invalidExpiryTimeGreaterThanStartTimeTooltip;
// }
// }
// }
// return { isInvalid: !isValid, help: tooltip };
// }
/**
* Functions to calculate DateTime Strings
*/
function _getLocalIsoDateTimeString(time: Date): string {
// yyyy-mm-ddThh:mm:ss.sss
// Not using the timezone offset (or 'Z'), which will make the
// date/time represent local time by default.
// var formatted = _string.sprintf(
// "%sT%02d:%02d:%02d.%03d",
// _getLocalIsoDateString(time),
// time.getHours(),
// time.getMinutes(),
// time.getSeconds(),
// time.getMilliseconds()
// );
// return formatted;
return (
_getLocalIsoDateString(time) +
"T" +
DateTimeUtilities.ensureDoubleDigits(time.getHours()) +
":" +
DateTimeUtilities.ensureDoubleDigits(time.getMinutes()) +
":" +
DateTimeUtilities.ensureDoubleDigits(time.getSeconds()) +
"." +
DateTimeUtilities.ensureTripleDigits(time.getMilliseconds())
);
}
function _getLocalIsoDateString(date: Date): string {
return _getLocalIsoDateStringFromParts(date.getFullYear(), date.getMonth(), date.getDate());
}
function _getLocalIsoDateStringFromParts(
fullYear: number,
month: number /* 0..11 */,
date: number /* 1..31 */
): string {
month = month + 1;
return (
fullYear + "-" + DateTimeUtilities.ensureDoubleDigits(month) + "-" + DateTimeUtilities.ensureDoubleDigits(date)
);
// return _string.sprintf(
// "%04d-%02d-%02d",
// fullYear,
// month + 1, // JS month is 0..11
// date); // but date is 1..31
}
function _addDaysHours(time: Date, days: number, hours: number): Date {
var msPerHour = 1000 * 60 * 60;
var daysMs = days * msPerHour * 24;
var hoursMs = hours * msPerHour;
var newTimeMs = time.getTime() + daysMs + hoursMs;
return new Date(newTimeMs);
}
function _daysHoursBeforeNow(days: number, hours: number): Date {
return _addDaysHours(new Date(), -days, -hours);
}
export function _queryLastDaysHours(days: number, hours: number): string {
/* tslint:disable: no-unused-variable */
var daysHoursAgo = _getLocalIsoDateTimeString(_daysHoursBeforeNow(days, hours));
daysHoursAgo = DateTimeUtilities.getUTCDateTime(daysHoursAgo);
return daysHoursAgo;
/* tslint:enable: no-unused-variable */
}
export function _queryCurrentMonthLocal(): string {
var now = new Date();
var start = _getLocalIsoDateStringFromParts(now.getFullYear(), now.getMonth(), 1);
start = DateTimeUtilities.getUTCDateTime(start);
return start;
}
export function _queryCurrentYearLocal(): string {
var now = new Date();
var start = _getLocalIsoDateStringFromParts(now.getFullYear(), 0, 1); // Month is 0..11, date is 1..31
start = DateTimeUtilities.getUTCDateTime(start);
return start;
}
function _addTime(time: Date, lastNumber: number, timeUnit: string): Date {
var timeMS: number;
switch (TimeUnit[Number(timeUnit)]) {
case TimeUnit.Days.toString():
timeMS = lastNumber * 1000 * 60 * 60 * 24;
break;
case TimeUnit.Hours.toString():
timeMS = lastNumber * 1000 * 60 * 60;
break;
case TimeUnit.Minutes.toString():
timeMS = lastNumber * 1000 * 60;
break;
case TimeUnit.Seconds.toString():
timeMS = lastNumber * 1000;
break;
default:
//throw new Errors.ArgumentOutOfRangeError(timeUnit);
}
var newTimeMS = time.getTime() + timeMS;
return new Date(newTimeMS);
}
function _timeBeforeNow(lastNumber: number, timeUnit: string): Date {
return _addTime(new Date(), -lastNumber, timeUnit);
}
export function _queryLastTime(lastNumber: number, timeUnit: string): string {
/* tslint:disable: no-unused-variable */
var daysHoursAgo = _getLocalIsoDateTimeString(_timeBeforeNow(lastNumber, timeUnit));
daysHoursAgo = DateTimeUtilities.getUTCDateTime(daysHoursAgo);
return daysHoursAgo;
/* tslint:enable: no-unused-variable */
}

View File

@@ -1,67 +1,67 @@
const epochTicks = 621355968000000000;
const ticksPerMillisecond = 10000;
export function getLocalDateTime(dateTime: string): string {
var dateTimeObject: Date = new Date(dateTime);
var year: number = dateTimeObject.getFullYear();
var month: string = ensureDoubleDigits(dateTimeObject.getMonth() + 1); // Month ranges from 0 to 11
var day: string = ensureDoubleDigits(dateTimeObject.getDate());
var hours: string = ensureDoubleDigits(dateTimeObject.getHours());
var minutes: string = ensureDoubleDigits(dateTimeObject.getMinutes());
var seconds: string = ensureDoubleDigits(dateTimeObject.getSeconds());
var milliseconds: string = ensureTripleDigits(dateTimeObject.getMilliseconds());
var localDateTime: string = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}`;
return localDateTime;
}
export function getUTCDateTime(dateTime: string): string {
var dateTimeObject: Date = new Date(dateTime);
return dateTimeObject.toISOString();
}
export function ensureDoubleDigits(num: number): string {
var doubleDigitsString: string = num.toString();
if (num < 10) {
doubleDigitsString = `0${doubleDigitsString}`;
} else if (num > 99) {
doubleDigitsString = doubleDigitsString.substring(0, 2);
}
return doubleDigitsString;
}
export function ensureTripleDigits(num: number): string {
var tripleDigitsString: string = num.toString();
if (num < 10) {
tripleDigitsString = `00${tripleDigitsString}`;
} else if (num < 100) {
tripleDigitsString = `0${tripleDigitsString}`;
} else if (num > 999) {
tripleDigitsString = tripleDigitsString.substring(0, 3);
}
return tripleDigitsString;
}
export function convertUnixToJSDate(unixTime: number): Date {
return new Date(unixTime * 1000);
}
export function convertJSDateToUnix(dateTime: string): number {
return Number((new Date(dateTime).getTime() / 1000).toFixed(0));
}
export function convertTicksToJSDate(ticks: string): Date {
var ticksJSBased = Number(ticks) - epochTicks;
var timeInMillisecond = ticksJSBased / ticksPerMillisecond;
return new Date(timeInMillisecond);
}
export function convertJSDateToTicksWithPadding(dateTime: string): string {
var ticks = epochTicks + new Date(dateTime).getTime() * ticksPerMillisecond;
return padDateTicksWithZeros(ticks.toString());
}
function padDateTicksWithZeros(value: string): string {
var s = "0000000000000000000" + value;
return s.substr(s.length - 20);
}
const epochTicks = 621355968000000000;
const ticksPerMillisecond = 10000;
export function getLocalDateTime(dateTime: string): string {
var dateTimeObject: Date = new Date(dateTime);
var year: number = dateTimeObject.getFullYear();
var month: string = ensureDoubleDigits(dateTimeObject.getMonth() + 1); // Month ranges from 0 to 11
var day: string = ensureDoubleDigits(dateTimeObject.getDate());
var hours: string = ensureDoubleDigits(dateTimeObject.getHours());
var minutes: string = ensureDoubleDigits(dateTimeObject.getMinutes());
var seconds: string = ensureDoubleDigits(dateTimeObject.getSeconds());
var milliseconds: string = ensureTripleDigits(dateTimeObject.getMilliseconds());
var localDateTime: string = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}`;
return localDateTime;
}
export function getUTCDateTime(dateTime: string): string {
var dateTimeObject: Date = new Date(dateTime);
return dateTimeObject.toISOString();
}
export function ensureDoubleDigits(num: number): string {
var doubleDigitsString: string = num.toString();
if (num < 10) {
doubleDigitsString = `0${doubleDigitsString}`;
} else if (num > 99) {
doubleDigitsString = doubleDigitsString.substring(0, 2);
}
return doubleDigitsString;
}
export function ensureTripleDigits(num: number): string {
var tripleDigitsString: string = num.toString();
if (num < 10) {
tripleDigitsString = `00${tripleDigitsString}`;
} else if (num < 100) {
tripleDigitsString = `0${tripleDigitsString}`;
} else if (num > 999) {
tripleDigitsString = tripleDigitsString.substring(0, 3);
}
return tripleDigitsString;
}
export function convertUnixToJSDate(unixTime: number): Date {
return new Date(unixTime * 1000);
}
export function convertJSDateToUnix(dateTime: string): number {
return Number((new Date(dateTime).getTime() / 1000).toFixed(0));
}
export function convertTicksToJSDate(ticks: string): Date {
var ticksJSBased = Number(ticks) - epochTicks;
var timeInMillisecond = ticksJSBased / ticksPerMillisecond;
return new Date(timeInMillisecond);
}
export function convertJSDateToTicksWithPadding(dateTime: string): string {
var ticks = epochTicks + new Date(dateTime).getTime() * ticksPerMillisecond;
return padDateTicksWithZeros(ticks.toString());
}
function padDateTicksWithZeros(value: string): string {
var s = "0000000000000000000" + value;
return s.substr(s.length - 20);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,285 +1,285 @@
import * as ko from "knockout";
import _ from "underscore";
import * as QueryBuilderConstants from "../Constants";
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import ClauseGroup from "./ClauseGroup";
import * as Utilities from "../Utilities";
export default class QueryClauseViewModel {
public checkedForGrouping: ko.Observable<boolean>;
public isFirstInGroup: ko.Observable<boolean>;
public clauseGroup: ClauseGroup;
public and_or: ko.Observable<string>;
public field: ko.Observable<string>;
public type: ko.Observable<string>;
public operator: ko.Observable<string>;
public value: ko.Observable<any>;
public timeValue: ko.Observable<string>;
public customTimeValue: ko.Observable<string>;
public canAnd: ko.Observable<boolean>;
public timestampType: ko.Observable<string>;
//public customLastTimestamp: ko.Observable<CustomTimestampHelper.ILastQuery>;
public isLocal: ko.Observable<boolean>;
public isOperaterEditable: ko.PureComputed<boolean>;
public isTypeEditable: ko.PureComputed<boolean>;
public isValue: ko.Observable<boolean>;
public isTimestamp: ko.Observable<boolean>;
public isCustomLastTimestamp: ko.Observable<boolean>;
public isCustomRangeTimestamp: ko.Observable<boolean>;
private _queryBuilderViewModel: QueryBuilderViewModel;
private _groupCheckSubscription: ko.Subscription;
private _id: string;
public isAndOrFocused: ko.Observable<boolean>;
public isDeleteButtonFocused: ko.Observable<boolean>;
constructor(
queryBuilderViewModel: QueryBuilderViewModel,
and_or: string,
field: string,
type: string,
operator: string,
value: any,
canAnd: boolean,
timeValue: string,
customTimeValue: string,
timestampType: string,
//customLastTimestamp: CustomTimestampHelper.ILastQuery,
isLocal: boolean,
id?: string
) {
this._queryBuilderViewModel = queryBuilderViewModel;
this.checkedForGrouping = ko.observable<boolean>(false);
this.isFirstInGroup = ko.observable<boolean>(false);
this.and_or = ko.observable<string>(and_or);
this.field = ko.observable<string>(field);
this.type = ko.observable<string>(type);
this.operator = ko.observable<string>(operator);
this.value = ko.observable<string>(value);
this.timeValue = ko.observable<string>(timeValue);
this.customTimeValue = ko.observable<string>(customTimeValue);
this.canAnd = ko.observable<boolean>(canAnd);
this.isLocal = ko.observable<boolean>(isLocal);
this._id = id ? id : Utilities.guid();
//this.customLastTimestamp = ko.observable<CustomTimestampHelper.ILastQuery>(customLastTimestamp);
//this.setCustomLastTimestamp();
this.timestampType = ko.observable<string>(timestampType);
this.getValueType();
this.isOperaterEditable = ko.pureComputed<boolean>(() => {
const isPreferredApiCassandra = this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.container.isPreferredApiCassandra();
const cassandraKeys = isPreferredApiCassandra
? this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.collection.cassandraKeys.partitionKeys.map(
key => key.property
)
: [];
return (
(this.isValue() || this.isCustomRangeTimestamp()) &&
(!isPreferredApiCassandra || !_.contains(cassandraKeys, this.field()))
);
});
this.isTypeEditable = ko.pureComputed<boolean>(
() =>
this.field() !== "Timestamp" &&
this.field() !== "PartitionKey" &&
this.field() !== "RowKey" &&
!this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.container.isPreferredApiCassandra()
);
this.and_or.subscribe(value => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this.field.subscribe(value => {
this.changeField();
});
this.type.subscribe(value => {
this.changeType();
});
this.timeValue.subscribe(value => {
// if (this.timeValue() === QueryBuilderConstants.timeOptions.custom) {
// this.customTimestampDialog();
// }
});
this.customTimeValue.subscribe(value => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this.value.subscribe(value => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this.operator.subscribe(value => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this._groupCheckSubscription = this.checkedForGrouping.subscribe(value => {
this._queryBuilderViewModel.updateCanGroupClauses();
});
this.isAndOrFocused = ko.observable<boolean>(false);
this.isDeleteButtonFocused = ko.observable<boolean>(false);
}
// private setCustomLastTimestamp() : void {
// if (this.customLastTimestamp() === null) {
// var lastNumberandType: CustomTimestampHelper.ILastQuery = {
// lastNumber: 7,
// lastTimeUnit: "Days"
// };
// this.customLastTimestamp(lastNumberandType);
// }
// }
private getValueType(): void {
switch (this.timestampType()) {
case "time":
this.isValue = ko.observable<boolean>(false);
this.isTimestamp = ko.observable<boolean>(true);
this.isCustomLastTimestamp = ko.observable<boolean>(false);
this.isCustomRangeTimestamp = ko.observable<boolean>(false);
break;
case "last":
this.isValue = ko.observable<boolean>(false);
this.isTimestamp = ko.observable<boolean>(false);
this.isCustomLastTimestamp = ko.observable<boolean>(true);
this.isCustomRangeTimestamp = ko.observable<boolean>(false);
break;
case "range":
this.isValue = ko.observable<boolean>(false);
this.isTimestamp = ko.observable<boolean>(false);
this.isCustomLastTimestamp = ko.observable<boolean>(false);
this.isCustomRangeTimestamp = ko.observable<boolean>(true);
break;
default:
this.isValue = ko.observable<boolean>(true);
this.isTimestamp = ko.observable<boolean>(false);
this.isCustomLastTimestamp = ko.observable<boolean>(false);
this.isCustomRangeTimestamp = ko.observable<boolean>(false);
}
}
private changeField(): void {
this.isCustomLastTimestamp(false);
this.isCustomRangeTimestamp(false);
if (this.field() === "Timestamp") {
this.isValue(false);
this.isTimestamp(true);
this.type(QueryBuilderConstants.TableType.DateTime);
this.operator(QueryBuilderConstants.Operator.GreaterThanOrEqualTo);
this.timestampType("time");
} else if (this.field() === "PartitionKey" || this.field() === "RowKey") {
this.resetFromTimestamp();
this.type(QueryBuilderConstants.TableType.String);
} else {
this.resetFromTimestamp();
if (this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.container.isPreferredApiCassandra()) {
const cassandraSchema = this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.collection
.cassandraSchema;
for (let i = 0, len = cassandraSchema.length; i < len; i++) {
if (cassandraSchema[i].property === this.field()) {
this.type(cassandraSchema[i].type);
i = len;
}
}
} else {
this.type(QueryBuilderConstants.TableType.String);
}
}
this._queryBuilderViewModel.checkIfClauseChanged(this);
}
private resetFromTimestamp(): void {
this.isValue(true);
this.isTimestamp(false);
this.operator(QueryBuilderConstants.Operator.Equal);
this.value("");
this.timestampType("");
this.timeValue("");
this.customTimeValue("");
}
private changeType(): void {
this.isCustomLastTimestamp(false);
this.isCustomRangeTimestamp(false);
if (this.type() === QueryBuilderConstants.TableType.DateTime) {
this.isValue(false);
this.isTimestamp(true);
this.operator(QueryBuilderConstants.Operator.GreaterThanOrEqualTo);
this.timestampType("time");
} else {
this.isValue(true);
this.isTimestamp(false);
this.timeValue("");
this.operator(QueryBuilderConstants.Operator.EqualTo);
this.value("");
this.timestampType("");
this.timeValue("");
this.customTimeValue("");
}
this._queryBuilderViewModel.checkIfClauseChanged(this);
}
// private customTimestampDialog(): Promise<any> {
// var lastNumber = this.customLastTimestamp().lastNumber;
// var lastTimeUnit = this.customLastTimestamp().lastTimeUnit;
// return this._host.executeOperation("Environment.openDialog", [{
// id: AzureConstants.registeredDialogs.customTimestampQueryDialog,
// width: 500,
// height: 300,
// parameters: { lastNumber, lastTimeUnit }
// }]).then((timestamp: CustomTimestampHelper.ITimestampQuery) => {
// if (timestamp) {
// this.isValue(false);
// this.isTimestamp(false);
// this.timestampType(timestamp.queryType);
// if (timestamp.queryType === "last") {
// this.isCustomLastTimestamp(true);
// this.isCustomRangeTimestamp(false);
// var lastNumberandType: CustomTimestampHelper.ILastQuery = {
// lastNumber: timestamp.lastNumber,
// lastTimeUnit: timestamp.lastTimeUnit
// };
// this.customLastTimestamp(lastNumberandType);
// this.customTimeValue(`Last ${timestamp.lastNumber} ${timestamp.lastTimeUnit}`);
// } else {
// if (timestamp.timeZone === "local") {
// this.isLocal = ko.observable(true);
// } else {
// this.isLocal = ko.observable(false);
// }
// this.isCustomLastTimestamp(false);
// this.isCustomRangeTimestamp(true);
// this.customTimeValue(timestamp.startTime);
// CustomTimestampHelper.addRangeTimestamp(timestamp, this._queryBuilderViewModel, this);
// }
// } else {
// this.timeValue(QueryBuilderConstants.timeOptions.lastHour);
// }
// });
// }
public getId(): string {
return this._id;
}
public get groupDepth(): number {
if (this.clauseGroup) {
return this.clauseGroup.getCurrentGroupDepth();
}
return -1;
}
public dispose(): void {
if (this._groupCheckSubscription) {
this._groupCheckSubscription.dispose();
}
this.clauseGroup = null;
this._queryBuilderViewModel = null;
}
}
import * as ko from "knockout";
import _ from "underscore";
import * as QueryBuilderConstants from "../Constants";
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import ClauseGroup from "./ClauseGroup";
import * as Utilities from "../Utilities";
export default class QueryClauseViewModel {
public checkedForGrouping: ko.Observable<boolean>;
public isFirstInGroup: ko.Observable<boolean>;
public clauseGroup: ClauseGroup;
public and_or: ko.Observable<string>;
public field: ko.Observable<string>;
public type: ko.Observable<string>;
public operator: ko.Observable<string>;
public value: ko.Observable<any>;
public timeValue: ko.Observable<string>;
public customTimeValue: ko.Observable<string>;
public canAnd: ko.Observable<boolean>;
public timestampType: ko.Observable<string>;
//public customLastTimestamp: ko.Observable<CustomTimestampHelper.ILastQuery>;
public isLocal: ko.Observable<boolean>;
public isOperaterEditable: ko.PureComputed<boolean>;
public isTypeEditable: ko.PureComputed<boolean>;
public isValue: ko.Observable<boolean>;
public isTimestamp: ko.Observable<boolean>;
public isCustomLastTimestamp: ko.Observable<boolean>;
public isCustomRangeTimestamp: ko.Observable<boolean>;
private _queryBuilderViewModel: QueryBuilderViewModel;
private _groupCheckSubscription: ko.Subscription;
private _id: string;
public isAndOrFocused: ko.Observable<boolean>;
public isDeleteButtonFocused: ko.Observable<boolean>;
constructor(
queryBuilderViewModel: QueryBuilderViewModel,
and_or: string,
field: string,
type: string,
operator: string,
value: any,
canAnd: boolean,
timeValue: string,
customTimeValue: string,
timestampType: string,
//customLastTimestamp: CustomTimestampHelper.ILastQuery,
isLocal: boolean,
id?: string
) {
this._queryBuilderViewModel = queryBuilderViewModel;
this.checkedForGrouping = ko.observable<boolean>(false);
this.isFirstInGroup = ko.observable<boolean>(false);
this.and_or = ko.observable<string>(and_or);
this.field = ko.observable<string>(field);
this.type = ko.observable<string>(type);
this.operator = ko.observable<string>(operator);
this.value = ko.observable<string>(value);
this.timeValue = ko.observable<string>(timeValue);
this.customTimeValue = ko.observable<string>(customTimeValue);
this.canAnd = ko.observable<boolean>(canAnd);
this.isLocal = ko.observable<boolean>(isLocal);
this._id = id ? id : Utilities.guid();
//this.customLastTimestamp = ko.observable<CustomTimestampHelper.ILastQuery>(customLastTimestamp);
//this.setCustomLastTimestamp();
this.timestampType = ko.observable<string>(timestampType);
this.getValueType();
this.isOperaterEditable = ko.pureComputed<boolean>(() => {
const isPreferredApiCassandra = this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.container.isPreferredApiCassandra();
const cassandraKeys = isPreferredApiCassandra
? this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.collection.cassandraKeys.partitionKeys.map(
(key) => key.property
)
: [];
return (
(this.isValue() || this.isCustomRangeTimestamp()) &&
(!isPreferredApiCassandra || !_.contains(cassandraKeys, this.field()))
);
});
this.isTypeEditable = ko.pureComputed<boolean>(
() =>
this.field() !== "Timestamp" &&
this.field() !== "PartitionKey" &&
this.field() !== "RowKey" &&
!this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.container.isPreferredApiCassandra()
);
this.and_or.subscribe((value) => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this.field.subscribe((value) => {
this.changeField();
});
this.type.subscribe((value) => {
this.changeType();
});
this.timeValue.subscribe((value) => {
// if (this.timeValue() === QueryBuilderConstants.timeOptions.custom) {
// this.customTimestampDialog();
// }
});
this.customTimeValue.subscribe((value) => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this.value.subscribe((value) => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this.operator.subscribe((value) => {
this._queryBuilderViewModel.checkIfClauseChanged(this);
});
this._groupCheckSubscription = this.checkedForGrouping.subscribe((value) => {
this._queryBuilderViewModel.updateCanGroupClauses();
});
this.isAndOrFocused = ko.observable<boolean>(false);
this.isDeleteButtonFocused = ko.observable<boolean>(false);
}
// private setCustomLastTimestamp() : void {
// if (this.customLastTimestamp() === null) {
// var lastNumberandType: CustomTimestampHelper.ILastQuery = {
// lastNumber: 7,
// lastTimeUnit: "Days"
// };
// this.customLastTimestamp(lastNumberandType);
// }
// }
private getValueType(): void {
switch (this.timestampType()) {
case "time":
this.isValue = ko.observable<boolean>(false);
this.isTimestamp = ko.observable<boolean>(true);
this.isCustomLastTimestamp = ko.observable<boolean>(false);
this.isCustomRangeTimestamp = ko.observable<boolean>(false);
break;
case "last":
this.isValue = ko.observable<boolean>(false);
this.isTimestamp = ko.observable<boolean>(false);
this.isCustomLastTimestamp = ko.observable<boolean>(true);
this.isCustomRangeTimestamp = ko.observable<boolean>(false);
break;
case "range":
this.isValue = ko.observable<boolean>(false);
this.isTimestamp = ko.observable<boolean>(false);
this.isCustomLastTimestamp = ko.observable<boolean>(false);
this.isCustomRangeTimestamp = ko.observable<boolean>(true);
break;
default:
this.isValue = ko.observable<boolean>(true);
this.isTimestamp = ko.observable<boolean>(false);
this.isCustomLastTimestamp = ko.observable<boolean>(false);
this.isCustomRangeTimestamp = ko.observable<boolean>(false);
}
}
private changeField(): void {
this.isCustomLastTimestamp(false);
this.isCustomRangeTimestamp(false);
if (this.field() === "Timestamp") {
this.isValue(false);
this.isTimestamp(true);
this.type(QueryBuilderConstants.TableType.DateTime);
this.operator(QueryBuilderConstants.Operator.GreaterThanOrEqualTo);
this.timestampType("time");
} else if (this.field() === "PartitionKey" || this.field() === "RowKey") {
this.resetFromTimestamp();
this.type(QueryBuilderConstants.TableType.String);
} else {
this.resetFromTimestamp();
if (this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.container.isPreferredApiCassandra()) {
const cassandraSchema = this._queryBuilderViewModel.tableEntityListViewModel.queryTablesTab.collection
.cassandraSchema;
for (let i = 0, len = cassandraSchema.length; i < len; i++) {
if (cassandraSchema[i].property === this.field()) {
this.type(cassandraSchema[i].type);
i = len;
}
}
} else {
this.type(QueryBuilderConstants.TableType.String);
}
}
this._queryBuilderViewModel.checkIfClauseChanged(this);
}
private resetFromTimestamp(): void {
this.isValue(true);
this.isTimestamp(false);
this.operator(QueryBuilderConstants.Operator.Equal);
this.value("");
this.timestampType("");
this.timeValue("");
this.customTimeValue("");
}
private changeType(): void {
this.isCustomLastTimestamp(false);
this.isCustomRangeTimestamp(false);
if (this.type() === QueryBuilderConstants.TableType.DateTime) {
this.isValue(false);
this.isTimestamp(true);
this.operator(QueryBuilderConstants.Operator.GreaterThanOrEqualTo);
this.timestampType("time");
} else {
this.isValue(true);
this.isTimestamp(false);
this.timeValue("");
this.operator(QueryBuilderConstants.Operator.EqualTo);
this.value("");
this.timestampType("");
this.timeValue("");
this.customTimeValue("");
}
this._queryBuilderViewModel.checkIfClauseChanged(this);
}
// private customTimestampDialog(): Promise<any> {
// var lastNumber = this.customLastTimestamp().lastNumber;
// var lastTimeUnit = this.customLastTimestamp().lastTimeUnit;
// return this._host.executeOperation("Environment.openDialog", [{
// id: AzureConstants.registeredDialogs.customTimestampQueryDialog,
// width: 500,
// height: 300,
// parameters: { lastNumber, lastTimeUnit }
// }]).then((timestamp: CustomTimestampHelper.ITimestampQuery) => {
// if (timestamp) {
// this.isValue(false);
// this.isTimestamp(false);
// this.timestampType(timestamp.queryType);
// if (timestamp.queryType === "last") {
// this.isCustomLastTimestamp(true);
// this.isCustomRangeTimestamp(false);
// var lastNumberandType: CustomTimestampHelper.ILastQuery = {
// lastNumber: timestamp.lastNumber,
// lastTimeUnit: timestamp.lastTimeUnit
// };
// this.customLastTimestamp(lastNumberandType);
// this.customTimeValue(`Last ${timestamp.lastNumber} ${timestamp.lastTimeUnit}`);
// } else {
// if (timestamp.timeZone === "local") {
// this.isLocal = ko.observable(true);
// } else {
// this.isLocal = ko.observable(false);
// }
// this.isCustomLastTimestamp(false);
// this.isCustomRangeTimestamp(true);
// this.customTimeValue(timestamp.startTime);
// CustomTimestampHelper.addRangeTimestamp(timestamp, this._queryBuilderViewModel, this);
// }
// } else {
// this.timeValue(QueryBuilderConstants.timeOptions.lastHour);
// }
// });
// }
public getId(): string {
return this._id;
}
public get groupDepth(): number {
if (this.clauseGroup) {
return this.clauseGroup.getCurrentGroupDepth();
}
return -1;
}
public dispose(): void {
if (this._groupCheckSubscription) {
this._groupCheckSubscription.dispose();
}
this.clauseGroup = null;
this._queryBuilderViewModel = null;
}
}

View File

@@ -1,237 +1,237 @@
import * as ko from "knockout";
import * as _ from "underscore";
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import QueryClauseViewModel from "./QueryClauseViewModel";
import TableEntityListViewModel from "../DataTable/TableEntityListViewModel";
import QueryTablesTab from "../../Tabs/QueryTablesTab";
import * as DataTableUtilities from "../DataTable/DataTableUtilities";
import { KeyCodes } from "../../../Common/Constants";
import { getQuotedCqlIdentifier } from "../CqlUtilities";
export default class QueryViewModel {
public topValueLimitMessage: string = "Please input a number between 0 and 1000.";
public queryBuilderViewModel = ko.observable<QueryBuilderViewModel>();
public isHelperActive = ko.observable<boolean>(true);
public isEditorActive = ko.observable<boolean>(false);
public isExpanded = ko.observable<boolean>(false);
public isWarningBox = ko.observable<boolean>();
public hasQueryError: ko.Computed<boolean>;
public queryErrorMessage: ko.Computed<string>;
public isSaveEnabled: ko.PureComputed<boolean>;
public isExceedingLimit: ko.Computed<boolean>;
public canRunQuery: ko.Computed<boolean>;
public queryTextIsReadOnly: ko.Computed<boolean>;
public queryText = ko.observable<string>();
public topValue = ko.observable<number>();
public selectText = ko.observableArray<string>();
public unchangedText = ko.observable<string>();
public unchangedSaveText = ko.observable<string>();
public unchangedSaveTop = ko.observable<number>();
public unchangedSaveSelect = ko.observableArray<string>();
public focusTopResult: ko.Observable<boolean>;
public focusExpandIcon: ko.Observable<boolean>;
public savedQueryName = ko.observable<string>();
public selectMessage = ko.observable<string>();
public columnOptions: ko.ObservableArray<string>;
public queryTablesTab: QueryTablesTab;
public id: string;
private _tableEntityListViewModel: TableEntityListViewModel;
constructor(queryTablesTab: QueryTablesTab) {
this.queryTablesTab = queryTablesTab;
this.id = `queryViewModel${this.queryTablesTab.tabId}`;
this._tableEntityListViewModel = queryTablesTab.tableEntityListViewModel();
this.queryTextIsReadOnly = ko.computed<boolean>(() => {
return !this.queryTablesTab.container.isPreferredApiCassandra();
});
let initialOptions = this._tableEntityListViewModel.headers;
this.columnOptions = ko.observableArray<string>(initialOptions);
this.focusTopResult = ko.observable<boolean>(false);
this.focusExpandIcon = ko.observable<boolean>(false);
this.queryBuilderViewModel(new QueryBuilderViewModel(this, this._tableEntityListViewModel));
this.isSaveEnabled = ko.pureComputed<boolean>(
() =>
this.queryText() !== this.unchangedSaveText() ||
this.selectText() !== this.unchangedSaveSelect() ||
this.topValue() !== this.unchangedSaveTop()
);
this.queryBuilderViewModel().clauseArray.subscribe(value => {
this.setFilter();
});
this.isExceedingLimit = ko.computed<boolean>(() => {
var currentTopValue: number = this.topValue();
return currentTopValue < 0 || currentTopValue > 1000;
});
this.canRunQuery = ko.computed<boolean>(() => {
return !this.isExceedingLimit();
});
this.hasQueryError = ko.computed<boolean>(() => {
return !!this._tableEntityListViewModel.queryErrorMessage();
});
this.queryErrorMessage = ko.computed<string>(() => {
return this._tableEntityListViewModel.queryErrorMessage();
});
}
public selectHelper = (): void => {
this.isHelperActive(true);
this.isEditorActive(false);
DataTableUtilities.forceRecalculateTableSize();
};
public selectEditor = (): void => {
this.setFilter();
if (!this.isEditorActive()) {
this.unchangedText(this.queryText());
}
this.isEditorActive(true);
this.isHelperActive(false);
DataTableUtilities.forceRecalculateTableSize();
};
public toggleAdvancedOptions = () => {
this.isExpanded(!this.isExpanded());
if (this.isExpanded()) {
this.focusTopResult(true);
} else {
this.focusExpandIcon(true);
}
DataTableUtilities.forceRecalculateTableSize(); // Fix for 261924, forces the resize event so DataTableBindingManager will redo the calculation on table size.
};
public ontoggleAdvancedOptionsKeyDown = (source: any, event: KeyboardEvent): boolean => {
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
this.toggleAdvancedOptions();
event.stopPropagation();
return false;
}
return true;
};
private _getSelectedResults = (): Array<string> => {
return this.selectText();
};
private setFilter = (): string => {
var queryString = this.isEditorActive()
? this.queryText()
: this.queryTablesTab.container.isPreferredApiCassandra()
? this.queryBuilderViewModel().getCqlFilterFromClauses()
: this.queryBuilderViewModel().getODataFilterFromClauses();
var filter = queryString;
this.queryText(filter);
return this.queryText();
};
private setSqlFilter = (): string => {
var filter = this.queryBuilderViewModel().getSqlFilterFromClauses();
return filter;
};
private setCqlFilter = (): string => {
var filter = this.queryBuilderViewModel().getCqlFilterFromClauses();
return filter;
};
public isHelperEnabled = ko
.computed<boolean>(() => {
return (
this.queryText() === this.unchangedText() ||
this.queryText() === null ||
this.queryText() === "" ||
this.isHelperActive()
);
})
.extend({
notify: "always"
});
public runQuery = (): DataTables.DataTable => {
var filter = this.setFilter();
if (filter && !this.queryTablesTab.container.isPreferredApiCassandra()) {
filter = filter.replace(/"/g, "'");
}
var top = this.topValue();
var selectOptions = this._getSelectedResults();
var select = selectOptions;
this._tableEntityListViewModel.tableQuery.filter = filter;
this._tableEntityListViewModel.tableQuery.top = top;
this._tableEntityListViewModel.tableQuery.select = select;
this._tableEntityListViewModel.oDataQuery(filter);
this._tableEntityListViewModel.sqlQuery(this.setSqlFilter());
this._tableEntityListViewModel.cqlQuery(filter);
return this._tableEntityListViewModel.reloadTable(/*useSetting*/ false, /*resetHeaders*/ false);
};
public clearQuery = (): DataTables.DataTable => {
this.queryText(null);
this.topValue(null);
this.selectText(null);
this.selectMessage("");
// clears the queryBuilder and adds a new blank clause
this.queryBuilderViewModel().queryClauses.removeAll();
this.queryBuilderViewModel().addNewClause();
this._tableEntityListViewModel.tableQuery.filter = null;
this._tableEntityListViewModel.tableQuery.top = null;
this._tableEntityListViewModel.tableQuery.select = null;
this._tableEntityListViewModel.oDataQuery("");
this._tableEntityListViewModel.sqlQuery("SELECT * FROM c");
this._tableEntityListViewModel.cqlQuery(
`SELECT * FROM ${getQuotedCqlIdentifier(this.queryTablesTab.collection.databaseId)}.${getQuotedCqlIdentifier(
this.queryTablesTab.collection.id()
)}`
);
return this._tableEntityListViewModel.reloadTable(false);
};
public selectQueryOptions(): Promise<any> {
this.queryTablesTab.container.querySelectPane.queryViewModel = this;
this.queryTablesTab.container.querySelectPane.open();
return null;
}
public onselectQueryOptionsKeyDown = (source: any, event: KeyboardEvent): boolean => {
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
this.selectQueryOptions();
event.stopPropagation();
return false;
}
return true;
};
public getSelectMessage(): void {
if (_.isEmpty(this.selectText()) || this.selectText() === null) {
this.selectMessage("");
} else {
this.selectMessage(`${this.selectText().length} of ${this.columnOptions().length} columns selected.`);
}
}
public isSelected = ko.computed<boolean>(() => {
return !(_.isEmpty(this.selectText()) || this.selectText() === null);
});
private setCheckToSave(): void {
this.unchangedSaveText(this.setFilter());
this.unchangedSaveTop(this.topValue());
this.unchangedSaveSelect(this.selectText());
this.isSaveEnabled(false);
}
public checkIfBuilderChanged(clause: QueryClauseViewModel): void {
this.setFilter();
}
}
import * as ko from "knockout";
import * as _ from "underscore";
import QueryBuilderViewModel from "./QueryBuilderViewModel";
import QueryClauseViewModel from "./QueryClauseViewModel";
import TableEntityListViewModel from "../DataTable/TableEntityListViewModel";
import QueryTablesTab from "../../Tabs/QueryTablesTab";
import * as DataTableUtilities from "../DataTable/DataTableUtilities";
import { KeyCodes } from "../../../Common/Constants";
import { getQuotedCqlIdentifier } from "../CqlUtilities";
export default class QueryViewModel {
public topValueLimitMessage: string = "Please input a number between 0 and 1000.";
public queryBuilderViewModel = ko.observable<QueryBuilderViewModel>();
public isHelperActive = ko.observable<boolean>(true);
public isEditorActive = ko.observable<boolean>(false);
public isExpanded = ko.observable<boolean>(false);
public isWarningBox = ko.observable<boolean>();
public hasQueryError: ko.Computed<boolean>;
public queryErrorMessage: ko.Computed<string>;
public isSaveEnabled: ko.PureComputed<boolean>;
public isExceedingLimit: ko.Computed<boolean>;
public canRunQuery: ko.Computed<boolean>;
public queryTextIsReadOnly: ko.Computed<boolean>;
public queryText = ko.observable<string>();
public topValue = ko.observable<number>();
public selectText = ko.observableArray<string>();
public unchangedText = ko.observable<string>();
public unchangedSaveText = ko.observable<string>();
public unchangedSaveTop = ko.observable<number>();
public unchangedSaveSelect = ko.observableArray<string>();
public focusTopResult: ko.Observable<boolean>;
public focusExpandIcon: ko.Observable<boolean>;
public savedQueryName = ko.observable<string>();
public selectMessage = ko.observable<string>();
public columnOptions: ko.ObservableArray<string>;
public queryTablesTab: QueryTablesTab;
public id: string;
private _tableEntityListViewModel: TableEntityListViewModel;
constructor(queryTablesTab: QueryTablesTab) {
this.queryTablesTab = queryTablesTab;
this.id = `queryViewModel${this.queryTablesTab.tabId}`;
this._tableEntityListViewModel = queryTablesTab.tableEntityListViewModel();
this.queryTextIsReadOnly = ko.computed<boolean>(() => {
return !this.queryTablesTab.container.isPreferredApiCassandra();
});
let initialOptions = this._tableEntityListViewModel.headers;
this.columnOptions = ko.observableArray<string>(initialOptions);
this.focusTopResult = ko.observable<boolean>(false);
this.focusExpandIcon = ko.observable<boolean>(false);
this.queryBuilderViewModel(new QueryBuilderViewModel(this, this._tableEntityListViewModel));
this.isSaveEnabled = ko.pureComputed<boolean>(
() =>
this.queryText() !== this.unchangedSaveText() ||
this.selectText() !== this.unchangedSaveSelect() ||
this.topValue() !== this.unchangedSaveTop()
);
this.queryBuilderViewModel().clauseArray.subscribe((value) => {
this.setFilter();
});
this.isExceedingLimit = ko.computed<boolean>(() => {
var currentTopValue: number = this.topValue();
return currentTopValue < 0 || currentTopValue > 1000;
});
this.canRunQuery = ko.computed<boolean>(() => {
return !this.isExceedingLimit();
});
this.hasQueryError = ko.computed<boolean>(() => {
return !!this._tableEntityListViewModel.queryErrorMessage();
});
this.queryErrorMessage = ko.computed<string>(() => {
return this._tableEntityListViewModel.queryErrorMessage();
});
}
public selectHelper = (): void => {
this.isHelperActive(true);
this.isEditorActive(false);
DataTableUtilities.forceRecalculateTableSize();
};
public selectEditor = (): void => {
this.setFilter();
if (!this.isEditorActive()) {
this.unchangedText(this.queryText());
}
this.isEditorActive(true);
this.isHelperActive(false);
DataTableUtilities.forceRecalculateTableSize();
};
public toggleAdvancedOptions = () => {
this.isExpanded(!this.isExpanded());
if (this.isExpanded()) {
this.focusTopResult(true);
} else {
this.focusExpandIcon(true);
}
DataTableUtilities.forceRecalculateTableSize(); // Fix for 261924, forces the resize event so DataTableBindingManager will redo the calculation on table size.
};
public ontoggleAdvancedOptionsKeyDown = (source: any, event: KeyboardEvent): boolean => {
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
this.toggleAdvancedOptions();
event.stopPropagation();
return false;
}
return true;
};
private _getSelectedResults = (): Array<string> => {
return this.selectText();
};
private setFilter = (): string => {
var queryString = this.isEditorActive()
? this.queryText()
: this.queryTablesTab.container.isPreferredApiCassandra()
? this.queryBuilderViewModel().getCqlFilterFromClauses()
: this.queryBuilderViewModel().getODataFilterFromClauses();
var filter = queryString;
this.queryText(filter);
return this.queryText();
};
private setSqlFilter = (): string => {
var filter = this.queryBuilderViewModel().getSqlFilterFromClauses();
return filter;
};
private setCqlFilter = (): string => {
var filter = this.queryBuilderViewModel().getCqlFilterFromClauses();
return filter;
};
public isHelperEnabled = ko
.computed<boolean>(() => {
return (
this.queryText() === this.unchangedText() ||
this.queryText() === null ||
this.queryText() === "" ||
this.isHelperActive()
);
})
.extend({
notify: "always",
});
public runQuery = (): DataTables.DataTable => {
var filter = this.setFilter();
if (filter && !this.queryTablesTab.container.isPreferredApiCassandra()) {
filter = filter.replace(/"/g, "'");
}
var top = this.topValue();
var selectOptions = this._getSelectedResults();
var select = selectOptions;
this._tableEntityListViewModel.tableQuery.filter = filter;
this._tableEntityListViewModel.tableQuery.top = top;
this._tableEntityListViewModel.tableQuery.select = select;
this._tableEntityListViewModel.oDataQuery(filter);
this._tableEntityListViewModel.sqlQuery(this.setSqlFilter());
this._tableEntityListViewModel.cqlQuery(filter);
return this._tableEntityListViewModel.reloadTable(/*useSetting*/ false, /*resetHeaders*/ false);
};
public clearQuery = (): DataTables.DataTable => {
this.queryText(null);
this.topValue(null);
this.selectText(null);
this.selectMessage("");
// clears the queryBuilder and adds a new blank clause
this.queryBuilderViewModel().queryClauses.removeAll();
this.queryBuilderViewModel().addNewClause();
this._tableEntityListViewModel.tableQuery.filter = null;
this._tableEntityListViewModel.tableQuery.top = null;
this._tableEntityListViewModel.tableQuery.select = null;
this._tableEntityListViewModel.oDataQuery("");
this._tableEntityListViewModel.sqlQuery("SELECT * FROM c");
this._tableEntityListViewModel.cqlQuery(
`SELECT * FROM ${getQuotedCqlIdentifier(this.queryTablesTab.collection.databaseId)}.${getQuotedCqlIdentifier(
this.queryTablesTab.collection.id()
)}`
);
return this._tableEntityListViewModel.reloadTable(false);
};
public selectQueryOptions(): Promise<any> {
this.queryTablesTab.container.querySelectPane.queryViewModel = this;
this.queryTablesTab.container.querySelectPane.open();
return null;
}
public onselectQueryOptionsKeyDown = (source: any, event: KeyboardEvent): boolean => {
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
this.selectQueryOptions();
event.stopPropagation();
return false;
}
return true;
};
public getSelectMessage(): void {
if (_.isEmpty(this.selectText()) || this.selectText() === null) {
this.selectMessage("");
} else {
this.selectMessage(`${this.selectText().length} of ${this.columnOptions().length} columns selected.`);
}
}
public isSelected = ko.computed<boolean>(() => {
return !(_.isEmpty(this.selectText()) || this.selectText() === null);
});
private setCheckToSave(): void {
this.unchangedSaveText(this.setFilter());
this.unchangedSaveTop(this.topValue());
this.unchangedSaveSelect(this.selectText());
this.isSaveEnabled(false);
}
public checkIfBuilderChanged(clause: QueryClauseViewModel): void {
this.setFilter();
}
}