Files
hr-appeals/src/features/feedback/model.ts
T
gorbenko.pavel 836a472fe0
Tests / frontend-test (push) Successful in 12s
fix: делает "Предложение" видом обращения по умолчанию
Порядок вариантов синхронизирован с новым дефолтом и восстановлен как в
исходной форме: "Предложение" первым в списке, а не "Жалоба".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 12:16:41 +05:00

103 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ISelectOption } from '@tnsu/ui-kit';
/** Вид обращения. Union вместо строк, чтобы опечатку поймал компилятор. */
export type AppealKind = 'complaint' | 'suggestion' | 'other';
/** Данные формы обращения. Одна плоская структура — один источник истины. */
export interface IFeedbackData {
company: string;
/** true — автор не указывает себя и не получит ответ. */
isAnonymous: boolean;
fullName: string;
position: string;
wantsFeedback: boolean;
kind: AppealKind;
/** Заполняется только при kind === 'other'. */
kindOther: string;
situation: string;
suggestion: string;
}
/**
* Компании группы. В value — реальный Id из справочника, а не slug: именно его
* ждёт бэкенд, когда появится отправка. Порядок как в источнике (по алфавиту).
*/
export const COMPANY_OPTIONS: ISelectOption[] = [
{ value: '8028abac-ac23-8fd8-11ef-cb57631a9ab0', label: 'ТОО AFL Engineering' },
{ value: '9de064a4-44c8-88ef-11ec-831c058b1141', label: 'ТОО CL MANAGEMENT' },
{ value: '9de064a4-44c8-88ef-11ec-8287fb7737a2', label: 'ТОО KazPromService' },
{ value: 'ec3c78a7-29ef-4725-11ed-a6d8fcd0911d', label: 'ТОО QAZGEOMAX' },
{ value: '15009595-005d-00fa-11ef-11309f5e395d', label: 'ТОО Selin Invest' },
{ value: '03f4deac-f543-e8cf-11f1-84eb25329fc3', label: 'ТОО Selin Studio' },
{ value: '9de064a4-44c8-88ef-11ec-8284930fad96', label: 'ТОО TANSU Construction' },
{ value: '9de064a4-44c8-88ef-11ec-8285925d83d2', label: 'ТОО АСТЕЛ-К' },
{ value: '15009595-005d-00fa-11ef-0b8bb5ec1a88', label: 'ТОО ГеоТрек' },
{ value: '15009595-005d-00fa-11ef-0b8714483372', label: 'ТОО Монтажник-Т' },
{ value: '8028beac-ac23-8fd8-11f0-5351706e5996', label: 'ТОО ОСН Беркут' },
{ value: '8028b0ac-ac23-8fd8-11ef-dcdb24b82e02', label: 'ТОО СТ Global' },
{ value: '15009595-005d-00fa-11ef-1131801d9f3e', label: 'ТОО ТехЛаб' },
{ value: '03f4deac-f543-e8cf-11f1-84f51483f59e', label: 'Частная компания Seline Holding Ltd' }
];
// Порядок как в исходной форме: «Предложение» первым — совпадает с дефолтным
// значением ниже (EMPTY_FEEDBACK.kind), так что выбор пользователя.
export const KIND_OPTIONS: ISelectOption[] = [
{ value: 'suggestion', label: 'Предложение' },
{ value: 'complaint', label: 'Жалоба' },
{ value: 'other', label: 'Другое' }
];
/** Показывать поле или нет, и если показывать — обязательно ли оно. */
export interface IAppealFieldConfig {
visible: boolean;
required: boolean;
}
/** Настройка текстовых полей для выбранного вида обращения. */
export interface IAppealFieldsConfig {
situation: IAppealFieldConfig;
suggestion: IAppealFieldConfig;
}
/**
* Состав полей зависит от вида обращения:
* жалоба — обязательно описание, а предложение — на желание автора;
* предложение — только само предложение, «ситуации» ещё нет;
* другое — свободное описание, без предложения.
* Одно правило на форму и на валидацию, чтобы они не разошлись.
*/
export function getAppealFieldsConfig(kind: AppealKind): IAppealFieldsConfig {
switch (kind) {
case 'complaint':
return {
situation: { visible: true, required: true },
suggestion: { visible: true, required: false }
};
case 'suggestion':
return {
situation: { visible: false, required: false },
suggestion: { visible: true, required: true }
};
case 'other':
return {
situation: { visible: true, required: true },
suggestion: { visible: false, required: false }
};
}
}
export const EMPTY_FEEDBACK: IFeedbackData = {
company: '',
isAnonymous: false,
fullName: '',
position: '',
wantsFeedback: false,
kind: 'suggestion',
kindOther: '',
situation: '',
suggestion: ''
};
/** Ключи полей, по которым показываем ошибку валидации. */
export type FeedbackErrors = Partial<Record<keyof IFeedbackData, string>>;