Skip to content

Commit

Permalink
Migrate query source to React: Set of updates (#4457)
Browse files Browse the repository at this point in the history
  • Loading branch information
kravets-levko authored Dec 17, 2019
1 parent f165631 commit 192ad22
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { UserPreviewCard } from "@/components/PreviewCard";
import notification from "@/services/notification";
import { User } from "@/services/user";

import "./PermissionsEditorDialog.less";
import "./index.less";

const { Option } = Select;
const DEBOUNCE_SEARCH_DURATION = 200;
Expand Down
3 changes: 3 additions & 0 deletions client/app/components/app-view/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class AppViewComponent {
$rootScope.$on("$routeChangeSuccess", (event, route) => {
const $$route = route.$$route || { authenticated: true };
this.applyLayout($$route);
if (route.title) {
document.title = route.title;
}
});

$rootScope.$on("$routeChangeError", (event, current, previous, rejection) => {
Expand Down
79 changes: 79 additions & 0 deletions client/app/components/queries/ApiKeyDialog/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { clone, extend } from "lodash";
import React, { useMemo, useState, useCallback } from "react";
import PropTypes from "prop-types";
import Modal from "antd/lib/modal";
import Input from "antd/lib/input";
import Button from "antd/lib/button";
import { wrap as wrapDialog, DialogPropType } from "@/components/DialogWrapper";
import CodeBlock from "@/components/CodeBlock";
import { $http } from "@/services/ng";
import { clientConfig } from "@/services/auth";
import notification from "@/services/notification";

import "./index.less";

function ApiKeyDialog({ dialog, ...props }) {
const [query, setQuery] = useState(props.query);
const [updatingApiKey, setUpdatingApiKey] = useState(false);

const regenerateQueryApiKey = useCallback(() => {
setUpdatingApiKey(true);
$http
.post(`api/queries/${query.id}/regenerate_api_key`)
.success(data => {
setUpdatingApiKey(false);
setQuery(extend(clone(query), { api_key: data.api_key }));
})
.error(() => {
setUpdatingApiKey(false);
notification.error("Failed to update API key");
});
}, [query]);

const { csvUrl, jsonUrl } = useMemo(
() => ({
csvUrl: `${clientConfig.basePath}api/queries/${query.id}/results.csv?api_key=${query.api_key}`,
jsonUrl: `${clientConfig.basePath}api/queries/${query.id}/results.json?api_key=${query.api_key}`,
}),
[query.id, query.api_key]
);

return (
<Modal {...dialog.props} width={600} footer={<Button onClick={() => dialog.close(query)}>Close</Button>}>
<div className="query-api-key-dialog-wrapper">
<h5>API Key</h5>
<div className="m-b-20">
<Input.Group compact>
<Input readOnly value={query.api_key} />
{query.can_edit && (
<Button disabled={updatingApiKey} loading={updatingApiKey} onClick={regenerateQueryApiKey}>
Regenerate
</Button>
)}
</Input.Group>
</div>

<h5>Example API Calls:</h5>
<div className="m-b-10">
<label>Results in CSV format:</label>
<CodeBlock copyable>{csvUrl}</CodeBlock>
</div>
<div>
<label>Results in JSON format:</label>
<CodeBlock copyable>{jsonUrl}</CodeBlock>
</div>
</div>
</Modal>
);
}

ApiKeyDialog.propTypes = {
dialog: DialogPropType.isRequired,
query: PropTypes.shape({
id: PropTypes.number.isRequired,
api_key: PropTypes.string,
can_edit: PropTypes.bool,
}).isRequired,
};

export default wrapDialog(ApiKeyDialog);
17 changes: 17 additions & 0 deletions client/app/components/queries/ApiKeyDialog/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.query-api-key-dialog-wrapper {
.ant-input-group.ant-input-group-compact {
display: flex;
flex-wrap: nowrap;

.ant-input {
flex-grow: 1;
flex-shrink: 1;
}

.ant-btn {
flex-grow: 0;
flex-shrink: 0;
height: auto;
}
}
}
2 changes: 0 additions & 2 deletions client/app/directives/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import autofocus from "./autofocus";
import compareTo from "./compare-to";
import title from "./title";
import resizeEvent from "./resize-event";
import resizableToggle from "./resizable-toggle";

export default function init(ngModule) {
autofocus(ngModule);
compareTo(ngModule);
title(ngModule);
resizeEvent(ngModule);
resizableToggle(ngModule);
}
Expand Down
42 changes: 0 additions & 42 deletions client/app/directives/title.js

This file was deleted.

13 changes: 4 additions & 9 deletions client/app/pages/dashboards/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import template from "./dashboard.html";
import ShareDashboardDialog from "./ShareDashboardDialog";
import AddWidgetDialog from "@/components/dashboards/AddWidgetDialog";
import TextboxDialog from "@/components/dashboards/TextboxDialog";
import PermissionsEditorDialog from "@/components/permissions-editor/PermissionsEditorDialog";
import PermissionsEditorDialog from "@/components/PermissionsEditorDialog";
import notification from "@/services/notification";

import "./dashboard.less";
Expand All @@ -29,7 +29,6 @@ function DashboardCtrl(
$q,
$uibModal,
$scope,
Title,
AlertDialog,
Dashboard,
currentUser,
Expand Down Expand Up @@ -151,12 +150,7 @@ function DashboardCtrl(
? this.dashboard.widgets.filter(widget =>
Object.values(widget.getParameterMappings())
.filter(({ type }) => type === "dashboard-level")
.some(({ mapTo }) =>
_.includes(
updatedParameters.map(p => p.name),
mapTo
)
)
.some(({ mapTo }) => _.includes(updatedParameters.map(p => p.name), mapTo))
)
: this.dashboard.widgets;

Expand All @@ -172,7 +166,8 @@ function DashboardCtrl(
};

const renderDashboard = (dashboard, force) => {
Title.set(dashboard.name);
// TODO: Title should be updated after editing as well
document.title = dashboard.name;
this.extractGlobalParameters();
collectFilters(dashboard, force);
};
Expand Down
8 changes: 6 additions & 2 deletions client/app/pages/queries/QuerySource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ function QuerySource(props) {
recordEvent("view_source", "query", query.id);
}, [query.id]);

useEffect(() => {
document.title = query.name;
}, [query.name]);

const handleDataSourceChange = useCallback(
dataSourceId => {
if (dataSourceId) {
Expand Down Expand Up @@ -185,7 +189,7 @@ export default function init(ngModule) {
...routesToAngularRoutes(
[
{
path: "/queries/new2",
path: "/queries-react/new",
},
],
{
Expand All @@ -200,7 +204,7 @@ export default function init(ngModule) {
...routesToAngularRoutes(
[
{
path: "/queries/:queryId/source2",
path: "/queries-react/:queryId/source",
},
],
{
Expand Down
45 changes: 21 additions & 24 deletions client/app/pages/queries/components/QueryPageHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import Icon from "antd/lib/icon";
import { EditInPlace } from "@/components/EditInPlace";
import { FavoritesControl } from "@/components/FavoritesControl";
import { QueryTagsControl } from "@/components/tags-control/TagsControl";
import PermissionsEditorDialog from "@/components/PermissionsEditorDialog";
import ApiKeyDialog from "@/components/queries/ApiKeyDialog";
import getTags from "@/services/getTags";
import { clientConfig } from "@/services/auth";
import recordEvent from "@/services/recordEvent";

import { saveQuery, archiveQuery, duplicateQuery } from "../utils";
import { updateQuery, publishQuery, unpublishQuery, renameQuery, archiveQuery, duplicateQuery } from "../utils";

function getQueryTags() {
return getTags("api/queries/tags").then(tags => map(tags, t => t.name));
Expand Down Expand Up @@ -56,32 +56,18 @@ function createMenu(menu) {
export default function QueryPageHeader({ query, sourceMode, onChange }) {
const saveName = useCallback(
name => {
recordEvent("edit_name", "query", query.id);
const changes = { name };
const options = {};

if (query.is_draft && clientConfig.autoPublishNamedQueries && query.name !== "New Query") {
changes.is_draft = false;
options.successMessage = "Query saved and published";
}

saveQuery(query, changes, options).then(onChange);
renameQuery(query, name).then(onChange);
},
[query, onChange]
);

const saveTags = useCallback(
tags => {
saveQuery(query, { tags }).then(onChange);
updateQuery(query, { tags }).then(onChange);
},
[query, onChange]
);

const togglePublished = useCallback(() => {
recordEvent("toggle_published", "query", query.id);
saveQuery(query, { is_draft: !query.is_draft }).then(onChange);
}, [query, onChange]);

const selectedTab = null; // TODO: replace with actual value
const canViewSource = true; // TODO: replace with actual value
const canForkQuery = () => true; // TODO: replace with actual value
Expand Down Expand Up @@ -116,26 +102,33 @@ export default function QueryPageHeader({ query, sourceMode, onChange }) {
isAvailable: !query.isNew() && query.can_edit && !query.is_archived && showPermissionsControl,
title: "Manage Permissions",
onClick: () => {
console.log("showManagePermissionsModal");
const aclUrl = `api/queries/${query.id}/acl`;
PermissionsEditorDialog.showModal({
aclUrl,
context: "query",
author: query.user,
});
},
},
unpublish: {
isAvailable: !query.isNew() && query.can_edit && !query.is_draft,
title: "Unpublish",
onClick: togglePublished,
onClick: () => {
unpublishQuery(query).then(onChange);
},
},
},
{
showAPIKey: {
isAvailable: !query.isNew(),
title: "Show API Key",
onClick: () => {
console.log("showApiKey");
ApiKeyDialog.showModal({ query }).result.then(onChange);
},
},
},
]),
[showPermissionsControl, query, togglePublished, onChange]
[showPermissionsControl, query, onChange]
);

return (
Expand All @@ -162,7 +155,11 @@ export default function QueryPageHeader({ query, sourceMode, onChange }) {
</h3>
<span className="flex-fill" />
{query.is_draft && !query.is_archived && !query.isNew() && query.can_edit && (
<Button className="hidden-xs m-r-5" onClick={togglePublished}>
<Button
className="hidden-xs m-r-5"
onClick={() => {
publishQuery(query).then(onChange);
}}>
<i className="fa fa-paper-plane m-r-5" /> Publish
</Button>
)}
Expand Down
29 changes: 27 additions & 2 deletions client/app/pages/queries/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
import saveQuery from "./saveQuery";
import updateQuery from "./updateQuery";
import archiveQuery from "./archiveQuery";
import duplicateQuery from "./duplicateQuery";
import { clientConfig } from "@/services/auth";
import recordEvent from "@/services/recordEvent";

export { saveQuery, archiveQuery, duplicateQuery };
function publishQuery(query) {
recordEvent("toggle_published", "query", query.id);
return updateQuery(query, { is_draft: false });
}

function unpublishQuery(query) {
recordEvent("toggle_published", "query", query.id);
return updateQuery(query, { is_draft: true });
}

function renameQuery(query, name) {
recordEvent("edit_name", "query", query.id);
const changes = { name };
const options = {};

if (query.is_draft && clientConfig.autoPublishNamedQueries && query.name !== "New Query") {
changes.is_draft = false;
options.successMessage = "Query saved and published";
}

return updateQuery(query, changes, options);
}

export { updateQuery, archiveQuery, duplicateQuery, publishQuery, unpublishQuery, renameQuery };
Loading

0 comments on commit 192ad22

Please sign in to comment.