feat: added no secret access views

This commit is contained in:
=
2024-10-09 22:31:49 +05:30
parent a9e6c229d0
commit 0f10874f80
9 changed files with 110 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
/* eslint-disable no-await-in-loop */
import { unpackRules } from "@casl/ability/extra";
import { packRules, unpackRules } from "@casl/ability/extra";
import { Knex } from "knex";
import {

View File

@@ -764,7 +764,7 @@ export const backfillPermissionV1SchemaToV2Schema = (data: z.infer<typeof Projec
const secretFolderPolicies = secretSubjects.map(({ subject, ...el }) => ({
...el,
subject: ProjectPermissionSub.DynamicSecrets
subject: ProjectPermissionSub.SecretFolders
}));
const dynamicSecretPolicies = secretSubjects.map(({ subject, ...el }) => ({

View File

@@ -38,7 +38,7 @@ import { ActionBar } from "./components/ActionBar";
import { CreateSecretForm } from "./components/CreateSecretForm";
import { PitDrawer } from "./components/PitDrawer";
import { SecretDropzone } from "./components/SecretDropzone";
import { SecretListView } from "./components/SecretListView";
import { SecretListView, SecretNoAccessListView } from "./components/SecretListView";
import { SnapshotView } from "./components/SnapshotView";
import { StoreProvider } from "./SecretMainPage.store";
import { Filter, RowType } from "./SecretMainPage.types";
@@ -315,7 +315,6 @@ export const SecretMainPage = () => {
setFilter(defaultFilterState);
setDebouncedSearchFilter("");
};
return (
<StoreProvider>
<div className="container mx-auto flex flex-col px-6 text-mineshaft-50 dark:[color-scheme:dark]">
@@ -418,6 +417,17 @@ export const SecretMainPage = () => {
isProtectedBranch={isProtectedBranch}
/>
)}
{canReadSecret && (
<SecretNoAccessListView
count={Math.max(
(page * perPage > totalCount ? totalCount % perPage : perPage) -
(folders?.length || 0) -
(secrets?.length || 0) -
(dynamicSecrets?.length || 0),
0
)}
/>
)}
{!canReadSecret &&
!canReadDynamicSecret &&
!canReadSecretImports &&

View File

@@ -16,7 +16,6 @@ import { WsTag } from "@app/hooks/api/types";
import { AddShareSecretModal } from "@app/views/ShareSecretPage/components/AddShareSecretModal";
import { useSelectedSecretActions, useSelectedSecrets } from "../../SecretMainPage.store";
import { Filter } from "../../SecretMainPage.types";
import { SecretDetailSidebar } from "./SecretDetaiSidebar";
import { SecretItem } from "./SecretItem";
import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
@@ -31,16 +30,6 @@ type Props = {
isProtectedBranch?: boolean;
};
export const filterSecrets = (secrets: SecretV3RawSanitized[], filter: Filter) =>
secrets.filter(({ key, value, tags }) => {
const isTagFilterActive = Boolean(Object.keys(filter.tags).length);
const searchTerm = filter.searchFilter.toLowerCase();
return (
(!isTagFilterActive || tags?.some(({ id }) => filter.tags?.[id])) &&
(key.toLowerCase().includes(searchTerm) || value?.toLowerCase().includes(searchTerm))
);
});
export const SecretListView = ({
secrets = [],
environment,

View File

@@ -10,6 +10,7 @@ import {
faCopy,
faEllipsis,
faKey,
faLock,
faShare,
faTags
} from "@fortawesome/free-solid-svg-icons";
@@ -71,7 +72,8 @@ export enum FontAwesomeSpriteName {
Close = "close",
CheckedCircle = "check-circle",
ReplicatedSecretKey = "secret-replicated",
ShareSecret = "share-secret"
ShareSecret = "share-secret",
KeyLock = "key-lock"
}
// this is an optimization technique
@@ -88,5 +90,6 @@ export const FontAwesomeSpriteSymbols = [
{ icon: faClose, symbol: FontAwesomeSpriteName.Close },
{ icon: faCheckCircle, symbol: FontAwesomeSpriteName.CheckedCircle },
{ icon: faClone, symbol: FontAwesomeSpriteName.ReplicatedSecretKey },
{ icon: faShare, symbol: FontAwesomeSpriteName.ShareSecret }
{ icon: faShare, symbol: FontAwesomeSpriteName.ShareSecret },
{ icon: faLock, symbol: FontAwesomeSpriteName.KeyLock }
];

View File

@@ -0,0 +1,44 @@
import { FontAwesomeSymbol, Input } from "@app/components/v2";
import { FontAwesomeSpriteName } from "./SecretListView.utils";
type Props = {
count: number;
};
export const SecretNoAccessListView = ({ count }: Props) => {
return (
<>
{Array.from(Array(count)).map((_, i) => (
<div
className="flex border-b border-mineshaft-600 bg-mineshaft-800 shadow-none hover:bg-mineshaft-700"
key={`no-access-secret-${i + 1}`}
>
<div className="flex h-11 w-11 items-center justify-center px-4 py-3">
<FontAwesomeSymbol
className="ml-3 block h-3.5 w-3.5"
symbolName={FontAwesomeSpriteName.KeyLock}
/>
</div>
<div className="flex h-11 w-80 flex-shrink-0 items-center px-4 py-2">
<Input
autoComplete="off"
isReadOnly
variant="plain"
value="NO ACCESS"
isDisabled
className="w-full px-0 blur-sm placeholder:text-red-500 focus:text-bunker-100 focus:ring-transparent"
/>
</div>
<div
className="flex w-80 flex-grow items-center border-x border-mineshaft-600 py-1 pl-4 pr-2"
tabIndex={0}
role="button"
>
<span className="blur">********</span>
</div>
</div>
))}
</>
);
};

View File

@@ -1 +1,2 @@
export { SecretListView } from "./SecretListView";
export { SecretNoAccessListView } from "./SecretNoAccessListView";

View File

@@ -0,0 +1,45 @@
import { faCircle } from "@fortawesome/free-regular-svg-icons";
import { faLock } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Td, Tr } from "@app/components/v2";
type Props = {
environments: { name: string; slug: string }[];
count: number;
};
export const SecretNoAccessOverviewTableRow = ({ environments = [], count }: Props) => {
return (
<>
{Array.from(Array(count)).map((_, j) => (
<Tr key={`no-access-secret-overview-${j + 1}`} isHoverable isSelectable className="group">
<Td className="sticky left-0 z-10 bg-mineshaft-800 bg-clip-padding py-0 px-0 group-hover:bg-mineshaft-700">
<div className="h-full w-full border-r border-mineshaft-600 py-2.5 px-5">
<div className="flex items-center space-x-5">
<div className="text-bunker-300">
<FontAwesomeIcon className="block" icon={faLock} />
</div>
<div className="blur-sm">NO ACCESS</div>
</div>
</div>
</Td>
{environments.map(({ slug }, i) => {
return (
<Td
key={`sec-overview-${slug}-${i + 1}-value`}
className="py-0 px-0 group-hover:bg-mineshaft-700"
>
<div className="h-full w-full border-r border-mineshaft-600 py-[0.85rem] px-5">
<div className="flex justify-center">
<FontAwesomeIcon icon={faCircle} />
</div>
</div>
</Td>
);
})}
</Tr>
))}
</>
);
};

View File

@@ -1 +1,2 @@
export { SecretNoAccessOverviewTableRow } from "./SecretNoAccessOverviewTableRow";
export { SecretOverviewTableRow } from "./SecretOverviewTableRow";