Skip to content

Commit

Permalink
Visualization Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrieldutra committed Dec 18, 2019
1 parent 0c468b8 commit 8a40649
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 43 deletions.
99 changes: 57 additions & 42 deletions client/app/pages/queries/QueryView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,84 @@ import recordEvent from "@/services/recordEvent";
import QueryVisualizationTabs from "./components/QueryVisualizationTabs";
import { EditVisualizationButton } from "@/components/EditVisualizationButton";
import useQueryResult from "@/lib/hooks/useQueryResult";
import useForceUpdate from "@/lib/hooks/useForceUpdate";
import { pluralize, durationHumanize } from "@/filters";
import { updateQuery } from "./utils";

import "./query-view.less";
import useVisualizationTabHandler from "./utils/useVisualizationTabHandler";
import deleteQueryVisualization from "./utils/deleteQueryVisualization";

function QueryPropertyList({ query, dataSource }) {
return (
<div className="query-property-list">
<div className="query-property">
<img src={query.user.profile_image_url} className="profile__image_thumb" alt={query.user.name} />
<strong>{query.user.name}</strong>
{" created "}
<TimeAgo date={query.created_at} />
</div>
<div className="query-property">
<img
src={query.last_modified_by.profile_image_url}
className="profile__image_thumb"
alt={query.last_modified_by.name}
/>
<strong>{query.last_modified_by.name}</strong>
{" updated "}
<TimeAgo date={query.updated_at} />
</div>
{dataSource && (
<div className="query-property">
<img src={`${IMG_ROOT}/${dataSource.type}.png`} width="20" alt={dataSource.type} />
{dataSource.name}
</div>
)}
<span className="flex-fill" />
<div className="query-property">
<i className="zmdi zmdi-refresh m-r-5" />
Refresh Schedule
<a className="clickable m-l-5">
<SchedulePhrase schedule={query.schedule} isNew={false} />
</a>
</div>
</div>
);
}

function QueryView(props) {
const [query, setQuery] = useState(props.query);
const [selectedTab, setSelectedTab] = useVisualizationTabHandler(query.visualizations);
const currentVisualization = useMemo(() => find(query.visualizations, { id: selectedTab }), [query.visualizations, selectedTab])
const currentVisualization = useMemo(() => find(query.visualizations, { id: selectedTab }), [
query.visualizations,
selectedTab,
]);
const parameters = useMemo(() => query.getParametersDefs(), [query]);
const [dataSource, setDataSource] = useState();
const queryResult = useMemo(() => query.getQueryResult(), [query]);
const queryResultData = useQueryResult(queryResult);
const forceUpdate = useForceUpdate();

const saveDescription = useCallback(
(description) => {
description => {
recordEvent("edit_description", "query", query.id);
updateQuery(query, { description }).then(setQuery);
},
[query],
[query]
);

const openVisualizationEditor = useCallback(
(visId) => {
visId => {
EditVisualizationDialog.showModal({
query,
visualization: find(query.visualizations, { id: visId }),
queryResult,
}).result.then(visualization => {
setSelectedTab(visualization.id);
// TODO: Properly update state
forceUpdate();
});
},
[query, queryResult, setSelectedTab],
[forceUpdate, query, queryResult, setSelectedTab]
);

useEffect(() => {
Expand All @@ -78,37 +121,7 @@ function QueryView(props) {
ignoreBlanks={false}
/>
<Divider />
<div className="query-property-list">
<div className="query-property">
<img src={query.user.profile_image_url} className="profile__image_thumb" alt={query.user.name} />
<strong>{query.user.name}</strong>
{" created "}
<TimeAgo date={query.created_at} />
</div>
<div className="query-property">
<img
src={query.last_modified_by.profile_image_url}
className="profile__image_thumb"
alt={query.last_modified_by.name}
/>
<strong>{query.last_modified_by.name}</strong>
{" updated "}
<TimeAgo date={query.updated_at} />
</div>
{dataSource && (
<div className="query-property">
<img src={`${IMG_ROOT}/${dataSource.type}.png`} width="20" alt={dataSource.type} />
{dataSource.name}
</div>
)}
<span className="flex-fill" />
<div className="query-property">
<i className="zmdi zmdi-refresh m-r-5" />Refresh Schedule
<a className="clickable m-l-5">
<SchedulePhrase schedule={query.schedule} isNew={false} />
</a>
</div>
</div>
<QueryPropertyList query={query} dataSource={dataSource} />
</div>
<div className="query-content tiled bg-white p-15 m-t-15">
{query.hasParameters() && <Parameters parameters={parameters} />}
Expand All @@ -120,6 +133,7 @@ function QueryView(props) {
selectedTab={selectedTab}
onChangeTab={setSelectedTab}
onClickNewVisualization={openVisualizationEditor}
onDeleteVisualization={vis => deleteQueryVisualization(query, vis).then(setQuery)}
/>
<Divider />
<div className="d-flex align-items-center">
Expand All @@ -129,9 +143,11 @@ function QueryView(props) {
queryResult={queryResult}
queryExecuting={false} /* TODO: Replace with executing state */
showEmbedDialog={() => EmbedQueryDialog.showEmbedDialog({ query, visualization: currentVisualization })}
openAddToDashboardForm={() => AddToDashboardDialog.showModal({
visualization: currentVisualization,
})}
openAddToDashboardForm={() =>
AddToDashboardDialog.showModal({
visualization: currentVisualization,
})
}
/>
{queryResultData.status === "done" && (
<>
Expand All @@ -147,8 +163,7 @@ function QueryView(props) {
<span className="flex-fill" />
{queryResultData.status === "done" && (
<span className="m-r-10 hidden-xs">
Updated{" "}
<TimeAgo date={queryResult.query_result.retrieved_at} />
Updated <TimeAgo date={queryResult.query_result.retrieved_at} />
</span>
)}
<Button type="primary">Execute</Button>
Expand Down
15 changes: 15 additions & 0 deletions client/app/pages/queries/utils/deleteQueryVisualization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { clone, extend, filter } from "lodash";
import { Visualization } from "@/services/visualization";
import notification from "@/services/notification";

export default function deleteQueryVisualization(query, visualization) {
return Visualization.delete({ id: visualization.id })
.$promise.then(() => {
const filteredVisualizations = filter(query.visualizations, v => v.id !== visualization.id);
return Promise.resolve(extend(clone(query), { visualizations: filteredVisualizations }));
})
.catch(() => {
notification.error("Error deleting visualization.", "Maybe it's used in a dashboard?");
return Promise.reject();
});
}
9 changes: 8 additions & 1 deletion client/app/pages/queries/utils/useVisualizationTabHandler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState, useEffect, useMemo } from "react";
import { first, orderBy } from "lodash";
import { first, orderBy, find } from "lodash";
import { $location, $rootScope } from "@/services/ng";

function updateUrlHash(...args) {
Expand Down Expand Up @@ -28,5 +28,12 @@ export default function useVisualizationTabHandler(visualizations) {
return unwatch;
}, [firstVisualization.id, selectedTab]);

// make sure selectedTab is in visualizations
useEffect(() => {
if (!find(visualizations, { id: selectedTab })) {
setSelectedTab(firstVisualization.id);
}
}, [firstVisualization.id, selectedTab, visualizations]);

return [selectedTab, setSelectedTab];
}

0 comments on commit 8a40649

Please sign in to comment.