mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 01:26:43 +00:00
Fixed dashboard for the corner case of purely personal secrets
This commit is contained in:
@@ -13,6 +13,7 @@ export interface SecretDataProps {
|
|||||||
value: string | undefined;
|
value: string | undefined;
|
||||||
valueOverride: string | undefined;
|
valueOverride: string | undefined;
|
||||||
id: string;
|
id: string;
|
||||||
|
idOverride?: string;
|
||||||
comment: string;
|
comment: string;
|
||||||
tags: Tag[];
|
tags: Tag[];
|
||||||
}
|
}
|
||||||
@@ -99,8 +99,8 @@ const DashboardInputField = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!error && <div className={`absolute right-0 top-0 text-red z-50 ${
|
{!error && <div className={`absolute right-0 top-0 text-red z-50 bg-mineshaft-800 group-hover:bg-mineshaft-700 ${
|
||||||
overrideEnabled ? 'visible group-hover:bg-mineshaft-700' : 'invisible group-hover:visible bg-mineshaft-700'
|
overrideEnabled ? 'visible' : 'invisible group-hover:visible'
|
||||||
} cursor-pointer duration-0 h-10 flex items-center px-2`}>
|
} cursor-pointer duration-0 h-10 flex items-center px-2`}>
|
||||||
<button type="button" onClick={() => {
|
<button type="button" onClick={() => {
|
||||||
if (modifyValueOverride) {
|
if (modifyValueOverride) {
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const colorsText = [
|
|||||||
/**
|
/**
|
||||||
* This component represent a single row for an environemnt variable on the dashboard
|
* This component represent a single row for an environemnt variable on the dashboard
|
||||||
* @param {object} obj
|
* @param {object} obj
|
||||||
* @param {String[]} obj.keyPair - data related to the environment variable (id, pos, key, value, public/private)
|
* @param {SecretDataProps[]} obj.keyPair - data related to the environment variable (id, pos, key, value, public/private)
|
||||||
* @param {function} obj.modifyKey - modify the key of a certain environment variable
|
* @param {function} obj.modifyKey - modify the key of a certain environment variable
|
||||||
* @param {function} obj.modifyValue - modify the value of a certain environment variable
|
* @param {function} obj.modifyValue - modify the value of a certain environment variable
|
||||||
* @param {function} obj.modifyValueOverride - modify the value of a certain environment variable if it is overriden
|
* @param {function} obj.modifyValueOverride - modify the value of a certain environment variable if it is overriden
|
||||||
@@ -108,7 +108,7 @@ const KeyPair = ({
|
|||||||
isCapitalized = {isCapitalized}
|
isCapitalized = {isCapitalized}
|
||||||
onChangeHandler={modifyKey}
|
onChangeHandler={modifyKey}
|
||||||
type="varName"
|
type="varName"
|
||||||
id={keyPair.id}
|
id={keyPair.id ? keyPair.id : (keyPair.idOverride || '')}
|
||||||
value={keyPair.key}
|
value={keyPair.key}
|
||||||
isDuplicate={isDuplicate}
|
isDuplicate={isDuplicate}
|
||||||
overrideEnabled={keyPair.valueOverride !== undefined}
|
overrideEnabled={keyPair.valueOverride !== undefined}
|
||||||
@@ -124,7 +124,7 @@ const KeyPair = ({
|
|||||||
<DashboardInputField
|
<DashboardInputField
|
||||||
onChangeHandler={keyPair.valueOverride !== undefined ? modifyValueOverride : modifyValue}
|
onChangeHandler={keyPair.valueOverride !== undefined ? modifyValueOverride : modifyValue}
|
||||||
type="value"
|
type="value"
|
||||||
id={keyPair.id}
|
id={keyPair.id ? keyPair.id : (keyPair.idOverride || '')}
|
||||||
value={keyPair.valueOverride !== undefined ? keyPair.valueOverride : keyPair.value}
|
value={keyPair.valueOverride !== undefined ? keyPair.valueOverride : keyPair.value}
|
||||||
blurred={isBlurred}
|
blurred={isBlurred}
|
||||||
overrideEnabled={keyPair.valueOverride !== undefined}
|
overrideEnabled={keyPair.valueOverride !== undefined}
|
||||||
@@ -137,7 +137,7 @@ const KeyPair = ({
|
|||||||
<DashboardInputField
|
<DashboardInputField
|
||||||
onChangeHandler={modifyComment}
|
onChangeHandler={modifyComment}
|
||||||
type="comment"
|
type="comment"
|
||||||
id={keyPair.id}
|
id={keyPair.id ? keyPair.id : (keyPair.idOverride || '')}
|
||||||
value={keyPair.comment}
|
value={keyPair.comment}
|
||||||
isDuplicate={isDuplicate}
|
isDuplicate={isDuplicate}
|
||||||
isSideBarOpen={keyPair.id === sidebarSecretId}
|
isSideBarOpen={keyPair.id === sidebarSecretId}
|
||||||
@@ -153,7 +153,7 @@ const KeyPair = ({
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<AddTagsMenu allTags={tags} currentTags={keyPair.tags} modifyTags={modifyTags} id={keyPair.id} />
|
<AddTagsMenu allTags={tags} currentTags={keyPair.tags} modifyTags={modifyTags} id={keyPair.id ? keyPair.id : (keyPair.idOverride || '')} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export default function Navbar() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row justify-between w-full bg-bunker text-white border-b border-mineshaft-500 z-[61]">
|
<div className="flex flex-row justify-between w-full bg-bunker text-white border-b border-mineshaft-500 z-[71]">
|
||||||
<div className="m-auto flex justify-start items-center mx-4">
|
<div className="m-auto flex justify-start items-center mx-4">
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<div className="flex justify-center py-4">
|
<div className="flex justify-center py-4">
|
||||||
@@ -166,7 +166,7 @@ export default function Navbar() {
|
|||||||
leaveFrom="transform opacity-100 scale-100"
|
leaveFrom="transform opacity-100 scale-100"
|
||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<Menu.Items className="absolute right-0 mt-0.5 w-64 origin-top-right divide-y divide-gray-700 rounded-md bg-bunker border border-mineshaft-700 shadow-lg ring-1 ring-black z-[65] ring-opacity-5 focus:outline-none">
|
<Menu.Items className="absolute right-0 mt-0.5 w-64 origin-top-right divide-y divide-gray-700 rounded-md bg-bunker border border-mineshaft-700 shadow-lg ring-1 ring-black z-[999] ring-opacity-5 focus:outline-none">
|
||||||
<div className="px-1 py-1 z-[100]">
|
<div className="px-1 py-1 z-[100]">
|
||||||
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
||||||
{t('nav:user.signed-in-as')}
|
{t('nav:user.signed-in-as')}
|
||||||
|
|||||||
@@ -102,7 +102,9 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const decryptedSecretVersions = secretSnapshotData.secretVersions.map(
|
const decryptedSecretVersions = secretSnapshotData.secretVersions.filter(
|
||||||
|
(sv: EncrypetedSecretVersionListProps) => (sv.type !== undefined && sv.environment !== undefined)
|
||||||
|
).map(
|
||||||
(encryptedSecretVersion: EncrypetedSecretVersionListProps, pos: number) => ({
|
(encryptedSecretVersion: EncrypetedSecretVersionListProps, pos: number) => ({
|
||||||
id: encryptedSecretVersion._id,
|
id: encryptedSecretVersion._id,
|
||||||
pos,
|
pos,
|
||||||
@@ -125,10 +127,13 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
|||||||
);
|
);
|
||||||
|
|
||||||
const secretKeys = [
|
const secretKeys = [
|
||||||
...new Set(decryptedSecretVersions.map((secret: SecretDataProps) => secret.key))
|
...new Set(decryptedSecretVersions.filter((dsv: any) => dsv.type !== undefined || dsv.environemnt !== undefined)
|
||||||
|
.map((secret: SecretDataProps) => secret.key))
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = secretKeys.map((key, index) => ({
|
const result = secretKeys.map((key, index) => (decryptedSecretVersions.filter(
|
||||||
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||||
|
)[0]?.id ? {
|
||||||
id: decryptedSecretVersions.filter(
|
id: decryptedSecretVersions.filter(
|
||||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||||
)[0].id,
|
)[0].id,
|
||||||
@@ -146,6 +151,24 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
|||||||
valueOverride: decryptedSecretVersions.filter(
|
valueOverride: decryptedSecretVersions.filter(
|
||||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||||
)[0]?.value
|
)[0]?.value
|
||||||
|
} : {
|
||||||
|
id: decryptedSecretVersions.filter(
|
||||||
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||||
|
)[0].id,
|
||||||
|
pos: index,
|
||||||
|
key,
|
||||||
|
environment: decryptedSecretVersions.filter(
|
||||||
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||||
|
)[0].environment,
|
||||||
|
tags: decryptedSecretVersions.filter(
|
||||||
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||||
|
)[0].tags,
|
||||||
|
value: decryptedSecretVersions.filter(
|
||||||
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||||
|
)[0]?.value,
|
||||||
|
valueOverride: decryptedSecretVersions.filter(
|
||||||
|
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||||
|
)[0]?.value
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setSnapshotData({
|
setSnapshotData({
|
||||||
@@ -161,7 +184,7 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
|||||||
<div
|
<div
|
||||||
className={`absolute border-l border-mineshaft-500 w-full min-w-sm max-w-sm ${
|
className={`absolute border-l border-mineshaft-500 w-full min-w-sm max-w-sm ${
|
||||||
isLoading ? 'bg-bunker-800' : 'bg-bunker'
|
isLoading ? 'bg-bunker-800' : 'bg-bunker'
|
||||||
} fixed h-full right-0 z-[70] shadow-xl flex flex-col justify-between sticky top-0`}
|
} fixed h-full right-0 z-[40] shadow-xl flex flex-col justify-between sticky top-0`}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="flex items-center justify-center h-full mb-8">
|
<div className="flex items-center justify-center h-full mb-8">
|
||||||
|
|||||||
@@ -332,27 +332,27 @@ export default function Dashboard() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const modifyValue = (value: string, id: string) => {
|
const modifyValue = (value: string, id: string) => {
|
||||||
setData((oldData) => oldData?.map((e) => (e.id === id ? { ...e, value } : e)));
|
setData((oldData) => oldData?.map((e) => ((e.id ? e.id : e.idOverride) === id ? { ...e, value } : e)));
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifyValueOverride = (valueOverride: string | undefined, id: string) => {
|
const modifyValueOverride = (valueOverride: string | undefined, id: string) => {
|
||||||
setData((oldData) => oldData?.map((e) => (e.id === id ? { ...e, valueOverride } : e)));
|
setData((oldData) => oldData?.map((e) => ((e.id ? e.id : e.idOverride) === id ? { ...e, valueOverride } : e)));
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifyKey = (key: string, id: string) => {
|
const modifyKey = (key: string, id: string) => {
|
||||||
setData((oldData) => oldData?.map((e) => (e.id === id ? { ...e, key } : e)));
|
setData((oldData) => oldData?.map((e) => ((e.id ? e.id : e.idOverride) === id ? { ...e, key } : e)));
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifyComment = (comment: string, id: string) => {
|
const modifyComment = (comment: string, id: string) => {
|
||||||
setData((oldData) => oldData?.map((e) => (e.id === id ? { ...e, comment } : e)));
|
setData((oldData) => oldData?.map((e) => ((e.id ? e.id : e.idOverride) === id ? { ...e, comment } : e)));
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifyTags = (tags: Tag[], id: string) => {
|
const modifyTags = (tags: Tag[], id: string) => {
|
||||||
setData((oldData) => oldData?.map((e) => (e.id === id ? { ...e, tags } : e)));
|
setData((oldData) => oldData?.map((e) => ((e.id ? e.id : e.idOverride) === id ? { ...e, tags } : e)));
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -444,7 +444,8 @@ export default function Dashboard() {
|
|||||||
initialData!
|
initialData!
|
||||||
.filter(
|
.filter(
|
||||||
(initDataPoint) =>
|
(initDataPoint) =>
|
||||||
newData!.map((dataPoint) => dataPoint.id).includes(initDataPoint.id) &&
|
newData!.filter((dataPoint) => dataPoint.id)
|
||||||
|
.map((dataPoint) => dataPoint.id).includes(initDataPoint.id) &&
|
||||||
(newData!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0].value !==
|
(newData!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0].value !==
|
||||||
initDataPoint.value ||
|
initDataPoint.value ||
|
||||||
newData!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0].key !==
|
newData!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0].key !==
|
||||||
@@ -477,7 +478,7 @@ export default function Dashboard() {
|
|||||||
const overridesToBeAdded = newOverrides!
|
const overridesToBeAdded = newOverrides!
|
||||||
.filter(
|
.filter(
|
||||||
(newDataPoint) =>
|
(newDataPoint) =>
|
||||||
!initOverrides.map((initDataPoint) => initDataPoint.id).includes(newDataPoint.id)
|
!initOverrides.map((initDataPoint) => initDataPoint.idOverride).includes(newDataPoint.idOverride)
|
||||||
)
|
)
|
||||||
.map((override) => ({
|
.map((override) => ({
|
||||||
pos: override.pos,
|
pos: override.pos,
|
||||||
@@ -496,18 +497,21 @@ export default function Dashboard() {
|
|||||||
initOverrides
|
initOverrides
|
||||||
.filter(
|
.filter(
|
||||||
(initDataPoint) =>
|
(initDataPoint) =>
|
||||||
newOverrides!.map((dataPoint) => dataPoint.id).includes(initDataPoint.id) &&
|
newOverrides!.map((dataPoint) => dataPoint.idOverride)
|
||||||
(newOverrides!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0]
|
.includes(initDataPoint.idOverride) &&
|
||||||
|
(newOverrides!.filter((dataPoint) => dataPoint.idOverride === initDataPoint.idOverride)[0]
|
||||||
.valueOverride !== initDataPoint.valueOverride ||
|
.valueOverride !== initDataPoint.valueOverride ||
|
||||||
newOverrides!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0].key !==
|
newOverrides!.filter((dataPoint) => dataPoint.idOverride === initDataPoint.idOverride)[0].key !==
|
||||||
initDataPoint.key ||
|
initDataPoint.key ||
|
||||||
newOverrides!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0]
|
(newOverrides!.filter((dataPoint) => dataPoint.idOverride === initDataPoint.idOverride)[0]
|
||||||
.comment !== initDataPoint.comment ||
|
.comment || '') !== (initDataPoint.comment || '')
|
||||||
JSON.stringify(newOverrides!.filter((dataPoint) => dataPoint.id === initDataPoint.id)[0]?.tags) !==
|
||
|
||||||
JSON.stringify(initDataPoint?.tags))
|
(JSON.stringify(newOverrides!.filter((dataPoint) => dataPoint.idOverride === initDataPoint.idOverride)[0]?.tags) || '') !==
|
||||||
|
(JSON.stringify(initDataPoint?.tags) || '')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.map((secret) => secret.id)
|
.map((secret) => secret.idOverride)
|
||||||
.includes(newDataPoint.id)
|
.includes(newDataPoint.idOverride)
|
||||||
)
|
)
|
||||||
.map((override) => ({
|
.map((override) => ({
|
||||||
pos: override.pos,
|
pos: override.pos,
|
||||||
@@ -665,7 +669,7 @@ export default function Dashboard() {
|
|||||||
idOverride: tempDecryptedSecrets.filter(
|
idOverride: tempDecryptedSecrets.filter(
|
||||||
(secret) => secret.key === key && secret.type === 'personal'
|
(secret) => secret.key === key && secret.type === 'personal'
|
||||||
)[0]?.id,
|
)[0]?.id,
|
||||||
pos: (newData?.filter(dp => !dp.id.includes('-'))?.length ?? 0) + index,
|
pos: (newData?.filter(dp => !dp.id?.includes('-'))?.length ?? 0) + index,
|
||||||
key,
|
key,
|
||||||
value: tempDecryptedSecrets.filter(
|
value: tempDecryptedSecrets.filter(
|
||||||
(secret) => secret.key === key && secret.type === 'shared'
|
(secret) => secret.key === key && secret.type === 'shared'
|
||||||
@@ -681,8 +685,8 @@ export default function Dashboard() {
|
|||||||
)[0]?.tags
|
)[0]?.tags
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setInitialData(structuredClone(newData?.filter(dp => !dp.id.includes('-')).concat(formattedNewDecryptedKeys.filter(dk => dk.id))));
|
setInitialData(structuredClone(newData?.filter(dp => !dp.id?.includes('-')).concat(formattedNewDecryptedKeys.filter(dk => dk.id))));
|
||||||
setData(structuredClone(newData?.filter(dp => !dp.id.includes('-')).concat(formattedNewDecryptedKeys.filter(dk => dk.id))))
|
setData(structuredClone(newData?.filter(dp => !dp.id?.includes('-')).concat(formattedNewDecryptedKeys.filter(dk => dk.id))))
|
||||||
} else {
|
} else {
|
||||||
setInitialData(structuredClone(newData));
|
setInitialData(structuredClone(newData));
|
||||||
}
|
}
|
||||||
@@ -882,17 +886,24 @@ export default function Dashboard() {
|
|||||||
comment: '',
|
comment: '',
|
||||||
tags: sv.tags
|
tags: sv.tags
|
||||||
}));
|
}));
|
||||||
setData(rolledBackSecrets);
|
|
||||||
|
|
||||||
// Perform the rollback globally
|
// Perform the rollback globally
|
||||||
performSecretRollback({ workspaceId, version: snapshotData.version });
|
const result = await performSecretRollback({ workspaceId, version: snapshotData.version });
|
||||||
|
if (result === undefined) {
|
||||||
setSnapshotData(undefined);
|
createNotification({
|
||||||
createNotification({
|
text: `Something went wrong during the rollback.`,
|
||||||
text: `Rollback has been performed successfully.`,
|
type: 'error'
|
||||||
type: 'success'
|
});
|
||||||
});
|
} else {
|
||||||
setHasUnsavedChanges(false);
|
setData(rolledBackSecrets);
|
||||||
|
createNotification({
|
||||||
|
text: `Successfully rolled back secrets.`,
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
setSnapshotData(undefined);
|
||||||
|
setHasUnsavedChanges(false);
|
||||||
|
togglePITSidebar(false);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
color="primary"
|
color="primary"
|
||||||
size="md"
|
size="md"
|
||||||
@@ -975,7 +986,7 @@ export default function Dashboard() {
|
|||||||
alt="infisical loading indicator"
|
alt="infisical loading indicator"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : data?.length !== 0 ? (
|
) : (data?.length !== 0 || snapshotData?.secretVersions) ? (
|
||||||
<div className="flex flex-col w-full mt-1">
|
<div className="flex flex-col w-full mt-1">
|
||||||
<div
|
<div
|
||||||
onScroll={onSecretsAreaScroll}
|
onScroll={onSecretsAreaScroll}
|
||||||
@@ -1038,7 +1049,7 @@ export default function Dashboard() {
|
|||||||
|| row.tags?.map(tag => tag.name).join(" ")?.toUpperCase().includes(searchKeys.toUpperCase())
|
|| row.tags?.map(tag => tag.name).join(" ")?.toUpperCase().includes(searchKeys.toUpperCase())
|
||||||
|| row.comment?.toUpperCase().includes(searchKeys.toUpperCase()))
|
|| row.comment?.toUpperCase().includes(searchKeys.toUpperCase()))
|
||||||
.filter((row) => !sharedToHide.includes(row.id))
|
.filter((row) => !sharedToHide.includes(row.id))
|
||||||
.filter((row) => row.value !== undefined)
|
// .filter((row) => row.value !== undefined)
|
||||||
.map((keyPair) => (
|
.map((keyPair) => (
|
||||||
<KeyPair
|
<KeyPair
|
||||||
isCapitalized={autoCapitalization}
|
isCapitalized={autoCapitalization}
|
||||||
@@ -1066,22 +1077,6 @@ export default function Dashboard() {
|
|||||||
?.sort((a, b) => a.key.localeCompare(b.key))
|
?.sort((a, b) => a.key.localeCompare(b.key))
|
||||||
.filter((row) => row.environment === selectedSnapshotEnv?.slug)
|
.filter((row) => row.environment === selectedSnapshotEnv?.slug)
|
||||||
.filter((row) => row.key.toUpperCase().includes(searchKeys.toUpperCase()))
|
.filter((row) => row.key.toUpperCase().includes(searchKeys.toUpperCase()))
|
||||||
.filter(
|
|
||||||
(row) =>
|
|
||||||
!snapshotData.secretVersions
|
|
||||||
?.filter((secretVersion) =>
|
|
||||||
snapshotData.secretVersions
|
|
||||||
?.map((item) => item.key)
|
|
||||||
.filter(
|
|
||||||
(item, index) =>
|
|
||||||
index !==
|
|
||||||
snapshotData.secretVersions?.map((i) => i.key).indexOf(item)
|
|
||||||
)
|
|
||||||
.includes(secretVersion.key)
|
|
||||||
)
|
|
||||||
?.map((item) => item.id)
|
|
||||||
.includes(row.id)
|
|
||||||
)
|
|
||||||
.map((keyPair) => (
|
.map((keyPair) => (
|
||||||
<KeyPair
|
<KeyPair
|
||||||
isCapitalized={autoCapitalization}
|
isCapitalized={autoCapitalization}
|
||||||
|
|||||||
Reference in New Issue
Block a user