feat: added notifications workflow
This commit is contained in:
@@ -39,6 +39,7 @@ export const ApprovalMatrix: React.FC<IApprovalMatrixProps> = ({
|
||||
<div className={styles.matrixNote}>{emptyText}</div>
|
||||
)}
|
||||
{!loading && !error && rows.length > 0 && (
|
||||
<div className={styles.matrixScroll}>
|
||||
<table className={styles.matrix}>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -51,45 +52,57 @@ export const ApprovalMatrix: React.FC<IApprovalMatrixProps> = ({
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((r, i) => (
|
||||
<tr key={i}>
|
||||
<td>{r.who}</td>
|
||||
<td>{r.position}</td>
|
||||
<td>{r.status && r.status !== '—' ? <StatusBadge status={r.status} /> : '—'}</td>
|
||||
<td>{r.date}</td>
|
||||
{editable && (
|
||||
<td className={styles.matrixActions}>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.iconBtn}
|
||||
disabled={i === 0}
|
||||
onClick={() => editor.moveUp(i)}
|
||||
title="Выше"
|
||||
>
|
||||
<Icon name="chevron-down" size="sm" className={styles.flipY} />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.iconBtn}
|
||||
disabled={i === rows.length - 1}
|
||||
onClick={() => editor.moveDown(i)}
|
||||
title="Ниже"
|
||||
>
|
||||
<Icon name="chevron-down" size="sm" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.iconBtn} ${styles.iconBtnDanger}`}
|
||||
onClick={() => editor.remove(i)}
|
||||
title="Удалить"
|
||||
>
|
||||
<Icon name="trash" size="sm" />
|
||||
</button>
|
||||
<React.Fragment key={i}>
|
||||
<tr className={r.comment ? styles.rowNoBorder : undefined}>
|
||||
<td data-label={roleLabel}>{r.who}</td>
|
||||
<td data-label="Должность">{r.position}</td>
|
||||
<td data-label="Статус">
|
||||
{r.status && r.status !== '—' ? <StatusBadge status={r.status} /> : '—'}
|
||||
</td>
|
||||
<td data-label="Дата">{r.date}</td>
|
||||
{editable && (
|
||||
<td className={styles.matrixActions}>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.iconBtn}
|
||||
disabled={i === 0}
|
||||
onClick={() => editor.moveUp(i)}
|
||||
title="Выше"
|
||||
>
|
||||
<Icon name="chevron-down" size="sm" className={styles.flipY} />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.iconBtn}
|
||||
disabled={i === rows.length - 1}
|
||||
onClick={() => editor.moveDown(i)}
|
||||
title="Ниже"
|
||||
>
|
||||
<Icon name="chevron-down" size="sm" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.iconBtn} ${styles.iconBtnDanger}`}
|
||||
onClick={() => editor.remove(i)}
|
||||
title="Удалить"
|
||||
>
|
||||
<Icon name="trash" size="sm" />
|
||||
</button>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
{r.comment && (
|
||||
<tr>
|
||||
<td colSpan={editable ? 5 : 4} className={styles.commentCell}>
|
||||
<span className={styles.commentLabel}>Комментарий:</span> {r.comment}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tr>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
{editable && !loading && (
|
||||
<div className={styles.matrixPicker}>
|
||||
|
||||
@@ -91,8 +91,16 @@
|
||||
color: $gray-500;
|
||||
}
|
||||
|
||||
// Обёртка таблицы: на промежуточных ширинах — горизонтальный скролл вместо
|
||||
// сплющивания колонок. На телефоне таблица становится карточками (медиазапрос ниже).
|
||||
.matrixScroll {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.matrix {
|
||||
width: 100%;
|
||||
min-width: 480px; // колонки не сжимаются; при нехватке места .matrixScroll прокручивает
|
||||
border-collapse: collapse;
|
||||
font-size: $fs-sm;
|
||||
|
||||
@@ -113,6 +121,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Строка, у которой ниже идёт комментарий: убираем нижнюю границу, чтобы строка
|
||||
// и её комментарий читались как единый блок (граница переезжает на .commentCell).
|
||||
.rowNoBorder td {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.commentCell {
|
||||
padding: 0 8px 8px !important;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
font-size: $fs-caption;
|
||||
color: $gray-500;
|
||||
line-height: 1.45;
|
||||
white-space: pre-wrap; // сохранить переносы строк из комментария
|
||||
}
|
||||
|
||||
.commentLabel {
|
||||
color: $gray-400;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.matrixActions {
|
||||
display: flex;
|
||||
gap: $sp-1;
|
||||
@@ -158,3 +186,54 @@
|
||||
.matrixPicker {
|
||||
margin-top: $sp-3;
|
||||
}
|
||||
|
||||
// ---- Мобильные экраны: таблица маршрута → карточки ----
|
||||
// Скрываем шапку, каждая строка — блок, ячейки в столбик с подписью поля
|
||||
// (из data-label). Так маршрут читается на телефоне без горизонтального скролла.
|
||||
@media (max-width: 640px) {
|
||||
.matrix {
|
||||
min-width: 0; // на телефоне не растягиваем — раскладываем в столбик
|
||||
}
|
||||
|
||||
.matrix thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.matrix tr {
|
||||
display: block;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
// Строка с комментарием: линия — на самом комментарии, не на строке.
|
||||
.rowNoBorder {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.matrix td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $sp-2;
|
||||
border: 0 !important;
|
||||
padding: 3px 0 !important;
|
||||
}
|
||||
|
||||
// Подпись поля перед значением (только у ячеек с data-label).
|
||||
.matrix td[data-label]::before {
|
||||
content: attr(data-label);
|
||||
flex: 0 0 44%;
|
||||
color: $gray-500;
|
||||
font-size: $fs-caption;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.matrixActions {
|
||||
justify-content: flex-start;
|
||||
padding-top: $sp-2 !important;
|
||||
}
|
||||
|
||||
.commentCell {
|
||||
display: block;
|
||||
padding: 2px 0 6px !important;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user