Редактирование заявок у конкретного пользователя (#14)
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/14
This commit was merged in pull request #14.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react';
|
||||
import { RequestListPartition } from '../models';
|
||||
import { ApprovalRouteApi } from '../services/api';
|
||||
import { AsyncList, useAsyncList } from './useAsyncList';
|
||||
|
||||
/**
|
||||
* Серия партиций (архив + текущая) ОДНОГО типа заявки — нужна экрану
|
||||
* редактирования заявок: заявка может лежать в любой из них, не только в
|
||||
* текущей (см. requestManageService.ts).
|
||||
*/
|
||||
export function useRequestTypeListPartitions(
|
||||
api: ApprovalRouteApi,
|
||||
requestTypeId: number | undefined
|
||||
): AsyncList<RequestListPartition> {
|
||||
const load = React.useCallback(
|
||||
() => (requestTypeId ? api.requestTypes.lists(requestTypeId) : Promise.resolve([])),
|
||||
[api, requestTypeId]
|
||||
);
|
||||
return useAsyncList(load);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import * as React from 'react';
|
||||
import { TemplateRouteStep } from '../models';
|
||||
import { ApprovalRouteApi } from '../services/api';
|
||||
import { AsyncList, useAsyncList } from './useAsyncList';
|
||||
|
||||
/** Шаги ВСЕХ маршрутов с данным ExecutorEmail — для экрана «Заявки по согласующему». */
|
||||
export function useTemplateRouteStepsByExecutor(
|
||||
api: ApprovalRouteApi,
|
||||
executorEmail: string | undefined
|
||||
): AsyncList<TemplateRouteStep> {
|
||||
const load = React.useCallback(
|
||||
() => (executorEmail ? api.templateRouteSteps.listByExecutorEmail(executorEmail) : Promise.resolve([])),
|
||||
[api, executorEmail]
|
||||
);
|
||||
return useAsyncList(load);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import * as React from 'react';
|
||||
import { TemplateRoute } from '../models';
|
||||
import { ApprovalRouteApi } from '../services/api';
|
||||
|
||||
export interface TemplateRoutesLookup {
|
||||
byId: Map<number, TemplateRoute>;
|
||||
isLoading: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Дочитывает TemplateRoute по списку id (например, найденных через
|
||||
* useTemplateRouteStepsByExecutor) — bulk-эндпоинта нет, поэтому по одному
|
||||
* запросу на маршрут параллельно. Нужен для отображения (тип заявки/компания/
|
||||
* отдел маршрута), сам TemplateRouteStepDto хранит только routeId.
|
||||
*/
|
||||
export function useTemplateRoutesLookup(api: ApprovalRouteApi, routeIds: number[]): TemplateRoutesLookup {
|
||||
const [byId, setById] = React.useState<Map<number, TemplateRoute>>(new Map());
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const [error, setError] = React.useState<string | undefined>();
|
||||
|
||||
// Стабильный ключ вместо самого массива routeIds — иначе (новая ссылка на
|
||||
// массив с тем же содержимым при каждом рендере вызывающего экрана) эффект
|
||||
// перезапускался бы бесконечно.
|
||||
const key = React.useMemo(() => Array.from(new Set(routeIds)).sort((a, b) => a - b).join(','), [routeIds]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const ids = key ? key.split(',').map(Number) : [];
|
||||
if (ids.length === 0) {
|
||||
setById(new Map());
|
||||
return;
|
||||
}
|
||||
|
||||
let alive = true;
|
||||
setIsLoading(true);
|
||||
setError(undefined);
|
||||
Promise.all(ids.map(id => api.templateRoutes.get(id)))
|
||||
.then(routes => {
|
||||
if (!alive) return;
|
||||
setById(new Map(routes.map(r => [r.id, r])));
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
if (alive) setError(e.message);
|
||||
})
|
||||
.finally(() => {
|
||||
if (alive) setIsLoading(false);
|
||||
});
|
||||
return () => {
|
||||
alive = false;
|
||||
};
|
||||
}, [api, key]);
|
||||
|
||||
return { byId, isLoading, error };
|
||||
}
|
||||
Reference in New Issue
Block a user