скрипт

This commit is contained in:
gorbenko.pavel
2026-08-17 13:19:43 +05:00
parent 364835eaf7
commit e2c7f96021
37 changed files with 377 additions and 198 deletions
@@ -24,8 +24,9 @@ import {
findUnassignedStep
} from '../../shared/approval';
import { IRequestFormProps } from '../../models/types';
import { IFormData, EMPTY_DATA, SetField } from './model';
import { saveVacationRequest, vacationApprovalService, DATA_LIST_TITLE, APPROVAL_LIST_TITLE } from './submit';
import { approvalListTitle, dataListTitle } from '../../shared/listTitles';
import { FORM_ID, IFormData, EMPTY_DATA, SetField } from './model';
import { saveVacationRequest, vacationApprovalService } from './submit';
import { loadVacationRequest } from './load';
import { RequestSection } from './sections/RequestSection';
@@ -170,8 +171,8 @@ const VacationForm: React.FC<IRequestFormProps> = ({ requestType, context, onCan
if (status === REQUEST_STATUS.onApproval) {
await notifyActiveStep(context, approval, id, {
requestTypeId: rtId,
dataListName: DATA_LIST_TITLE,
approvalListName: APPROVAL_LIST_TITLE
dataListName: dataListTitle(FORM_ID),
approvalListName: approvalListTitle(FORM_ID)
});
}
};
@@ -206,7 +207,7 @@ const VacationForm: React.FC<IRequestFormProps> = ({ requestType, context, onCan
<FormCard
title={requestType.title}
subtitle="Категория: Отдел кадров"
belowSubtitle={<InitiatorLine listTitle={DATA_LIST_TITLE} itemId={requestId} />}
belowSubtitle={<InitiatorLine listTitle={dataListTitle(FORM_ID)} itemId={requestId} />}
headerRight={
requestId || requestStatus ? (
<>
@@ -12,9 +12,10 @@ import {
notifyActiveStep,
useRequestTypeId
} from '../../shared/approval';
import { IFormData, EMPTY_DATA, SetField } from './model';
import { approvalListTitle, dataListTitle } from '../../shared/listTitles';
import { FORM_ID, IFormData, EMPTY_DATA, SetField } from './model';
import { loadVacationRequest } from './load';
import { vacationApprovalService, DATA_LIST_TITLE, APPROVAL_LIST_TITLE } from './submit';
import { vacationApprovalService } from './submit';
import { RequestSection } from './sections/RequestSection';
interface IVacationViewProps {
@@ -39,7 +40,7 @@ const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey }
const approval = useMemo(() => vacationApprovalService(), []);
const { id: requestTypeId } = useRequestTypeId(context, formKey);
const approverService = useMemo(() => new ApproverService(approval, DATA_LIST_TITLE), [approval]);
const approverService = useMemo(() => new ApproverService(approval, dataListTitle(FORM_ID)), [approval]);
// Матрица маршрута из фактических строк заявки (read-only). decisionSeq в
// reloadKey: после решения строки на сервере меняются — перечитываем матрицу.
@@ -93,8 +94,8 @@ const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey }
if (!requestTypeId) return;
notifyActiveStep(context, approval, itemId, {
requestTypeId,
dataListName: DATA_LIST_TITLE,
approvalListName: APPROVAL_LIST_TITLE
dataListName: dataListTitle(FORM_ID),
approvalListName: approvalListTitle(FORM_ID)
}).catch(() => undefined);
};
@@ -108,7 +109,7 @@ const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey }
<FormCard
title="Заявка на отпуск"
subtitle={`№${code || itemId}`}
belowSubtitle={<InitiatorLine listTitle={DATA_LIST_TITLE} itemId={itemId} />}
belowSubtitle={<InitiatorLine listTitle={dataListTitle(FORM_ID)} itemId={itemId} />}
headerRight={status ? <StatusBadge status={status} /> : undefined}
>
<FormModeProvider readOnly>
@@ -1,7 +1,6 @@
import { getSP } from '../../shared/pnp/pnpjs';
import { IFormData, EMPTY_DATA } from './model';
const LIST_TITLE = 'Заявка на отпуск — данные';
import { dataListTitle } from '../../shared/listTitles';
import { FORM_ID, IFormData, EMPTY_DATA } from './model';
export interface ILoadedRequest {
data: IFormData;
@@ -15,7 +14,7 @@ export interface ILoadedRequest {
/** Прочитать заявку на отпуск по id: модель формы + статус (правка / просмотр). */
export async function loadVacationRequest(itemId: number): Promise<ILoadedRequest> {
const item = (await getSP()
.web.lists.getByTitle(LIST_TITLE)
.web.lists.getByTitle(dataListTitle(FORM_ID))
.items.getById(itemId)
.select(
'Id',
@@ -1,8 +1,15 @@
import { WebPartContext } from '@microsoft/sp-webpart-base';
import { RequestTypeId } from '../../models/types';
/**
* Тип заявки этой формы — ключ реестра форм (forms/registry.ts). Имена списков
* SharePoint выводятся из него, см. shared/listTitles.ts.
*/
export const FORM_ID: RequestTypeId = 'hr-vacation';
/**
* Данные формы «Заявка на отпуск». Ключи по возможности = internalName колонок
* SP-списка «Заявка на отпуск — данные». Employee хранит e-mail выбранного
* списка данных этой формы (см. shared/listTitles.ts). Employee хранит e-mail выбранного
* сотрудника (то, что отдаёт PeopleField) — по нему же резолвится маршрут
* согласования, поэтому заявку можно подать и за другого сотрудника.
* EndDate в форме не вводится: считается при сохранении как начало + (дни − 1).
@@ -1,14 +1,12 @@
import { getSP } from '../../shared/pnp/pnpjs';
import { ApprovalListService, IApproverToWrite, writeRoute } from '../../shared/approval';
import { buildRequestUniqueCode } from '../../shared/requestCode';
import { IFormData } from './model';
export const DATA_LIST_TITLE = 'Заявка на отпуск — данные';
export const APPROVAL_LIST_TITLE = 'Заявка на отпуск — согласование';
import { approvalListTitle, dataListTitle } from '../../shared/listTitles';
import { FORM_ID, IFormData } from './model';
/** Экземпляр сервиса списка согласования этой формы. */
export function vacationApprovalService(): ApprovalListService {
return new ApprovalListService(APPROVAL_LIST_TITLE);
return new ApprovalListService(approvalListTitle(FORM_ID));
}
/** email / claims-логин → пользователь сайта (Id для Person-поля + Title для заголовка). */
@@ -67,7 +65,7 @@ export async function saveVacationRequest(
approvers: IApproverToWrite[],
status: string
): Promise<ISaveResult> {
const list = getSP().web.lists.getByTitle(DATA_LIST_TITLE);
const list = getSP().web.lists.getByTitle(dataListTitle(FORM_ID));
const employee = await ensureEmployee(data.Employee);
const item = buildItem(data, status, employee.Id, employee.Title || data.Employee);