mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
fix: align event log filter buttons (#7726)
Fixes an issue where the filter buttons were both too far down and too far to the right. The issue was that the wrapper body imposed a pretty substantial bit of padding. However, the filter buttons already came with their own bit of padding. The result of this was alignment issues. To fix it I have: - opened the `Filters` component up to be styled with styled components And conditionally (when isEnterprise and the flag is on): - set the page body to have no padding. - added a wrapper with padding around the event search results for This feels a little messy to me, but I also think that because it's still in heavy development, it might change later. I'd be happy to have suggestions forbetter implementations. What makes this extra tricky is that the top padding differs depending on whether you have the filters there or not, so I couldn't find a way to just remove that component and be done with it. I may very well have missed somehing, though. Before: ![image](https://github.com/user-attachments/assets/1552d1ec-2c14-450f-9ce8-8e74389f11a1) After: ![image](https://github.com/user-attachments/assets/d58b6fe5-437f-4488-bf01-cabfef669e2e)
This commit is contained in:
parent
643cfeb5bb
commit
2d0fb765f0
@ -30,6 +30,17 @@ const StyledEventsList = styled('ul')(({ theme }) => ({
|
||||
gap: theme.spacing(2),
|
||||
}));
|
||||
|
||||
const StyledFilters = styled(EventLogFilters)({
|
||||
padding: 0,
|
||||
});
|
||||
|
||||
const EventResultWrapper = styled('div')(({ theme }) => ({
|
||||
padding: theme.spacing(2, 4, 4, 4),
|
||||
display: 'flex',
|
||||
flexFlow: 'column',
|
||||
gap: theme.spacing(1),
|
||||
}));
|
||||
|
||||
export const EventLog = ({ title, project, feature }: IEventLogProps) => {
|
||||
const [query, setQuery] = useState('');
|
||||
const { events, totalEvents, fetchNextPage } = useEventSearch(
|
||||
@ -41,7 +52,7 @@ export const EventLog = ({ title, project, feature }: IEventLogProps) => {
|
||||
const { eventSettings, setEventSettings } = useEventSettings();
|
||||
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
||||
const { isEnterprise } = useUiConfig();
|
||||
const showFilters = useUiFlag('newEventSearch');
|
||||
const showFilters = useUiFlag('newEventSearch') && isEnterprise();
|
||||
|
||||
// Cache the previous search results so that we can show those while
|
||||
// fetching new results for a new search query in the background.
|
||||
@ -67,31 +78,12 @@ export const EventLog = ({ title, project, feature }: IEventLogProps) => {
|
||||
/>
|
||||
);
|
||||
|
||||
const logType = project ? 'project' : feature ? 'flag' : 'global';
|
||||
const count = events?.length || 0;
|
||||
const totalCount = totalEvents || 0;
|
||||
const countText = `${count} of ${totalCount}`;
|
||||
|
||||
return (
|
||||
<PageContent
|
||||
header={
|
||||
<PageHeader
|
||||
title={`${title} (${countText})`}
|
||||
actions={
|
||||
<>
|
||||
{showDataSwitch}
|
||||
{!isSmallScreen && searchInputField}
|
||||
</>
|
||||
}
|
||||
>
|
||||
{isSmallScreen && searchInputField}
|
||||
</PageHeader>
|
||||
}
|
||||
>
|
||||
<ConditionallyRender
|
||||
condition={isEnterprise() && showFilters}
|
||||
show={<EventLogFilters logType={logType} />}
|
||||
/>
|
||||
const EventResults = (
|
||||
<>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(cache && cache.length === 0)}
|
||||
show={<p>No events found.</p>}
|
||||
@ -111,6 +103,45 @@ export const EventLog = ({ title, project, feature }: IEventLogProps) => {
|
||||
</StyledEventsList>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<PageContent
|
||||
bodyClass={showFilters ? 'no-padding' : ''}
|
||||
header={
|
||||
<PageHeader
|
||||
title={`${title} (${countText})`}
|
||||
actions={
|
||||
<>
|
||||
{showDataSwitch}
|
||||
{!isSmallScreen && searchInputField}
|
||||
</>
|
||||
}
|
||||
>
|
||||
{isSmallScreen && searchInputField}
|
||||
</PageHeader>
|
||||
}
|
||||
>
|
||||
<ConditionallyRender
|
||||
condition={showFilters}
|
||||
show={
|
||||
<EventResultWrapper>
|
||||
<StyledFilters
|
||||
logType={
|
||||
project
|
||||
? 'project'
|
||||
: feature
|
||||
? 'flag'
|
||||
: 'global'
|
||||
}
|
||||
/>
|
||||
{EventResults}
|
||||
</EventResultWrapper>
|
||||
}
|
||||
elseShow={EventResults}
|
||||
/>
|
||||
|
||||
<div ref={fetchNextPageRef} />
|
||||
</PageContent>
|
||||
);
|
||||
|
@ -4,6 +4,10 @@ import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||
import { useFeatureSearch } from 'hooks/api/getters/useFeatureSearch/useFeatureSearch';
|
||||
import { EventSchemaType } from 'openapi';
|
||||
|
||||
type FilterProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const flagLogFilters: IFilterItem[] = [
|
||||
{
|
||||
label: 'Date From',
|
||||
@ -42,9 +46,10 @@ const flagLogFilters: IFilterItem[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const FlagLogFilters = () => {
|
||||
export const FlagLogFilters: FC<FilterProps> = ({ className }) => {
|
||||
return (
|
||||
<Filters
|
||||
className={className}
|
||||
availableFilters={flagLogFilters}
|
||||
state={{}}
|
||||
onChange={(v) => console.log(v)}
|
||||
@ -81,11 +86,12 @@ const useProjectLogFilters = () => {
|
||||
return availableFilters;
|
||||
};
|
||||
|
||||
export const ProjectLogFilters = () => {
|
||||
export const ProjectLogFilters: FC<FilterProps> = ({ className }) => {
|
||||
const availableFilters = useProjectLogFilters();
|
||||
|
||||
return (
|
||||
<Filters
|
||||
className={className}
|
||||
availableFilters={availableFilters}
|
||||
state={{}}
|
||||
onChange={(v) => console.log(v)}
|
||||
@ -93,7 +99,7 @@ export const ProjectLogFilters = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const GlobalLogFilters = () => {
|
||||
export const GlobalLogFilters: FC<FilterProps> = ({ className }) => {
|
||||
const projectFilters = useProjectLogFilters();
|
||||
const { projects } = useProjects();
|
||||
|
||||
@ -127,6 +133,7 @@ export const GlobalLogFilters = () => {
|
||||
|
||||
return (
|
||||
<Filters
|
||||
className={className}
|
||||
availableFilters={availableFilters}
|
||||
state={{}}
|
||||
onChange={(v) => console.log(v)}
|
||||
@ -136,17 +143,17 @@ export const GlobalLogFilters = () => {
|
||||
|
||||
type EventLogFiltersProps = {
|
||||
logType: 'flag' | 'project' | 'global';
|
||||
};
|
||||
} & FilterProps;
|
||||
export const EventLogFilters: FC<EventLogFiltersProps> = (
|
||||
{ logType },
|
||||
{ logType, ...props },
|
||||
// {state, onChange,} // these are to fill in later to make the filters work
|
||||
) => {
|
||||
switch (logType) {
|
||||
case 'flag':
|
||||
return <FlagLogFilters />;
|
||||
return <FlagLogFilters {...props} />;
|
||||
case 'project':
|
||||
return <ProjectLogFilters />;
|
||||
return <ProjectLogFilters {...props} />;
|
||||
case 'global':
|
||||
return <GlobalLogFilters />;
|
||||
return <GlobalLogFilters {...props} />;
|
||||
}
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ interface IFilterProps {
|
||||
state: FilterItemParamHolder;
|
||||
onChange: (value: FilterItemParamHolder) => void;
|
||||
availableFilters: IFilterItem[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
type IBaseFilterItem = {
|
||||
@ -61,6 +62,7 @@ export const Filters: FC<IFilterProps> = ({
|
||||
state,
|
||||
onChange,
|
||||
availableFilters,
|
||||
className,
|
||||
}) => {
|
||||
const [unselectedFilters, setUnselectedFilters] = useState<string[]>([]);
|
||||
const [selectedFilters, setSelectedFilters] = useState<string[]>([]);
|
||||
@ -115,7 +117,7 @@ export const Filters: FC<IFilterProps> = ({
|
||||
|
||||
const hasAvailableFilters = unselectedFilters.length > 0;
|
||||
return (
|
||||
<StyledBox>
|
||||
<StyledBox className={className}>
|
||||
{selectedFilters.map((selectedFilter) => {
|
||||
const filter = availableFilters.find(
|
||||
(filter) => filter.label === selectedFilter,
|
||||
|
Loading…
Reference in New Issue
Block a user