Bläddra i källkod

refactor SelectableAppList into SelectableList (#4258)

d-g-town 2 år sedan
förälder
incheckning
d995244a66

+ 13 - 4
dashboard/src/components/porter/SelectableList.tsx

@@ -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) => {
@@ -58,6 +63,7 @@ const SelectableList: React.FC<ListProps> = ({ listItems, scroll = true }) => {
             selected={li.isSelected}
             onSelect={li.onSelect}
             onDeselect={li.onDeselect}
+            selectedIcon={selectedIcon}
           />
         );
       })}
@@ -69,14 +75,15 @@ 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 }>`
@@ -84,8 +91,10 @@ const ResourceOption = styled.div<{ selected?: boolean; isHoverable: boolean }>`
   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;

+ 38 - 95
dashboard/src/main/home/app-dashboard/apps/SelectableAppList.tsx

@@ -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";
@@ -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;
@@ -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;
-      }
-    `}
-`;