From 8ed948a14d99735d493c5b3dce95cabbdf3120c1 Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Thu, 24 Feb 2022 15:41:38 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B8=D1=81=D0=BA=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8F=D0=BC=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=B5=D0=B4?= =?UTF-8?q?=D1=91=D0=BD=20=D0=BD=D0=B0=20RxJs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/DrillingProgram/CategoryEditor.jsx | 74 +++++++++++--------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/src/pages/DrillingProgram/CategoryEditor.jsx b/src/pages/DrillingProgram/CategoryEditor.jsx index b9568bd..3cbb1c9 100644 --- a/src/pages/DrillingProgram/CategoryEditor.jsx +++ b/src/pages/DrillingProgram/CategoryEditor.jsx @@ -1,10 +1,11 @@ import { Input, Modal, Radio } from 'antd' import { memo, useCallback, useEffect, useState } from 'react' +import { BehaviorSubject, debounceTime, distinctUntilChanged, filter, map } from 'rxjs' import { UserView } from '@components/views' import LoaderPortal from '@components/LoaderPortal' -import { makeColumn, makeNumericSorter, Table } from '@components/Table' import { invokeWebApiWrapperAsync } from '@components/factory' +import { makeColumn, makeNumericSorter, Table } from '@components/Table' import { DrillingProgramService } from '@api' import { arrayOrDefault } from '@utils' @@ -14,31 +15,19 @@ const userRules = [ { label: 'Согласовант', value: 2 }, ] -const SEARCH_TIMEOUT = 1000 +const SEARCH_TIMEOUT = 400 export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => { const [title, setTitle] = useState() const [users, setUsers] = useState([]) const [allUsers, setAllUsers] = useState([]) const [filteredUsers, setFilteredUsers] = useState([]) - const [searchTimeout, setSearchTimeout] = useState(null) const [showLoader, setShowLoader] = useState(false) const [searchValue, setSearchValue] = useState('') + const [subject, setSubject] = useState(null) useEffect(() => invokeWebApiWrapperAsync( async () => { - const allUsers = arrayOrDefault(await DrillingProgramService.getAvailableUsers(idWell)) - setAllUsers(allUsers) - }, - setShowLoader, - `Не удалось загрузить список доступных пользователей скважины "${idWell}"` - ), [idWell]) - - const calcFilteredUsers = useCallback(async (value, users) => await invokeWebApiWrapperAsync( - async () => { - if (searchTimeout) - clearTimeout(searchTimeout) - setSearchTimeout(null) const filteredUsers = users.filter(({ user }) => user && [ user.login ?? '', user.name ?? '', @@ -48,12 +37,40 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => user.phone ?? '', user.position ?? '', user.company?.caption ?? '', - ].join(' ').toLowerCase().includes(value)) + ].join(' ').toLowerCase().includes(searchValue)) setFilteredUsers(filteredUsers) }, setShowLoader, `Не удалось произвести поиск пользователей` - ), [searchTimeout]) + ), [users, searchValue]) + + useEffect(() => { + if (!subject) { + const sub = new BehaviorSubject('') + setSubject(sub) + } else { + const observable = subject.pipe( + debounceTime(SEARCH_TIMEOUT), + map(s => s.trim().toLowerCase() ?? ''), + distinctUntilChanged(), + filter(s => s.length <= 0 || s.length >= 2), + ).subscribe(value => setSearchValue(value)) + + return () => { + observable.unsubscribe() + subject.unsubscribe() + } + } + }, [subject]) + + useEffect(() => invokeWebApiWrapperAsync( + async () => { + const allUsers = arrayOrDefault(await DrillingProgramService.getAvailableUsers(idWell)) + setAllUsers(allUsers) + }, + setShowLoader, + `Не удалось загрузить список доступных пользователей скважины "${idWell}"` + ), [idWell]) const calcUsers = useCallback(() => { if (!visible) return @@ -68,8 +85,7 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => ...approvers.map((user) => ({ user, status: 2 })), ] setUsers(users) - calcFilteredUsers(searchValue, users) - }, [category, visible, allUsers, calcFilteredUsers, searchValue]) + }, [category, visible, allUsers]) useEffect(calcUsers, [calcUsers]) @@ -114,17 +130,9 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => }) ] - const onSearchTextChange = useCallback((value) => { - value = value.trim().toLowerCase() ?? '' - setSearchValue(value) + const onSearchTextChange = useCallback((e) => subject?.next(e?.target?.value), [subject]) - if (!searchTimeout) { - clearTimeout(searchTimeout) - setSearchTimeout(setTimeout(() => calcFilteredUsers(value, users), SEARCH_TIMEOUT)) - } - }, [searchTimeout, calcFilteredUsers, users]) - - const onModalCanceled = useCallback(() => { + const onModalClosed = useCallback(() => { onClosed?.() calcUsers() }, [onClosed, calcUsers]) @@ -135,16 +143,14 @@ export const CategoryEditor = memo(({ idWell, visible, category, onClosed }) => width={1000} visible={visible} footer={null} - onCancel={onModalCanceled} - title={`Редактирование категории ${title}`} + onCancel={onModalClosed} + title={`Редактирование пользователей категории ${title}`} >
onSearchTextChange(e?.target?.value)} - onSearch={(text) => calcFilteredUsers(text, users)} - value={searchValue} + onChange={onSearchTextChange} style={{ marginBottom: '15px' }} />