From 74c31605286f9e3b0a45269c30cf4abb08831480 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 8 Oct 2025 21:20:54 +0545 Subject: [PATCH 1/5] feat: add creator avatar to permissions table - Join with people table to fetch created_by user info - Display avatar in Created By column - Handle missing creator gracefully --- src/api/services/permissions.ts | 5 +++-- src/api/types/permissions.ts | 1 + src/components/Permissions/PermissionsTable.tsx | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/api/services/permissions.ts b/src/api/services/permissions.ts index fa45bfe5d..fa600a726 100644 --- a/src/api/services/permissions.ts +++ b/src/api/services/permissions.ts @@ -1,6 +1,7 @@ import { IncidentCommander } from "../axios"; import { resolvePostGrestRequestWithPagination } from "../resolve"; import { PermissionsSummary, PermissionTable } from "../types/permissions"; +import { AVATAR_INFO } from "@flanksource-ui/constants"; export type FetchPermissionsInput = { componentId?: string; @@ -68,11 +69,11 @@ export function fetchPermissions( } ) { const queryParam = composeQueryParamForFetchPermissions(input); - const selectFields = ["*"]; + const selectFields = `*,created_by(${AVATAR_INFO})`; const { pageSize, pageIndex } = pagination; - const url = `/permissions_summary?${queryParam}&select=${selectFields.join(",")}&deleted_at=is.null&limit=${pageSize}&offset=${pageIndex * pageSize}`; + const url = `/permissions_summary?${queryParam}&select=${selectFields}&deleted_at=is.null&limit=${pageSize}&offset=${pageIndex * pageSize}`; return resolvePostGrestRequestWithPagination( IncidentCommander.get(url, { headers: { diff --git a/src/api/types/permissions.ts b/src/api/types/permissions.ts index 03ed79ccf..d1a07ddd5 100644 --- a/src/api/types/permissions.ts +++ b/src/api/types/permissions.ts @@ -69,6 +69,7 @@ export type PermissionsSummary = PermissionTable & { subject: string; person: User; createdBy: User; + created_by?: User; tags: Record | null; agents: string[] | null; diff --git a/src/components/Permissions/PermissionsTable.tsx b/src/components/Permissions/PermissionsTable.tsx index 5962c5b34..bbeab70b1 100644 --- a/src/components/Permissions/PermissionsTable.tsx +++ b/src/components/Permissions/PermissionsTable.tsx @@ -280,7 +280,7 @@ const permissionsTableColumns: MRT_ColumnDef[] = [ header: "Created By", size: 40, Cell: ({ row }) => { - const createdBy = row.original.createdBy; + const createdBy = row.original.created_by; const source = row.original.source; if (source?.toLowerCase() === "KubernetesCRD".toLowerCase()) { @@ -288,6 +288,10 @@ const permissionsTableColumns: MRT_ColumnDef[] = [ return ; } + if (!createdBy) { + return null; + } + return ; } } From 9d5a94e9ec64f3e35094d3d3ea9ba1b24e86bf86 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 8 Oct 2025 21:21:11 +0545 Subject: [PATCH 2/5] feat: make permission form read-only for CRD-managed permissions - Add read-only banner when source is KubernetesCRD - Disable all form fields with pointer-events-none and opacity - Add disabled prop to PermissionSubjectControls - Display linked CRD in footer via CanEditResource - Only show delete button for UI-created permissions --- .../Forms/PermissionForm.tsx | 107 ++++++++++-------- .../Forms/PermissionSubjectControls.tsx | 28 ++++- 2 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/components/Permissions/ManagePermissions/Forms/PermissionForm.tsx b/src/components/Permissions/ManagePermissions/Forms/PermissionForm.tsx index 7d19512d0..bd4cdf4b5 100644 --- a/src/components/Permissions/ManagePermissions/Forms/PermissionForm.tsx +++ b/src/components/Permissions/ManagePermissions/Forms/PermissionForm.tsx @@ -18,7 +18,6 @@ import { Button } from "@flanksource-ui/ui/Buttons/Button"; import { Modal } from "@flanksource-ui/ui/Modal"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { AxiosError } from "axios"; -import clsx from "clsx"; import { Form, Formik, useFormikContext } from "formik"; import { useMemo } from "react"; import { FaSpinner } from "react-icons/fa"; @@ -78,22 +77,45 @@ function PermissionFormContent({ return (
- - {isResourceIdProvided && isReadOnly ? ( -
- - + {isReadOnly && ( +
+

+ Read-Only Mode: This resource is managed by Kubernetes CRD and + cannot be edited from the UI. +

- ) : ( - )} - - - + +
+ +
+ +
+ {isResourceIdProvided && isReadOnly ? ( +
+ + +
+ ) : ( + + )} +
+ +
+ +
+ +
+ +
+ +
+ +
); } @@ -247,41 +269,36 @@ export default function PermissionForm({ id={permissionData?.id} resourceType={"permissions"} source={permissionData?.source} - className="flex items-center bg-gray-100 px-5 py-4" + className="flex items-center justify-between bg-gray-100 px-5 py-4" > - -
- {permissionData?.id && ( +
+ {permissionData?.id && permissionData.source === "UI" && ( + - )} -
+ + )} +
+ +
{switchOption === "Team" && ( - + )} {switchOption === "Person" && ( - + )} {switchOption === "Notification" && ( - + )} {switchOption === "Role" && ( - + )} {switchOption === "Playbook" && ( - + )} From 8d5f04fc6999001d836116d5f04d19f0bf19b0df Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 8 Oct 2025 21:25:25 +0545 Subject: [PATCH 3/5] refactor: remove tags and agents fields from permissions - Remove tags and agents from PermissionTable type - Remove tags and agents from PermissionsSummary type - Remove badge rendering logic from permissions table - Simplify Resource column display --- src/api/types/permissions.ts | 7 +-- .../Permissions/PermissionsTable.tsx | 50 ------------------- 2 files changed, 2 insertions(+), 55 deletions(-) diff --git a/src/api/types/permissions.ts b/src/api/types/permissions.ts index d1a07ddd5..54512bf8f 100644 --- a/src/api/types/permissions.ts +++ b/src/api/types/permissions.ts @@ -32,8 +32,6 @@ export type PermissionTable = { updated_at: string; until?: string; source?: string; - tags?: Record; - agents?: string[]; // Resources object?: PermissionGlobalObject; @@ -70,8 +68,6 @@ export type PermissionsSummary = PermissionTable & { person: User; createdBy: User; created_by?: User; - tags: Record | null; - agents: string[] | null; // These represent global objects object: PermissionGlobalObject; @@ -79,7 +75,8 @@ export type PermissionsSummary = PermissionTable & { // These represent object selectors per type object_selector?: PermissionObjectSelector; - // These are objects that are specifically chosen + // These are objects that are specifically chosen (from the dropdown). + // We store their ID. config_object: Pick; playbook_object: Pick; connection_object: Pick; diff --git a/src/components/Permissions/PermissionsTable.tsx b/src/components/Permissions/PermissionsTable.tsx index bbeab70b1..9065b0d8f 100644 --- a/src/components/Permissions/PermissionsTable.tsx +++ b/src/components/Permissions/PermissionsTable.tsx @@ -12,13 +12,8 @@ import { permissionObjectList } from "./ManagePermissions/Forms/FormikPermission import { permissionsActionsList } from "./PermissionsView"; import { BsBan } from "react-icons/bs"; import { Link } from "react-router-dom"; -import { Badge } from "@flanksource-ui/ui/Badge/Badge"; import CRDSource from "../Settings/CRDSource"; -const formatTagText = (key: string, value: string): string => { - return `${key}: ${value}`; -}; - const permissionsTableColumns: MRT_ColumnDef[] = [ { header: "Subject", @@ -108,41 +103,6 @@ const permissionsTableColumns: MRT_ColumnDef[] = [ const connection = row.original.connection_object; const object = row.original.object; const objectSelector = row.original.object_selector; - const { tags, agents } = row.original; - - const renderRlsBadges = (): JSX.Element[] => { - const badges: JSX.Element[] = []; - - // Add tag badges - if (tags && Object.keys(tags).length > 0) { - Object.entries(tags).forEach(([key, value]) => { - badges.push( - - ); - }); - } - - // Add agent badges - if (agents && agents.length > 0) { - agents.forEach((agent, index) => { - badges.push( - - ); - }); - } - - return badges; - }; - - const rlsBadges = renderRlsBadges(); if (objectSelector) { return ( @@ -153,9 +113,6 @@ const permissionsTableColumns: MRT_ColumnDef[] = [ > {JSON.stringify(objectSelector)} - {rlsBadges.length > 0 && ( -
{rlsBadges}
- )} ); } @@ -166,9 +123,6 @@ const permissionsTableColumns: MRT_ColumnDef[] = [ {permissionObjectList.find((o) => o.value === object)?.label} - {rlsBadges.length > 0 && ( -
{rlsBadges}
- )} ); } @@ -216,10 +170,6 @@ const permissionsTableColumns: MRT_ColumnDef[] = [ )} - - {rlsBadges.length > 0 && ( -
{rlsBadges}
- )} ); } From e7fc98cbd52ee386d24b9cc1769f7b6a8233f350 Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 8 Oct 2025 21:26:09 +0545 Subject: [PATCH 4/5] fix: remove unsupported disabled prop from Switch component --- .../ManagePermissions/Forms/PermissionSubjectControls.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx b/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx index dc1b07ccf..fb955c8bf 100644 --- a/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx +++ b/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx @@ -86,7 +86,6 @@ export default function PermissionsSubjectControls({ setFieldValue("notification_id", undefined); setFieldValue("team_id", undefined); }} - disabled={disabled} /> From 6f2f47894e92699fc4c90641edc0235b69fe421c Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 8 Oct 2025 21:30:34 +0545 Subject: [PATCH 5/5] fix: remove disabled prop from Formik dropdowns that don't support it --- src/api/types/permissions.ts | 1 - .../Forms/PermissionSubjectControls.tsx | 18 +++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/api/types/permissions.ts b/src/api/types/permissions.ts index 54512bf8f..d12cabee3 100644 --- a/src/api/types/permissions.ts +++ b/src/api/types/permissions.ts @@ -66,7 +66,6 @@ export type PermissionsSummary = PermissionTable & { group: any; subject: string; person: User; - createdBy: User; created_by?: User; // These represent global objects diff --git a/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx b/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx index fb955c8bf..ca4f4643a 100644 --- a/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx +++ b/src/components/Permissions/ManagePermissions/Forms/PermissionSubjectControls.tsx @@ -90,27 +90,19 @@ export default function PermissionsSubjectControls({ {switchOption === "Team" && ( - + )} {switchOption === "Person" && ( - + )} {switchOption === "Notification" && ( - + )} {switchOption === "Role" && ( - + )} {switchOption === "Playbook" && ( - + )}