кнопка выбрать все в таблице

This commit is contained in:
gorbenko.pavel
2026-08-19 16:44:40 +05:00
parent d9fa4b392b
commit ef7f27171d
3 changed files with 41 additions and 16 deletions
@@ -12,3 +12,9 @@
font-weight: 600; font-weight: 600;
color: $gray-700; color: $gray-700;
} }
.panelActions {
display: flex;
align-items: center;
gap: 8px;
}
@@ -158,6 +158,13 @@ export const ManageByUserScreen: React.FC<IManageByUserScreenProps> = ({ api, di
const checkedLiveRows = liveRows.filter(r => checkedLiveKeys.has(liveRowKey(r))); const checkedLiveRows = liveRows.filter(r => checkedLiveKeys.has(liveRowKey(r)));
const checkedTemplateRows = templateRows.filter(r => checkedTemplateIds.has(r.id)); const checkedTemplateRows = templateRows.filter(r => checkedTemplateIds.has(r.id));
const allLiveChecked = liveRows.length > 0 && checkedLiveRows.length === liveRows.length;
const toggleAllLive = (): void => setCheckedLiveKeys(allLiveChecked ? new Set() : new Set(liveRows.map(liveRowKey)));
const allTemplatesChecked = templateRows.length > 0 && checkedTemplateRows.length === templateRows.length;
const toggleAllTemplates = (): void =>
setCheckedTemplateIds(allTemplatesChecked ? new Set() : new Set(templateRows.map(r => r.id)));
const [replaceScope, setReplaceScope] = React.useState<IReplaceScope | undefined>(); const [replaceScope, setReplaceScope] = React.useState<IReplaceScope | undefined>();
const [resultToast, setResultToast] = React.useState<{ message: string; kind: 'ok' | 'err' } | undefined>(); const [resultToast, setResultToast] = React.useState<{ message: string; kind: 'ok' | 'err' } | undefined>();
@@ -297,14 +304,19 @@ export const ManageByUserScreen: React.FC<IManageByUserScreenProps> = ({ api, di
<Panel> <Panel>
<div className={styles.panelHeader}> <div className={styles.panelHeader}>
<div className={styles.panelTitle}>{`${texts.manageByUser.liveTitle} (${liveRows.length})`}</div> <div className={styles.panelTitle}>{`${texts.manageByUser.liveTitle} (${liveRows.length})`}</div>
<Button <div className={styles.panelActions}>
variant="secondary" <Button variant="ghost" size="sm" disabled={liveRows.length === 0} onClick={toggleAllLive}>
size="sm" {allLiveChecked ? texts.manageByUser.deselectAll : texts.manageByUser.selectAll}
disabled={checkedLiveRows.length === 0} </Button>
onClick={() => setReplaceScope({ live: checkedLiveRows, templates: [] })} <Button
> variant="secondary"
{texts.manageByUser.replaceSelected(checkedLiveRows.length)} size="sm"
</Button> disabled={checkedLiveRows.length === 0}
onClick={() => setReplaceScope({ live: checkedLiveRows, templates: [] })}
>
{texts.manageByUser.replaceSelected(checkedLiveRows.length)}
</Button>
</div>
</div> </div>
{liveError && <Alert kind="err">{`${texts.manageByUser.liveLoadError}: ${liveError}`}</Alert>} {liveError && <Alert kind="err">{`${texts.manageByUser.liveLoadError}: ${liveError}`}</Alert>}
{liveLoading && <div>{texts.common.loading}</div>} {liveLoading && <div>{texts.common.loading}</div>}
@@ -318,14 +330,19 @@ export const ManageByUserScreen: React.FC<IManageByUserScreenProps> = ({ api, di
<Panel> <Panel>
<div className={styles.panelHeader}> <div className={styles.panelHeader}>
<div className={styles.panelTitle}>{`${texts.manageByUser.templatesTitle} (${templateRows.length})`}</div> <div className={styles.panelTitle}>{`${texts.manageByUser.templatesTitle} (${templateRows.length})`}</div>
<Button <div className={styles.panelActions}>
variant="secondary" <Button variant="ghost" size="sm" disabled={templateRows.length === 0} onClick={toggleAllTemplates}>
size="sm" {allTemplatesChecked ? texts.manageByUser.deselectAll : texts.manageByUser.selectAll}
disabled={checkedTemplateRows.length === 0} </Button>
onClick={() => setReplaceScope({ live: [], templates: checkedTemplateRows })} <Button
> variant="secondary"
{texts.manageByUser.replaceSelected(checkedTemplateRows.length)} size="sm"
</Button> disabled={checkedTemplateRows.length === 0}
onClick={() => setReplaceScope({ live: [], templates: checkedTemplateRows })}
>
{texts.manageByUser.replaceSelected(checkedTemplateRows.length)}
</Button>
</div>
</div> </div>
{templateSteps.error && <Alert kind="err">{`${texts.manageByUser.templatesLoadError}: ${templateSteps.error}`}</Alert>} {templateSteps.error && <Alert kind="err">{`${texts.manageByUser.templatesLoadError}: ${templateSteps.error}`}</Alert>}
{templateSteps.isLoading && <div>{texts.common.loading}</div>} {templateSteps.isLoading && <div>{texts.common.loading}</div>}
@@ -464,6 +464,8 @@ export const texts = {
columnStepStatus: 'Статус шага', columnStepStatus: 'Статус шага',
columnCondition: 'Условие', columnCondition: 'Условие',
replaceOne: 'Заменить', replaceOne: 'Заменить',
selectAll: 'Выбрать все',
deselectAll: 'Снять выделение',
replaceSelected: (count: number): string => `Заменить выбранные (${count})`, replaceSelected: (count: number): string => `Заменить выбранные (${count})`,
replaceModalTitle: 'Новый согласующий', replaceModalTitle: 'Новый согласующий',
newEmployeeLabel: 'Сотрудник', newEmployeeLabel: 'Сотрудник',