MDM/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.tsx

223 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuery } from '@apollo/client/react'
import { memo, useCallback, useEffect, useMemo } from 'react'
import { useSearchParams } from 'react-router-dom'
import {
GET_PHONES_TABS_STATS_QUERY,
} from '../../../../entities/device/api/device.graphql'
import type {
GetPhonesTabsStatsData,
GetPhonesTabsStatsVariables,
} from '../../../../entities/device/model/types'
import {
PageTabs,
type PageTabItem,
} from '../../../../shared/ui/PageTabs/PageTabs'
type DevicesTab = 'working' | 'lost' | 'locked' | 'maintenance' | 'service'
type DevicesTabsValue = DevicesTab | 'none'
function getActiveTab(searchParams: URLSearchParams): DevicesTabsValue {
const locked = searchParams.get('dLocked')
const needMaintenance = searchParams.get('dNeedMaintenance')
const networkStatus = searchParams.get('dNetwork')
const technicalStatus = searchParams.get('dTechnicalStatus')
if (locked === 'true') return 'locked'
if (technicalStatus === 'NeedsMaintenance') return 'maintenance'
if (technicalStatus === 'InService') return 'service'
if (needMaintenance === 'true') return 'maintenance'
if (networkStatus === 'Lost') return 'lost'
if (networkStatus === 'Online') return 'working'
return 'none'
}
function formatCount(value?: number) {
if (typeof value !== 'number') return '...'
return value.toLocaleString('ru-RU')
}
export const DevicesTabs = memo(function DevicesTabs() {
const [searchParams, setSearchParams] = useSearchParams()
const activeTab = useMemo(() => getActiveTab(searchParams), [searchParams])
useEffect(() => {
const legacyNeedMaintenance = searchParams.get('dNeedMaintenance')
if (
searchParams.has('dTechnicalStatus') ||
(legacyNeedMaintenance !== 'true' && legacyNeedMaintenance !== 'false')
) {
return
}
const nextParams = new URLSearchParams(searchParams)
nextParams.delete('dNeedMaintenance')
nextParams.set(
'dTechnicalStatus',
legacyNeedMaintenance === 'true' ? 'NeedsMaintenance' : 'Healthy',
)
setSearchParams(nextParams, { replace: true })
}, [searchParams, setSearchParams])
const query = searchParams.get('dQuery')?.trim() || undefined
const selectedOrganisationIds = useMemo(() => {
return searchParams.get('dOrgs')?.split(',').filter(Boolean) ?? []
}, [searchParams])
const queryVariables = useMemo<GetPhonesTabsStatsVariables>(() => {
return {
query,
orgs:
selectedOrganisationIds.length > 0
? selectedOrganisationIds
: undefined,
}
}, [query, selectedOrganisationIds])
const { data, previousData } = useQuery<
GetPhonesTabsStatsData,
GetPhonesTabsStatsVariables
>(GET_PHONES_TABS_STATS_QUERY, {
variables: queryVariables,
fetchPolicy: 'cache-and-network',
notifyOnNetworkStatusChange: true,
})
const stats = data ?? previousData
const onlineCount = stats?.onlinePhones.totalElements
const totalCount = stats?.totalPhones.totalElements
const lockedCount = stats?.lockedPhones.totalElements
const lostCount = stats?.lostPhones.totalElements
const maintenanceCount = stats?.maintenancePhones.totalElements
const serviceCount = stats?.servicePhones.totalElements
const tabs = useMemo<Array<PageTabItem<DevicesTabsValue>>>(() => {
const nextTabs: Array<PageTabItem<DevicesTabsValue>> = [
{
value: 'working',
label: (
<>
В сети: <b>{formatCount(onlineCount)} из {formatCount(totalCount)}</b>
</>
),
},
]
if ((lostCount ?? 0) > 0) {
nextTabs.push({
value: 'lost',
label: (
<>
Потеряно: <b>{formatCount(lostCount)}</b>
</>
),
alert: true,
})
}
if ((lockedCount ?? 0) > 0) {
nextTabs.push({
value: 'locked',
label: (
<>
Заблокировано: <b>{formatCount(lockedCount)}</b>
</>
),
alert: true,
})
}
if ((maintenanceCount ?? 0) > 0) {
nextTabs.push({
value: 'maintenance',
label: (
<>
Требуют ТО: <b>{formatCount(maintenanceCount)}</b>
</>
),
alert: true,
})
}
if ((serviceCount ?? 0) > 0) {
nextTabs.push({
value: 'service',
label: (
<>
На обслуживании: <b>{formatCount(serviceCount)}</b>
</>
),
})
}
return nextTabs
}, [lockedCount, lostCount, maintenanceCount, onlineCount, serviceCount, totalCount])
const applyQuickFilter = useCallback((tab: DevicesTabsValue) => {
if (tab === 'none') return
const nextParams = new URLSearchParams(searchParams)
nextParams.delete('dPage')
if (activeTab === tab) {
nextParams.delete('dLocked')
nextParams.delete('dNetwork')
nextParams.delete('dNeedMaintenance')
nextParams.delete('dTechnicalStatus')
setSearchParams(nextParams, { replace: true })
return
}
if (tab === 'working') {
nextParams.set('dNetwork', 'Online')
nextParams.delete('dLocked')
nextParams.delete('dNeedMaintenance')
nextParams.delete('dTechnicalStatus')
}
if (tab === 'locked') {
nextParams.set('dLocked', 'true')
nextParams.delete('dNetwork')
nextParams.delete('dNeedMaintenance')
nextParams.delete('dTechnicalStatus')
}
if (tab === 'lost') {
nextParams.set('dNetwork', 'Lost')
nextParams.delete('dLocked')
nextParams.delete('dNeedMaintenance')
nextParams.delete('dTechnicalStatus')
}
if (tab === 'maintenance') {
nextParams.delete('dLocked')
nextParams.delete('dNetwork')
nextParams.delete('dNeedMaintenance')
nextParams.set('dTechnicalStatus', 'NeedsMaintenance')
}
if (tab === 'service') {
nextParams.delete('dLocked')
nextParams.delete('dNetwork')
nextParams.delete('dNeedMaintenance')
nextParams.set('dTechnicalStatus', 'InService')
}
setSearchParams(nextParams, { replace: true })
}, [activeTab, searchParams, setSearchParams])
return (
<PageTabs
activeValue={activeTab}
items={tabs}
onChange={applyQuickFilter}
/>
)
})