Обходной лист (#12)
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/12
This commit was merged in pull request #12.
This commit is contained in:
@@ -31,6 +31,7 @@ export const headTypeLabels: Record<HeadType, string> = {
|
||||
[HeadType.Chief]: 'Непосредственный руководитель',
|
||||
[HeadType.DirectionHead]: 'Руководитель направления',
|
||||
[HeadType.DirectorTansu]: 'Директор Tansu',
|
||||
[HeadType.ManagingDirectorTansu]: 'Управляющий директор Tansu',
|
||||
[HeadType.DepartmentHead]: 'Руководитель указанного отдела'
|
||||
};
|
||||
|
||||
@@ -158,6 +159,7 @@ export const texts = {
|
||||
filterAll: 'Все типы заявок',
|
||||
dictionaryFailed: (message: string): string => `Справочник компаний и отделов недоступен: ${message}`,
|
||||
emptyList: 'Маршрутов пока нет.',
|
||||
columnId: '№ маршрута',
|
||||
columnRequestType: 'Тип заявки',
|
||||
columnCompany: 'Компания',
|
||||
columnDepartment: 'Отдел',
|
||||
@@ -185,6 +187,38 @@ export const texts = {
|
||||
controlLabel: 'Контроль',
|
||||
controlCheckbox: 'Требуется отдельный контроль исполнения',
|
||||
validationRequestType: 'Выберите тип заявки.',
|
||||
|
||||
// ---- Копирование маршрута ----
|
||||
copy: 'Копировать',
|
||||
copyTitle: (routeId: number): string => `Копия маршрута #${routeId}`,
|
||||
copyAction: 'Создать копию',
|
||||
copyInProgress: 'Копирование...',
|
||||
copyHint:
|
||||
'Копия создаётся для того же типа заявки вместе со всеми шагами. Маршрут различается по компании, ' +
|
||||
'отделу и признаку «по проекту» — измените хотя бы одно из них, иначе копия совпадёт с исходным маршрутом.',
|
||||
copySource: (requestTypeName: string, company: string, department: string): string =>
|
||||
`Копируем: ${requestTypeName} · ${company} · ${department}`,
|
||||
copyStepsCount: (count: number): string =>
|
||||
`Шагов будет скопировано: ${count} ${pluralRu(count, ['шаг', 'шага', 'шагов'])}`,
|
||||
copyStepsLoading: 'Загрузка шагов исходного маршрута...',
|
||||
copyStepsEmpty: 'В исходном маршруте нет шагов — копия будет пустой.',
|
||||
validationCopySame:
|
||||
'Копия совпадает с исходным маршрутом. Измените компанию, отдел или признак «по проекту» — ' +
|
||||
'иначе такой маршрут уже существует.',
|
||||
// Роль в проекте допустима только у маршрута с признаком «по проекту» (проверка
|
||||
// на бэкенде, TemplateRouteStepService) — предупреждаем ДО копирования, иначе
|
||||
// копия сорвётся на середине переноса шагов.
|
||||
copyProjectRoleWarning: (count: number): string =>
|
||||
`В исходном маршруте ${count} ${pluralRu(count, ['шаг', 'шага', 'шагов'])} с ролью в проекте. ` +
|
||||
'Без признака «по проекту» такие шаги скопировать нельзя — включите его или удалите эти шаги в исходном маршруте.',
|
||||
copyStepFailed: (orderNo: number, message: string): string =>
|
||||
`Не удалось скопировать шаг ${orderNo}: ${message}`,
|
||||
// Частично скопированный маршрут опаснее, чем несозданный: он бы резолвился
|
||||
// с недостающими согласующими. Поэтому при ошибке копию удаляем целиком.
|
||||
copyRolledBack: 'Копия не создана — маршрут удалён, чтобы не остался наполовину скопированным.',
|
||||
copyRollbackFailed: (routeId: number): string =>
|
||||
`ВНИМАНИЕ: маршрут #${routeId} создан, но шаги скопированы не полностью, и удалить его автоматически не вышло. Удалите маршрут вручную.`,
|
||||
|
||||
deleteTitle: 'Удалить маршрут?',
|
||||
deleteText: (routeId: number): string =>
|
||||
`Маршрут #${routeId} и все его шаги будут удалены безвозвратно.`
|
||||
@@ -193,10 +227,20 @@ export const texts = {
|
||||
routeSteps: {
|
||||
breadcrumb: (routeId: number): string => `Шаги маршрута #${routeId}`,
|
||||
title: (routeId: number): string => `Маршрут #${routeId}`,
|
||||
subtitle: (requestTypeName: string): string => requestTypeName,
|
||||
/** Подзаголовок экрана шагов: по нему видно, ЧЕЙ это маршрут (тип заявки · компания · отдел). */
|
||||
subtitle: (requestTypeName: string, company: string, department: string): string =>
|
||||
`${requestTypeName} · ${company} · ${department}`,
|
||||
/** Маршрут без компании/отдела — запасной, применяется когда своего маршрута нет. */
|
||||
anyCompany: 'любая компания',
|
||||
anyDepartment: 'любой отдел',
|
||||
back: 'К маршрутам',
|
||||
add: 'Добавить шаг',
|
||||
emptyList: 'Шагов пока нет — добавьте первый.',
|
||||
moveUp: 'Шаг выше',
|
||||
moveDown: 'Шаг ниже',
|
||||
mergeWithPrev: 'Объединить с предыдущим шагом (выполнять параллельно)',
|
||||
splitFromPrev: 'Отделить от предыдущего шага (выполнять после него)',
|
||||
reorderFailed: (message: string): string => `Не удалось изменить порядок шагов: ${message}`,
|
||||
columnOrderNo: '№',
|
||||
columnExecutor: 'Исполнитель',
|
||||
columnStatus: 'Статус',
|
||||
@@ -220,6 +264,32 @@ export const texts = {
|
||||
executorPlaceholder: 'Выберите сотрудника',
|
||||
positionLabel: 'Должность',
|
||||
positionHint: 'Ищется в справочнике api.tnsu.kz по компании инициатора.',
|
||||
// Подсказка «кого найдёт эта должность» — считается по загруженному справочнику.
|
||||
positionPreviewLoading: 'Проверяем по справочнику сотрудников...',
|
||||
positionPreviewFound: (count: number): string =>
|
||||
count === 1
|
||||
? 'Сейчас эту должность занимает:'
|
||||
: `Эту должность занимают ${count} ${pluralRu(count, ['сотрудник', 'сотрудника', 'сотрудников'])} — ` +
|
||||
'на согласование пойдёт тот, чья компания совпадёт с компанией инициатора:',
|
||||
// У маршрута задана конкретная компания (не запасной «любая компания») —
|
||||
// резолвиться будет только сотрудник этой компании, остальные найденные
|
||||
// (в других компаниях) этому маршруту не подойдут ни при каких условиях.
|
||||
positionPreviewFoundInCompany: (company: string, count: number): string =>
|
||||
count === 1
|
||||
? `Эту должность в компании «${company}» (компания маршрута) занимает:`
|
||||
: `Эту должность в компании «${company}» (компания маршрута) занимают ${count} ` +
|
||||
`${pluralRu(count, ['сотрудник', 'сотрудника', 'сотрудников'])}:`,
|
||||
positionPreviewWrongCompany: (company: string): string =>
|
||||
`Такая должность есть в справочнике, но не в компании «${company}» — а маршрут применяется именно к её ` +
|
||||
'инициаторам. При резолве шаг останется без исполнителя.',
|
||||
positionPreviewOtherCompanies: 'Есть в других компаниях:',
|
||||
positionPreviewNone:
|
||||
'Точно такой должности в справочнике нет — на резолве шаг останется без исполнителя. Проверьте написание.',
|
||||
positionPreviewSimilar: 'Похожие должности в справочнике (нажмите, чтобы подставить точное написание):',
|
||||
/** Сколько ещё человек занимают ту же должность, кроме показанного. */
|
||||
positionPreviewMore: (count: number): string =>
|
||||
`и ещё ${count} ${pluralRu(count, ['человек', 'человека', 'человек'])}`,
|
||||
positionPreviewNoDictionary: 'Справочник сотрудников недоступен — проверить должность не удалось.',
|
||||
positionPlaceholder: 'Главный инженер',
|
||||
projectRoleLabel: 'Роль в проекте',
|
||||
headTypeLabel: 'Тип руководителя',
|
||||
@@ -233,7 +303,9 @@ export const texts = {
|
||||
askOverdueReasonHint: '«Не задано» — берётся значение типа заявки.',
|
||||
conditionLabel: 'Условие видимости шага',
|
||||
conditionCheckbox: 'Показывать шаг только при выполнении условия',
|
||||
conditionDisabledHint: 'Недоступно: у типа заявки не указан список SharePoint (list_name).',
|
||||
conditionDisabledHint:
|
||||
'У типа заявки не указан список SharePoint (list_name) — доступно только служебное поле «Инициатор — руководитель».',
|
||||
conditionFieldIsManagerLabel: 'Должность в заявке — руководящая (IsManager)',
|
||||
conditionFieldNameLabel: 'Поле списка',
|
||||
conditionFieldNamePlaceholder: 'Выберите столбец списка',
|
||||
conditionFieldNameLoading: 'Загрузка столбцов списка...',
|
||||
@@ -371,7 +443,10 @@ export const texts = {
|
||||
missingInDictionary: 'Нет в справочнике',
|
||||
loadingDictionary: 'Загрузка справочника...',
|
||||
searching: 'Поиск...',
|
||||
employeeSearchPlaceholder: 'Поиск по ФИО или email...',
|
||||
// Не перечисляем поля: искать можно и по ФИО, и по email, и по должности
|
||||
// (см. toEmployeeOption — должность попадает в sublabel, а SearchableSelect
|
||||
// ищет и по нему). Перечисление всё равно устарело бы при следующем поле.
|
||||
employeeSearchPlaceholder: 'Поиск...',
|
||||
employeesEmpty: 'Сотрудники не найдены в справочнике'
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user