Skip to content

Commit

Permalink
Keyboard shortcuts; handle parameters changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kravets-levko committed Dec 23, 2019
1 parent 14e0b36 commit 2320544
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
37 changes: 34 additions & 3 deletions client/app/pages/queries/QuerySource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function QuerySource(props) {
const refreshSchemaTokenRef = useRef(null);
const [selectedTab, setSelectedTab] = useVisualizationTabHandler(query.visualizations);
const parameters = useMemo(() => query.getParametersDefs(), [query]);
const [dirtyParameters, setDirtyParameters] = useState(query.getParameters().hasPendingValues());

const { queryResult, queryResultData, isQueryExecuting, executeQuery, executeAdhocQuery } = useQueryExecute(query);

Expand Down Expand Up @@ -246,9 +247,9 @@ function QuerySource(props) {

const canExecuteQuery = useMemo(
() =>
!query.getParameters().hasPendingValues() &&
!dirtyParameters &&
(query.is_safe || (currentUser.hasPermission("execute_query") && dataSource && !dataSource.view_only)),
[query, dataSource]
[dirtyParameters, query, dataSource]
);
const isDirty = query.query !== originalQuerySource;

Expand All @@ -261,6 +262,20 @@ function QuerySource(props) {
}
}, [query, isDirty, selectedText, executeQuery, executeAdhocQuery]);

useEffect(() => {
const shortcuts = {
"mod+enter": doExecuteQuery,
"alt+enter": doExecuteQuery,
"mod+s": saveQuery,
"mod+p": openAddNewParameterDialog,
"mod+shift+f": () => formatQuery,
};
KeyboardShortcuts.bind(shortcuts);
return () => {
KeyboardShortcuts.unbind(shortcuts);
};
}, [doExecuteQuery, saveQuery, openAddNewParameterDialog, formatQuery]);

const modKey = KeyboardShortcuts.modKey;

return (
Expand Down Expand Up @@ -371,7 +386,23 @@ function QuerySource(props) {
style={{ left: 0, top: 0, right: 0, bottom: 0 }}>
{query.hasParameters() && (
<div className="p-t-15 p-b-5">
<Parameters parameters={parameters} />
<Parameters
editable={query.can_edit}
disableUrlUpdate={query.isNew()}
parameters={parameters}
onPendingValuesChange={() => setDirtyParameters(query.getParameters().hasPendingValues()) }
onValuesChange={() => {
setDirtyParameters(false);
doExecuteQuery();
}}
onParametersEdit={() => {
// save if query clean
// https://discuss.redash.io/t/query-unsaved-changes-indication/3302/5
if (!isDirty) {
saveQuery();
}
}}
/>
</div>
)}
{queryResult && queryResultData.status !== "done" && (
Expand Down
11 changes: 7 additions & 4 deletions client/app/pages/queries/utils/useQueryExecute.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { useState, useMemo } from "react";
import { useState, useMemo, useEffect } from "react";
import { includes } from "lodash";
import useQueryResult from "@/lib/hooks/useQueryResult";
import { useCallback } from "react";
import { $location } from "@/services/ng";
import { useEffect } from "react";

function getMaxAge() {
const maxAge = $location.search().maxAge;
return maxAge !== undefined ? maxAge : -1;
}

export default function useQueryExecute(query) {
const [queryResult, setQueryResult] = useState(
query.hasResult() || query.paramsRequired() ? query.getQueryResult(getMaxAge()) : null
// This variable should be initialized only once on component mount
const initialQueryResult = useMemo(
() => (query.hasResult() || query.paramsRequired() ? query.getQueryResult(getMaxAge()) : null),
[] // eslint-disable-line react-hooks/exhaustive-deps
);

const [queryResult, setQueryResult] = useState(initialQueryResult);
const queryResultData = useQueryResult(queryResult);
const isQueryExecuting = useMemo(() => queryResult && !includes(["done", "failed"], queryResultData.status), [
queryResult,
Expand Down
8 changes: 8 additions & 0 deletions client/app/services/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
each,
some,
clone,
find,
} from "lodash";

import { Parameter } from "./parameters";
Expand Down Expand Up @@ -68,6 +69,13 @@ class Parameters {

updateParameters(update) {
if (this.query.query && this.query.query === this.cachedQueryText) {
const parameters = this.query.options.parameters;
const hasUnprocessedParameters = find(parameters, p => !(p instanceof Parameter));
if (hasUnprocessedParameters) {
this.query.options.parameters = map(parameters, p =>
p instanceof Parameter ? p : Parameter.create(p, this.query.id)
);
}
return;
}

Expand Down

0 comments on commit 2320544

Please sign in to comment.