Skip to content

Fix/chart-link-cluster-mode #474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 13 additions & 65 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,39 @@
# Helm dashboard V2
# Helm dashboard React

Welcome to our new project, upgrading helm dashbord, we call it, Helm Dashboard version... 2! 🤩

Helm dashboard V2 is an open source effort to modernize the helm-dashboard.
Our goals are to create a version which is more:

1. Maintable
Welcome to the frontend of the helm dashboard.
We care most about keeping the project:
1. Maintainable
2. Extendable
3. Contributor friendly

## What is helm?

First thing first, if you are new here please check out these resources to see what helm is all about
[Video](https://www.youtube.com/watch?v=fy8SHvNZGeE)
[Article](https://kruschecompany.com/helm-kubernetes/)

# Legacy dashboard vs dashboard V2

The legacy dashboard found [here](https://github.com/komodorio/helm-dashboard/tree/main/pkg/dashboard/static) is a static webapp and was written vanilla css, jquery, javascript and html. If you inspect the code abit you may notice that its relitvly hard to extend and maintain such a project.

Our goal with dashboard V2 is to improve the ability to maintain and extend our dashboard app. To achive this we are using a more modern frontend stack.
# The FE Stack

- Vite, as our build tool.
- React will be used to make this project more inviting for developers to contribute too.
- React, as our UI library.
- TypeScript and ESLint will keep the project safe, please keep them clean.
- Tailwind will be used for styling.
- React-Query will be used to fetch data from the backend.
- Tailwind for styling.
- React-Query for fetching data from the backend.
- Storybook is utilized to develop a component library.

Please follow through the file structure to understand how things are structured and should be used.

# Contribution guide

## Running legacy dashboard

The legacy dashboard is great for refrence and checking that you have implemented the UI correctly.

1. Install [helm](https://helm.sh/docs/intro/install/) and [kubectl](https://kubernetes.io/docs/tasks/tools/).
2. `git clone https://github.com/komodorio/helm-dashboard.git`.
3. `go build -o bin/dashboard .`
4. `bin/dashboard`

The UI should now be running on http://localhost:8080/
If you're having issues with that please follow the main README in the main folder.
If you still having troubles please contact us on our [Slack community channel](https://join.slack.com/t/komodorkommunity/shared_invite/zt-1lz4cme86-2zIKTRtTFnzL_UNxaUS9yw)

## Setting up your development environment

1. First you should fork this repositroy.
1. First you should fork this repository.
2. Clone your new repository using `git clone <https_or_ssh_url>`.
3. Make sure to checkout branch `helm-dashboard-v2`.
- `git fetch`
- `git checkout helm-dashboard-v2`

## Running dashboard V2
## Running helm dashboard

1. Make sure you cloned the project correctly. This is explained in this [stage](https://github.com/komodorio/helm-dashboard/blob/helm-dashboard-v2/dashboard/README.md#setting-up-your-development-environment).
2. go to `helm-dashboard-v2/dashboard` in your local project.
3. inorder to install dependncies and start the development server
2. run the backend server. This is also explained in the above link.
2. go to `frontend` in your local project.
3. in order to install dependencies and start the development server
- `npm i`
- `npm run dev`
4. with the default integration the dashboard should run on http://localhost:5173/

## Setting up a local cluster with ease

1. Install [Docker](https://docs.docker.com/engine/install/ubuntu/)
2. Install [Minikube](https://minikube.sigs.k8s.io/docs/start/)
3. Start your cluster `minikube start`

You should now be able to follow the [Helm tutorial](https://helm.sh/docs/intro/quickstart/) and interact with Helm normally.

## Choosing a task

If you are completely new to the project its recommended to look for tasks labled: `good first issue`.
These tasks should be simple enough for a begginer or for someone looking to learn the code base.

You are also free to reachout to us on [Slack](https://join.slack.com/t/komodorkommunity/shared_invite/zt-1lz4cme86-2zIKTRtTFnzL_UNxaUS9yw), we can help you find a task that suits your perfectly.

## Opening a pull request

Inorder to open a pull request with your changes. \

1. make sure you are synced with `helm-dashboard-v2` and that all conflicts are resolved. \
2. commit your changes and push to your fork. \
3. then navigate to https://github.com/komodorio/helm-dashboard and open a pull request. Make sure you are merging from your branch to `helm-dashboard-v2`. \
4. you should now tag a main developer (@chad11111
for example) and get your pull request reviewed.

# Component library

Expand Down
15 changes: 12 additions & 3 deletions frontend/src/API/apiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ class ApiService {
}): Promise<ReleaseHealthStatus[] | null> => {
if (!release) return null;

const data = await this.fetchWithDefaults(
const data = await this.fetchWithDefaults<
Promise<ReleaseHealthStatus[] | null>
>(
`/api/helm/releases/${release.namespace}/${release.name}/resources?health=true`
);
return data;
Expand All @@ -129,14 +131,21 @@ class ApiService {

if (!params.namespace || !params.chart) return [];

const data = await this.fetchWithDefaults(
const data = await this.fetchWithDefaults<ReleaseRevision[]>(
`/api/helm/releases/${params.namespace}/${params.chart}/history`
);

return data;
};

getValues = async ({ queryKey }: any) => {
getValues = async ({
queryKey,
}: {
queryKey: [
string,
{ namespace: string; chart: { name: string }; version: number }
];
}) => {
const [, params] = queryKey;
const { namespace, chart, version } = params;

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/API/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface Scanner {

export interface ScanResult {
scannerType: string;
result: any;
result: string;
}

export interface ScannersList {
Expand Down
65 changes: 46 additions & 19 deletions frontend/src/API/releases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,56 @@ export function useGetInstalledReleases(
) {
return useQuery<Release[]>(
["installedReleases", context],
() =>
apiService.fetchWithDefaults<Release[]>("/api/helm/releases", {
headers: {
"X-Kubecontext": context,
},
}),
() => apiService.fetchWithDefaults<Release[]>("/api/helm/releases"),
options
);
}

export interface ReleaseManifest {
apiVersion: string;
kind: string;
metadata: {
name: string;
namespace: string;
labels: Record<string, string>;
};
spec: {
replicas: number;
selector: Record<string, string>;
template: {
metadata: {
labels: Record<string, string>;
};
spec: {
containers: {
name: string;
image: string;
ports: {
containerPort: number;
}[];
env: {
name: string;
value: string;
}[];
}[];
};
};
};
}

export function useGetReleaseManifest({
namespace,
chartName,
options,
}: {
namespace: string;
chartName: string;
options?: UseQueryOptions<any>;
options?: UseQueryOptions<ReleaseManifest[]>;
}) {
return useQuery<any>(
return useQuery<ReleaseManifest[]>(
["manifest", namespace, chartName],
() =>
apiService.fetchWithDefaults<any>(
apiService.fetchWithDefaults<ReleaseManifest[]>(
`/api/helm/releases/${namespace}/${chartName}/manifests`
),
options
Expand Down Expand Up @@ -219,12 +246,12 @@ export function useChartReleaseValues({
userDefinedValue?: string;
revision?: number;
version?: string;
options?: UseQueryOptions<any>;
options?: UseQueryOptions<unknown>;
}) {
return useQuery<any>(
return useQuery<unknown>(
["values", namespace, release, userDefinedValue, version],
() =>
apiService.fetchWithDefaults<any>(
apiService.fetchWithDefaults<unknown>(
`/api/helm/releases/${namespace}/${release}/values?${"userDefined=true"}${
revision ? `&revision=${revision}` : ""
}`,
Expand Down Expand Up @@ -253,7 +280,7 @@ export const useVersionData = ({
namespace: string;
releaseName: string;
isInstallRepoChart?: boolean;
options?: UseQueryOptions<any>;
options?: UseQueryOptions;
}) => {
return useQuery(
[
Expand Down Expand Up @@ -287,7 +314,7 @@ export const useVersionData = ({

return data;
},

// @ts-ignore
options
);
};
Expand All @@ -311,12 +338,12 @@ export interface StructuredResources {
export interface Metadata {
name: string;
namespace: string;
creationTimestamp: any;
labels: any;
creationTimestamp: Date;
labels: string[];
}

export interface Spec {
[key: string]: any;
[key: string]: string;
}

export interface Status {
Expand All @@ -326,8 +353,8 @@ export interface Status {
export interface Condition {
type: string;
status: string;
lastProbeTime: any;
lastTransitionTime: any;
lastProbeTime: Date;
lastTransitionTime: Date;
reason: string;
message: string;
}
4 changes: 2 additions & 2 deletions frontend/src/API/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ export function useChartRepoValues({
version: string;
chart: string;
}) {
return useQuery<any>(
return useQuery<string>(
["helm", "repositories", "values", chart, version],
() =>
apiService.fetchWithDefaults<any>(
apiService.fetchWithDefaults<string>(
`/api/helm/repositories/values?chart=${chart}&version=${version}`,
{
headers: { "Content-Type": "text/plain; charset=utf-8" },
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/API/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const useDiffData = ({
selectedRepo: string;
versionsError: string;
currentVerManifest: string;
selectedVerData: any;
selectedVerData: { [key: string]: string };
chart: string;
}) => {
return useQuery(
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function App() {
<Routes>
<Route path="docs/" element={<DocsPage />} />
<Route path="*" element={<PageLayout />}>
<Route path=":context/*" element={<SyncContext />}>
<Route path=":context?/*" element={<SyncContext />}>
<Route path="installed/?" element={<Installed />} />
<Route
path=":namespace/:chart/installed/revision/:revision"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { useGetLatestVersion } from "../../API/releases";
import { isNewerVersion } from "../../utils";
import { LatestChartVersion } from "../../API/interfaces";
import useNavigateWithSearchParams from "../../hooks/useNavigateWithSearchParams";
import { useParams } from "react-router-dom";

type InstalledPackageCardProps = {
release: Release;
Expand All @@ -26,15 +25,14 @@ export default function InstalledPackageCard({
}: InstalledPackageCardProps) {
const navigate = useNavigateWithSearchParams();

const { context: selectedCluster } = useParams();
const [isMouseOver, setIsMouseOver] = useState(false);

const { data: latestVersionResult } = useGetLatestVersion(release.chartName, {
queryKey: ["chartName", release.chartName],
cacheTime: 0,
});

const { data: statusData } = useQuery<any>({
const { data: statusData } = useQuery<unknown>({
queryKey: ["resourceStatus", release],
queryFn: () => apiService.getResourceStatus({ release }),
});
Expand All @@ -61,10 +59,9 @@ export default function InstalledPackageCard({

const handleOnClick = () => {
const { name, namespace } = release;
navigate(
`/${selectedCluster}/${namespace}/${name}/installed/revision/${release.revision}`,
{ state: release }
);
navigate(`/${namespace}/${name}/installed/revision/${release.revision}`, {
state: release,
});
};

const statusColor = getStatusColor(release.status as DeploymentStatus);
Expand Down
15 changes: 12 additions & 3 deletions frontend/src/components/LinkWithSearchParams.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NavLink, useLocation } from "react-router-dom";
import { NavLink, useLocation, useParams } from "react-router-dom";
import { useAppContext } from "../context/AppContext";

const LinkWithSearchParams = ({
to,
Expand All @@ -11,14 +12,22 @@ const LinkWithSearchParams = ({
children: React.ReactNode;
}) => {
const { search } = useLocation();
const params = new URLSearchParams(search);
const { context } = useParams();
const {clusterMode} = useAppContext();

const params = new URLSearchParams(search);
// For state we don't want to keep while navigating
props.exclude?.forEach((key) => {
params.delete(key);
});

return <NavLink to={`${to}/?${params.toString()}`} {...props} />;
let prefixedUrl = to;

if (!clusterMode) {
prefixedUrl = `/${context}${to}`;
}

return <NavLink to={`${prefixedUrl}/?${params.toString()}`} {...props} />;
};

export default LinkWithSearchParams;
Loading