Обходной лист (#12)
Tests / backend-test (push) Successful in 1m38s
Tests / frontend-test (push) Successful in 47s

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:
2026-08-17 05:43:52 +00:00
parent d076f4e98d
commit 48ede1420d
37 changed files with 1351 additions and 435 deletions
@@ -18,10 +18,17 @@
.full { grid-column: 1 / -1; }
.label {
// display:block + min-height на 2 строки — так подпись из одной строки
// и подпись, свернувшаяся на две (например «Спрашивать причину
// просрочки»), одинаково резервируют место, и контролы двух полей одной
// строки грида начинаются на одном уровне независимо от переноса текста.
display: block;
font-size: 12px;
font-weight: 500;
color: $gray-700;
letter-spacing: .2px;
line-height: 16px;
min-height: 32px;
}
.req { color: $gold-600; }
@@ -9,6 +9,10 @@ export interface IFormModalProps {
/** Текст ошибки: и валидации формы, и ответа бэкенда. */
error?: string;
isSaving: boolean;
/** Подпись кнопки подтверждения — по умолчанию «Сохранить» (см. копирование маршрута). */
submitLabel?: string;
/** Подпись той же кнопки во время запроса — по умолчанию «Сохранение...». */
savingLabel?: string;
onSubmit: () => void;
onClose: () => void;
children: React.ReactNode;
@@ -18,7 +22,16 @@ export interface IFormModalProps {
* Модальное окно формы: одинаковая обвязка «ошибка сверху, Отмена/Сохранить снизу»
* для всех справочников, чтобы экраны описывали только поля.
*/
export const FormModal: React.FC<IFormModalProps> = ({ title, error, isSaving, onSubmit, onClose, children }) => (
export const FormModal: React.FC<IFormModalProps> = ({
title,
error,
isSaving,
submitLabel = texts.common.save,
savingLabel = texts.common.saving,
onSubmit,
onClose,
children
}) => (
<Modal
title={title}
onClose={onClose}
@@ -26,7 +39,7 @@ export const FormModal: React.FC<IFormModalProps> = ({ title, error, isSaving, o
<>
<Button variant="secondary" onClick={onClose} disabled={isSaving}>{texts.common.cancel}</Button>
<Button variant="accent" icon="check" onClick={onSubmit} disabled={isSaving}>
{isSaving ? texts.common.saving : texts.common.save}
{isSaving ? savingLabel : submitLabel}
</Button>
</>
}
@@ -24,7 +24,8 @@ export type IconName =
| 'briefcase'
| 'flag'
| 'crown'
| 'refresh';
| 'refresh'
| 'copy';
let spriteInjected = false;
@@ -51,6 +52,7 @@ const SPRITE_SVG = `
<symbol id="i-flag" viewBox="0 0 24 24"><path d="M5 3v18"/><path d="M5 4h13l-3 4 3 4H5"/></symbol>
<symbol id="i-crown" viewBox="0 0 24 24"><path d="m3 8 4 3 5-6 5 6 4-3-2 11H5z"/></symbol>
<symbol id="i-refresh" viewBox="0 0 24 24"><path d="M21 12a9 9 0 1 1-3-6.7"/><path d="M21 3v6h-6"/></symbol>
<symbol id="i-copy" viewBox="0 0 24 24"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1"/></symbol>
`;
function ensureSpriteInjected(): void {