скрипт
This commit is contained in:
@@ -35,8 +35,9 @@ import {
|
||||
} from '../../shared/attachments/attachments.service';
|
||||
import { effectiveUserEmail } from '../../shared/impersonation';
|
||||
import { IRequestFormProps } from '../../models/types';
|
||||
import { IFormData, EMPTY_DATA, SetField } from './model';
|
||||
import { saveSelectionRequest, selectionApprovalService, DATA_LIST_TITLE, APPROVAL_LIST_TITLE } from './submit';
|
||||
import { approvalListTitle, dataListTitle } from '../../shared/listTitles';
|
||||
import { FORM_ID, IFormData, EMPTY_DATA, SetField } from './model';
|
||||
import { saveSelectionRequest, selectionApprovalService } from './submit';
|
||||
import { loadSelectionRequest } from './load';
|
||||
import { ApplicationSection } from './sections/ApplicationSection';
|
||||
import { DepartmentSection } from './sections/DepartmentSection';
|
||||
@@ -63,7 +64,7 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({ requestType, con
|
||||
return;
|
||||
}
|
||||
let alive = true;
|
||||
Promise.all([loadSelectionRequest(editId), getAttachments(DATA_LIST_TITLE, editId)])
|
||||
Promise.all([loadSelectionRequest(editId), getAttachments(dataListTitle(FORM_ID), editId)])
|
||||
.then(([loaded, atts]) => {
|
||||
if (alive) {
|
||||
setData(loaded.data);
|
||||
@@ -131,7 +132,7 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({ requestType, con
|
||||
if (requestId === undefined) {
|
||||
return;
|
||||
}
|
||||
deleteAttachment(DATA_LIST_TITLE, requestId, fileName)
|
||||
deleteAttachment(dataListTitle(FORM_ID), requestId, fileName)
|
||||
.then(() => setExistingAttachments((prev) => prev.filter((a) => a.fileName !== fileName)))
|
||||
.catch(() => undefined);
|
||||
};
|
||||
@@ -151,9 +152,9 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({ requestType, con
|
||||
setRequestCode(code);
|
||||
}
|
||||
if (files.length > 0) {
|
||||
await uploadAttachments(DATA_LIST_TITLE, id, files); // файлы — после создания элемента
|
||||
await uploadAttachments(dataListTitle(FORM_ID), id, files); // файлы — после создания элемента
|
||||
setFiles([]); // выгруженные файлы убираем, чтобы пересохранение не дублировало
|
||||
setExistingAttachments(await getAttachments(DATA_LIST_TITLE, id));
|
||||
setExistingAttachments(await getAttachments(dataListTitle(FORM_ID), id));
|
||||
}
|
||||
if (onSaved) {
|
||||
onSaved();
|
||||
@@ -162,8 +163,8 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({ requestType, con
|
||||
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)
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -198,7 +199,7 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({ requestType, con
|
||||
<FormCard
|
||||
title={requestType.title}
|
||||
subtitle="Категория: Отдел рекрутинга"
|
||||
belowSubtitle={<InitiatorLine listTitle={DATA_LIST_TITLE} itemId={requestId} />}
|
||||
belowSubtitle={<InitiatorLine listTitle={dataListTitle(FORM_ID)} itemId={requestId} />}
|
||||
headerRight={
|
||||
requestId || requestStatus ? (
|
||||
<>
|
||||
|
||||
@@ -13,9 +13,10 @@ import {
|
||||
useRequestTypeId
|
||||
} from '../../shared/approval';
|
||||
import { getAttachments, IAttachmentInfo } from '../../shared/attachments/attachments.service';
|
||||
import { IFormData, EMPTY_DATA, SetField } from './model';
|
||||
import { approvalListTitle, dataListTitle } from '../../shared/listTitles';
|
||||
import { FORM_ID, IFormData, EMPTY_DATA, SetField } from './model';
|
||||
import { loadSelectionRequest } from './load';
|
||||
import { selectionApprovalService, DATA_LIST_TITLE, APPROVAL_LIST_TITLE } from './submit';
|
||||
import { selectionApprovalService } from './submit';
|
||||
import { ApplicationSection } from './sections/ApplicationSection';
|
||||
import { DepartmentSection } from './sections/DepartmentSection';
|
||||
import { VacancySection } from './sections/VacancySection';
|
||||
@@ -44,7 +45,7 @@ const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ cont
|
||||
|
||||
const approval = useMemo(() => selectionApprovalService(), []);
|
||||
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: после решения строки на сервере меняются — перечитываем матрицу.
|
||||
@@ -57,7 +58,7 @@ const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ cont
|
||||
useEffect(() => {
|
||||
let alive = true;
|
||||
setLoading(true);
|
||||
Promise.all([loadSelectionRequest(itemId), getAttachments(DATA_LIST_TITLE, itemId)])
|
||||
Promise.all([loadSelectionRequest(itemId), getAttachments(dataListTitle(FORM_ID), itemId)])
|
||||
.then(([loaded, files]) => {
|
||||
if (alive) {
|
||||
setData(loaded.data);
|
||||
@@ -96,8 +97,8 @@ const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ cont
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -111,7 +112,7 @@ const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ cont
|
||||
<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';
|
||||
|
||||
// Категории полей — определяют, как читать значение из элемента списка.
|
||||
const PERSON_FIELDS: (keyof IFormData)[] = ['Responsible', 'ProposedMentor', 'DirectManager'];
|
||||
@@ -30,7 +29,7 @@ export async function loadSelectionRequest(itemId: number): Promise<ILoadedReque
|
||||
const expands = [...PERSON_FIELDS, ...MULTI_PERSON_FIELDS];
|
||||
|
||||
const item = (await getSP()
|
||||
.web.lists.getByTitle(LIST_TITLE)
|
||||
.web.lists.getByTitle(dataListTitle(FORM_ID))
|
||||
.items.getById(itemId)
|
||||
.select(...scalarSelects, 'RequestStatus', 'RequestUniqueCode', ...personSelects)
|
||||
.expand(...expands)()) as Record<string, unknown>;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { ISelectOption } from '../../shared/ui';
|
||||
import { RequestTypeId } from '../../models/types';
|
||||
|
||||
/**
|
||||
* Тип заявки этой формы — ключ реестра форм (forms/registry.ts). Имена списков
|
||||
* SharePoint выводятся из него, см. shared/listTitles.ts.
|
||||
*/
|
||||
export const FORM_ID: RequestTypeId = 'recruiting-selection';
|
||||
|
||||
/**
|
||||
* Данные формы «Заявка на подбор». Ключи = internalName колонок SP-списка
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
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';
|
||||
|
||||
// Поля-люди (один человек): логин → ensureUser → Id в колонку <Field>Id.
|
||||
const PERSON_FIELDS: (keyof IFormData)[] = ['Responsible', 'ProposedMentor', 'DirectManager'];
|
||||
@@ -15,7 +13,7 @@ const NUMBER_FIELDS: (keyof IFormData)[] = ['DepartmentHeadcount', 'RateProbatio
|
||||
|
||||
/** Экземпляр сервиса списка согласования этой формы. */
|
||||
export function selectionApprovalService(): ApprovalListService {
|
||||
return new ApprovalListService(APPROVAL_LIST_TITLE);
|
||||
return new ApprovalListService(approvalListTitle(FORM_ID));
|
||||
}
|
||||
|
||||
/** Логин → числовой Id пользователя на текущем сайте. */
|
||||
@@ -78,7 +76,7 @@ export async function saveSelectionRequest(
|
||||
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 item = buildScalarBody(data);
|
||||
item.RequestStatus = status;
|
||||
await applyPeople(item, data);
|
||||
|
||||
Reference in New Issue
Block a user