Skip to content

Commit

Permalink
New datastore tabs (#4419)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feroze Mohideen authored Mar 18, 2024
1 parent b980cd4 commit 137bca4
Show file tree
Hide file tree
Showing 21 changed files with 696 additions and 392 deletions.
9 changes: 9 additions & 0 deletions api/server/handlers/datastore/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ func (c *GetDatastoreHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusNotFound))
return
}
connectedClusterIds := make([]uint, 0)
if matchingDatastore.ConnectedClusters != nil {
for _, cc := range matchingDatastore.ConnectedClusters.ConnectedClusterIds {
connectedClusterIds = append(connectedClusterIds, uint(cc))
}
}

encoded, err := helpers.MarshalContractObject(ctx, matchingDatastore)
if err != nil {
err = telemetry.Error(ctx, span, err, "error marshaling datastore")
Expand All @@ -159,6 +166,8 @@ func (c *GetDatastoreHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Status: string(datastoreRecord.Status),
CloudProvider: SupportedDatastoreCloudProvider_AWS,
CloudProviderCredentialIdentifier: datastoreRecord.CloudProviderCredentialIdentifier,
ConnectedClusterIds: connectedClusterIds,
OnManagementCluster: true,
B64Proto: b64,
}

Expand Down
15 changes: 2 additions & 13 deletions api/server/handlers/datastore/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/porter-dev/porter/api/server/authz"
"github.com/porter-dev/porter/api/server/handlers"
"github.com/porter-dev/porter/api/server/handlers/cloud_provider"
"github.com/porter-dev/porter/api/server/handlers/environment_groups"
"github.com/porter-dev/porter/api/server/shared"
"github.com/porter-dev/porter/api/server/shared/apierrors"
"github.com/porter-dev/porter/api/server/shared/config"
Expand Down Expand Up @@ -140,8 +139,6 @@ func Datastores(ctx context.Context, inp DatastoresInput) ([]datastore.Datastore
CloudProvider: inp.CloudProvider.Type,
CloudProviderAccountId: inp.CloudProvider.AccountID,
Name: inp.Name,
IncludeEnvGroup: inp.IncludeEnvGroup,
IncludeMetadata: inp.IncludeMetadata,
}
if inp.Type != porterv1.EnumDatastore_ENUM_DATASTORE_UNSPECIFIED {
message.Type = &inp.Type
Expand All @@ -168,18 +165,10 @@ func Datastores(ctx context.Context, inp DatastoresInput) ([]datastore.Datastore
Engine: datastoreRecord.Engine,
CreatedAtUTC: datastoreRecord.CreatedAt,
Status: string(datastoreRecord.Status),
Metadata: ds.Metadata,
CloudProvider: datastoreRecord.CloudProvider,
CloudProviderCredentialIdentifier: datastoreRecord.CloudProviderCredentialIdentifier,
}
if inp.IncludeEnvGroup && ds.Env != nil {
encodedDatastore.Env = environment_groups.EnvironmentGroupListItem{
Name: ds.Env.Name,
LatestVersion: int(ds.Env.Version),
Variables: ds.Env.Variables,
SecretVariables: ds.Env.SecretVariables,
LinkedApplications: ds.Env.LinkedApplications,
}
ConnectedClusterIds: []uint{uint(ds.ConnectedClusterId)},
OnManagementCluster: false,
}
datastores = append(datastores, encodedDatastore)
}
Expand Down
5 changes: 3 additions & 2 deletions api/server/handlers/environment_groups/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ func (c *ListEnvironmentGroupsHandler) ServeHTTP(w http.ResponseWriter, r *http.
}

var translateProtoTypeToEnvGroupType = map[porterv1.EnumEnvGroupProviderType]string{
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER: "doppler",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_PORTER: "porter",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DATASTORE: "datastore",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER: "doppler",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_PORTER: "porter",
}
2 changes: 2 additions & 0 deletions dashboard/src/lib/databases/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export const datastoreValidator = z.object({
cloud_provider: z.string().pipe(cloudProviderValidator.catch("UNKNOWN")),
cloud_provider_credential_identifier: z.string(),
credential: datastoreCredentialValidator,
connected_cluster_ids: z.number().array().optional().default([]),
on_management_cluster: z.boolean().default(false),
});

export type SerializedDatastore = z.infer<typeof datastoreValidator>;
Expand Down
18 changes: 16 additions & 2 deletions dashboard/src/lib/env-groups/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,21 @@ export const envGroupFormValidator = z.object({
locked: z.boolean(),
})
)
.min(1, { message: "At least one environment variable is required" })
.min(1, { message: "At least one environment variable is required" }),
});

export type EnvGroupFormData = z.infer<typeof envGroupFormValidator>;
export type EnvGroupFormData = z.infer<typeof envGroupFormValidator>;

export const envGroupValidator = z.object({
name: z.string(),
variables: z.record(z.string()).optional().default({}),
secret_variables: z.record(z.string()).optional().default({}),
created_at: z.string(),
type: z
.string()
.pipe(
z.enum(["UNKNOWN", "datastore", "doppler", "porter"]).catch("UNKNOWN")
),
});

export type ClientEnvGroup = z.infer<typeof envGroupValidator>;
2 changes: 0 additions & 2 deletions dashboard/src/lib/hooks/useDatabaseMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ type DatastoreHook = {
attachDatastoreToAppInstances: ({
name,
appInstanceIds,
clusterId,
}: {
name: string;
appInstanceIds: string[];
clusterId: number;
}) => Promise<void>;
};
type CreateDatastoreInput = {
Expand Down
50 changes: 50 additions & 0 deletions dashboard/src/lib/hooks/useEnvGroups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useContext } from "react";
import { useQuery } from "@tanstack/react-query";
import { z } from "zod";

import { envGroupValidator, type ClientEnvGroup } from "lib/env-groups/types";

import api from "shared/api";
import { Context } from "shared/Context";

type TUseEnvGroupList = {
envGroups: ClientEnvGroup[];
isLoading: boolean;
};
export const useEnvGroupList = ({
clusterId,
}: {
clusterId?: number;
}): TUseEnvGroupList => {
const { currentProject } = useContext(Context);

const envGroupReq = useQuery(
["getEnvGroups", currentProject?.id],
async () => {
if (!currentProject?.id || currentProject.id === -1 || !clusterId) {
return;
}

const res = await api.getAllEnvGroups(
"<token>",
{},
{
id: currentProject?.id,
cluster_id: clusterId,
}
);
const parsed = await z
.object({ environment_groups: z.array(envGroupValidator) })
.parseAsync(res.data);
return parsed.environment_groups;
},
{
enabled: !!currentProject && currentProject.id !== -1,
}
);

return {
envGroups: envGroupReq.data ?? [],
isLoading: envGroupReq.isLoading,
};
};
Original file line number Diff line number Diff line change
@@ -1,94 +1,124 @@
import React, {useContext, useMemo} from "react";
import styled from "styled-components";

import React, { useContext, useMemo } from "react";
import { useHistory } from "react-router";

import doppler from "assets/doppler.png";
import key from "assets/key.svg";
import styled from "styled-components";

import Container from "components/porter/Container";
import Expandable from "components/porter/Expandable";
import Image from "components/porter/Image";
import Spacer from "components/porter/Spacer";
import Text from "components/porter/Text";
import EnvGroupArray from "main/home/env-dashboard/EnvGroupArray";
import {envGroupPath} from "shared/util";
import {Context} from "shared/Context";

import { Context } from "shared/Context";
import { envGroupPath } from "shared/util";
import database from "assets/database.svg";
import doppler from "assets/doppler.png";
import key from "assets/key.svg";

type Props = {
onRemove: (name: string) => void;
envGroup: {
name: string;
id: number;
type: string;
isActive: boolean;
variables: Record<string, string>;
secret_variables: Record<string, string>;
};
canDelete?: boolean;
};

// TODO: support footer for consolidation w/ app services
const EnvGroupRow: React.FC<Props> = ({ envGroup, onRemove }) => {
const EnvGroupRow: React.FC<Props> = ({
envGroup,
onRemove,
canDelete = true,
}) => {
const { currentProject } = useContext(Context);
const history = useHistory();

const variables = useMemo(() => {
const normalVariables = Object.entries(
envGroup.variables || {}
).map(([key, value]) => ({
key,
value,
hidden: value.includes("PORTERSECRET"),
locked: value.includes("PORTERSECRET"),
deleted: false,
}));
const secretVariables = Object.entries(
envGroup.secret_variables || {}
).map(([key, value]) => ({
key,
value,
hidden: true,
locked: true,
deleted: false,
}));
const normalVariables = Object.entries(envGroup.variables || {}).map(
([key, value]) => ({
key,
value,
hidden: value.includes("PORTERSECRET"),
locked: value.includes("PORTERSECRET"),
deleted: false,
})
);

const secretVariables = Object.entries(envGroup.secret_variables || {}).map(
([key, value]) => ({
key,
value,
hidden: true,
locked: true,
deleted: false,
})
);

return [...normalVariables, ...secretVariables];
}, [envGroup]);

return (
<Expandable
header={(
header={
<Container row spaced>
<Container row>
<Image
size={20}
src={envGroup.type === "doppler" ? doppler : key}
src={
envGroup.type === "doppler"
? doppler
: envGroup.type === "datastore"
? database
: key
}
/>
<Spacer inline x={1} />
<Text size={14}>{envGroup.name}</Text>
</Container>
<Container row>
<Svg
onClick={() => {
history.push(envGroupPath(currentProject, `/${envGroup.name}/synced-apps`))
<Svg
onClick={() => {
history.push(
envGroupPath(currentProject, `/${envGroup.name}/synced-apps`)
);
}}
data-testid="geist-icon" fill="none" height="27px" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round" strokeLinejoin="round" stroke-width="2" viewBox="0 0 24 24" width="27px" data-darkreader-inline-stroke="" data-darkreader-inline-color=""><path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path><path d="M15 3h6v6"></path><path d="M10 14L21 3"></path></Svg>
<Spacer inline x={.5} />
<I
className="material-icons"
onClick={() => { onRemove(envGroup.name) }}
data-testid="geist-icon"
fill="none"
height="27px"
shape-rendering="geometricPrecision"
stroke="currentColor"
stroke-linecap="round"
strokeLinejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="27px"
data-darkreader-inline-stroke=""
data-darkreader-inline-color=""
>
delete
</I>
<path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path>
<path d="M15 3h6v6"></path>
<path d="M10 14L21 3"></path>
</Svg>
{canDelete && (
<>
<Spacer inline x={0.5} />
<I
className="material-icons"
onClick={() => {
onRemove(envGroup.name);
}}
>
delete
</I>
</>
)}
</Container>
</Container>
)}
}
>
<EnvGroupArray
values={variables}
disabled={true}
/>
<EnvGroupArray values={variables} disabled={true} />
</Expandable>
);
};
Expand All @@ -113,4 +143,4 @@ const Svg = styled.svg`
:hover {
stroke: white;
}
`;
`;
13 changes: 6 additions & 7 deletions dashboard/src/main/home/database-dashboard/DatabaseTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TabSelector from "components/TabSelector";

import { useDatastoreContext } from "./DatabaseContextProvider";
import DatastoreProvisioningIndicator from "./DatastoreProvisioningIndicator";
import ConnectedAppsTab from "./tabs/ConnectedAppsTab";
import ConfigurationTab from "./tabs/ConfigurationTab";
import ConnectTab from "./tabs/ConnectTab";
import MetricsTab from "./tabs/MetricsTab";
import SettingsTab from "./tabs/SettingsTab";
Expand Down Expand Up @@ -43,9 +43,9 @@ const DatabaseTabs: React.FC<DbTabProps> = ({ tabParam }) => {

const tabs = useMemo(() => {
return [
{ label: "Connect", value: "connect" },
{ label: "Connected Apps", value: "connected-apps" },
// { label: "Configuration", value: "configuration" },
{ label: "Connectivity", value: "connect" },
// { label: "Connected Apps", value: "connected-apps" },
{ label: "Configuration", value: "configuration" },
{ label: "Settings", value: "settings" },
];
}, []);
Expand All @@ -69,10 +69,9 @@ const DatabaseTabs: React.FC<DbTabProps> = ({ tabParam }) => {
.with("connect", () => <ConnectTab />)
.with("settings", () => <SettingsTab />)
.with("metrics", () => <MetricsTab />)
// .with("configuration", () => <ConfigurationTab />)
.with("connected-apps", () => <ConnectedAppsTab />)
.with("configuration", () => <ConfigurationTab />)
// .with("connected-apps", () => <ConnectedAppsTab />)
.otherwise(() => null)}
<Spacer y={2} />
</div>
);
};
Expand Down
Loading

0 comments on commit 137bca4

Please sign in to comment.