diff --git a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCard.tsx b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCard.tsx index 4705eec80c..0f7034e40e 100644 --- a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCard.tsx +++ b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCard.tsx @@ -2,12 +2,12 @@ import { styled, Tooltip } from '@mui/material'; import type { IGroup } from 'interfaces/group'; import { Link, useNavigate } from 'react-router-dom'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { GroupCardAvatars } from './GroupCardAvatars/GroupCardAvatars'; import { Badge } from 'component/common/Badge/Badge'; import { GroupCardActions } from './GroupCardActions/GroupCardActions'; import TopicOutlinedIcon from '@mui/icons-material/TopicOutlined'; import { RoleBadge } from 'component/common/RoleBadge/RoleBadge'; import { useScimSettings } from 'hooks/api/getters/useScimSettings/useScimSettings'; +import { GroupCardAvatars } from './GroupCardAvatars/NewGroupCardAvatars'; const StyledLink = styled(Link)(({ theme }) => ({ textDecoration: 'none', diff --git a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx deleted file mode 100644 index 64313dc7c1..0000000000 --- a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import type { IGroupUser } from 'interfaces/group'; -import type React from 'react'; -import { useMemo, useState } from 'react'; -import { GroupPopover } from './GroupPopover/GroupPopover'; -import { UserAvatar } from 'component/common/UserAvatar/UserAvatar'; - -const StyledAvatars = styled('div')(({ theme }) => ({ - display: 'inline-flex', - alignItems: 'center', - flexWrap: 'wrap', - marginLeft: theme.spacing(1), -})); - -const StyledAvatar = styled(UserAvatar)(({ theme }) => ({ - outline: `${theme.spacing(0.25)} solid ${theme.palette.background.paper}`, - marginLeft: theme.spacing(-1), - '&:hover': { - outlineColor: theme.palette.primary.main, - }, -})); - -interface IGroupCardAvatarsProps { - users: IGroupUser[]; -} - -/** - * @deprecated Remove after with `projectsListNewCards` flag - */ -export const GroupCardAvatars = ({ users }: IGroupCardAvatarsProps) => { - const shownUsers = useMemo( - () => - users - .sort((a, b) => b?.joinedAt!.getTime() - a?.joinedAt!.getTime()) - .slice(0, 9), - [users], - ); - - const [anchorEl, setAnchorEl] = useState(null); - const [popupUser, setPopupUser] = useState(); - - const onPopoverOpen = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - - const onPopoverClose = () => { - setAnchorEl(null); - }; - - const avatarOpen = Boolean(anchorEl); - - return ( - - {shownUsers.map((user) => ( - { - onPopoverOpen(event); - setPopupUser(user); - }} - onMouseLeave={onPopoverClose} - /> - ))} - 9} - show={ - - +{users.length - shownUsers.length} - - } - /> - - - ); -}; diff --git a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/NewGroupCardAvatars.tsx b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/NewGroupCardAvatars.tsx index 17f9c503a9..adb8abfb4b 100644 --- a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/NewGroupCardAvatars.tsx +++ b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/NewGroupCardAvatars.tsx @@ -27,12 +27,6 @@ const StyledAvatar = styled(UserAvatar)(({ theme }) => ({ }, })); -const StyledUsername = styled('div')(({ theme }) => ({ - fontSize: theme.typography.body2.fontSize, - color: theme.palette.text.primary, - marginLeft: theme.spacing(1), -})); - const StyledHeader = styled('h3')(({ theme }) => ({ margin: theme.spacing(0, 0, 1), fontSize: theme.typography.caption.fontSize, diff --git a/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts b/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts deleted file mode 100644 index 5d3e73a6a3..0000000000 --- a/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { styled } from '@mui/material'; -import { Card, Box } from '@mui/material'; -import Delete from '@mui/icons-material/Delete'; -import Edit from '@mui/icons-material/Edit'; -import { ReactComponent as ProjectIcon } from 'assets/icons/projectIcon.svg'; -import { flexRow } from 'themes/themeStyles'; - -export const StyledProjectCard = styled(Card)(({ theme }) => ({ - padding: theme.spacing(1, 2, 2, 2), - width: '220px', - height: '204px', - display: 'flex', - flexDirection: 'column', - justifyContent: 'space-between', - margin: theme.spacing(1), - boxShadow: 'none', - border: `1px solid ${theme.palette.divider}`, - [theme.breakpoints.down('sm')]: { - justifyContent: 'center', - }, - '&:hover': { - transition: 'background-color 0.2s ease-in-out', - backgroundColor: theme.palette.neutral.light, - }, -})); - -export const StyledDivHeader = styled('div')(() => ({ - ...flexRow, - width: '100%', -})); - -export const StyledH2Title = styled('h2')(({ theme }) => ({ - fontWeight: 'normal', - fontSize: theme.fontSizes.bodySize, - lineClamp: 2, - display: '-webkit-box', - boxOrient: 'vertical', - textOverflow: 'ellipsis', - overflow: 'hidden', - alignItems: 'flex-start', -})); - -export const StyledBox = styled(Box)(() => ({ - ...flexRow, - marginRight: 'auto', -})); - -export const StyledEditIcon = styled(Edit)(({ theme }) => ({ - color: theme.palette.neutral.main, - marginRight: theme.spacing(1), -})); - -export const StyledDeleteIcon = styled(Delete)(({ theme }) => ({ - color: theme.palette.neutral.main, - marginRight: theme.spacing(1), -})); - -export const StyledProjectIcon = styled(ProjectIcon)(({ theme }) => ({ - margin: theme.spacing(2, 'auto'), - width: '80px', - display: 'block', - fill: 'red', -})); - -export const StyledDivInfo = styled('div')(({ theme }) => ({ - display: 'flex', - justifyContent: 'space-between', - fontSize: theme.fontSizes.smallerBody, -})); - -export const StyledDivInfoContainer = styled('div')(() => ({ - textAlign: 'center', -})); - -export const StyledParagraphInfo = styled('p')(({ theme }) => ({ - color: theme.palette.primary.dark, - fontWeight: 'bold', -})); - -export const StyledIconBox = styled(Box)(() => ({ - display: 'flex', - justifyContent: 'center', -})); diff --git a/frontend/src/component/project/ProjectCard/ProjectCard.tsx b/frontend/src/component/project/ProjectCard/ProjectCard.tsx deleted file mode 100644 index 6ba1c57f65..0000000000 --- a/frontend/src/component/project/ProjectCard/ProjectCard.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { Menu, MenuItem } from '@mui/material'; -import MoreVertIcon from '@mui/icons-material/MoreVert'; -import type React from 'react'; -import { type SyntheticEvent, useContext, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { getProjectEditPath } from 'utils/routePathHelpers'; -import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; -import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions'; -import AccessContext from 'contexts/AccessContext'; -import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId'; -import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import useProjects from 'hooks/api/getters/useProjects/useProjects'; -import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { FavoriteIconButton } from 'component/common/FavoriteIconButton/FavoriteIconButton'; -import { DeleteProjectDialogue } from '../Project/DeleteProject/DeleteProjectDialogue'; -import { - StyledProjectCard, - StyledDivHeader, - StyledBox, - StyledH2Title, - StyledEditIcon, - StyledProjectIcon, - StyledDivInfo, - StyledDivInfoContainer, - StyledParagraphInfo, - StyledIconBox, -} from './ProjectCard.styles'; -import useToast from 'hooks/useToast'; -import { HiddenProjectIconWithTooltip } from '../Project/HiddenProjectIconWithTooltip/HiddenProjectIconWithTooltip'; - -interface IProjectCardProps { - name: string; - featureCount: number; - health: number; - memberCount: number; - id: string; - onHover: () => void; - isFavorite?: boolean; - mode: string; -} - -export const ProjectCard = ({ - name, - featureCount, - health, - memberCount, - onHover, - id, - mode, - isFavorite = false, -}: IProjectCardProps) => { - const { hasAccess } = useContext(AccessContext); - const { setToastApiError } = useToast(); - const { isOss } = useUiConfig(); - const [anchorEl, setAnchorEl] = useState(null); - const [showDelDialog, setShowDelDialog] = useState(false); - const navigate = useNavigate(); - const { favorite, unfavorite } = useFavoriteProjectsApi(); - const { refetch } = useProjects(); - - const handleClick = (event: React.SyntheticEvent) => { - event.preventDefault(); - setAnchorEl(event.currentTarget); - }; - - const onFavorite = async (e: React.SyntheticEvent) => { - e.preventDefault(); - try { - if (isFavorite) { - await unfavorite(id); - } else { - await favorite(id); - } - refetch(); - } catch (error) { - setToastApiError('Something went wrong, could not update favorite'); - } - }; - - return ( - - - - - {name} - - - - - { - event.preventDefault(); - }} - onClose={(event: SyntheticEvent) => { - event.preventDefault(); - setAnchorEl(null); - }} - > - { - e.preventDefault(); - navigate(getProjectEditPath(id)); - }} - > - - Edit project - - - - - } - elseShow={} - /> - - - - - {featureCount} - -

toggles

-
- - - {health}% - -

health

-
- - - - {memberCount} - -

members

- - } - /> -
- { - e.preventDefault(); - setAnchorEl(null); - setShowDelDialog(false); - }} - /> -
- ); -}; diff --git a/frontend/src/component/project/ProjectList/ProjectGroup.tsx b/frontend/src/component/project/ProjectList/ProjectGroup.tsx index 72a1945bc8..2c95b152e3 100644 --- a/frontend/src/component/project/ProjectList/ProjectGroup.tsx +++ b/frontend/src/component/project/ProjectList/ProjectGroup.tsx @@ -1,23 +1,11 @@ import { Link } from 'react-router-dom'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { ProjectCard as LegacyProjectCard } from '../ProjectCard/ProjectCard'; -import { ProjectCard as NewProjectCard } from '../NewProjectCard/NewProjectCard'; +import { ProjectCard } from '../NewProjectCard/NewProjectCard'; + import type { IProjectCard } from 'interfaces/project'; import loadingData from './loadingData'; import { TablePlaceholder } from 'component/common/Table'; import { styled, Typography } from '@mui/material'; -import { useUiFlag } from 'hooks/useUiFlag'; - -/** - * @deprecated Remove after with `projectsListNewCards` flag - */ -const StyledDivContainer = styled('div')(({ theme }) => ({ - display: 'flex', - flexWrap: 'wrap', - [theme.breakpoints.down('sm')]: { - justifyContent: 'center', - }, -})); const StyledGridContainer = styled('div')(({ theme }) => ({ display: 'grid', @@ -41,12 +29,6 @@ export const ProjectGroup: React.FC<{ loading: boolean; searchValue: string; }> = ({ sectionTitle, projects, loading, searchValue }) => { - const useNewProjectCards = useUiFlag('projectsListNewCards'); - - const [StyledItemsContainer, ProjectCard] = useNewProjectCards - ? [StyledGridContainer, NewProjectCard] - : [StyledDivContainer, LegacyProjectCard]; - return (
} elseShow={ - + @@ -126,7 +108,7 @@ export const ProjectGroup: React.FC<{ )} /> - + } />
diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index 04767386f6..f6ecac82c3 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -82,7 +82,6 @@ export type UiFlags = { featureLifecycle?: boolean; scimApi?: boolean; createProjectWithEnvironmentConfig?: boolean; - projectsListNewCards?: boolean; newCreateProjectUI?: boolean; manyStrategiesPagination?: boolean; enableLegacyVariants?: boolean; diff --git a/src/lib/__snapshots__/create-config.test.ts.snap b/src/lib/__snapshots__/create-config.test.ts.snap index e28df3c6d5..1893ab606e 100644 --- a/src/lib/__snapshots__/create-config.test.ts.snap +++ b/src/lib/__snapshots__/create-config.test.ts.snap @@ -141,7 +141,6 @@ exports[`should create default config 1`] = ` "parseProjectFromSession": false, "personalAccessTokensKillSwitch": false, "projectOverviewRefactorFeedback": false, - "projectsListNewCards": false, "queryMissingTokens": false, "responseTimeMetricsFix": false, "responseTimeWithAppNameKillSwitch": false, diff --git a/src/lib/features/project/project-controller.ts b/src/lib/features/project/project-controller.ts index 0b7f12f4ba..8229c8fd30 100644 --- a/src/lib/features/project/project-controller.ts +++ b/src/lib/features/project/project-controller.ts @@ -223,24 +223,15 @@ export default class ProjectController extends Controller { user.id, ); - if (this.flagResolver.isEnabled('projectsListNewCards')) { - const projectsWithOwners = - await this.projectService.addOwnersToProjects(projects); + const projectsWithOwners = + await this.projectService.addOwnersToProjects(projects); - this.openApiService.respondWithValidation( - 200, - res, - projectsSchema.$id, - { version: 1, projects: serializeDates(projectsWithOwners) }, - ); - } else { - this.openApiService.respondWithValidation( - 200, - res, - projectsSchema.$id, - { version: 1, projects: serializeDates(projects) }, - ); - } + this.openApiService.respondWithValidation( + 200, + res, + projectsSchema.$id, + { version: 1, projects: serializeDates(projectsWithOwners) }, + ); } async getDeprecatedProjectOverview( diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index 9a97a62934..c71b8a3849 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -55,7 +55,6 @@ export type IFlagKey = | 'projectOverviewRefactorFeedback' | 'featureLifecycle' | 'featureLifecycleMetrics' - | 'projectsListNewCards' | 'parseProjectFromSession' | 'createProjectWithEnvironmentConfig' | 'manyStrategiesPagination' @@ -275,10 +274,6 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_CREATE_PROJECT_WITH_ENVIRONMENT_CONFIG, false, ), - projectsListNewCards: parseEnvVarBoolean( - process.env.UNLEASH_EXPERIMENTAL_PROJECTS_LIST_NEW_CARDS, - false, - ), newCreateProjectUI: parseEnvVarBoolean( process.env.UNLEASH_EXPERIMENTAL_NEW_CREATE_PROJECT_UI, false, diff --git a/src/server-dev.ts b/src/server-dev.ts index 18656f02fd..b35f5f11de 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -49,7 +49,6 @@ process.nextTick(async () => { disableShowContextFieldSelectionValues: false, projectOverviewRefactorFeedback: true, featureLifecycle: true, - projectsListNewCards: true, parseProjectFromSession: true, createProjectWithEnvironmentConfig: true, manyStrategiesPagination: true,