1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-19 01:17:18 +02:00

Sticky batch actions bar (#3366)

This commit is contained in:
Tymoteusz Czech 2023-03-22 13:15:53 +01:00 committed by GitHub
parent e03307e286
commit 5585a9bed0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 268 additions and 240 deletions

View File

@ -1,6 +1,6 @@
import { FC, useState } from 'react';
import { Button } from '@mui/material';
import { Undo } from '@mui/icons-material';
import { Delete, Undo } from '@mui/icons-material';
import {
DELETE_FEATURE,
UPDATE_FEATURE,
@ -69,7 +69,7 @@ export const ArchiveBatchActions: FC<IArchiveBatchActionsProps> = ({
{({ hasAccess }) => (
<Button
disabled={!hasAccess}
startIcon={<Undo />}
startIcon={<Delete />}
variant="outlined"
size="small"
onClick={onDelete}

View File

@ -294,6 +294,7 @@ export const ArchiveTable = ({
}, [loading, sortBy, searchValue]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<>
<PageContent
isLoading={loading}
header={
@ -334,7 +335,8 @@ export const ArchiveTable = ({
}
elseShow={
<TablePlaceholder>
None of the feature toggles were archived yet.
None of the feature toggles were archived
yet.
</TablePlaceholder>
}
/>
@ -347,11 +349,12 @@ export const ArchiveTable = ({
setOpen={setDeleteModalOpen}
refetch={refetch}
/>
</PageContent>
<ConditionallyRender
condition={Boolean(projectId)}
show={
<BatchSelectionActionsBar
selectedIds={Object.keys(selectedRowIds)}
count={Object.keys(selectedRowIds).length}
>
<ArchiveBatchActions
selectedIds={Object.keys(selectedRowIds)}
@ -360,6 +363,6 @@ export const ArchiveTable = ({
</BatchSelectionActionsBar>
}
/>
</PageContent>
</>
);
};

View File

@ -2,14 +2,21 @@ import { FC } from 'react';
import { Box, Paper, styled, Typography } from '@mui/material';
interface IBatchSelectionActionsBarProps {
selectedIds: string[];
count: number;
}
const StyledContainer = styled(Box)(() => ({
const StyledStickyContainer = styled('div')(() => ({
position: 'sticky',
marginTop: 'auto',
bottom: 0,
}));
const StyledContainer = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'center',
width: '100%',
flexWrap: 'wrap',
paddingBottom: theme.spacing(2),
}));
const StyledBar = styled(Paper)(({ theme }) => ({
@ -40,22 +47,24 @@ const StyledText = styled(Typography)(({ theme }) => ({
}));
export const BatchSelectionActionsBar: FC<IBatchSelectionActionsBarProps> = ({
selectedIds,
count,
children,
}) => {
if (selectedIds.length === 0) {
if (count === 0) {
return null;
}
return (
<StyledStickyContainer>
<StyledContainer>
<StyledBar elevation={4}>
<StyledText>
<StyledCount>{selectedIds.length}</StyledCount>
<StyledCount>{count}</StyledCount>
&ensp;selected
</StyledText>
{children}
</StyledBar>
</StyledContainer>
</StyledStickyContainer>
);
};

View File

@ -91,7 +91,6 @@ export const InstanceStatus: FC = ({ children }) => {
useInstanceStatus();
const { extendTrial } = useInstanceStatusApi();
const { setToastApiError } = useToast();
const theme = useTheme();
const onExtendTrial = async () => {
try {
@ -103,12 +102,7 @@ export const InstanceStatus: FC = ({ children }) => {
};
return (
<div
style={{
height: '100%',
backgroundColor: theme.palette.background.paper,
}}
>
<>
<ConditionallyRender
condition={isBilling && Boolean(instanceStatus)}
show={() => (
@ -124,7 +118,7 @@ export const InstanceStatus: FC = ({ children }) => {
)}
/>
{children}
</div>
</>
);
};

View File

@ -21,12 +21,15 @@ interface IMainLayoutProps {
const MainLayoutContainer = styled(Grid)(() => ({
height: '100%',
justifyContent: 'space-between',
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
position: 'relative',
}));
const MainLayoutContentWrapper = styled('main')(({ theme }) => ({
margin: theme.spacing(0, 'auto'),
overflow: 'auto', // prevent margin collapsing
flex: 1,
flexGrow: 1,
width: '100%',
backgroundColor: theme.palette.background.application,
position: 'relative',

View File

@ -554,6 +554,7 @@ export const ProjectFeatureToggles = ({
]);
return (
<>
<PageContent
isLoading={loading}
className={styles.container}
@ -596,7 +597,8 @@ export const ProjectFeatureToggles = ({
setShowExportDialog(true)
}
sx={theme => ({
marginRight: theme.spacing(2),
marginRight:
theme.spacing(2),
})}
>
<FileDownload />
@ -663,7 +665,10 @@ export const ProjectFeatureToggles = ({
/>
<EnvironmentStrategyDialog
onClose={() =>
setStrategiesDialogState(prev => ({ ...prev, open: false }))
setStrategiesDialogState(prev => ({
...prev,
open: false,
}))
}
projectId={projectId}
{...strategiesDialogState}
@ -696,15 +701,20 @@ export const ProjectFeatureToggles = ({
onConfirm={onChangeRequestToggleConfirm}
messageComponent={
<UpdateEnabledMessage
featureName={changeRequestDialogDetails.featureName!}
featureName={
changeRequestDialogDetails.featureName!
}
enabled={changeRequestDialogDetails.enabled!}
environment={changeRequestDialogDetails?.environment!}
environment={
changeRequestDialogDetails?.environment!
}
/>
}
/>
<ConditionallyRender
condition={
Boolean(uiConfig?.flags?.featuresExportImport) && !loading
Boolean(uiConfig?.flags?.featuresExportImport) &&
!loading
}
show={
<ExportDialog
@ -715,13 +725,16 @@ export const ProjectFeatureToggles = ({
/>
}
/>
<BatchSelectionActionsBar selectedIds={Object.keys(selectedRowIds)}>
</PageContent>
<BatchSelectionActionsBar
count={Object.keys(selectedRowIds).length}
>
<ProjectFeaturesBatchActions
selectedIds={Object.keys(selectedRowIds)}
data={features}
projectId={projectId}
/>
</BatchSelectionActionsBar>
</PageContent>
</>
);
};

View File

@ -9,10 +9,13 @@ html {
}
body {
height: 100%;
min-height: 100%;
font-family: 'Sen', sans-serif;
font-size: 16px;
font-variant-ligatures: none;
padding: 0;
display: flex;
flex-direction: column;
}
button {
@ -139,7 +142,10 @@ a:hover {
}
#app {
height: 100%;
flex-grow: 1;
min-height: 100%;
display: flex;
flex-direction: column;
}
.MuiCardHeader-title {