Skip to content

Commit

Permalink
refactor SelectableAppList into SelectableList (#4258)
Browse files Browse the repository at this point in the history
  • Loading branch information
d-g-town authored Feb 9, 2024
1 parent ac7b61b commit d995244
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 99 deletions.
17 changes: 13 additions & 4 deletions dashboard/src/components/porter/SelectableList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ type ListProps = {
isSelected?: boolean;
}>;
scroll?: boolean;
selectedIcon?: string;
};

const SelectableList: React.FC<ListProps> = ({ listItems, scroll = true }) => {
const SelectableList: React.FC<ListProps> = ({
listItems,
scroll = true,
selectedIcon,
}) => {
return (
<StyledSelectableList scroll={scroll}>
{listItems.map((li) => {
Expand All @@ -58,6 +63,7 @@ const SelectableList: React.FC<ListProps> = ({ listItems, scroll = true }) => {
selected={li.isSelected}
onSelect={li.onSelect}
onDeselect={li.onDeselect}
selectedIcon={selectedIcon}
/>
);
})}
Expand All @@ -69,23 +75,26 @@ export default SelectableList;

const StyledSelectableList = styled.div<{ scroll?: boolean }>`
display: flex;
row-gap: 10px;
row-gap: 15px;
flex-direction: column;
overflow-y: auto;
${(props) =>
props.scroll &&
css`
max-height: 400px;
overflow-y: scroll;
`}
transition: all 0.2s;
`;

const ResourceOption = styled.div<{ selected?: boolean; isHoverable: boolean }>`
background: ${(props) => props.theme.clickable.bg};
border: 1px solid
${(props) => (props.selected ? "#ffffff" : props.theme.border)};
width: 100%;
padding: 10px 15px;
padding: 15px;
border-radius: 5px;
animation: fadeIn 0.3s 0s;
transition: all 0.2s;
display: flex;
justify-content: space-between;
align-items: center;
Expand Down
133 changes: 38 additions & 95 deletions dashboard/src/main/home/app-dashboard/apps/SelectableAppList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useMemo } from "react";
import { PorterApp } from "@porter-dev/api-contracts";
import styled, { css } from "styled-components";

import Container from "components/porter/Container";
import Icon from "components/porter/Icon";
import SelectableList from "components/porter/SelectableList";
import Spacer from "components/porter/Spacer";
import Text from "components/porter/Text";
import { AppIcon, AppSource } from "main/home/app-dashboard/apps/AppMeta";
Expand All @@ -12,57 +11,6 @@ import healthy from "assets/status-healthy.png";

import { type AppRevisionWithSource } from "./types";

type SelectableAppRowProps = {
app: AppRevisionWithSource;
onSelect?: () => void;
onDeselect?: () => void;
selected?: boolean;
};

const SelectableAppRow: React.FC<SelectableAppRowProps> = ({
app,
selected,
onSelect,
onDeselect,
}) => {
const proto = useMemo(() => {
return PorterApp.fromJsonString(atob(app.app_revision.b64_app_proto), {
ignoreUnknownFields: true,
});
}, [app.app_revision.b64_app_proto]);

return (
<ResourceOption
selected={selected}
onClick={() => {
if (selected) {
onDeselect?.();
} else {
onSelect?.();
}
}}
isHoverable={onSelect != null || onDeselect != null}
>
<Container row>
<Spacer inline width="1px" />
<AppIcon
buildpacks={proto.build?.buildpacks ?? []}
size="larger"
/>
<Spacer inline width="12px" />
<Text size={14}>{proto.name}</Text>
<Spacer inline x={1} />
</Container>
<Spacer height="15px" />
<Container row>
<AppSource source={app.source} />
<Spacer inline x={1} />
</Container>
{selected && <Icon height="18px" src={healthy} />}
</ResourceOption>
);
};

type AppListProps = {
appListItems: Array<{
app: AppRevisionWithSource;
Expand All @@ -75,50 +23,45 @@ type AppListProps = {

const SelectableAppList: React.FC<AppListProps> = ({ appListItems }) => {
return (
<StyledSelectableAppList>
{appListItems.map((ali) => {
return (
<SelectableAppRow
key={ali.key}
app={ali.app}
selected={ali.isSelected}
onSelect={ali.onSelect}
onDeselect={ali.onDeselect}
/>
);
<SelectableList
selectedIcon={healthy}
listItems={appListItems.map((ali) => {
const proto = useMemo(() => {
return PorterApp.fromJsonString(
atob(ali.app.app_revision.b64_app_proto),
{
ignoreUnknownFields: true,
}
);
}, [ali.app.app_revision.b64_app_proto]);
return {
selectable: (
<>
<Container row>
<Spacer inline width="1px" />
<AppIcon
buildpacks={proto.build?.buildpacks ?? []}
size="larger"
/>
<Spacer inline width="12px" />
<Text size={14}>{proto.name}</Text>
<Spacer inline x={1} />
</Container>
<Spacer height="15px" />
<Container row>
<AppSource source={ali.app.source} />
<Spacer inline x={1} />
</Container>
</>
),
key: ali.key,
onSelect: ali.onSelect,
onDeselect: ali.onDeselect,
isSelected: ali.isSelected,
};
})}
</StyledSelectableAppList>
/>
);
};

export default SelectableAppList;

const StyledSelectableAppList = styled.div`
display: flex;
row-gap: 15px;
flex-direction: column;
max-height: 400px;
overflow-y: auto;
transition: all 0.2s;
`;

const ResourceOption = styled.div<{ selected?: boolean; isHoverable: boolean }>`
background: ${(props) => props.theme.clickable.bg};
border: 1px solid
${(props) => (props.selected ? "#ffffff" : props.theme.border)};
width: 100%;
padding: 15px;
margin-botton: 15px;
border-radius: 5px;
animation: fadeIn 0.3s 0s;
transition: all 0.2s;
${(props) => props.isHoverable && "cursor: pointer;"}
${(props) =>
props.isHoverable &&
!props.selected &&
css`
&:hover {
border: 1px solid #7a7b80;
}
`}
`;

0 comments on commit d995244

Please sign in to comment.