Skip to content

Commit

Permalink
Init image automation (weaveworks#3258)
Browse files Browse the repository at this point in the history
* init image automation

* chore: Add sample manifests for image automation objects

* create image automation kind

* set last updates

* add image automation updates details page

* add imagePolicy

* make ui-prettify-format

* init onboarding Image update widget

* useCheckCRDInstalled

* run prettier

* run make proto

* update snap

* make proto

* update snap -_-

* revert docs changes

* address PR comments

* Update ui/components/ImageAutomation/updates/ImageAutomationUpdatesDetails.tsx

Co-authored-by: Jordan Pellizzari <[email protected]>

Co-authored-by: Yiannis <[email protected]>
Co-authored-by: Jordan Pellizzari <[email protected]>
  • Loading branch information
3 people authored Jan 19, 2023
1 parent 46ce7c8 commit c9da1a0
Show file tree
Hide file tree
Showing 22 changed files with 791 additions and 81 deletions.
23 changes: 13 additions & 10 deletions api/core/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ message Interval {
}

enum Kind {
GitRepository = 0;
Bucket = 1;
HelmRepository = 2;
HelmChart = 3;
Kustomization = 4;
HelmRelease = 5;
Cluster = 6;
OCIRepository = 7;
Provider = 8;
Alert = 9;
GitRepository = 0;
Bucket = 1;
HelmRepository = 2;
HelmChart = 3;
Kustomization = 4;
HelmRelease = 5;
Cluster = 6;
OCIRepository = 7;
Provider = 8;
Alert = 9;
ImageRepository = 10;
ImageUpdateAutomation = 11;
ImagePolicy = 12;
};

enum HelmRepositoryType {
Expand Down
89 changes: 51 additions & 38 deletions pkg/api/core/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { ThemeProvider } from "styled-components";
import ErrorBoundary from "./components/ErrorBoundary";
import ImageAutomationRepoDetails from "./components/ImageAutomation/repositories/ImageAutomationRepoDetails";
import ImageAutomationUpdatesDetails from "./components/ImageAutomation/updates/ImageAutomationUpdatesDetails";
import Layout from "./components/Layout";
import PendoContainer from "./components/PendoContainer";
import AppContextProvider from "./contexts/AppContext";
Expand All @@ -30,6 +32,7 @@ import GitRepositoryDetail from "./pages/v2/GitRepositoryDetail";
import HelmChartDetail from "./pages/v2/HelmChartDetail";
import HelmReleasePage from "./pages/v2/HelmReleasePage";
import HelmRepositoryDetail from "./pages/v2/HelmRepositoryDetail";
import ImageAutomationPage from "./pages/v2/ImageAutomationPage";
import KustomizationPage from "./pages/v2/KustomizationPage";
import Notifications from "./pages/v2/Notifications";
import OCIRepositoryPage from "./pages/v2/OCIRepositoryPage";
Expand All @@ -45,7 +48,6 @@ function withSearchParams(Cmp) {
return <Cmp {...rest} {...params} />;
};
}

const App = () => (
<Layout>
<PendoContainer />
Expand All @@ -57,6 +59,18 @@ const App = () => (
component={withSearchParams(KustomizationPage)}
/>
<Route path={V2Routes.Sources} component={Sources} />
<Route
path={V2Routes.ImageAutomation}
component={ImageAutomationPage}
/>
<Route
path={V2Routes.ImageAutomationUpdatesDetails}
component={withSearchParams(ImageAutomationUpdatesDetails)}
/>
<Route
path={V2Routes.ImageAutomationRepositoriesDetails}
component={withSearchParams(ImageAutomationRepoDetails)}
/>
<Route path={V2Routes.FluxRuntime} component={FluxRuntime} />
<Route
path={V2Routes.GitRepo}
Expand Down Expand Up @@ -90,7 +104,9 @@ const App = () => (
path={V2Routes.Provider}
component={withSearchParams(ProviderPage)}
/>

<Redirect exact from="/" to={V2Routes.Automations} />

<Route exact path="*" component={Error} />
</Switch>
</ErrorBoundary>
Expand Down
1 change: 0 additions & 1 deletion ui/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import Link from "./Link";
export const Breadcrumbs = () => {
const { currentPage } = useNavigation();
const { search } = useLocation();

const parentValue = getParentNavValue(currentPage) as V2Routes;
const label = getPageLabel(parentValue);
const parsed = qs.parse(search);
Expand Down
46 changes: 46 additions & 0 deletions ui/components/ImageAutomation/ImageAutomation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from "react";
import { useRouteMatch } from "react-router-dom";
import ImageRepositoriesTable from "../../components/ImageAutomation/repositories/ImageRepositoriesTable";
import ImageAutomationUpdatesTable from "../../components/ImageAutomation/updates/ImageAutomationUpdatesTable";
import { routeTab } from "../../components/KustomizationDetail";
import SubRouterTabs, { RouterTab } from "../../components/SubRouterTabs";
import Flex from "../Flex";

const ImageAutomation = () => {
const { path } = useRouteMatch();

const tabs: Array<routeTab> = [
{
name: "Image Update Automations",
path: `${path}/updates`,
component: () => {
return <ImageAutomationUpdatesTable />;
},
visible: true,
},
{
name: "Image Repositories",
path: `${path}/repositories`,
component: () => {
return <ImageRepositoriesTable />;
},
visible: true,
},
];
return (
<Flex wide tall column>
<SubRouterTabs rootPath={tabs[0].path} clearQuery>
{tabs.map(
(subRoute, index) =>
subRoute.visible && (
<RouterTab name={subRoute.name} path={subRoute.path} key={index}>
{subRoute.component()}
</RouterTab>
)
)}
</SubRouterTabs>
</Flex>
);
};

export default ImageAutomation;
79 changes: 79 additions & 0 deletions ui/components/ImageAutomation/ImageAutomationDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from "react";
import { Kind } from "../../lib/api/core/types.pb";
import EventsTable from "../EventsTable";
import Flex from "../Flex";
import InfoList, { InfoField } from "../InfoList";
import PageStatus from "../PageStatus";
import Spacer from "../Spacer";
import SubRouterTabs, { RouterTab } from "../SubRouterTabs";
import Text from "../Text";
import YamlView from "../YamlView";

interface Props {
data: any;
kind: Kind;
rootPath: string;
infoFields: InfoField[];
children?: any;
}

const ImageAutomationDetails = ({
data,
kind,
rootPath,
infoFields,
children,
}: Props) => {
const { name, namespace, clusterName, suspended, conditions } = data;
return (
<Flex wide tall column>
<Text size="large" semiBold titleHeight>
{name}
</Text>
<Spacer margin="xs" />
<PageStatus conditions={conditions} suspended={suspended} />
<Spacer margin="xs" />
{/* ImageUpdateAutomation sync is not supported yet and it'll be added in future PR */}
{/* <SyncActions
name={name}
namespace={namespace}
clusterName={clusterName}
kind={kind}
/>
<Spacer margin="xs" /> */}

<SubRouterTabs rootPath={`${rootPath}/details`}>
<RouterTab name="Details" path={`${rootPath}/details`}>
<>
<InfoList items={infoFields} />
<Spacer margin="xs" />
{children}
</>
</RouterTab>
<RouterTab name="Events" path={`${rootPath}/events`}>
<EventsTable
namespace={namespace}
involvedObject={{
kind: kind,
name: name,
namespace: namespace,
clusterName: clusterName,
}}
/>
</RouterTab>
<RouterTab name="yaml" path={`${rootPath}/yaml`}>
<YamlView
yaml={data.yaml}
object={{
kind: kind,
name: name,
namespace: namespace,
}}
/>
</RouterTab>
</SubRouterTabs>
</Flex>
);
};

export default ImageAutomationDetails;
63 changes: 63 additions & 0 deletions ui/components/ImageAutomation/SyncActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from "react";
import { useSyncFluxObject } from "../../hooks/automations";
import { useToggleSuspend } from "../../hooks/flux";
import { Kind } from "../../lib/api/core/types.pb";
import Button from "../Button";
import Flex from "../Flex";
import Spacer from "../Spacer";
import SyncButton from "../SyncButton";

interface Props {
name?: string;
namespace?: string;
clusterName?: string;
kind?: Kind;
suspended?: boolean;
}
const SyncActions = ({
name,
namespace,
clusterName,
kind,
suspended,
}: Props) => {
const suspend = useToggleSuspend(
{
objects: [
{
name,
namespace,
clusterName,
kind,
},
],
suspend: !suspended,
},
"sources"
);

const sync = useSyncFluxObject([
{
name,
namespace,
clusterName,
kind,
},
]);
return (
<Flex wide start>
<SyncButton
onClick={() => sync.mutateAsync({ withSource: false })}
loading={sync.isLoading}
disabled={suspended}
hideDropdown={true}
/>
<Spacer padding="xs" />
<Button onClick={() => suspend.mutateAsync()} loading={suspend.isLoading}>
{suspended ? "Resume" : "Suspend"}
</Button>
</Flex>
);
};

export default SyncActions;
Loading

0 comments on commit c9da1a0

Please sign in to comment.