mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 21:26:17 +00:00
feat: corrected dummy column in overview and main page
This commit is contained in:
@@ -1301,7 +1301,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
secretName: commit.key,
|
secretName: commit.key,
|
||||||
secretTags: commitTagIds[commit.key].map((secretTagId) => tagsGroupById[secretTagId][0].slug)
|
secretTags: commitTagIds?.[commit.key]?.map((secretTagId) => tagsGroupById[secretTagId][0].slug)
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import Ajv from "ajv";
|
import Ajv from "ajv";
|
||||||
|
|
||||||
import { ProjectVersion } from "@app/db/schemas";
|
import { ProjectVersion, TableName } from "@app/db/schemas";
|
||||||
import { decryptSymmetric128BitHexKeyUTF8, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
import { decryptSymmetric128BitHexKeyUTF8, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { TProjectPermission } from "@app/lib/types";
|
import { TProjectPermission } from "@app/lib/types";
|
||||||
@@ -106,7 +106,7 @@ export const secretRotationServiceFactory = ({
|
|||||||
if (shouldUseBridge) {
|
if (shouldUseBridge) {
|
||||||
const selectedSecrets = await secretV2BridgeDAL.find({
|
const selectedSecrets = await secretV2BridgeDAL.find({
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
$in: { id: Object.values(outputs) }
|
$in: { [`${TableName.SecretV2}.id` as "id"]: Object.values(outputs) }
|
||||||
});
|
});
|
||||||
if (selectedSecrets.length !== Object.values(outputs).length)
|
if (selectedSecrets.length !== Object.values(outputs).length)
|
||||||
throw new NotFoundError({ message: "Secrets not found" });
|
throw new NotFoundError({ message: "Secrets not found" });
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError, PureAbility, subject } from "@casl/ability";
|
import { ForbiddenError, PureAbility, subject } from "@casl/ability";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { ProjectMembershipRole, SecretsV2Schema, SecretType } from "@app/db/schemas";
|
import { ProjectMembershipRole, SecretsV2Schema, SecretType, TableName } from "@app/db/schemas";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
|
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
|
||||||
@@ -1617,7 +1617,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
const sourceSecrets = await secretDAL.find({
|
const sourceSecrets = await secretDAL.find({
|
||||||
type: SecretType.Shared,
|
type: SecretType.Shared,
|
||||||
$in: {
|
$in: {
|
||||||
id: secretIds
|
[`${TableName.SecretV2}.id` as "id"]: secretIds
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sourceSecrets.forEach((secret) => {
|
sourceSecrets.forEach((secret) => {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
} from "@app/hooks/api/dashboard/types";
|
} from "@app/hooks/api/dashboard/types";
|
||||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||||
import { mergePersonalSecrets } from "@app/hooks/api/secrets/queries";
|
import { mergePersonalSecrets } from "@app/hooks/api/secrets/queries";
|
||||||
|
import { unique } from "@app/lib/fn/array";
|
||||||
|
|
||||||
export const dashboardKeys = {
|
export const dashboardKeys = {
|
||||||
all: () => ["dashboard"] as const,
|
all: () => ["dashboard"] as const,
|
||||||
@@ -154,10 +155,24 @@ export const useGetProjectSecretsOverview = (
|
|||||||
},
|
},
|
||||||
select: useCallback((data: Awaited<ReturnType<typeof fetchProjectSecretsOverview>>) => {
|
select: useCallback((data: Awaited<ReturnType<typeof fetchProjectSecretsOverview>>) => {
|
||||||
const { secrets, ...select } = data;
|
const { secrets, ...select } = data;
|
||||||
|
const uniqueSecrets = secrets
|
||||||
|
? unique(secrets, (i) => `${i.secretKey}:${i.environment}`)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const uniqueFolders = select.folders
|
||||||
|
? unique(select.folders, (i) => `${i.name}:${i.environment}`)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const uniqueDynamicSecrets = select.dynamicSecrets
|
||||||
|
? unique(select.dynamicSecrets, (i) => `${i.name}:${i.environment}`)
|
||||||
|
: [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...select,
|
...select,
|
||||||
secrets: secrets ? mergePersonalSecrets(secrets) : undefined
|
secrets: secrets ? mergePersonalSecrets(secrets) : undefined,
|
||||||
|
totalUniqueSecretsInPage: uniqueSecrets.length,
|
||||||
|
totalUniqueDynamicSecretsInPage: uniqueDynamicSecrets.length,
|
||||||
|
totalUniqueFoldersInPage: uniqueFolders.length
|
||||||
};
|
};
|
||||||
}, []),
|
}, []),
|
||||||
keepPreviousData: true
|
keepPreviousData: true
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ export type DashboardProjectSecretsOverviewResponse = {
|
|||||||
totalFolderCount?: number;
|
totalFolderCount?: number;
|
||||||
totalDynamicSecretCount?: number;
|
totalDynamicSecretCount?: number;
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
|
totalUniqueSecretsInPage: number;
|
||||||
|
totalUniqueDynamicSecretsInPage: number;
|
||||||
|
totalUniqueFoldersInPage: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DashboardProjectSecretsDetailsResponse = {
|
export type DashboardProjectSecretsDetailsResponse = {
|
||||||
|
|||||||
@@ -13,3 +13,22 @@ export const groupBy = <T, Key extends string | number | symbol>(
|
|||||||
acc[groupId].push(item);
|
acc[groupId].push(item);
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<Key, T[]>);
|
}, {} as Record<Key, T[]>);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a list of items returns a new list with only
|
||||||
|
* unique items. Accepts an optional identity function
|
||||||
|
* to convert each item in the list to a comparable identity
|
||||||
|
* value
|
||||||
|
*/
|
||||||
|
export const unique = <T, K extends string | number | symbol>(
|
||||||
|
array: readonly T[],
|
||||||
|
toKey?: (item: T) => K
|
||||||
|
): T[] => {
|
||||||
|
const valueMap = array.reduce((acc, item) => {
|
||||||
|
const key = toKey ? toKey(item) : (item as unknown as string | number | symbol);
|
||||||
|
if (acc[key]) return acc;
|
||||||
|
acc[key] = item;
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<string | number | symbol, T>);
|
||||||
|
return Object.values(valueMap);
|
||||||
|
};
|
||||||
|
|||||||
@@ -409,6 +409,7 @@ export const SecretMainPage = () => {
|
|||||||
<SecretNoAccessListView
|
<SecretNoAccessListView
|
||||||
count={Math.max(
|
count={Math.max(
|
||||||
(page * perPage > totalCount ? totalCount % perPage : perPage) -
|
(page * perPage > totalCount ? totalCount % perPage : perPage) -
|
||||||
|
(imports?.length || 0) -
|
||||||
(folders?.length || 0) -
|
(folders?.length || 0) -
|
||||||
(secrets?.length || 0) -
|
(secrets?.length || 0) -
|
||||||
(dynamicSecrets?.length || 0),
|
(dynamicSecrets?.length || 0),
|
||||||
|
|||||||
@@ -71,7 +71,10 @@ import { SecretType, TSecretFolder } from "@app/hooks/api/types";
|
|||||||
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
||||||
import { useDynamicSecretOverview, useFolderOverview, useSecretOverview } from "@app/hooks/utils";
|
import { useDynamicSecretOverview, useFolderOverview, useSecretOverview } from "@app/hooks/utils";
|
||||||
import { SecretOverviewDynamicSecretRow } from "@app/views/SecretOverviewPage/components/SecretOverviewDynamicSecretRow";
|
import { SecretOverviewDynamicSecretRow } from "@app/views/SecretOverviewPage/components/SecretOverviewDynamicSecretRow";
|
||||||
import { SecretOverviewTableRow } from "@app/views/SecretOverviewPage/components/SecretOverviewTableRow";
|
import {
|
||||||
|
SecretNoAccessOverviewTableRow,
|
||||||
|
SecretOverviewTableRow
|
||||||
|
} from "@app/views/SecretOverviewPage/components/SecretOverviewTableRow";
|
||||||
import { SecretTableResourceCount } from "@app/views/SecretOverviewPage/components/SecretTableResourceCount";
|
import { SecretTableResourceCount } from "@app/views/SecretOverviewPage/components/SecretTableResourceCount";
|
||||||
|
|
||||||
import { FolderForm } from "../SecretMainPage/components/ActionBar/FolderForm";
|
import { FolderForm } from "../SecretMainPage/components/ActionBar/FolderForm";
|
||||||
@@ -239,7 +242,10 @@ export const SecretOverviewPage = () => {
|
|||||||
totalFolderCount,
|
totalFolderCount,
|
||||||
totalSecretCount,
|
totalSecretCount,
|
||||||
totalDynamicSecretCount,
|
totalDynamicSecretCount,
|
||||||
totalCount = 0
|
totalCount = 0,
|
||||||
|
totalUniqueFoldersInPage,
|
||||||
|
totalUniqueSecretsInPage,
|
||||||
|
totalUniqueDynamicSecretsInPage
|
||||||
} = overview ?? {};
|
} = overview ?? {};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -968,6 +974,16 @@ export const SecretOverviewPage = () => {
|
|||||||
expandableColWidth={expandableTableWidth}
|
expandableColWidth={expandableTableWidth}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
<SecretNoAccessOverviewTableRow
|
||||||
|
environments={visibleEnvs}
|
||||||
|
count={Math.max(
|
||||||
|
(page * perPage > totalCount ? totalCount % perPage : perPage) -
|
||||||
|
(totalUniqueFoldersInPage || 0) -
|
||||||
|
(totalUniqueDynamicSecretsInPage || 0) -
|
||||||
|
(totalUniqueSecretsInPage || 0),
|
||||||
|
0
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</TBody>
|
</TBody>
|
||||||
|
|||||||
Reference in New Issue
Block a user