223 lines
6.2 KiB
TypeScript
223 lines
6.2 KiB
TypeScript
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}
|
||
/>
|
||
)
|
||
})
|