Заявление на увольнение (#15)
Tests / frontend-test (push) Successful in 1m17s

Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/15
This commit was merged in pull request #15.
This commit is contained in:
2026-08-26 07:07:03 +00:00
parent f751f03060
commit df29d080ed
39 changed files with 2460 additions and 46 deletions
@@ -0,0 +1,30 @@
@import '../../../../../styles/design-tokens';
// Read-only «карточка» со ссылкой — те же радиус/паддинг/приглушённый фон, что у
// OrganizationField (сигнал «подставлено автоматически, не редактируется»),
// отличается только тем, что содержимое кликабельно.
.box {
box-sizing: border-box;
padding: 11px 13px;
border: 1px solid $gray-200;
border-radius: $r-sm;
background: $gray-50;
font-family: $font-sans;
font-size: 13.5px;
color: $gray-700;
}
.link {
display: inline-flex;
align-items: center;
gap: $sp-2;
color: $navy-700;
text-decoration: none;
transition: color .18s;
&:hover,
&:focus {
color: $gold-600;
text-decoration: underline;
}
}
@@ -0,0 +1,52 @@
import * as React from 'react';
import styles from './LinkField.module.scss';
import { FormField, Icon } from '@tnsu/ui-kit';
import { navigateToRequestLink } from '../../routing';
interface ILinkFieldProps {
label: string;
/** Адрес. Пусто — поле не рендерится вовсе (см. ниже). */
url: string;
/** Текст ссылки. По умолчанию — сам адрес. */
text?: string;
}
/**
* Поле-ссылка: read-only, кликабельное, руками не редактируется.
*
* Пустой url — ничего не рендерим (а не пустую рамку): такие поля появляются
* только когда связь уже есть (напр. ClearanceUrl заявления на увольнение
* заполняется автосозданием обходного листа), и до этого момента их нет смысла
* показывать.
*
* Открывается в ТОЙ ЖЕ вкладке, и если ссылка ведёт на заявку этого же портала —
* вообще без перезагрузки страницы (navigateToRequestLink: та же страница, другие
* rp-параметры). href при этом настоящий, а не «#»: ссылку можно скопировать,
* открыть в новой вкладке через Ctrl/⌘+клик или среднюю кнопку — такие клики
* перехват намеренно пропускает.
*/
export const LinkField: React.FC<ILinkFieldProps> = ({ label, url, text }) => {
if (!url) return null;
const handleClick = (e: React.MouseEvent<HTMLAnchorElement>): void => {
// Клик с модификатором или не левой кнопкой — осознанное «открыть отдельно»,
// отдаём браузеру. Иначе пробуем перейти внутри портала.
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
return;
}
if (navigateToRequestLink(url)) {
e.preventDefault();
}
};
return (
<FormField label={label} full>
<div className={styles.box}>
<a className={styles.link} href={url} onClick={handleClick}>
<span>{text || url}</span>
<Icon name="chevron-right" size="sm" />
</a>
</div>
</FormField>
);
};
@@ -39,6 +39,7 @@ export { parseExcelRows } from './ItemsTable/parseExcelRows';
export { PeopleField } from './PeopleField/PeopleField';
export { PeopleFieldMulti } from './PeopleField/PeopleFieldMulti';
export { OrganizationField } from './OrganizationField/OrganizationField';
export { LinkField } from './LinkField/LinkField';
export { ErrorOverlay } from './ErrorOverlay/ErrorOverlay';
export { SubmitActions } from './SubmitActions/SubmitActions';
export { InitiatorLine } from './InitiatorLine/InitiatorLine';