mirror of
https://github.com/fleetdm/fleet
synced 2026-05-06 06:48:54 +00:00
Schedules Page: Surface all teams schedule on team schedule page (#2080)
* Render inherited queries table on teams page * e2e team schedules on e2e premium testing
This commit is contained in:
parent
fc00940660
commit
7dee7c56ef
9 changed files with 356 additions and 93 deletions
1
changes/issue-1894-surface-inherited-queries
Normal file
1
changes/issue-1894-surface-inherited-queries
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Fleet premium teams schedules surfaces inherited queries from All teams (global) schedule
|
||||
|
|
@ -9,50 +9,43 @@ describe(
|
|||
cy.login();
|
||||
});
|
||||
|
||||
// TODO - Fix tests according to improved query experience - MP
|
||||
it("Create, check, edit, and delete a query successfully and create, edit, and delete a global scheduled query successfully", () => {
|
||||
cy.visit("/queries/manage");
|
||||
|
||||
cy.findByRole("button", { name: /create new query/i }).should("exist");
|
||||
// cy.findByRole("button", { name: /create new query/i }).click();
|
||||
cy.findByRole("button", { name: /create new query/i }).click();
|
||||
|
||||
// cy.findByLabelText(/query name/i)
|
||||
// .click()
|
||||
// .type("Query all window crashes");
|
||||
// Using class selector because third party element doesn't work with Cypress Testing Selector Library
|
||||
cy.get(".ace_scroller")
|
||||
.click({ force: true })
|
||||
.type("{selectall}SELECT * FROM windows_crashes;");
|
||||
|
||||
// // Using class selector because third party element doesn't work with Cypress Testing Selector Library
|
||||
// cy.get(".ace_scroller")
|
||||
// .click({ force: true })
|
||||
// .type("{selectall}{backspace}SELECT * FROM windows_crashes;");
|
||||
cy.findByRole("button", { name: /save/i }).click();
|
||||
|
||||
// cy.findByLabelText(/description/i)
|
||||
// .click()
|
||||
// .type("See all window crashes");
|
||||
cy.findByLabelText(/name/i).click().type("Query all window crashes");
|
||||
|
||||
// cy.findByRole("button", { name: /save/i }).click();
|
||||
cy.findByLabelText(/description/i)
|
||||
.click()
|
||||
.type("See all window crashes");
|
||||
|
||||
// cy.findByRole("button", { name: /save as new/i }).click();
|
||||
cy.findByRole("button", { name: /save query/i }).click();
|
||||
|
||||
// Just refreshes to create new query, needs success alert to user that they created a query
|
||||
// cy.visit("/queries/manage");
|
||||
cy.findByText(/query created/i).should("exist");
|
||||
cy.findByText(/back to queries/i).should("exist");
|
||||
cy.visit("/queries/manage");
|
||||
|
||||
// cy.findByText(/query all/i).click();
|
||||
cy.findByText(/query all/i).click();
|
||||
|
||||
// cy.findByText(/edit & run query/i).should("exist");
|
||||
cy.findByText(/run query/i).should("exist");
|
||||
|
||||
// cy.get(".ace_scroller")
|
||||
// .click({ force: true })
|
||||
// .type(
|
||||
// "{selectall}{backspace}SELECT datetime, username FROM windows_crashes;"
|
||||
// );
|
||||
cy.get(".ace_scroller")
|
||||
.click({ force: true })
|
||||
.type("{selectall}SELECT datetime, username FROM windows_crashes;");
|
||||
|
||||
// cy.findByRole("button", { name: /save/i }).click();
|
||||
cy.findByRole("button", { name: /^Save$/ }).click();
|
||||
|
||||
// cy.findByRole("button", { name: /save changes/i }).click();
|
||||
cy.findByText(/query updated/i).should("be.visible");
|
||||
|
||||
// cy.findByText(/query updated/i).should("be.visible");
|
||||
|
||||
// // Test Schedules
|
||||
// // Start e2e test for schedules
|
||||
// cy.visit("/schedule/manage");
|
||||
|
||||
// cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
|
|
@ -85,64 +78,67 @@ describe(
|
|||
// .contains("button", /schedule/i)
|
||||
// .click();
|
||||
|
||||
// cy.visit("/schedule/manage");
|
||||
// cy.visit("/schedule/manage");
|
||||
|
||||
// cy.wait(3000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
// cy.findByText(/query all window crashes/i).should("exist");
|
||||
// cy.wait(2000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
// cy.findByText(/query all window crashes/i).should("exist");
|
||||
|
||||
// cy.findByText(/actions/i).click();
|
||||
// cy.findByText(/edit/i).click();
|
||||
// cy.findByText(/actions/i).click();
|
||||
// cy.findByText(/edit/i).click();
|
||||
|
||||
// cy.get(
|
||||
// ".schedule-editor-modal__form-field--frequency > .dropdown__select"
|
||||
// ).click();
|
||||
// cy.get(
|
||||
// ".schedule-editor-modal__form-field--frequency > .dropdown__select"
|
||||
// ).click();
|
||||
|
||||
// cy.findByText(/every 6 hours/i).click();
|
||||
// cy.findByText(/every 6 hours/i).click();
|
||||
|
||||
// cy.findByText(/show advanced options/i).click();
|
||||
// cy.findByText(/show advanced options/i).click();
|
||||
|
||||
// cy.findByText(/ignore removals/i).click();
|
||||
// cy.findByText(/snapshot/i).click();
|
||||
// cy.findByText(/ignore removals/i).click();
|
||||
// cy.findByText(/snapshot/i).click();
|
||||
|
||||
// cy.get(".schedule-editor-modal__form-field--shard > .input-field")
|
||||
// .click()
|
||||
// .type("{selectall}{backspace}10");
|
||||
// cy.get(".schedule-editor-modal__form-field--shard > .input-field")
|
||||
// .click()
|
||||
// .type("{selectall}{backspace}10");
|
||||
|
||||
// cy.get(".schedule-editor-modal__btn-wrap")
|
||||
// .contains("button", /schedule/i)
|
||||
// .click();
|
||||
// cy.get(".schedule-editor-modal__btn-wrap")
|
||||
// .contains("button", /schedule/i)
|
||||
// .click();
|
||||
|
||||
// cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
// cy.findByText(/actions/i).click();
|
||||
// cy.findByText(/remove/i).click();
|
||||
// cy.visit("/schedule/manage");
|
||||
|
||||
// cy.get(".remove-scheduled-query-modal__btn-wrap")
|
||||
// .contains("button", /remove/i)
|
||||
// .click();
|
||||
// cy.wait(2000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
// cy.findByText(/actions/i).click();
|
||||
// cy.findByText(/remove/i).click();
|
||||
|
||||
// cy.findByText(/query all window crashes/i).should("not.exist");
|
||||
// // End Test Schedules
|
||||
// cy.get(".remove-scheduled-query-modal__btn-wrap")
|
||||
// .contains("button", /remove/i)
|
||||
// .click();
|
||||
|
||||
// cy.visit("/queries/manage");
|
||||
// cy.findByText(/query all window crashes/i).should("not.exist");
|
||||
|
||||
// cy.findByText(/query all window crashes/i)
|
||||
// .parent()
|
||||
// .parent()
|
||||
// .within(() => {
|
||||
// cy.get(".fleet-checkbox__input").check({ force: true });
|
||||
// });
|
||||
// // End e2e test for schedules
|
||||
|
||||
// cy.findByRole("button", { name: /delete/i }).click();
|
||||
cy.visit("/queries/manage");
|
||||
|
||||
// // Can't figure out how attach findByRole onto modal button
|
||||
// // Can't use findByText because delete button under modal
|
||||
// cy.get(".remove-query-modal")
|
||||
// .contains("button", /delete/i)
|
||||
// .click();
|
||||
cy.findByText(/query all window crashes/i)
|
||||
.parent()
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get(".fleet-checkbox__input").check({ force: true });
|
||||
});
|
||||
|
||||
// cy.findByText(/successfully removed query/i).should("be.visible");
|
||||
cy.findByRole("button", { name: /delete/i }).click();
|
||||
|
||||
// cy.findByText(/query all/i).should("not.exist");
|
||||
// Can't figure out how attach findByRole onto modal button
|
||||
// Can't use findByText because delete button under modal
|
||||
cy.get(".remove-query-modal")
|
||||
.contains("button", /delete/i)
|
||||
.click();
|
||||
|
||||
cy.findByText(/successfully removed query/i).should("be.visible");
|
||||
|
||||
cy.findByText(/query all/i).should("not.exist");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -65,13 +65,11 @@ describe("Free tier - Observer user", () => {
|
|||
cy.findByText(/show sql/i).click();
|
||||
cy.findByRole("button", { name: /run query/i }).should("exist");
|
||||
|
||||
cy.visit("/queries/manage");
|
||||
|
||||
cy.findByText(/get authorized/i).should("not.exist");
|
||||
|
||||
// On the Profile page, they should…
|
||||
// See Observer in Role section, and no Team section
|
||||
cy.visit("/profile");
|
||||
|
||||
cy.wait(2000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByText(/teams/i).should("not.exist");
|
||||
cy.findByText("Role")
|
||||
.next()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ describe("Teams flow", () => {
|
|||
});
|
||||
|
||||
/* TODO fix and reenable
|
||||
This test is causing major flake issues due to the dropdown menu
|
||||
This test is causing major flake issues due to the dropdown menu */
|
||||
|
||||
it("Create, edit, and delete a team successfully", () => {
|
||||
cy.visit("/settings/teams");
|
||||
|
|
@ -44,13 +44,77 @@ describe("Teams flow", () => {
|
|||
cy.contains(/config:/i).should("be.visible");
|
||||
cy.contains(/options:/i).should("be.visible");
|
||||
|
||||
// Check team in schedules
|
||||
cy.visit("/queries/manage");
|
||||
|
||||
cy.findByRole("button", { name: /create new query/i }).click();
|
||||
|
||||
// Using class selector because third party element doesn't work with Cypress Testing Selector Library
|
||||
cy.get(".ace_scroller")
|
||||
.click({ force: true })
|
||||
.type("{selectall}SELECT * FROM windows_crashes;");
|
||||
|
||||
cy.findByRole("button", { name: /save/i }).click();
|
||||
|
||||
cy.findByLabelText(/name/i).click().type("Query all window crashes");
|
||||
|
||||
cy.findByLabelText(/description/i)
|
||||
.click()
|
||||
.type("See all window crashes");
|
||||
|
||||
cy.findByRole("button", { name: /save query/i }).click();
|
||||
|
||||
cy.visit("/schedule/manage");
|
||||
|
||||
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
|
||||
cy.findByRole("button", { name: /schedule a query/i }).click();
|
||||
|
||||
cy.findByText(/select query/i).click();
|
||||
|
||||
cy.findByText(/query all window crashes/i).click();
|
||||
|
||||
cy.get(
|
||||
".schedule-editor-modal__form-field--frequency > .dropdown__select"
|
||||
).click();
|
||||
|
||||
cy.findByText(/every week/i).click();
|
||||
|
||||
cy.findByText(/show advanced options/i).click();
|
||||
|
||||
cy.get(
|
||||
".schedule-editor-modal__form-field--logging > .dropdown__select"
|
||||
).click();
|
||||
|
||||
cy.findByText(/ignore removals/i).click();
|
||||
|
||||
cy.get(".schedule-editor-modal__form-field--shard > .input-field")
|
||||
.click()
|
||||
.type("50");
|
||||
|
||||
cy.get(".schedule-editor-modal__btn-wrap")
|
||||
.contains("button", /schedule/i)
|
||||
.click();
|
||||
|
||||
cy.visit("/schedule/manage");
|
||||
|
||||
cy.wait(2000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByText(/all teams/i).click();
|
||||
cy.findByText(/valor/i).click();
|
||||
|
||||
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByText(/query all window crashes/i).should("not.exist");
|
||||
cy.findByText(/inherited query/i).click();
|
||||
cy.findByText(/query all window crashes/i).should("exist");
|
||||
|
||||
// Edit Team
|
||||
cy.visit("/settings/teams");
|
||||
|
||||
cy.contains("Valor").get(".Select-arrow-zone").click();
|
||||
|
||||
// need force:true for dropdown
|
||||
cy.findByText(/edit/i).click({ force: true });
|
||||
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByText(/actions/i).click({ force: true });
|
||||
cy.findByText(/edit/i).click({ force: true }); // need force:true for dropdown
|
||||
|
||||
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByLabelText(/team name/i)
|
||||
.click()
|
||||
.type("{selectall}{backspace}Mystic");
|
||||
|
|
@ -66,6 +130,7 @@ describe("Teams flow", () => {
|
|||
|
||||
cy.findByText(/delete/i).click({ force: true });
|
||||
|
||||
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByRole("button", { name: /delete/i }).click();
|
||||
|
||||
cy.findByText(/successfully deleted/i).should("be.visible");
|
||||
|
|
@ -77,5 +142,4 @@ describe("Teams flow", () => {
|
|||
|
||||
cy.findByText(/mystic/i).should("not.exist");
|
||||
});
|
||||
*/
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import enrollSecretInterface from "interfaces/enroll_secret";
|
|||
import EnrollSecretTable from "components/config/EnrollSecretTable";
|
||||
import InputField from "components/forms/fields/InputField";
|
||||
import OrgLogoIcon from "components/icons/OrgLogoIcon";
|
||||
import Slider from "components/forms/fields/Slider";
|
||||
import validate from "components/forms/admin/AppConfigForm/validate";
|
||||
import IconToolTip from "components/IconToolTip";
|
||||
import InfoBanner from "components/InfoBanner/InfoBanner";
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import paths from "router/paths";
|
|||
import Button from "components/buttons/Button";
|
||||
// @ts-ignore
|
||||
import Dropdown from "components/forms/fields/Dropdown";
|
||||
import IconToolTip from "components/IconToolTip";
|
||||
import TableDataError from "components/TableDataError";
|
||||
import ScheduleListWrapper from "./components/ScheduleListWrapper";
|
||||
import ScheduleEditorModal from "./components/ScheduleEditorModal";
|
||||
|
|
@ -33,8 +34,10 @@ import RemoveScheduledQueryModal from "./components/RemoveScheduledQueryModal";
|
|||
const baseClass = "manage-schedule-page";
|
||||
|
||||
const renderTable = (
|
||||
onRemoveScheduledQueryClick: React.MouseEventHandler<HTMLButtonElement>,
|
||||
onEditScheduledQueryClick: React.MouseEventHandler<HTMLButtonElement>,
|
||||
onRemoveScheduledQueryClick: (selectIds: number[]) => void,
|
||||
onEditScheduledQueryClick: (
|
||||
selectedQuery: IGlobalScheduledQuery | ITeamScheduledQuery
|
||||
) => void,
|
||||
allScheduledQueriesList: IGlobalScheduledQuery[] | ITeamScheduledQuery[],
|
||||
allScheduledQueriesError: { name: string; reason: string }[],
|
||||
toggleScheduleEditorModal: () => void,
|
||||
|
|
@ -55,6 +58,26 @@ const renderTable = (
|
|||
);
|
||||
};
|
||||
|
||||
const renderAllTeamsTable = (
|
||||
teamId: number,
|
||||
allTeamsScheduledQueriesList: IGlobalScheduledQuery[],
|
||||
allTeamsScheduledQueriesError: { name: string; reason: string }[]
|
||||
): JSX.Element => {
|
||||
if (Object.keys(allTeamsScheduledQueriesError).length > 0) {
|
||||
return <TableDataError />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`${baseClass}__all-teams-table`}>
|
||||
<ScheduleListWrapper
|
||||
inheritedQueries
|
||||
allScheduledQueriesList={allTeamsScheduledQueriesList}
|
||||
teamId={teamId}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface ITeamSchedulesPageProps {
|
||||
params: {
|
||||
team_id: string;
|
||||
|
|
@ -139,6 +162,18 @@ const ManageSchedulePage = (props: ITeamSchedulesPageProps): JSX.Element => {
|
|||
const allScheduledQueriesList = Object.values(allScheduledQueries.data);
|
||||
const allScheduledQueriesError = allScheduledQueries.errors;
|
||||
|
||||
const allTeamsScheduledQueries = useSelector((state: IRootState) => {
|
||||
return state.entities.global_scheduled_queries;
|
||||
});
|
||||
|
||||
const allTeamsScheduledQueriesList = Object.values(
|
||||
allTeamsScheduledQueries.data
|
||||
);
|
||||
const allTeamsScheduledQueriesError = allTeamsScheduledQueries.errors;
|
||||
|
||||
const inheritedQueryOrQueries =
|
||||
allTeamsScheduledQueriesList.length === 1 ? "query" : "queries";
|
||||
|
||||
const allTeams = useSelector((state: IRootState) => state.entities.teams);
|
||||
const allTeamsList = Object.values(allTeams.data);
|
||||
|
||||
|
|
@ -148,7 +183,7 @@ const ManageSchedulePage = (props: ITeamSchedulesPageProps): JSX.Element => {
|
|||
const teamOptions: ITeamOptions[] = [
|
||||
{
|
||||
disabled: false,
|
||||
label: "Global",
|
||||
label: "All teams",
|
||||
value: "global",
|
||||
},
|
||||
];
|
||||
|
|
@ -163,6 +198,9 @@ const ManageSchedulePage = (props: ITeamSchedulesPageProps): JSX.Element => {
|
|||
return teamOptions;
|
||||
};
|
||||
|
||||
const [showInheritedQueries, setShowInheritedQueries] = useState<boolean>(
|
||||
false
|
||||
);
|
||||
const [showScheduleEditorModal, setShowScheduleEditorModal] = useState(false);
|
||||
const [
|
||||
showRemoveScheduledQueryModal,
|
||||
|
|
@ -175,6 +213,10 @@ const ManageSchedulePage = (props: ITeamSchedulesPageProps): JSX.Element => {
|
|||
IGlobalScheduledQuery | ITeamScheduledQuery
|
||||
>();
|
||||
|
||||
const toggleInheritedQueries = () => {
|
||||
setShowInheritedQueries(!showInheritedQueries);
|
||||
};
|
||||
|
||||
const toggleScheduleEditorModal = useCallback(() => {
|
||||
setSelectedScheduledQuery(undefined); // create modal renders
|
||||
setShowScheduleEditorModal(!showScheduleEditorModal);
|
||||
|
|
@ -184,12 +226,16 @@ const ManageSchedulePage = (props: ITeamSchedulesPageProps): JSX.Element => {
|
|||
setShowRemoveScheduledQueryModal(!showRemoveScheduledQueryModal);
|
||||
}, [showRemoveScheduledQueryModal, setShowRemoveScheduledQueryModal]);
|
||||
|
||||
const onRemoveScheduledQueryClick = (selectedTableQueryIds: any): void => {
|
||||
const onRemoveScheduledQueryClick = (
|
||||
selectedTableQueryIds: number[]
|
||||
): void => {
|
||||
toggleRemoveScheduledQueryModal();
|
||||
setSelectedQueryIds(selectedTableQueryIds);
|
||||
};
|
||||
|
||||
const onEditScheduledQueryClick = (selectedQuery: any): void => {
|
||||
const onEditScheduledQueryClick = (
|
||||
selectedQuery: IGlobalScheduledQuery | ITeamScheduledQuery
|
||||
): void => {
|
||||
toggleScheduleEditorModal();
|
||||
setSelectedScheduledQuery(selectedQuery); // edit modal renders
|
||||
};
|
||||
|
|
@ -379,6 +425,39 @@ const ManageSchedulePage = (props: ITeamSchedulesPageProps): JSX.Element => {
|
|||
teamId
|
||||
)}
|
||||
</div>
|
||||
{/* must use ternary for NaN */}
|
||||
{teamId && allTeamsScheduledQueriesList.length > 0 ? (
|
||||
<>
|
||||
<span>
|
||||
<Button
|
||||
variant="unstyled"
|
||||
className={`${showInheritedQueries ? "upcarat" : "rightcarat"}
|
||||
${baseClass}__inherited-queries-button`}
|
||||
onClick={toggleInheritedQueries}
|
||||
>
|
||||
{showInheritedQueries
|
||||
? `Hide ${allTeamsScheduledQueriesList.length} inherited ${inheritedQueryOrQueries}`
|
||||
: `Show ${allTeamsScheduledQueriesList.length} inherited ${inheritedQueryOrQueries}`}
|
||||
</Button>
|
||||
</span>
|
||||
<div className={`${baseClass}__details`}>
|
||||
<IconToolTip
|
||||
isHtml
|
||||
text={
|
||||
"\
|
||||
<center><p>Queries from the “All teams”<br/>schedule run on this team’s hosts.</p></center>\
|
||||
"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
{showInheritedQueries &&
|
||||
renderAllTeamsTable(
|
||||
teamId,
|
||||
allTeamsScheduledQueriesList,
|
||||
allTeamsScheduledQueriesError
|
||||
)}
|
||||
{showScheduleEditorModal && (
|
||||
<ScheduleEditorModal
|
||||
onCancel={toggleScheduleEditorModal}
|
||||
|
|
|
|||
|
|
@ -174,4 +174,64 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__inherited-queries-button {
|
||||
margin: $pad-medium 0 0 0;
|
||||
color: $core-vibrant-blue;
|
||||
font-weight: $bold;
|
||||
font-size: $x-small;
|
||||
}
|
||||
|
||||
.rightcarat {
|
||||
&::before {
|
||||
content: url("../assets/images/icon-chevron-blue-16x16@2x.png");
|
||||
transform: scale(0.5) rotate(-90deg);
|
||||
width: 16px;
|
||||
border-radius: 0px;
|
||||
padding: 0px;
|
||||
padding-right: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.upcarat {
|
||||
&::before {
|
||||
content: url("../assets/images/icon-chevron-blue-16x16@2x.png");
|
||||
transform: scale(0.5) rotate(180deg);
|
||||
width: 16px;
|
||||
border-radius: 0px;
|
||||
padding: 0px;
|
||||
padding-right: 2px;
|
||||
margin-right: $pad-small;
|
||||
margin-top: 5px;
|
||||
position: relative;
|
||||
top: -4px;
|
||||
left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&__details {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
margin-left: $pad-small;
|
||||
margin-top: -20px;
|
||||
|
||||
.hint {
|
||||
color: $core-fleet-black;
|
||||
|
||||
&--brand {
|
||||
color: $core-vibrant-blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__all-teams-table {
|
||||
.table-container__header {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
border-right: 1px solid #e2e4ea !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,11 @@ import { ITeamScheduledQuery } from "interfaces/team_scheduled_query";
|
|||
import globalScheduledQueryActions from "redux/nodes/entities/global_scheduled_queries/actions";
|
||||
|
||||
import TableContainer from "components/TableContainer";
|
||||
import { generateTableHeaders, generateDataSet } from "./ScheduleTableConfig";
|
||||
import {
|
||||
generateInheritedQueriesTableHeaders,
|
||||
generateTableHeaders,
|
||||
generateDataSet,
|
||||
} from "./ScheduleTableConfig";
|
||||
// @ts-ignore
|
||||
import scheduleSvg from "../../../../../../assets/images/schedule.svg";
|
||||
|
||||
|
|
@ -21,11 +25,14 @@ const baseClass = "schedule-list-wrapper";
|
|||
const noScheduleClass = "no-schedule";
|
||||
|
||||
interface IScheduleListWrapperProps {
|
||||
onRemoveScheduledQueryClick: any;
|
||||
onEditScheduledQueryClick: any;
|
||||
onRemoveScheduledQueryClick?: (selectIds: number[]) => void;
|
||||
onEditScheduledQueryClick?: (
|
||||
selectedQuery: IGlobalScheduledQuery | ITeamScheduledQuery
|
||||
) => void;
|
||||
allScheduledQueriesList: IGlobalScheduledQuery[] | ITeamScheduledQuery[];
|
||||
toggleScheduleEditorModal: () => void;
|
||||
toggleScheduleEditorModal?: () => void;
|
||||
teamId: number;
|
||||
inheritedQueries?: boolean;
|
||||
}
|
||||
interface IRootState {
|
||||
entities: {
|
||||
|
|
@ -47,6 +54,7 @@ const ScheduleListWrapper = (props: IScheduleListWrapperProps): JSX.Element => {
|
|||
toggleScheduleEditorModal,
|
||||
onEditScheduledQueryClick,
|
||||
teamId,
|
||||
inheritedQueries,
|
||||
} = props;
|
||||
const dispatch = useDispatch();
|
||||
const { MANAGE_PACKS } = paths;
|
||||
|
|
@ -92,10 +100,14 @@ const ScheduleListWrapper = (props: IScheduleListWrapperProps): JSX.Element => {
|
|||
): void => {
|
||||
switch (action) {
|
||||
case "edit":
|
||||
onEditScheduledQueryClick(global_scheduled_query);
|
||||
if (onEditScheduledQueryClick) {
|
||||
onEditScheduledQueryClick(global_scheduled_query);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
onRemoveScheduledQueryClick([global_scheduled_query.id]);
|
||||
if (onRemoveScheduledQueryClick) {
|
||||
onRemoveScheduledQueryClick([global_scheduled_query.id]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
@ -123,6 +135,33 @@ const ScheduleListWrapper = (props: IScheduleListWrapperProps): JSX.Element => {
|
|||
[dispatch]
|
||||
);
|
||||
|
||||
const loadingInheritedQueriesTableData = useSelector((state: IRootState) => {
|
||||
return state.entities.global_scheduled_queries.isLoading;
|
||||
});
|
||||
|
||||
if (inheritedQueries) {
|
||||
const inheritedQueriesTableHeaders = generateInheritedQueriesTableHeaders();
|
||||
|
||||
return (
|
||||
<div className={`${baseClass}`}>
|
||||
<TableContainer
|
||||
resultsTitle={"queries"}
|
||||
columns={inheritedQueriesTableHeaders}
|
||||
data={generateDataSet(allScheduledQueriesList, teamId)}
|
||||
isLoading={loadingInheritedQueriesTableData}
|
||||
defaultSortHeader={"query"}
|
||||
defaultSortDirection={"desc"}
|
||||
showMarkAllPages={false}
|
||||
isAllPagesSelected={false}
|
||||
searchable={false}
|
||||
disablePagination
|
||||
disableCount
|
||||
emptyComponent={NoScheduledQueries}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`${baseClass}`}>
|
||||
<TableContainer
|
||||
|
|
|
|||
|
|
@ -115,6 +115,29 @@ const generateTableHeaders = (
|
|||
];
|
||||
};
|
||||
|
||||
const generateInheritedQueriesTableHeaders = (): IDataColumn[] => {
|
||||
return [
|
||||
{
|
||||
title: "Query",
|
||||
Header: "Query",
|
||||
disableSortBy: true,
|
||||
accessor: "query_name",
|
||||
Cell: (cellProps: ICellProps): JSX.Element => (
|
||||
<TextCell value={cellProps.cell.value} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Frequency",
|
||||
Header: "Frequency",
|
||||
disableSortBy: true,
|
||||
accessor: "interval",
|
||||
Cell: (cellProps: ICellProps): JSX.Element => (
|
||||
<TextCell value={secondsToDhms(cellProps.cell.value)} />
|
||||
),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const generateActionDropdownOptions = (): IDropdownOption[] => {
|
||||
const dropdownOptions = [
|
||||
{
|
||||
|
|
@ -162,4 +185,8 @@ const generateDataSet = (
|
|||
return [...enhanceAllScheduledQueryData(all_scheduled_queries, teamId)];
|
||||
};
|
||||
|
||||
export { generateTableHeaders, generateDataSet };
|
||||
export {
|
||||
generateInheritedQueriesTableHeaders,
|
||||
generateTableHeaders,
|
||||
generateDataSet,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue