fix(ServiceRequest): строка сметы/объёмов работ не влезала в узкий Drawer
Форма открывается в боковом Drawer, а не на всю страницу — его ширина не связана с viewport, поэтому брейкпоинты CollapseSection/FormGrid (следят за шириной окна) не спасают. Фикс-колонки строки (ед.изм/кол-во/цена/ сумма) при этом не сжимались (grid-колонки по умолчанию не сжимаются своего содержимого) и вылезали за рамку карточки. Обернул строки в горизонтально скроллящийся контейнер (тот же приём, что раньше был у плоской таблицы — .tableWrap в AnnexesSection) вместо попытки сжать поля до нечитаемости. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+17
-2
@@ -54,12 +54,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Строка = наименование / ед.изм / кол-во / цена / сумма (+ кнопка удаления).
|
||||
// Строка целиком в фикс-колонках (ед.изм/кол-во/цена/сумма) физически не
|
||||
// влезает в узкую панель — форма открывается в Drawer сбоку, а не на всю
|
||||
// страницу, и его ширина не связана с шириной окна браузера (в отличие от
|
||||
// брейкпоинтов CollapseSection/FormGrid, которые следят за viewport, а не за
|
||||
// шириной своего контейнера). Вместо того чтобы сжимать поля до
|
||||
// нечитаемости, даём строке её естественную минимальную ширину и скроллим
|
||||
// горизонтально контейнером — тот же приём, что раньше был у плоской таблицы
|
||||
// (см. AnnexesSection .tableWrap), а не «резиновая» вёрстка, которая сама себя
|
||||
// сжать до бесконечности не умеет (grid-колонки по умолчанию не сжимаются
|
||||
// уже своего содержимого).
|
||||
.rowsWrap {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 96px 110px 140px 140px 32px;
|
||||
grid-template-columns: minmax(160px, 1fr) 84px 96px 128px 128px 30px;
|
||||
gap: $sp-2;
|
||||
align-items: center;
|
||||
min-width: 640px;
|
||||
|
||||
& + & {
|
||||
margin-top: $sp-2;
|
||||
|
||||
@@ -44,61 +44,63 @@ const CostGroup: React.FC<IGroupProps> = ({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.row} role="row">
|
||||
<span className={styles.colHead}>Наименование позиции</span>
|
||||
<span className={styles.colHead}>Ед. изм.</span>
|
||||
<span className={styles.colHead}>Количество</span>
|
||||
<span className={styles.colHead}>Цена</span>
|
||||
<span className={styles.colHead}>Сумма</span>
|
||||
{!readOnly && <span className={styles.colHead} aria-hidden />}
|
||||
</div>
|
||||
<div className={styles.rowsWrap}>
|
||||
<div className={styles.row} role="row">
|
||||
<span className={styles.colHead}>Наименование позиции</span>
|
||||
<span className={styles.colHead}>Ед. изм.</span>
|
||||
<span className={styles.colHead}>Количество</span>
|
||||
<span className={styles.colHead}>Цена</span>
|
||||
<span className={styles.colHead}>Сумма</span>
|
||||
{!readOnly && <span className={styles.colHead} aria-hidden />}
|
||||
</div>
|
||||
|
||||
{group.items.length === 0 ? (
|
||||
<div className={styles.empty}>Позиции не добавлены</div>
|
||||
) : (
|
||||
group.items.map((item, i) =>
|
||||
readOnly ? (
|
||||
<div className={styles.row} key={i} role="row">
|
||||
<span className={styles.cellStatic}>{item.description || '—'}</span>
|
||||
<span className={styles.cellStatic}>{item.unit || '—'}</span>
|
||||
<span className={styles.cellStatic}>{item.qty || '—'}</span>
|
||||
<span className={styles.cellStatic}>{item.rate || '—'}</span>
|
||||
<span className={styles.cellAmount}>{formatAmount(rowAmount(item))}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.row} key={i} role="row">
|
||||
<TextInput
|
||||
value={item.description}
|
||||
onChange={(v) => onChangeItem(i, { description: v })}
|
||||
placeholder="Наименование"
|
||||
ariaLabel="Наименование позиции"
|
||||
/>
|
||||
<TextInput
|
||||
value={item.unit}
|
||||
onChange={(v) => onChangeItem(i, { unit: v })}
|
||||
placeholder="шт."
|
||||
ariaLabel="Единица измерения"
|
||||
/>
|
||||
<TextInput
|
||||
value={item.qty}
|
||||
onChange={(v) => onChangeItem(i, { qty: v })}
|
||||
placeholder="0"
|
||||
ariaLabel="Количество"
|
||||
/>
|
||||
<TextInput
|
||||
value={item.rate}
|
||||
onChange={(v) => onChangeItem(i, { rate: v })}
|
||||
placeholder="0"
|
||||
ariaLabel="Цена за единицу"
|
||||
/>
|
||||
<span className={styles.cellAmount}>{item.qty || item.rate ? formatAmount(rowAmount(item)) : 'авто'}</span>
|
||||
<button type="button" className={styles.removeItem} title="Удалить позицию" onClick={() => onRemoveItem(i)}>
|
||||
<Icon name="trash" size="sm" />
|
||||
</button>
|
||||
</div>
|
||||
{group.items.length === 0 ? (
|
||||
<div className={styles.empty}>Позиции не добавлены</div>
|
||||
) : (
|
||||
group.items.map((item, i) =>
|
||||
readOnly ? (
|
||||
<div className={styles.row} key={i} role="row">
|
||||
<span className={styles.cellStatic}>{item.description || '—'}</span>
|
||||
<span className={styles.cellStatic}>{item.unit || '—'}</span>
|
||||
<span className={styles.cellStatic}>{item.qty || '—'}</span>
|
||||
<span className={styles.cellStatic}>{item.rate || '—'}</span>
|
||||
<span className={styles.cellAmount}>{formatAmount(rowAmount(item))}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.row} key={i} role="row">
|
||||
<TextInput
|
||||
value={item.description}
|
||||
onChange={(v) => onChangeItem(i, { description: v })}
|
||||
placeholder="Наименование"
|
||||
ariaLabel="Наименование позиции"
|
||||
/>
|
||||
<TextInput
|
||||
value={item.unit}
|
||||
onChange={(v) => onChangeItem(i, { unit: v })}
|
||||
placeholder="шт."
|
||||
ariaLabel="Единица измерения"
|
||||
/>
|
||||
<TextInput
|
||||
value={item.qty}
|
||||
onChange={(v) => onChangeItem(i, { qty: v })}
|
||||
placeholder="0"
|
||||
ariaLabel="Количество"
|
||||
/>
|
||||
<TextInput
|
||||
value={item.rate}
|
||||
onChange={(v) => onChangeItem(i, { rate: v })}
|
||||
placeholder="0"
|
||||
ariaLabel="Цена за единицу"
|
||||
/>
|
||||
<span className={styles.cellAmount}>{item.qty || item.rate ? formatAmount(rowAmount(item)) : 'авто'}</span>
|
||||
<button type="button" className={styles.removeItem} title="Удалить позицию" onClick={() => onRemoveItem(i)}>
|
||||
<Icon name="trash" size="sm" />
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
)
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.groupFoot}>
|
||||
{!readOnly && (
|
||||
|
||||
Reference in New Issue
Block a user