роутинг и подсветы
This commit is contained in:
@@ -19,6 +19,7 @@ import { usePortalEmployees } from '../../hooks/usePortalEmployees';
|
||||
import { useLocalStorageState } from '../../hooks/useLocalStorageState';
|
||||
import { findEmployeeByEmail } from '../../utils/employee';
|
||||
import { markParallel, withOrdersFrom } from '../../utils/orderBlocks';
|
||||
import { IManageRequestRouteParams, replaceRoute } from '../../routing';
|
||||
import {
|
||||
Alert,
|
||||
AsyncSearchableSelect,
|
||||
@@ -39,6 +40,9 @@ export interface IManageRequestsScreenProps {
|
||||
/** Undefined, пока SPFx выдаёт AAD-клиент для api.tnsu.kz. */
|
||||
dictionary?: PortalDictionaryClient;
|
||||
requestManage: RequestManageService;
|
||||
/** Заполнение из URL (глубокая ссылка на конкретную заявку) — есть, только
|
||||
* если в адресе заданы aamtype/aamreq (см. routing.ts). */
|
||||
route?: IManageRequestRouteParams;
|
||||
}
|
||||
|
||||
// Цвет плашки статуса — те же группы смысла, что и в request-portal
|
||||
@@ -97,12 +101,39 @@ const SELECTION_STORAGE_KEY = 'approvalAdmin.manageRequestsSelection';
|
||||
// решение через request-portal), а вкладка могла быть открыта давно.
|
||||
const AUTO_REFRESH_MS = 2 * 60 * 1000;
|
||||
|
||||
export const ManageRequestsScreen: React.FC<IManageRequestsScreenProps> = ({ api, dictionary, requestManage }) => {
|
||||
export const ManageRequestsScreen: React.FC<IManageRequestsScreenProps> = ({ api, dictionary, requestManage, route }) => {
|
||||
const requestTypes = useRequestTypes(api);
|
||||
const employees = usePortalEmployees(dictionary);
|
||||
|
||||
const [selection, setSelection] = useLocalStorageState<IPersistedSelection>(SELECTION_STORAGE_KEY, EMPTY_SELECTION);
|
||||
const { requestTypeId, selectedRequest } = selection;
|
||||
|
||||
// Открыли по глубокой ссылке (aamtype/aamreq в URL) — перекрывает то, что
|
||||
// было в localStorage. Только на монтировании — см. тот же приём в
|
||||
// ResolveScreen (route меняется при каждом собственном replaceRoute ниже).
|
||||
// title/status заявки в URL не хранятся (их полностью определяет requestId) —
|
||||
// ставим пустыми, реальные подтянутся, как только матрица загрузится (см.
|
||||
// reloadMatrix ниже: там selection.selectedRequest патчится из matrix.request).
|
||||
React.useEffect(() => {
|
||||
if (!route) return;
|
||||
setSelection({
|
||||
requestTypeId: route.requestTypeId,
|
||||
selectedRequest: { id: Number(route.requestId), title: '', status: '', created: '', authorName: '' }
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
// Держим URL синхронным с выбором — открытую заявку можно скопировать и
|
||||
// прислать коллеге. replaceRoute, а не navigate: смена заявки — это правка
|
||||
// состояния текущего экрана, а не переход на новую страницу с отдельным
|
||||
// шагом в истории браузера. title/status заявки в URL не пишем — их выводит
|
||||
// сам requestId, хранить производные данные в ссылке незачем.
|
||||
React.useEffect(() => {
|
||||
replaceRoute({
|
||||
tab: 'manageRequests',
|
||||
manage: selectedRequest ? { requestTypeId, requestId: String(selectedRequest.id) } : undefined
|
||||
});
|
||||
}, [requestTypeId, selectedRequest]);
|
||||
const [matrix, setMatrix] = React.useState<ManagedRequestMatrix | undefined>();
|
||||
const [matrixLoading, setMatrixLoading] = React.useState(false);
|
||||
const [matrixError, setMatrixError] = React.useState<string | undefined>();
|
||||
@@ -156,7 +187,17 @@ export const ManageRequestsScreen: React.FC<IManageRequestsScreenProps> = ({ api
|
||||
setMatrixError(undefined);
|
||||
requestManage
|
||||
.getMatrix(requestType, selectedRequest.id)
|
||||
.then(setMatrix)
|
||||
.then(m => {
|
||||
setMatrix(m);
|
||||
// title/status в комбобоксе (а значит, и в localStorage) держим
|
||||
// синхронными с сервером — особенно важно после захода по глубокой
|
||||
// ссылке, где изначально они пустые (см. эффект-затравку выше).
|
||||
setSelection(prev =>
|
||||
prev.selectedRequest && prev.selectedRequest.id === m.request.id
|
||||
? { ...prev, selectedRequest: m.request }
|
||||
: prev
|
||||
);
|
||||
})
|
||||
.catch((e: Error) => setMatrixError(e.message))
|
||||
.finally(() => {
|
||||
if (!silent) setMatrixLoading(false);
|
||||
|
||||
Reference in New Issue
Block a user