разные правки
This commit is contained in:
@@ -32,6 +32,15 @@ import {
|
||||
export interface IRouteStepFormModalProps {
|
||||
api: ApprovalRouteApi;
|
||||
route: TemplateRoute;
|
||||
/**
|
||||
* Название компании маршрута, если она задана (route.companyId) — undefined
|
||||
* для запасного маршрута («любая компания»). Резолв шага «по должности»
|
||||
* ищет исполнителя ИМЕННО в этой компании (initiatorCompany = компания
|
||||
* инициатора, а маршрут с заданной компанией применяется только к таким
|
||||
* инициаторам), поэтому подсказка должности должна сужаться под неё же —
|
||||
* иначе показала бы человека, которого этот маршрут никогда не найдёт.
|
||||
*/
|
||||
routeCompanyName?: string;
|
||||
/** Undefined, пока грузится тип заявки маршрута. */
|
||||
requestType?: RequestType;
|
||||
sharePoint: SharePointListsClient;
|
||||
@@ -132,6 +141,7 @@ function toFormState(editing: TemplateRouteStep | undefined, nextOrderNo: number
|
||||
export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
|
||||
api,
|
||||
route,
|
||||
routeCompanyName,
|
||||
requestType,
|
||||
sharePoint,
|
||||
editing,
|
||||
@@ -208,11 +218,42 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
|
||||
}
|
||||
|
||||
if (positionMatches.exact.length > 0) {
|
||||
// У маршрута задана конкретная компания — резолв ищет исполнителя ИМЕННО
|
||||
// в ней (route.companyId сужает круг инициаторов до этой компании, а
|
||||
// бэкенд ищет по компании инициатора). Найденные в других компаниях
|
||||
// этому маршруту не подойдут — их надо не прятать, а объяснить, что они не в счёт.
|
||||
const inRouteCompany = routeCompanyName
|
||||
? positionMatches.exact.filter(e => e.company === routeCompanyName)
|
||||
: positionMatches.exact;
|
||||
|
||||
if (inRouteCompany.length > 0) {
|
||||
return (
|
||||
<div className={`${styles.positionPreview} ${styles.previewOk}`}>
|
||||
<span className={styles.previewTitle}>
|
||||
{routeCompanyName
|
||||
? texts.routeSteps.positionPreviewFoundInCompany(routeCompanyName, inRouteCompany.length)
|
||||
: texts.routeSteps.positionPreviewFound(inRouteCompany.length)}
|
||||
</span>
|
||||
<ul className={styles.previewList}>
|
||||
{inRouteCompany.map(e => (
|
||||
<li key={e.email}>
|
||||
<span className={styles.previewPerson}>{e.fio}</span>
|
||||
{e.company && <span className={styles.previewCompany}> · {e.company}</span>}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// routeCompanyName задан, но среди найденных нет никого из этой компании —
|
||||
// должность существует, но не там, где её будет искать этот маршрут.
|
||||
return (
|
||||
<div className={`${styles.positionPreview} ${styles.previewOk}`}>
|
||||
<div className={`${styles.positionPreview} ${styles.previewMiss}`}>
|
||||
<span className={styles.previewTitle}>
|
||||
{texts.routeSteps.positionPreviewFound(positionMatches.exact.length)}
|
||||
{texts.routeSteps.positionPreviewWrongCompany(routeCompanyName as string)}
|
||||
</span>
|
||||
<div className={styles.previewTitle}>{texts.routeSteps.positionPreviewOtherCompanies}</div>
|
||||
<ul className={styles.previewList}>
|
||||
{positionMatches.exact.map(e => (
|
||||
<li key={e.email}>
|
||||
|
||||
@@ -11,6 +11,33 @@
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
// Колонка «№» закреплена слева при горизонтальном скролле — на узких экранах/
|
||||
// в редакторе SharePoint таблица шире контейнера, и без этого номер шага
|
||||
// (единственный ориентир при длинном горизонтальном скролле) уезжал за край
|
||||
// вместе с остальными колонками. Зеркало правого .stickyCell в
|
||||
// DataTable.module.scss (там — action-колонка у правого края).
|
||||
.stepColSticky {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
background: #fff;
|
||||
box-shadow: 6px 0 6px -6px rgba(15, 36, 64, .12);
|
||||
}
|
||||
|
||||
.table thead th.stepColSticky {
|
||||
background: $gray-50;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.table tbody td.stepColSticky {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// Явно, а не полагаясь на специфичность: .rowHover td и .stepColSticky иначе
|
||||
// шли бы вровень, и было бы неочевидно, какой фон победит при следующей правке.
|
||||
.rowHover td.stepColSticky {
|
||||
background: $gold-50;
|
||||
}
|
||||
|
||||
// Шаг, идущий одновременно с соседним (общий orderNo) — помечаем знаком ∥,
|
||||
// иначе два одинаковых номера подряд выглядят как ошибка данных.
|
||||
.parallelMark {
|
||||
|
||||
@@ -174,7 +174,7 @@ export const RouteStepsScreen: React.FC<IRouteStepsScreenProps> = ({ api, route,
|
||||
<table className={tableStyles.table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className={styles.stepCol}>{texts.routeSteps.columnOrderNo}</th>
|
||||
<th className={`${styles.stepCol} ${styles.stepColSticky}`}>{texts.routeSteps.columnOrderNo}</th>
|
||||
<th>{texts.routeSteps.columnExecutor}</th>
|
||||
<th>{texts.routeSteps.columnStatus}</th>
|
||||
<th style={{ textAlign: 'center' }}>{texts.routeSteps.columnReassign}</th>
|
||||
@@ -198,7 +198,7 @@ export const RouteStepsScreen: React.FC<IRouteStepsScreenProps> = ({ api, route,
|
||||
onMouseLeave={() => setHoveredBlock(undefined)}
|
||||
>
|
||||
{isBlockStart && (
|
||||
<td className={styles.stepCol} rowSpan={block.end - block.start + 1}>
|
||||
<td className={`${styles.stepCol} ${styles.stepColSticky}`} rowSpan={block.end - block.start + 1}>
|
||||
{block.end > block.start ? (
|
||||
<span className={styles.parallelMark} title={texts.routeSteps.mergeWithPrev}>
|
||||
{r.order} ∥
|
||||
@@ -280,6 +280,10 @@ export const RouteStepsScreen: React.FC<IRouteStepsScreenProps> = ({ api, route,
|
||||
|
||||
{showForm && (
|
||||
<RouteStepFormModal
|
||||
// Undefined, если у маршрута компания не задана (запасной маршрут,
|
||||
// применяется к любой компании инициатора) — тогда подсказка
|
||||
// должности показывает всех, как раньше, а не сужает по компании.
|
||||
routeCompanyName={route.companyId ? companyName : undefined}
|
||||
api={api}
|
||||
route={route}
|
||||
requestType={requestType}
|
||||
|
||||
Reference in New Issue
Block a user