mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02:00
fix: misc UI/UX fixes, mostly related with favorites (#2683)
https://linear.app/unleash/issue/2-504/misc-frontend-related-fixes-mostly-related-with-favorites
This commit is contained in:
parent
a8cd3166d1
commit
e05d924663
@ -1,11 +1,5 @@
|
|||||||
import { useEffect, useMemo, useState, VFC } from 'react';
|
import { useEffect, useMemo, useState, VFC } from 'react';
|
||||||
import {
|
import { IconButton, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||||
IconButton,
|
|
||||||
styled,
|
|
||||||
Tooltip,
|
|
||||||
useMediaQuery,
|
|
||||||
useTheme,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { useSearchParams, Link } from 'react-router-dom';
|
import { useSearchParams, Link } from 'react-router-dom';
|
||||||
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
|
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
|
||||||
import { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
|
import { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
|
||||||
@ -41,14 +35,6 @@ import {
|
|||||||
UG_REMOVE_USER_BTN_ID,
|
UG_REMOVE_USER_BTN_ID,
|
||||||
} from 'utils/testIds';
|
} from 'utils/testIds';
|
||||||
|
|
||||||
const StyledEdit = styled(Edit)(({ theme }) => ({
|
|
||||||
fontSize: theme.fontSizes.mainHeader,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledDelete = styled(Delete)(({ theme }) => ({
|
|
||||||
fontSize: theme.fontSizes.mainHeader,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const groupUsersPlaceholder: IGroupUser[] = Array(15).fill({
|
export const groupUsersPlaceholder: IGroupUser[] = Array(15).fill({
|
||||||
name: 'Name of the user',
|
name: 'Name of the user',
|
||||||
username: 'Username of the user',
|
username: 'Username of the user',
|
||||||
@ -248,7 +234,7 @@ export const Group: VFC = () => {
|
|||||||
title: 'Edit group',
|
title: 'Edit group',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledEdit />
|
<Edit />
|
||||||
</PermissionIconButton>
|
</PermissionIconButton>
|
||||||
<PermissionIconButton
|
<PermissionIconButton
|
||||||
data-testid={UG_DELETE_BTN_ID}
|
data-testid={UG_DELETE_BTN_ID}
|
||||||
@ -259,7 +245,7 @@ export const Group: VFC = () => {
|
|||||||
title: 'Delete group',
|
title: 'Delete group',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledDelete />
|
<Delete />
|
||||||
</PermissionIconButton>
|
</PermissionIconButton>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { IconButton, SxProps, Theme } from '@mui/material';
|
import { IconButton, IconButtonProps } from '@mui/material';
|
||||||
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
|
||||||
import {
|
import {
|
||||||
Star as StarIcon,
|
Star as StarIcon,
|
||||||
@ -7,30 +7,24 @@ import {
|
|||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { TooltipResolver } from '../TooltipResolver/TooltipResolver';
|
import { TooltipResolver } from '../TooltipResolver/TooltipResolver';
|
||||||
|
|
||||||
interface IFavoriteIconButtonProps {
|
interface IFavoriteIconButtonProps extends IconButtonProps {
|
||||||
onClick: (event?: any) => void;
|
|
||||||
isFavorite: boolean;
|
isFavorite: boolean;
|
||||||
size?: 'medium' | 'large';
|
size?: 'medium' | 'large';
|
||||||
sx?: SxProps<Theme>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FavoriteIconButton: VFC<IFavoriteIconButtonProps> = ({
|
export const FavoriteIconButton: VFC<IFavoriteIconButtonProps> = ({
|
||||||
onClick,
|
|
||||||
isFavorite,
|
isFavorite,
|
||||||
size = 'large',
|
size = 'large',
|
||||||
sx,
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<TooltipResolver
|
||||||
size={size}
|
title={isFavorite ? 'Remove from favorites' : 'Add to favorites'}
|
||||||
data-loading
|
|
||||||
sx={{ mr: 1, ...sx }}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
<IconButton size={size} data-loading {...props}>
|
||||||
condition={isFavorite}
|
<ConditionallyRender
|
||||||
show={
|
condition={isFavorite}
|
||||||
<TooltipResolver title={'Remove from favorites'}>
|
show={
|
||||||
<StarIcon
|
<StarIcon
|
||||||
color="primary"
|
color="primary"
|
||||||
sx={{
|
sx={{
|
||||||
@ -40,10 +34,8 @@ export const FavoriteIconButton: VFC<IFavoriteIconButtonProps> = ({
|
|||||||
: theme.spacing(3),
|
: theme.spacing(3),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TooltipResolver>
|
}
|
||||||
}
|
elseShow={
|
||||||
elseShow={
|
|
||||||
<TooltipResolver title={'Add to favorites'}>
|
|
||||||
<StarBorderIcon
|
<StarBorderIcon
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: theme =>
|
fontSize: theme =>
|
||||||
@ -52,9 +44,9 @@ export const FavoriteIconButton: VFC<IFavoriteIconButtonProps> = ({
|
|||||||
: theme.spacing(3),
|
: theme.spacing(3),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TooltipResolver>
|
}
|
||||||
}
|
/>
|
||||||
/>
|
</IconButton>
|
||||||
</IconButton>
|
</TooltipResolver>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,7 @@ const StyledMainHeader = styled(Paper)(({ theme }) => ({
|
|||||||
|
|
||||||
const StyledTitleHeader = styled('div')(({ theme }) => ({
|
const StyledTitleHeader = styled('div')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'flex-start',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -4,6 +4,11 @@ export const useStyles = makeStyles()(() => ({
|
|||||||
row: {
|
row: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
'&:hover': {
|
||||||
|
'.show-row-hover': {
|
||||||
|
display: 'inherit',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
cell: {
|
cell: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
StarBorder as StarBorderIcon,
|
StarBorder as StarBorderIcon,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { TooltipResolver } from '../../../TooltipResolver/TooltipResolver';
|
import { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver';
|
||||||
|
|
||||||
interface IFavoriteIconCellProps {
|
interface IFavoriteIconCellProps {
|
||||||
value?: boolean;
|
value?: boolean;
|
||||||
@ -13,17 +13,15 @@ interface IFavoriteIconCellProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const InactiveIconButton = styled(IconButton)(({ theme }) => ({
|
const InactiveIconButton = styled(IconButton)(({ theme }) => ({
|
||||||
color: 'transparent',
|
color: theme.palette.primary.main,
|
||||||
'&:hover, &:focus': {
|
display: 'none',
|
||||||
color: theme.palette.primary.main,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const FavoriteIconCell: VFC<IFavoriteIconCellProps> = ({
|
export const FavoriteIconCell: VFC<IFavoriteIconCellProps> = ({
|
||||||
value = false,
|
value = false,
|
||||||
onClick,
|
onClick,
|
||||||
}) => (
|
}) => (
|
||||||
<Box sx={{ pl: 1.25 }}>
|
<Box sx={{ pl: 1.25, display: 'inline-flex' }}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={value}
|
condition={value}
|
||||||
show={
|
show={
|
||||||
@ -41,6 +39,7 @@ export const FavoriteIconCell: VFC<IFavoriteIconCellProps> = ({
|
|||||||
elseShow={
|
elseShow={
|
||||||
<TooltipResolver title={'Add to favorites'}>
|
<TooltipResolver title={'Add to favorites'}>
|
||||||
<InactiveIconButton
|
<InactiveIconButton
|
||||||
|
className="show-row-hover"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ padding: 1.25 }}
|
sx={{ padding: 1.25 }}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Tab, Tabs, useMediaQuery } from '@mui/material';
|
import { Tab, Tabs, useMediaQuery } from '@mui/material';
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Archive, FileCopy, Label, WatchLater } from '@mui/icons-material';
|
import { Archive, FileCopy, Label, WatchLater } from '@mui/icons-material';
|
||||||
import {
|
import {
|
||||||
Link,
|
Link,
|
||||||
@ -123,7 +123,6 @@ export const FeatureView = () => {
|
|||||||
<FavoriteIconButton
|
<FavoriteIconButton
|
||||||
onClick={onFavorite}
|
onClick={onFavorite}
|
||||||
isFavorite={feature?.favorite}
|
isFavorite={feature?.favorite}
|
||||||
sx={{ pr: 0.25 }}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -48,7 +48,6 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
fontSize: theme.fontSizes.mainHeader,
|
fontSize: theme.fontSizes.mainHeader,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
marginBottom: '0.5rem',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
@ -7,7 +7,7 @@ import { styled, Tab, Tabs } from '@mui/material';
|
|||||||
import { Delete, Edit } from '@mui/icons-material';
|
import { Delete, Edit } from '@mui/icons-material';
|
||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import useQueryParams from 'hooks/useQueryParams';
|
import useQueryParams from 'hooks/useQueryParams';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import ProjectEnvironment from '../ProjectEnvironment/ProjectEnvironment';
|
import ProjectEnvironment from '../ProjectEnvironment/ProjectEnvironment';
|
||||||
import { ProjectFeaturesArchive } from './ProjectFeaturesArchive/ProjectFeaturesArchive';
|
import { ProjectFeaturesArchive } from './ProjectFeaturesArchive/ProjectFeaturesArchive';
|
||||||
import ProjectOverview from './ProjectOverview';
|
import ProjectOverview from './ProjectOverview';
|
||||||
@ -28,18 +28,18 @@ import { MainLayout } from 'component/layout/MainLayout/MainLayout';
|
|||||||
import { ProjectChangeRequests } from '../../changeRequest/ProjectChangeRequests/ProjectChangeRequests';
|
import { ProjectChangeRequests } from '../../changeRequest/ProjectChangeRequests/ProjectChangeRequests';
|
||||||
import { ProjectSettings } from './ProjectSettings/ProjectSettings';
|
import { ProjectSettings } from './ProjectSettings/ProjectSettings';
|
||||||
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
||||||
import { FavoriteIconButton } from '../../common/FavoriteIconButton/FavoriteIconButton';
|
import { FavoriteIconButton } from 'component/common/FavoriteIconButton/FavoriteIconButton';
|
||||||
import { useFavoriteProjectsApi } from '../../../hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi';
|
import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi';
|
||||||
|
|
||||||
const StyledDiv = styled('div')(() => ({
|
const StyledDiv = styled('div')(() => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Row = styled('div')(({ theme }) => ({
|
const StyledTopRow = styled('div')(() => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'center',
|
justifyContent: 'space-between',
|
||||||
paddingBottom: theme.spacing(0.25),
|
width: '100%',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Column = styled('div')(() => ({
|
const Column = styled('div')(() => ({
|
||||||
@ -47,11 +47,10 @@ const Column = styled('div')(() => ({
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledName = styled('div')(({ theme }) => ({
|
const StyledName = styled('div')(() => ({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
paddingTop: theme.spacing(1),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledTitle = styled('span')(({ theme }) => ({
|
const StyledTitle = styled('span')(({ theme }) => ({
|
||||||
@ -62,6 +61,10 @@ const StyledText = styled(StyledTitle)(({ theme }) => ({
|
|||||||
color: theme.palette.grey[800],
|
color: theme.palette.grey[800],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledFavoriteIconButton = styled(FavoriteIconButton)(({ theme }) => ({
|
||||||
|
marginLeft: theme.spacing(-1.5),
|
||||||
|
}));
|
||||||
|
|
||||||
const Project = () => {
|
const Project = () => {
|
||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
const params = useQueryParams();
|
const params = useQueryParams();
|
||||||
@ -158,21 +161,54 @@ const Project = () => {
|
|||||||
>
|
>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.innerContainer}>
|
<div className={styles.innerContainer}>
|
||||||
<Row>
|
<StyledTopRow>
|
||||||
<ConditionallyRender
|
<StyledDiv>
|
||||||
condition={Boolean(uiConfig?.flags?.favorites)}
|
<ConditionallyRender
|
||||||
show={() => (
|
condition={Boolean(uiConfig?.flags?.favorites)}
|
||||||
<FavoriteIconButton
|
show={() => (
|
||||||
onClick={onFavorite}
|
<StyledFavoriteIconButton
|
||||||
isFavorite={project?.favorite}
|
onClick={onFavorite}
|
||||||
sx={{ pl: 0, pr: 0.25 }}
|
isFavorite={project?.favorite}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<h2 className={styles.title}>
|
<h2 className={styles.title}>
|
||||||
<StyledName data-loading>{projectName}</StyledName>
|
<StyledName data-loading>
|
||||||
</h2>
|
{projectName}
|
||||||
</Row>
|
</StyledName>
|
||||||
|
</h2>
|
||||||
|
</StyledDiv>
|
||||||
|
<StyledDiv>
|
||||||
|
<PermissionIconButton
|
||||||
|
permission={UPDATE_PROJECT}
|
||||||
|
projectId={projectId}
|
||||||
|
sx={{
|
||||||
|
visibility: isOss() ? 'hidden' : 'visible',
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/projects/${projectId}/edit`)
|
||||||
|
}
|
||||||
|
tooltipProps={{ title: 'Edit project' }}
|
||||||
|
data-loading
|
||||||
|
>
|
||||||
|
<Edit />
|
||||||
|
</PermissionIconButton>
|
||||||
|
<PermissionIconButton
|
||||||
|
permission={DELETE_PROJECT}
|
||||||
|
projectId={projectId}
|
||||||
|
sx={{
|
||||||
|
visibility: isOss() ? 'hidden' : 'visible',
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setShowDelDialog(true);
|
||||||
|
}}
|
||||||
|
tooltipProps={{ title: 'Delete project' }}
|
||||||
|
data-loading
|
||||||
|
>
|
||||||
|
<Delete />
|
||||||
|
</PermissionIconButton>
|
||||||
|
</StyledDiv>
|
||||||
|
</StyledTopRow>
|
||||||
<Column>
|
<Column>
|
||||||
<h2 className={styles.title}>
|
<h2 className={styles.title}>
|
||||||
<div>
|
<div>
|
||||||
@ -198,40 +234,6 @@ const Project = () => {
|
|||||||
</StyledText>
|
</StyledText>
|
||||||
</StyledDiv>
|
</StyledDiv>
|
||||||
</div>
|
</div>
|
||||||
<StyledDiv>
|
|
||||||
<PermissionIconButton
|
|
||||||
permission={UPDATE_PROJECT}
|
|
||||||
projectId={projectId}
|
|
||||||
sx={{
|
|
||||||
visibility: isOss()
|
|
||||||
? 'hidden'
|
|
||||||
: 'visible',
|
|
||||||
}}
|
|
||||||
onClick={() =>
|
|
||||||
navigate(`/projects/${projectId}/edit`)
|
|
||||||
}
|
|
||||||
tooltipProps={{ title: 'Edit project' }}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Edit />
|
|
||||||
</PermissionIconButton>
|
|
||||||
<PermissionIconButton
|
|
||||||
permission={DELETE_PROJECT}
|
|
||||||
projectId={projectId}
|
|
||||||
sx={{
|
|
||||||
visibility: isOss()
|
|
||||||
? 'hidden'
|
|
||||||
: 'visible',
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
setShowDelDialog(true);
|
|
||||||
}}
|
|
||||||
tooltipProps={{ title: 'Delete project' }}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Delete />
|
|
||||||
</PermissionIconButton>
|
|
||||||
</StyledDiv>
|
|
||||||
</h2>
|
</h2>
|
||||||
</Column>
|
</Column>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,7 +56,7 @@ export const ProjectCard = ({
|
|||||||
const canDeleteProject =
|
const canDeleteProject =
|
||||||
hasAccess(DELETE_PROJECT, id) && id !== DEFAULT_PROJECT_ID;
|
hasAccess(DELETE_PROJECT, id) && id !== DEFAULT_PROJECT_ID;
|
||||||
|
|
||||||
const onFavorite = async (e: Event) => {
|
const onFavorite = async (e: React.SyntheticEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (isFavorite) {
|
if (isFavorite) {
|
||||||
await unfavorite(id);
|
await unfavorite(id);
|
||||||
|
Loading…
Reference in New Issue
Block a user