diff --git a/src/dashboard/src/app/client/servers/page.tsx b/src/dashboard/src/app/client/servers/page.tsx index 63976822..f6797b8e 100644 --- a/src/dashboard/src/app/client/servers/page.tsx +++ b/src/dashboard/src/app/client/servers/page.tsx @@ -2,18 +2,22 @@ import { AllocationTable, Col } from '@/components'; import { useAuth } from '@/hooks'; -import { useServerItems } from '@/hooks/data'; +import { useOperatingSystemItems, useServerItems } from '@/hooks/data'; import { useDashboard, useFiltered } from '@/store'; import { redirect, useRouter } from 'next/navigation'; export default function Page() { const router = useRouter(); const state = useAuth(); - const { isReady, serverItems } = useServerItems({ useSimple: true, init: true }); + const { isReady: isReadyOperatingSystemItems } = useOperatingSystemItems({ init: true }); + const { isReady: isReadyServerItems, serverItems } = useServerItems({ + useSimple: true, + init: true, + }); const setFilteredServerItem = useFiltered((state) => state.setServerItem); const setDashboardServerItems = useDashboard((state) => state.setServerItems); - // Only allow HSB role to view this page. + // Only allow Client role to view this page. if (state.status === 'loading') return
Loading...
; if (!state.isClient) redirect('/'); @@ -22,7 +26,7 @@ export default function Page() {

All Servers

{ if (serverItem) { setFilteredServerItem(serverItem); diff --git a/src/dashboard/src/components/dashboard/Dashboard.tsx b/src/dashboard/src/components/dashboard/Dashboard.tsx index 757fa5a9..7f3caeea 100644 --- a/src/dashboard/src/components/dashboard/Dashboard.tsx +++ b/src/dashboard/src/components/dashboard/Dashboard.tsx @@ -50,7 +50,9 @@ export const Dashboard = () => { selectedServerItems.length === 1 || (selectedOrganizations.length === 1 && selectedOperatingSystemItems.length > 1); const showAllocationByOS = - selectedOrganizations.length === 1 && selectedOperatingSystemItems.length > 1; + selectedOrganizations.length === 1 && + selectedOperatingSystemItems.length > 1 && + selectedServerItems.length !== 1; const showAllocationByVolume = selectedServerItems.length === 1; const showAllOrganizations = selectedOrganizations.length > 1 && diff --git a/src/dashboard/src/components/filter/Filter.tsx b/src/dashboard/src/components/filter/Filter.tsx index 645f8ab2..8dcd040c 100644 --- a/src/dashboard/src/components/filter/Filter.tsx +++ b/src/dashboard/src/components/filter/Filter.tsx @@ -83,62 +83,55 @@ export const Filter: React.FC = () => { const serverItemKey = currentParams.get('serverItem'); React.useEffect(() => { - // Only update filtered selected values if they haven't already been set. - if (tenantId) { - const tenant = tenantId ? tenants.find((t) => t.id === +tenantId) : undefined; - if (tenant) { - setFilteredTenant(tenant); - readyKey.current = readyKey.current | 1; - } - } - }, [readyKey, setFilteredTenant, tenantId, tenants]); + // Create a key to unlock a dashboard update. + // A key requires all URL query parameters to be ready. + const tenant = tenantId ? tenants.find((t) => t.id === +tenantId) : undefined; + const organization = organizationId + ? organizations.find((t) => t.id === +organizationId) + : undefined; + const operatingSystemItem = operatingSystemItemId + ? operatingSystemItems.find((t) => t.id === +operatingSystemItemId) + : undefined; + const serverItem = serverItemKey + ? serverItems.find((t) => t.serviceNowKey === serverItemKey) + : undefined; + + if (tenant) readyKey.current = readyKey.current | 1; + if (organization) readyKey.current = readyKey.current | 2; + if (operatingSystemItem) readyKey.current = readyKey.current | 4; + if (serverItem) readyKey.current = readyKey.current | 8; + }, [ + operatingSystemItemId, + operatingSystemItems, + organizationId, + organizations, + readyKey, + serverItemKey, + serverItems, + tenantId, + tenants, + ]); React.useEffect(() => { - // Only update filtered selected values if they haven't already been set. - if (organizationId) { + // We only want to update the dashboard once. + // If we don't have an update key it will attempt to update every time 'anything' changes. + if (readyKey.current && lockKey === readyKey.current) { + const tenant = tenantId ? tenants.find((t) => t.id === +tenantId) : undefined; const organization = organizationId ? organizations.find((t) => t.id === +organizationId) : undefined; - if (organization) { - setFilteredOrganization(organization); - readyKey.current = readyKey.current | 2; - } - } - }, [organizationId, organizations, readyKey, setFilteredOrganization]); - - React.useEffect(() => { - // Only update filtered selected values if they haven't already been set. - if (operatingSystemItemId) { const operatingSystemItem = operatingSystemItemId ? operatingSystemItems.find((t) => t.id === +operatingSystemItemId) : undefined; - if (operatingSystemItem) { - setFilteredOperatingSystemItem(operatingSystemItem); - readyKey.current = readyKey.current | 4; - } - } - }, [operatingSystemItemId, operatingSystemItems, readyKey, setFilteredOperatingSystemItem]); - - React.useEffect(() => { - // Only update filtered selected values if they haven't already been set. - if (serverItemKey) { const serverItem = serverItemKey ? serverItems.find((t) => t.serviceNowKey === serverItemKey) : undefined; - if (serverItem) { - setFilteredServerItem(serverItem); - readyKey.current = readyKey.current | 8; - } - } - }, [readyKey, serverItemKey, serverItems, setFilteredServerItem]); - React.useEffect(() => { - // We only want to update the dashboard once. - // If we don't have an update key it will attempt to update every time 'anything' changes. - if (readyKey.current && lockKey === readyKey.current) { readyKey.current = 0; // Destroy key so that it does not update the dashboard again. - updateDashboard(); + updateDashboard({ tenant, organization, operatingSystemItem, serverItem }); } + // We only want to update the dashboard when the URL values change. + // eslint-disable-next-line react-hooks/exhaustive-deps }, [readyKey, updateDashboard, lockKey]); React.useEffect(() => { diff --git a/src/dashboard/src/components/filter/hooks/useUrlParamsUpdateKey.ts b/src/dashboard/src/components/filter/hooks/useUrlParamsUpdateKey.ts index 27fb73d5..36104fb1 100644 --- a/src/dashboard/src/components/filter/hooks/useUrlParamsUpdateKey.ts +++ b/src/dashboard/src/components/filter/hooks/useUrlParamsUpdateKey.ts @@ -1,3 +1,4 @@ +import { useFiltered } from '@/store'; import { useSearchParams } from 'next/navigation'; import React from 'react'; @@ -8,26 +9,25 @@ import React from 'react'; */ export const useUrlParamsUpdateKey = () => { const params = useSearchParams(); - - const currentParams = React.useMemo( - () => new URLSearchParams(Array.from(params.entries())), - [params], - ); + const filteredServerItem = useFiltered((state) => state.serverItem); const readyKey = React.useRef(0); - var lockKey = 0; + const lockKey = React.useRef(0); - // Extract URL query parameters and initialize state. - const tenantId = currentParams.get('tenant'); - const organizationId = currentParams.get('organization'); - const operatingSystemItemId = currentParams.get('operatingSystemItem'); - const serverItemKey = currentParams.get('serverItem'); + React.useEffect(() => { + const currentParams = new URLSearchParams(Array.from(params.entries())); + // Extract URL query parameters and initialize state. + const tenantId = currentParams.get('tenant'); + const organizationId = currentParams.get('organization'); + const operatingSystemItemId = currentParams.get('operatingSystemItem'); + const serverItemKey = currentParams.get('serverItem'); - // Generate a lock that matches the provided URL parameters. - if (tenantId) lockKey = lockKey | 1; - if (organizationId) lockKey = lockKey | 2; - if (operatingSystemItemId) lockKey = lockKey | 4; - if (serverItemKey) lockKey = lockKey | 8; + // Generate a lock that matches the provided URL parameters. + if (tenantId) lockKey.current = lockKey.current | 1; + if (organizationId) lockKey.current = lockKey.current | 2; + if (operatingSystemItemId) lockKey.current = lockKey.current | 4; + if (serverItemKey) lockKey.current = lockKey.current | 8; + }, [params]); - return { readyKey, lockKey }; + return { readyKey, lockKey: lockKey.current }; }; diff --git a/src/libs/dal/Services/ServerItemService.cs b/src/libs/dal/Services/ServerItemService.cs index a1f1444a..4a3cb71e 100644 --- a/src/libs/dal/Services/ServerItemService.cs +++ b/src/libs/dal/Services/ServerItemService.cs @@ -50,7 +50,8 @@ public IEnumerable FindForUser(long userId, ServerItemFilter filter) select ut.TenantId; var query = (from si in this.Context.ServerItems - where userTenants.Contains(si.TenantId!.Value) || userOrganizationQuery.Contains(si.OrganizationId) + where si.TenantId != null + && (userTenants.Contains(si.TenantId!.Value) || userOrganizationQuery.Contains(si.OrganizationId)) select si) .Where(filter.GeneratePredicate()) .Distinct(); @@ -100,7 +101,8 @@ public IEnumerable FindSimpleForUser(long userId, ServerIt select ut.TenantId; var query = (from si in this.Context.ServerItems - where userTenants.Contains(si.TenantId!.Value) || userOrganizationQuery.Contains(si.OrganizationId) + where si.TenantId != null + && (userTenants.Contains(si.TenantId!.Value) || userOrganizationQuery.Contains(si.OrganizationId)) select si) .Where(filter.GeneratePredicate()) .Distinct();