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:
parent
e03307e286
commit
5585a9bed0
@ -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}
|
||||
|
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
 selected
|
||||
</StyledText>
|
||||
{children}
|
||||
</StyledBar>
|
||||
</StyledContainer>
|
||||
</StyledStickyContainer>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user