import * as ko from "knockout"; import React from "react"; import * as _ from "underscore"; import { KeyCodes } from "../../../Common/Constants"; import { useSidePanel } from "../../../hooks/useSidePanel"; import { userContext } from "../../../UserContext"; import { TableQuerySelectPanel } from "../../Panes/Tables/TableQuerySelectPanel/TableQuerySelectPanel"; import NewQueryTablesTab from "../../Tabs/QueryTablesTab/QueryTablesTab"; import { getQuotedCqlIdentifier } from "../CqlUtilities"; import * as DataTableUtilities from "../DataTable/DataTableUtilities"; import TableEntityListViewModel from "../DataTable/TableEntityListViewModel"; import QueryBuilderViewModel from "./QueryBuilderViewModel"; export default class QueryViewModel { public readonly topValueLimitMessage: string = "Please input a number between 0 and 1000."; public queryBuilderViewModel = ko.observable(); public isHelperActive = ko.observable(true); public isEditorActive = ko.observable(false); public isExpanded = ko.observable(false); public isWarningBox = ko.observable(); public hasQueryError: ko.Computed; public queryErrorMessage: ko.Computed; public isSaveEnabled: ko.PureComputed; public isExceedingLimit: ko.Computed; public canRunQuery: ko.Computed; public queryTextIsReadOnly: ko.Computed; public queryText = ko.observable(); public topValue = ko.observable(); public selectText = ko.observableArray(); public unchangedText = ko.observable(); public unchangedSaveText = ko.observable(); public unchangedSaveTop = ko.observable(); public unchangedSaveSelect = ko.observableArray(); public focusTopResult: ko.Observable; public focusExpandIcon: ko.Observable; public savedQueryName = ko.observable(); public selectMessage = ko.observable(); public columnOptions: ko.ObservableArray; public queryTablesTab: NewQueryTablesTab; // public queryTablesTab: QueryTablesTab; public id: string; private _tableEntityListViewModel: TableEntityListViewModel; // constructor(queryTablesTab: QueryTablesTab) { constructor(queryTablesTab: NewQueryTablesTab) { this.queryTablesTab = queryTablesTab; this.id = `queryViewModel${this.queryTablesTab.tabId}`; this._tableEntityListViewModel = queryTablesTab.tableEntityListViewModel; this.queryTextIsReadOnly = ko.computed(() => { return userContext.apiType !== "Cassandra"; }); const initialOptions = this._tableEntityListViewModel.headers; this.columnOptions = ko.observableArray(initialOptions); this.focusTopResult = ko.observable(false); this.focusExpandIcon = ko.observable(false); this.queryBuilderViewModel(new QueryBuilderViewModel(this, this._tableEntityListViewModel)); this.isSaveEnabled = ko.pureComputed( () => this.queryText() !== this.unchangedSaveText() || this.selectText() !== this.unchangedSaveSelect() || this.topValue() !== this.unchangedSaveTop() ); this.queryBuilderViewModel().clauseArray.subscribe(() => { this.setFilter(); }); this.isExceedingLimit = ko.computed(() => { const currentTopValue: number = this.topValue(); return currentTopValue < 0 || currentTopValue > 1000; }); this.canRunQuery = ko.computed(() => { return !this.isExceedingLimit(); }); this.hasQueryError = ko.computed(() => { return !!this._tableEntityListViewModel.queryErrorMessage(); }); this.queryErrorMessage = ko.computed(() => { 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: string, event: KeyboardEvent): boolean => { if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) { this.toggleAdvancedOptions(); event.stopPropagation(); return false; } return true; }; private _getSelectedResults = (): Array => { return this.selectText(); }; private setFilter = (): string => { const queryString = this.isEditorActive() ? this.queryText() : userContext.apiType === "Cassandra" ? this.queryBuilderViewModel().getCqlFilterFromClauses() : this.queryBuilderViewModel().getODataFilterFromClauses(); const filter = queryString; this.queryText(filter); return this.queryText(); }; private setSqlFilter = (): string => { return this.queryBuilderViewModel().getSqlFilterFromClauses(); }; private setCqlFilter = (): string => { return this.queryBuilderViewModel().getCqlFilterFromClauses(); }; public isHelperEnabled = ko .computed(() => { return ( this.queryText() === this.unchangedText() || this.queryText() === undefined || this.queryText() === "" || this.isHelperActive() ); }) .extend({ notify: "always", }); public runQuery = (): void => { let filter = this.setFilter(); if (filter && userContext.apiType !== "Cassandra") { filter = filter.replace(/"/g, "'"); } const top = this.topValue(); const selectOptions = this._getSelectedResults(); const 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(); this.topValue(); this.selectText(); this.selectMessage(""); // clears the queryBuilder and adds a new blank clause this.queryBuilderViewModel().queryClauses.removeAll(); this.queryBuilderViewModel().addNewClause(); this._tableEntityListViewModel.tableQuery.filter = undefined; this._tableEntityListViewModel.tableQuery.top = undefined; this._tableEntityListViewModel.tableQuery.select = undefined; 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(headers: string[], getSelectMessage: (selectMessage: string) => void): void { this.columnOptions(headers); useSidePanel .getState() .openSidePanel( "Select Column", ); } public onselectQueryOptionsKeyDown = ( source: string, event: KeyboardEvent, headers: string[], getSelectMessage: (selectMessage: string) => void ): boolean => { if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) { this.selectQueryOptions(headers, getSelectMessage); event.stopPropagation(); return false; } return true; }; public getSelectMessage(): void { if (_.isEmpty(this.selectText()) || this.selectText() === undefined) { this.selectMessage(""); } else { this.selectMessage(`${this.selectText().length} of ${this.columnOptions().length} columns selected.`); } } public isSelected = ko.computed(() => { return !(_.isEmpty(this.selectText()) || this.selectText() === undefined); }); private setCheckToSave(): void { this.unchangedSaveText(this.setFilter()); this.unchangedSaveTop(this.topValue()); this.unchangedSaveSelect(this.selectText()); this.isSaveEnabled(false); } public checkIfBuilderChanged(): void { this.setFilter(); } }