|
|
@@ -2,6 +2,9 @@ import React, { useEffect, useState, useContext } from "react";
|
|
|
import styled from "styled-components";
|
|
|
|
|
|
import web from "assets/web.png";
|
|
|
+import github from "assets/github.png";
|
|
|
+import time from "assets/time.png";
|
|
|
+import healthy from "assets/status-healthy.png";
|
|
|
|
|
|
import { Context } from "shared/Context";
|
|
|
import api from "shared/api";
|
|
|
@@ -10,14 +13,35 @@ import DashboardHeader from "../cluster-dashboard/DashboardHeader";
|
|
|
import Container from "components/porter/Container";
|
|
|
import Button from "components/porter/Button";
|
|
|
import Spacer from "components/porter/Spacer";
|
|
|
+import Text from "components/porter/Text";
|
|
|
+import SearchBar from "components/porter/SearchBar";
|
|
|
|
|
|
type Props = {
|
|
|
};
|
|
|
|
|
|
+const icons = [
|
|
|
+ "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/ruby/ruby-plain.svg",
|
|
|
+ "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nodejs/nodejs-plain.svg",
|
|
|
+ "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-plain.svg",
|
|
|
+ "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/go/go-original-wordmark.svg",
|
|
|
+ web,
|
|
|
+];
|
|
|
+
|
|
|
+const namespaceBlacklist = [
|
|
|
+ "cert-manager",
|
|
|
+ "default",
|
|
|
+ "ingress-nginx",
|
|
|
+ "kube-node-lease",
|
|
|
+ "kube-public",
|
|
|
+ "kube-system",
|
|
|
+ "monitoring",
|
|
|
+];
|
|
|
+
|
|
|
const AppDashboard: React.FC<Props> = ({
|
|
|
}) => {
|
|
|
const { currentProject, currentCluster } = useContext(Context);
|
|
|
const [apps, setApps] = useState([]);
|
|
|
+ const [searchValue, setSearchValue] = useState("");
|
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
|
|
const getApps = async () => {
|
|
|
@@ -50,36 +74,74 @@ const AppDashboard: React.FC<Props> = ({
|
|
|
disableLineBreak
|
|
|
/>
|
|
|
<Container row spaced>
|
|
|
- <Button onClick={() => console.log("cool")} height="30px">
|
|
|
+ <SearchBar
|
|
|
+ value={searchValue}
|
|
|
+ setValue={setSearchValue}
|
|
|
+ placeholder="Search applications . . ."
|
|
|
+ width="100%"
|
|
|
+ />
|
|
|
+ <Spacer inline x={2} />
|
|
|
+ <Button onClick={() => console.log("cool")} height="30px" width="150px">
|
|
|
<I className="material-icons">add</I> Add application
|
|
|
</Button>
|
|
|
- <div>x/o</div>
|
|
|
</Container>
|
|
|
<Spacer y={1} />
|
|
|
<GridList>
|
|
|
- {apps.map((app: any) => {
|
|
|
- return (
|
|
|
- <Block></Block>
|
|
|
- );
|
|
|
+ {apps.map((app: any, i: number) => {
|
|
|
+ if (!namespaceBlacklist.includes(app.name)) {
|
|
|
+ return (
|
|
|
+ <Block>
|
|
|
+ <Text size={14}>
|
|
|
+ <Icon src={icons[i % icons.length]} />
|
|
|
+ {app.name}
|
|
|
+ </Text>
|
|
|
+ <StatusIcon src={healthy} />
|
|
|
+ <Text size={13} color="#ffffff44">
|
|
|
+ <SmallIcon opacity="0.6" src={github} />
|
|
|
+ porter-dev/porter
|
|
|
+ </Text>
|
|
|
+ <Text size={13} color="#ffffff44">
|
|
|
+ <SmallIcon opacity="0.4" src={time} />
|
|
|
+ Updated 6:35 PM on 4/23/2023
|
|
|
+ </Text>
|
|
|
+ </Block>
|
|
|
+ );
|
|
|
+ }
|
|
|
})}
|
|
|
</GridList>
|
|
|
+ <Spacer y={5} />
|
|
|
</StyledAppDashboard>
|
|
|
);
|
|
|
};
|
|
|
|
|
|
export default AppDashboard;
|
|
|
|
|
|
+const StatusIcon = styled.img`
|
|
|
+ position: absolute;
|
|
|
+ top: 20px;
|
|
|
+ right: 20px;
|
|
|
+ height: 18px;
|
|
|
+`;
|
|
|
+
|
|
|
+const Icon = styled.img`
|
|
|
+ height: 18px;
|
|
|
+ margin-right: 15px;
|
|
|
+`;
|
|
|
+
|
|
|
+const SmallIcon = styled.img<{ opacity?: string }>`
|
|
|
+ margin-left: 2px;
|
|
|
+ height: 14px;
|
|
|
+ opacity: ${props => props.opacity || 1};
|
|
|
+ margin-right: 10px;
|
|
|
+`;
|
|
|
+
|
|
|
const Block = styled.div`
|
|
|
- align-items: center;
|
|
|
- user-select: none;
|
|
|
- display: flex;
|
|
|
- font-size: 13px;
|
|
|
- padding: 3px 0px 5px;
|
|
|
+ height: 150px;
|
|
|
flex-direction: column;
|
|
|
- align-item: center;
|
|
|
+ display: flex;
|
|
|
justify-content: space-between;
|
|
|
- height: 170px;
|
|
|
cursor: pointer;
|
|
|
+ padding: 20px;
|
|
|
color: ${props => props.theme.text.primary};
|
|
|
position: relative;
|
|
|
border-radius: 5px;
|
|
|
@@ -104,7 +166,7 @@ const GridList = styled.div`
|
|
|
display: grid;
|
|
|
grid-column-gap: 25px;
|
|
|
grid-row-gap: 25px;
|
|
|
- grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
|
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
|
`;
|
|
|
|
|
|
const I = styled.i`
|