mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Fleet UI: Surface delete previous results modals (#14257)
This commit is contained in:
parent
be0ce917c1
commit
5ed443590e
5 changed files with 46 additions and 16 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useContext, useEffect } from "react";
|
||||
import React, { useContext } from "react";
|
||||
import { useQuery } from "react-query";
|
||||
import { InjectedRouter, Params } from "react-router/lib/Router";
|
||||
import { useErrorHandler } from "react-error-boundary";
|
||||
|
|
@ -112,7 +112,7 @@ const QueryDetailsPage = ({
|
|||
);
|
||||
|
||||
const isLoading = isStoredQueryLoading; // TODO: Add || isCachedResultsLoading for new API response
|
||||
const isApiError = storedQueryError || true; // TODO: Add || isCachedResultsError for new API response
|
||||
const isApiError = storedQueryError || false; // TODO: Add || isCachedResultsError for new API response
|
||||
|
||||
const renderHeader = () => {
|
||||
const canEditQuery =
|
||||
|
|
|
|||
|
|
@ -100,13 +100,14 @@ const EditQueryPage = ({
|
|||
const [showOpenSchemaActionText, setShowOpenSchemaActionText] = useState(
|
||||
false
|
||||
);
|
||||
const [showSaveChangesModal, setShowSaveChangesModal] = useState(false);
|
||||
|
||||
// disabled on page load so we can control the number of renders
|
||||
// else it will re-populate the context on occasion
|
||||
const {
|
||||
isLoading: isStoredQueryLoading,
|
||||
data: storedQuery,
|
||||
error: storedQueryError,
|
||||
refetch: refetchStoredQuery,
|
||||
} = useQuery<IGetQueryResponse, Error, ISchedulableQuery>(
|
||||
["query", queryId],
|
||||
() => queryAPI.load(queryId as number),
|
||||
|
|
@ -215,6 +216,7 @@ const EditQueryPage = ({
|
|||
try {
|
||||
await queryAPI.update(queryId, updatedQuery);
|
||||
renderFlash("success", "Query updated!");
|
||||
refetchStoredQuery(); // Required to compare recently saved query to a subsequent save to the query
|
||||
} catch (updateError: any) {
|
||||
console.error(updateError);
|
||||
if (updateError.data.errors[0].reason.includes("Duplicate")) {
|
||||
|
|
@ -228,6 +230,7 @@ const EditQueryPage = ({
|
|||
}
|
||||
|
||||
setIsQueryUpdating(false);
|
||||
setShowSaveChangesModal(false); // Closes conditionally opened modal when discarding previous results
|
||||
|
||||
return false;
|
||||
};
|
||||
|
|
@ -304,6 +307,8 @@ const EditQueryPage = ({
|
|||
isQuerySaving={isQuerySaving}
|
||||
isQueryUpdating={isQueryUpdating}
|
||||
hostId={parseInt(location.query.host_ids as string, 10)}
|
||||
showSaveChangesModal={showSaveChangesModal}
|
||||
setShowSaveChangesModal={setShowSaveChangesModal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ describe("QueryForm - component", () => {
|
|||
onOpenSchemaSidebar={jest.fn()}
|
||||
renderLiveQueryWarning={jest.fn()}
|
||||
backendValidators={{}}
|
||||
showSaveChangesModal={false}
|
||||
setShowSaveChangesModal={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ interface IQueryFormProps {
|
|||
renderLiveQueryWarning: () => JSX.Element | null;
|
||||
backendValidators: { [key: string]: string };
|
||||
hostId?: number;
|
||||
showSaveChangesModal: boolean;
|
||||
setShowSaveChangesModal: (bool: boolean) => void;
|
||||
}
|
||||
|
||||
const validateQuerySQL = (query: string) => {
|
||||
|
|
@ -120,6 +122,8 @@ const QueryForm = ({
|
|||
renderLiveQueryWarning,
|
||||
backendValidators,
|
||||
hostId,
|
||||
showSaveChangesModal,
|
||||
setShowSaveChangesModal,
|
||||
}: IQueryFormProps): JSX.Element => {
|
||||
// Note: The QueryContext values should always be used for any mutable query data such as query name
|
||||
// The storedQuery prop should only be used to access immutable metadata such as author id
|
||||
|
|
@ -158,7 +162,6 @@ const QueryForm = ({
|
|||
const savedQueryMode = !!queryIdForEdit;
|
||||
const [errors, setErrors] = useState<{ [key: string]: any }>({}); // string | null | undefined or boolean | undefined
|
||||
const [showSaveQueryModal, setShowSaveQueryModal] = useState(false);
|
||||
const [showSaveChangesModal, setShowSaveChangesModal] = useState(false); // #7766 implementation
|
||||
const [showQueryEditor, setShowQueryEditor] = useState(
|
||||
isObserverPlus || isAnyTeamObserverPlus || false
|
||||
);
|
||||
|
|
@ -211,7 +214,6 @@ const QueryForm = ({
|
|||
setShowSaveQueryModal(!showSaveQueryModal);
|
||||
};
|
||||
|
||||
// #7766 implementation
|
||||
const toggleSaveChangesModal = () => {
|
||||
setShowSaveChangesModal(!showSaveChangesModal);
|
||||
};
|
||||
|
|
@ -411,12 +413,6 @@ const QueryForm = ({
|
|||
logging: lastEditedQueryLoggingType,
|
||||
});
|
||||
}
|
||||
|
||||
// #7766 implementation
|
||||
// savedQueryMode
|
||||
// ? setShowSaveChangesModal(true)
|
||||
// : setShowSaveQueryModal(true);
|
||||
// TODO: onUpdate for saveChangesModal
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -609,6 +605,26 @@ const QueryForm = ({
|
|||
|
||||
const hasSavePermissions = isGlobalAdmin || isGlobalMaintainer;
|
||||
|
||||
const hasSqlChange = storedQuery && lastEditedQueryBody !== storedQuery.query;
|
||||
const hasSnapshotChange =
|
||||
storedQuery &&
|
||||
lastEditedQueryLoggingType !== "snapshot" &&
|
||||
storedQuery.logging === "snapshot";
|
||||
// Use commented out logic when discard data checkbox is implemented #13470
|
||||
const hasEnabledDiscardData = false;
|
||||
// const hasEnabledDiscardData =
|
||||
// storedQuery && lastEditedDiscardData && !storedQuery.discardData;
|
||||
|
||||
const confirmChanges = (): boolean => {
|
||||
// Confirm changes if the query has been edited, removed snapshot logging, or enabled discard data
|
||||
return hasSqlChange || hasSnapshotChange || hasEnabledDiscardData;
|
||||
};
|
||||
|
||||
const confirmSqlChange = (): boolean => {
|
||||
// Confirm sql changes message if sql changed but snapshot and enabling discard data has not
|
||||
return !!hasSqlChange && !hasSnapshotChange && !hasEnabledDiscardData;
|
||||
};
|
||||
|
||||
// Global admin, any maintainer, any observer+ on new query
|
||||
const renderEditableQueryForm = () => {
|
||||
// Save disabled for team maintainer/admins viewing global queries
|
||||
|
|
@ -640,7 +656,9 @@ const QueryForm = ({
|
|||
onLoad={onLoad}
|
||||
wrapperClassName={`${baseClass}__text-editor-wrapper`}
|
||||
onChange={onChangeQuery}
|
||||
handleSubmit={promptSaveQuery}
|
||||
handleSubmit={
|
||||
confirmChanges() ? toggleSaveChangesModal : promptSaveQuery
|
||||
}
|
||||
wrapEnabled
|
||||
focus={!savedQueryMode}
|
||||
/>
|
||||
|
|
@ -743,7 +761,11 @@ const QueryForm = ({
|
|||
<Button
|
||||
className="save-loading"
|
||||
variant="brand"
|
||||
onClick={promptSaveQuery()}
|
||||
onClick={
|
||||
confirmChanges()
|
||||
? toggleSaveChangesModal
|
||||
: promptSaveQuery()
|
||||
}
|
||||
// Button disabled for team maintainer/admins viewing global queries
|
||||
disabled={
|
||||
disableSavePermissionDenied || disableSaveFormErrors
|
||||
|
|
@ -796,9 +818,10 @@ const QueryForm = ({
|
|||
)}
|
||||
{showSaveChangesModal && (
|
||||
<SaveChangesModal
|
||||
onSaveChanges={saveQuery}
|
||||
onSaveChanges={promptSaveQuery()}
|
||||
toggleSaveChangesModal={toggleSaveChangesModal}
|
||||
isUpdating={isQuerySaving}
|
||||
isUpdating={isQueryUpdating}
|
||||
sqlUpdated={confirmSqlChange()}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const baseClass = "save-changes-modal";
|
|||
|
||||
export interface ISaveChangesModalProps {
|
||||
isUpdating: boolean;
|
||||
onSaveChanges: (formData: ICreateQueryRequestBody) => void;
|
||||
onSaveChanges: (evt: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
toggleSaveChangesModal: () => void;
|
||||
sqlUpdated?: boolean;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue