mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Correct instances of multiple requests for same resource (#3631)
This commit is contained in:
parent
09efce8ea8
commit
e64f1a63ba
8 changed files with 41 additions and 45 deletions
1
changes/issue-3575-multiple-requests
Normal file
1
changes/issue-3575-multiple-requests
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Correct instances of multiple requests for same resource
|
||||
|
|
@ -228,10 +228,7 @@ describe(
|
|||
.contains("button", /schedule/i)
|
||||
.click();
|
||||
|
||||
cy.visit("/schedule/manage");
|
||||
|
||||
cy.wait(2000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
cy.findByText(/detect presence/i).should("exist");
|
||||
cy.get(".flash-message--success").should("exist");
|
||||
|
||||
cy.visit("/hosts/manage");
|
||||
cy.contains(".table-container .data-table__table th", "Team").should(
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ const generateDropdownOptions = (
|
|||
interface ITeamsDropdownProps {
|
||||
currentUserTeams: ITeam[];
|
||||
selectedTeamId: number;
|
||||
includeAll?: boolean;
|
||||
includeAll?: boolean; // Include "All Teams" option for all users
|
||||
disableAll?: boolean; // Disable "All Teams" option for global users
|
||||
isDisabled?: boolean;
|
||||
onChange: (newSelectedValue: number) => void;
|
||||
onOpen?: () => void;
|
||||
|
|
@ -46,7 +47,8 @@ const baseClass = "component__team-dropdown";
|
|||
const TeamsDropdown = ({
|
||||
currentUserTeams,
|
||||
selectedTeamId,
|
||||
includeAll,
|
||||
includeAll = false,
|
||||
disableAll = false,
|
||||
isDisabled,
|
||||
onChange,
|
||||
onOpen,
|
||||
|
|
@ -56,7 +58,10 @@ const TeamsDropdown = ({
|
|||
|
||||
const teamOptions = useMemo(
|
||||
() =>
|
||||
generateDropdownOptions(currentUserTeams, isOnGlobalTeam || includeAll),
|
||||
generateDropdownOptions(
|
||||
currentUserTeams,
|
||||
(isOnGlobalTeam && !disableAll) || includeAll
|
||||
),
|
||||
[currentUserTeams, isOnGlobalTeam]
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -233,14 +233,13 @@ const MembersPage = ({
|
|||
setIsFormSubmitting(true);
|
||||
|
||||
if (formData.newUserType === NewUserType.AdminInvited) {
|
||||
// Do some data formatting adding `invited_by` for the request to be correct and deleteing uncessary fields
|
||||
const requestData = {
|
||||
...formData,
|
||||
invited_by: formData.currentUserId,
|
||||
};
|
||||
delete requestData.currentUserId; // this field is not needed for the request
|
||||
delete requestData.newUserType; // this field is not needed for the request
|
||||
delete requestData.password; // this field is not needed for the request
|
||||
delete requestData.currentUserId;
|
||||
delete requestData.newUserType;
|
||||
delete requestData.password;
|
||||
dispatch(inviteActions.create(requestData))
|
||||
.then(() => {
|
||||
dispatch(
|
||||
|
|
@ -270,12 +269,11 @@ const MembersPage = ({
|
|||
setIsFormSubmitting(false);
|
||||
});
|
||||
} else {
|
||||
// Do some data formatting deleteing uncessary fields
|
||||
const requestData = {
|
||||
...formData,
|
||||
};
|
||||
delete requestData.currentUserId; // this field is not needed for the request
|
||||
delete requestData.newUserType; // this field is not needed for the request
|
||||
delete requestData.currentUserId;
|
||||
delete requestData.newUserType;
|
||||
dispatch(userActions.createUserWithoutInvitation(requestData))
|
||||
.then(() => {
|
||||
dispatch(
|
||||
|
|
@ -325,8 +323,6 @@ const MembersPage = ({
|
|||
.then(() => {
|
||||
dispatch(renderFlash("success", `Successfully edited ${userName}.`));
|
||||
if (currentUser && userEditing && currentUser.id === userEditing.id) {
|
||||
// If user edits self and removes "admin" role,
|
||||
// redirect to home
|
||||
const currentTeam = formData.teams.filter(
|
||||
(thisTeam) => thisTeam.id === teamId
|
||||
);
|
||||
|
|
@ -354,17 +350,17 @@ const MembersPage = ({
|
|||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch users when Redux team_id state changes
|
||||
fetchUsers(tableQueryData);
|
||||
}, [team_id]);
|
||||
|
||||
// NOTE: this will fire on initial render, so we use this to get the list of
|
||||
// users for this team, as well as use it as a handler when the table query
|
||||
// changes.
|
||||
const onQueryChange = useCallback(
|
||||
(queryData) => {
|
||||
setSearchString(queryData.searchQuery);
|
||||
tableQueryData = { ...queryData, teamId };
|
||||
fetchUsers(queryData);
|
||||
if (users) {
|
||||
setSearchString(queryData.searchQuery);
|
||||
tableQueryData = { ...queryData, teamId };
|
||||
fetchUsers(queryData);
|
||||
}
|
||||
},
|
||||
[fetchUsers, teamId, setSearchString]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ const TeamDetailsWrapper = ({
|
|||
selectedTeamId={toNumber(routeParams.team_id)}
|
||||
currentUserTeams={adminTeams || []}
|
||||
isDisabled={isLoadingTeams}
|
||||
disableAll
|
||||
onChange={(newSelectedValue: number) =>
|
||||
handleTeamSelect(newSelectedValue)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,16 +70,17 @@ const TeamManagementPage = (): JSX.Element => {
|
|||
[showEditTeamModal, setShowEditTeamModal, setTeamEditing]
|
||||
);
|
||||
|
||||
// NOTE: called once on the initial render of this component.
|
||||
const onQueryChange = useCallback(
|
||||
(queryData) => {
|
||||
setSearchString(queryData.searchQuery);
|
||||
const { pageIndex, pageSize, searchQuery } = queryData;
|
||||
teamsAPI.loadAll({
|
||||
page: pageIndex,
|
||||
perPage: pageSize,
|
||||
globalFilter: searchQuery,
|
||||
});
|
||||
if (teams) {
|
||||
setSearchString(queryData.searchQuery);
|
||||
const { pageIndex, pageSize, searchQuery } = queryData;
|
||||
teamsAPI.loadAll({
|
||||
page: pageIndex,
|
||||
perPage: pageSize,
|
||||
globalFilter: searchQuery,
|
||||
});
|
||||
}
|
||||
},
|
||||
[dispatch, setSearchString]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -231,6 +231,10 @@ const ManageHostsPage = ({
|
|||
);
|
||||
const [tableQueryData, setTableQueryData] = useState<ITableQueryProps>();
|
||||
const [clearSelectionCount, setClearSelectionCount] = useState<number>(0);
|
||||
const [
|
||||
currentQueryOptions,
|
||||
setCurrentQueryOptions,
|
||||
] = useState<ILoadHostsOptions>();
|
||||
|
||||
// ======== end states
|
||||
|
||||
|
|
@ -477,15 +481,17 @@ const ManageHostsPage = ({
|
|||
policyId,
|
||||
policyResponse,
|
||||
softwareId,
|
||||
page: tableQueryData ? tableQueryData.pageIndex : 0,
|
||||
perPage: tableQueryData ? tableQueryData.pageSize : 100,
|
||||
};
|
||||
|
||||
if (tableQueryData) {
|
||||
options.page = tableQueryData.pageIndex;
|
||||
options.perPage = tableQueryData.pageSize;
|
||||
if (isEqual(options, currentQueryOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
retrieveHosts(options);
|
||||
retrieveHostCount(options);
|
||||
setCurrentQueryOptions(options);
|
||||
}, [location, labels]);
|
||||
|
||||
const handleLabelChange = ({ slug }: ILabel): boolean => {
|
||||
|
|
@ -657,11 +663,9 @@ const ManageHostsPage = ({
|
|||
// NOTE: this is called once on initial render and every time the query changes
|
||||
const onTableQueryChange = async (newTableQuery: ITableQueryProps) => {
|
||||
if (isEqual(newTableQuery, tableQueryData)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
setIsHostsLoading(true);
|
||||
|
||||
setTableQueryData({ ...newTableQuery });
|
||||
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -195,15 +195,6 @@ const ManageSchedulePage = ({
|
|||
handleTeamSelect(teams[0].id);
|
||||
}
|
||||
|
||||
// TODO: move team scheduled queries and global scheduled queries into services entities, remove redux
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
selectedTeamId
|
||||
? teamScheduledQueryActions.loadAll(selectedTeamId)
|
||||
: globalScheduledQueryActions.loadAll()
|
||||
);
|
||||
}, [dispatch, selectedTeamId]);
|
||||
|
||||
const allScheduledQueries = useSelector((state: IRootState) => {
|
||||
if (selectedTeamId) {
|
||||
return state.entities.team_scheduled_queries;
|
||||
|
|
|
|||
Loading…
Reference in a new issue