integrate with API to show query name and sql query for live query activity (#8864)

* integrate with API to show query name and sql query for live query activity

* move ShowQueryModal to common components
This commit is contained in:
Gabriel Hernandez
2022-11-29 16:55:17 +00:00
committed by GitHub
parent 486590186a
commit 550feef040
6 changed files with 53 additions and 22 deletions
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useRef, useState } from "react";
import { useQuery } from "react-query";
import { isEmpty } from "lodash";
@@ -6,8 +6,9 @@ import activitiesAPI, {
IActivitiesResponse,
} from "services/entities/activities";
import { IActivity } from "interfaces/activity";
import { IActivity, IActivityDetails } from "interfaces/activity";
import ShowQueryModal from "components/modals/ShowQueryModal";
import DataError from "components/DataError";
import Button from "components/buttons/Button";
import Spinner from "components/Spinner";
@@ -16,7 +17,6 @@ import FleetIcon from "components/icons/FleetIcon";
import ActivityItem from "./ActivityItem";
const baseClass = "activity-feed";
interface IActvityCardProps {
setShowActivityFeedTitle: (showActivityFeedTitle: boolean) => void;
}
@@ -28,6 +28,8 @@ const ActivityFeed = ({
}: IActvityCardProps): JSX.Element => {
const [pageIndex, setPageIndex] = useState(0);
const [showMore, setShowMore] = useState(true);
const [showShowQueryModal, setShowShowQueryModal] = useState(false);
const queryShown = useRef("");
const {
data: activities,
@@ -74,6 +76,11 @@ const ActivityFeed = ({
setPageIndex(pageIndex + 1);
};
const handleDetailsClick = (details: IActivityDetails) => {
queryShown.current = details.query_sql ?? "";
setShowShowQueryModal(true);
};
const renderError = () => {
return <DataError card />;
};
@@ -91,12 +98,6 @@ const ActivityFeed = ({
);
};
const renderActivityBlock = (activity: IActivity) => {
const { id } = activity;
return <ActivityItem activity={activity} key={id} />;
};
// Renders opaque information as activity feed is loading
const opacity = isFetchingActivities ? { opacity: 0.4 } : { opacity: 1 };
@@ -113,7 +114,13 @@ const ActivityFeed = ({
</div>
)}
<div style={opacity}>
{activities?.map((activity) => renderActivityBlock(activity))}
{activities?.map((activity) => (
<ActivityItem
activity={activity}
onDetailsClick={handleDetailsClick}
key={activity.id}
/>
))}
</div>
</>
)}
@@ -142,6 +149,12 @@ const ActivityFeed = ({
</Button>
</div>
)}
{showShowQueryModal && (
<ShowQueryModal
query={queryShown.current}
onCancel={() => setShowShowQueryModal(false)}
/>
)}
</div>
);
};
@@ -82,6 +82,7 @@ describe("Activity Feed", () => {
screen.getByText("ran the query as a live query .")
).toBeInTheDocument();
expect(screen.getByText("Test Query")).toBeInTheDocument();
expect(screen.getByText("Show query")).toBeInTheDocument();
});
it("renders an applied_spec_pack type activity", () => {
@@ -2,7 +2,7 @@ import React from "react";
import { find, lowerCase, noop } from "lodash";
import { formatDistanceToNowStrict } from "date-fns";
import { ActivityType, IActivity } from "interfaces/activity";
import { ActivityType, IActivity, IActivityDetails } from "interfaces/activity";
import { addGravatarUrlToResource } from "utilities/helpers";
import Avatar from "components/Avatar";
import Button from "components/buttons/Button";
@@ -14,7 +14,10 @@ const DEFAULT_GRAVATAR_URL =
"https://www.gravatar.com/avatar/00000000000000000000000000000000?d=blank&size=200";
const TAGGED_TEMPLATES = {
liveQueryActivityTemplate: (activity: IActivity) => {
liveQueryActivityTemplate: (
activity: IActivity,
onDetailsClick?: (details: IActivityDetails) => void
) => {
const count = activity.details?.targets_count;
const queryName = activity.details?.query_name;
const querySql = activity.details?.query_sql;
@@ -37,15 +40,12 @@ const TAGGED_TEMPLATES = {
<span>
ran {savedQueryName} a live query {hostCount}.
</span>
{/* TODO: the API does not yet send back querySql yet so will implement
the onClick handler when we get it. We dont show this for now. */}
{false && (
{querySql && (
<>
<Button
className={`${baseClass}__show-query-link`}
variant="text-link"
onClick={noop}
onClick={() => onDetailsClick?.({ query_sql: querySql })}
>
Show query{" "}
<Icon className={`${baseClass}__show-query-icon`} name="eye" />
@@ -107,10 +107,16 @@ const TAGGED_TEMPLATES = {
},
};
const getDetail = (activity: IActivity) => {
const getDetail = (
activity: IActivity,
onDetailsClick?: (details: IActivityDetails) => void
) => {
switch (activity.type) {
case ActivityType.LiveQuery: {
return TAGGED_TEMPLATES.liveQueryActivityTemplate(activity);
return TAGGED_TEMPLATES.liveQueryActivityTemplate(
activity,
onDetailsClick
);
}
case ActivityType.AppliedSpecPack: {
return TAGGED_TEMPLATES.editPackCtlActivityTemplate();
@@ -138,9 +144,18 @@ const getDetail = (activity: IActivity) => {
interface IActivityItemProps {
activity: IActivity;
/** A handler for handling clicking on the details of an activity. Not all
* activites have more details so this is optional. An example of additonal
* details is showing the query for a live query action.
*/
onDetailsClick?: (details: IActivityDetails) => void;
}
const ActivityItem = ({ activity }: IActivityItemProps) => {
const ActivityItem = ({
activity,
onDetailsClick = noop,
}: IActivityItemProps) => {
const { actor_email } = activity;
const { gravatarURL } = actor_email
? addGravatarUrlToResource({ email: actor_email })
@@ -156,7 +171,8 @@ const ActivityItem = ({ activity }: IActivityItemProps) => {
<div className={`${baseClass}__details`}>
<p>
<span className={`${baseClass}__details-topline`}>
<b>{activity.actor_full_name}</b> {getDetail(activity)}
<b>{activity.actor_full_name}</b>{" "}
{getDetail(activity, onDetailsClick)}
</span>
<br />
<span className={`${baseClass}__details-bottomline`}>
@@ -29,10 +29,11 @@ import Spinner from "components/Spinner";
import TeamsDropdown from "components/TeamsDropdown";
import TableDataError from "components/DataError";
import MainContent from "components/MainContent";
import ShowQueryModal from "components/modals/ShowQueryModal";
import ScheduleTable from "./components/ScheduleTable";
import ScheduleEditorModal from "./components/ScheduleEditorModal";
import RemoveScheduledQueryModal from "./components/RemoveScheduledQueryModal";
import ShowQueryModal from "./components/ShowQueryModal";
const baseClass = "manage-schedule-page";