Skip to content

Commit

Permalink
feat: add permissions view for connections
Browse files Browse the repository at this point in the history
fixes #2246

fix: fix incorrect reference to permissions instead of connection
  • Loading branch information
mainawycliffe committed Sep 25, 2024
1 parent 1e66998 commit fb38f21
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 21 deletions.
14 changes: 10 additions & 4 deletions src/api/services/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type FetchPermissionsInput = {
checkId?: string;
canaryId?: string;
playbookId?: string;
connectionId?: string;
};

function composeQueryParamForFetchPermissions({
Expand All @@ -20,7 +21,8 @@ function composeQueryParamForFetchPermissions({
configId,
checkId,
canaryId,
playbookId
playbookId,
connectionId
}: FetchPermissionsInput) {
if (componentId) {
return `component_id=eq.${componentId}`;
Expand All @@ -43,6 +45,9 @@ function composeQueryParamForFetchPermissions({
if (playbookId) {
return `playbook_id=eq.${playbookId}`;
}
if (connectionId) {
return `connection_id=eq.${connectionId}`;
}
return undefined;
}

Expand All @@ -56,14 +61,15 @@ export function fetchPermissions(
const queryParam = composeQueryParamForFetchPermissions(input);
const selectFields = [
"*",
"checks:check_id(id, name, status, type)",
// "checks:check_id(id, name, status, type)",
"catalog:config_id(id, name, type, config_class)",
"component:component_id(id, name, icon)",
"canary:canary_id(id, name, icon)",
"canary:canary_id(id, name)",
"playbook:playbook_id(id, title, name, icon)",
"team:team_id(id, name, icon)",
`person:person_id(${AVATAR_INFO})`,
`createdBy:created_by(${AVATAR_INFO})`
`createdBy:created_by(${AVATAR_INFO})`,
`connection:connection_id(id,name,type)`
];

const { pageSize, pageIndex } = pagination;
Expand Down
10 changes: 7 additions & 3 deletions src/api/types/permissions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Connection } from "@flanksource-ui/components/Connections/ConnectionFormModal";
import { ConfigItem } from "./configs";
import { HealthCheck } from "./health";
import { PlaybookSpec } from "./playbooks";
import { Topology } from "./topology";
import { Team, User } from "./users";
Expand All @@ -23,12 +23,16 @@ export type PermissionTable = {
};

export type PermissionAPIResponse = PermissionTable & {
checks: Pick<HealthCheck, "id" | "name" | "type" | "status">;
// checks: Pick<HealthCheck, "id" | "name" | "type" | "status">;
catalog: Pick<ConfigItem, "id" | "name" | "type" | "config_class">;
component: Pick<Topology, "id" | "name" | "icon">;
canary: Pick<Topology, "id" | "name" | "icon">;
canary: {
id: string;
name: string;
};
playbook: Pick<PlaybookSpec, "id" | "name" | "icon" | "title">;
team: Pick<Team, "id" | "name" | "icon">;
connection: Pick<Connection, "id" | "name" | "type">;
person: User;
createdBy: User;
};
61 changes: 51 additions & 10 deletions src/components/Connections/ConnectionFormModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Tab, Tabs } from "@flanksource-ui/ui/Tabs/Tabs";
import React, { useEffect, useState } from "react";
import { Icon } from "../../ui/Icons/Icon";
import { Modal } from "../../ui/Modal";
import PermissionsView from "../Permissions/PermissionsView";
import ConnectionForm from "./ConnectionForm";
import ConnectionListView from "./ConnectionListView";
import ConnectionSpecEditor from "./ConnectionSpecEditor";
Expand Down Expand Up @@ -81,6 +83,8 @@ export default function ConnectionFormModal({
ConnectionType | undefined
>(() => connectionTypes.find((item) => item.title === formValue?.type));

const [activeTab, setActiveTab] = useState<"form" | "permissions">("form");

useEffect(() => {
let connection = connectionTypes.find(
(item) => item.value === formValue?.type
Expand Down Expand Up @@ -122,16 +126,53 @@ export default function ConnectionFormModal({
helpLink="reference/connections/"
>
{type ? (
<ConnectionForm
handleBack={() => setConnectionType(undefined)}
connectionType={type}
onConnectionSubmit={onConnectionSubmit}
onConnectionDelete={onConnectionDelete}
formValue={formValue}
className={className}
isSubmitting={isSubmitting}
isDeleting={isDeleting}
/>
formValue?.id ? (
<Tabs
activeTab={activeTab}
onSelectTab={(label) => setActiveTab(label)}
className="flex-1"
>
<Tab
label="Edit Connection"
value={"form"}
className="flex flex-col"
>
<ConnectionForm
handleBack={() => setConnectionType(undefined)}
connectionType={type}
onConnectionSubmit={onConnectionSubmit}
onConnectionDelete={onConnectionDelete}
formValue={formValue}
className={className}
isSubmitting={isSubmitting}
isDeleting={isDeleting}
/>
</Tab>

<Tab
label="Permissions"
value={"connections"}
className="flex flex-col"
>
<PermissionsView
permissionRequest={{
connectionId: formValue.id
}}
/>
</Tab>
</Tabs>
) : (
<ConnectionForm
handleBack={() => setConnectionType(undefined)}
connectionType={type}
onConnectionSubmit={onConnectionSubmit}
onConnectionDelete={onConnectionDelete}
formValue={formValue}
className={className}
isSubmitting={isSubmitting}
isDeleting={isDeleting}
/>
)
) : formValue?.id ? (
<ConnectionSpecEditor
handleBack={() => setConnectionType(undefined)}
Expand Down
30 changes: 30 additions & 0 deletions src/components/Connections/ConnectionIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Icon } from "@flanksource-ui/ui/Icons/Icon";
import { useMemo } from "react";
import { Connection } from "./ConnectionFormModal";
import { connectionTypes } from "./connectionTypes";

type ConnectionIconProps = {
connection: Pick<Connection, "type" | "name" | "id">;
showLabel?: boolean;
};
export default function ConnectionIcon({
connection,
showLabel = false
}: ConnectionIconProps) {
const icon = useMemo(() => {
return connectionTypes.find((item) => item.value === connection.type)?.icon;
}, [connection.type]);

return (
<div className="flex flex-row items-center gap-1">
{typeof icon === "string" ? (
<Icon name={icon} className="h-5" />
) : (
// if not a string, it's a react component
// eslint-disable-next-line react/jsx-no-useless-fragment
icon && <>{icon}</>
)}
{showLabel && <span>{connection.name}</span>}
</div>
);
}
2 changes: 1 addition & 1 deletion src/components/Connections/connectionTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export const enum ConnectionValueType {
export type ConnectionType = {
title: string;
value: ConnectionValueType;
icon?: React.ReactNode | string | null;
icon?: JSX.Element | string | null;
fields: ConnectionFormFields[];
convertToFormSpecificValue?: (data: Record<string, string>) => Connection;
preSubmitConverter?: (data: Record<string, string>) => object;
Expand Down
8 changes: 5 additions & 3 deletions src/components/Permissions/PermissionsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { MRTDateCell } from "@flanksource-ui/ui/MRTDataTable/Cells/MRTDateCells"
import MRTDataTable from "@flanksource-ui/ui/MRTDataTable/MRTDataTable";
import { MRT_ColumnDef } from "mantine-react-table";
import CanaryLink from "../Canary/CanaryLink";
import { CheckLink } from "../Canary/HealthChecks/CheckLink";
import ConfigLink from "../Configs/ConfigLink/ConfigLink";
import ConnectionIcon from "../Connections/ConnectionIcon";
import PlaybookSpecIcon from "../Playbooks/Settings/PlaybookSpecIcon";
import { TopologyLink } from "../Topology/TopologyLink";

Expand All @@ -17,18 +17,20 @@ const permissionsTableColumns: MRT_ColumnDef<PermissionAPIResponse>[] = [
size: 250,
Cell: ({ row }) => {
const config = row.original.catalog;
const check = row.original.checks;
// const check = row.original.checks;
const playbook = row.original.playbook;
const canary = row.original.canary;
const component = row.original.component;
const connection = row.original.connection;

return (
<div className="flex flex-col">
{config && <ConfigLink config={config} />}
{check && <CheckLink check={check} />}
{/* {check && <CheckLink check={check} />} */}
{playbook && <PlaybookSpecIcon playbook={playbook} showLabel />}
{canary && <CanaryLink canary={canary} />}
{component && <TopologyLink topology={component} />}
{connection && <ConnectionIcon connection={connection} showLabel />}
</div>
);
}
Expand Down

0 comments on commit fb38f21

Please sign in to comment.