Merge branch 'main' into ENG-2801

This commit is contained in:
x032205
2025-05-23 11:18:45 -04:00
30 changed files with 429 additions and 69 deletions
+1
View File
@@ -110,6 +110,7 @@ import { TWorkflowIntegrationServiceFactory } from "@app/services/workflow-integ
declare module "@fastify/request-context" { declare module "@fastify/request-context" {
interface RequestContextData { interface RequestContextData {
reqId: string; reqId: string;
orgId?: string;
identityAuthInfo?: { identityAuthInfo?: {
identityId: string; identityId: string;
oidc?: { oidc?: {
+13 -4
View File
@@ -95,11 +95,20 @@ const extractReqId = () => {
try { try {
return requestContext.get("reqId") || UNKNOWN_REQUEST_ID; return requestContext.get("reqId") || UNKNOWN_REQUEST_ID;
} catch (err) { } catch (err) {
// eslint-disable-next-line no-console
console.log("failed to get request context", err); console.log("failed to get request context", err);
return UNKNOWN_REQUEST_ID; return UNKNOWN_REQUEST_ID;
} }
}; };
const extractOrgId = () => {
try {
return requestContext.get("orgId");
} catch {
return "";
}
};
export const initLogger = () => { export const initLogger = () => {
const cfg = loggerConfig.parse(process.env); const cfg = loggerConfig.parse(process.env);
const targets: pino.TransportMultiOptions["targets"][number][] = [ const targets: pino.TransportMultiOptions["targets"][number][] = [
@@ -135,22 +144,22 @@ export const initLogger = () => {
const wrapLogger = (originalLogger: Logger): CustomLogger => { const wrapLogger = (originalLogger: Logger): CustomLogger => {
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
originalLogger.info = (obj: unknown, msg?: string, ...args: any[]) => { originalLogger.info = (obj: unknown, msg?: string, ...args: any[]) => {
return originalLogger.child({ reqId: extractReqId() }).info(obj, msg, ...args); return originalLogger.child({ reqId: extractReqId(), orgId: extractOrgId() }).info(obj, msg, ...args);
}; };
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
originalLogger.error = (obj: unknown, msg?: string, ...args: any[]) => { originalLogger.error = (obj: unknown, msg?: string, ...args: any[]) => {
return originalLogger.child({ reqId: extractReqId() }).error(obj, msg, ...args); return originalLogger.child({ reqId: extractReqId(), orgId: extractOrgId() }).error(obj, msg, ...args);
}; };
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
originalLogger.warn = (obj: unknown, msg?: string, ...args: any[]) => { originalLogger.warn = (obj: unknown, msg?: string, ...args: any[]) => {
return originalLogger.child({ reqId: extractReqId() }).warn(obj, msg, ...args); return originalLogger.child({ reqId: extractReqId(), orgId: extractOrgId() }).warn(obj, msg, ...args);
}; };
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
originalLogger.debug = (obj: unknown, msg?: string, ...args: any[]) => { originalLogger.debug = (obj: unknown, msg?: string, ...args: any[]) => {
return originalLogger.child({ reqId: extractReqId() }).debug(obj, msg, ...args); return originalLogger.child({ reqId: extractReqId(), orgId: extractOrgId() }).debug(obj, msg, ...args);
}; };
return originalLogger; return originalLogger;
@@ -123,6 +123,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
switch (authMode) { switch (authMode) {
case AuthMode.JWT: { case AuthMode.JWT: {
const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token); const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token);
requestContext.set("orgId", orgId);
req.auth = { req.auth = {
authMode: AuthMode.JWT, authMode: AuthMode.JWT,
user, user,
@@ -138,6 +139,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
case AuthMode.IDENTITY_ACCESS_TOKEN: { case AuthMode.IDENTITY_ACCESS_TOKEN: {
const identity = await server.services.identityAccessToken.fnValidateIdentityAccessToken(token, req.realIp); const identity = await server.services.identityAccessToken.fnValidateIdentityAccessToken(token, req.realIp);
const serverCfg = await getServerCfg(); const serverCfg = await getServerCfg();
requestContext.set("orgId", identity.orgId);
req.auth = { req.auth = {
authMode: AuthMode.IDENTITY_ACCESS_TOKEN, authMode: AuthMode.IDENTITY_ACCESS_TOKEN,
actor, actor,
@@ -157,6 +159,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
} }
case AuthMode.SERVICE_TOKEN: { case AuthMode.SERVICE_TOKEN: {
const serviceToken = await server.services.serviceToken.fnValidateServiceToken(token); const serviceToken = await server.services.serviceToken.fnValidateServiceToken(token);
requestContext.set("orgId", serviceToken.orgId);
req.auth = { req.auth = {
orgId: serviceToken.orgId, orgId: serviceToken.orgId,
authMode: AuthMode.SERVICE_TOKEN as const, authMode: AuthMode.SERVICE_TOKEN as const,
@@ -181,6 +184,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
} }
case AuthMode.SCIM_TOKEN: { case AuthMode.SCIM_TOKEN: {
const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token); const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token);
requestContext.set("orgId", orgId);
req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null }; req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null };
break; break;
} }
@@ -51,6 +51,7 @@ type Props = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange" | "val
isVisible?: boolean; isVisible?: boolean;
isReadOnly?: boolean; isReadOnly?: boolean;
isDisabled?: boolean; isDisabled?: boolean;
canEditButNotView?: boolean;
secretPath?: string; secretPath?: string;
environment?: string; environment?: string;
containerClassName?: string; containerClassName?: string;
@@ -70,6 +71,7 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
containerClassName, containerClassName,
secretPath: propSecretPath, secretPath: propSecretPath,
environment: propEnvironment, environment: propEnvironment,
canEditButNotView,
...props ...props
}, },
ref ref
@@ -273,6 +275,7 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
<Popover.Trigger asChild> <Popover.Trigger asChild>
<SecretInput <SecretInput
{...props} {...props}
canEditButNotView={canEditButNotView}
ref={handleRef} ref={handleRef}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
value={value} value={value}
@@ -3,6 +3,7 @@ import { forwardRef, TextareaHTMLAttributes } from "react";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { useToggle } from "@app/hooks"; import { useToggle } from "@app/hooks";
import { HIDDEN_SECRET_VALUE } from "@app/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem";
const REGEX = /(\${([a-zA-Z0-9-_.]+)})/g; const REGEX = /(\${([a-zA-Z0-9-_.]+)})/g;
const replaceContentWithDot = (str: string) => { const replaceContentWithDot = (str: string) => {
@@ -51,6 +52,7 @@ type Props = TextareaHTMLAttributes<HTMLTextAreaElement> & {
isReadOnly?: boolean; isReadOnly?: boolean;
isDisabled?: boolean; isDisabled?: boolean;
containerClassName?: string; containerClassName?: string;
canEditButNotView?: boolean;
}; };
const commonClassName = "font-mono text-sm caret-white border-none outline-none w-full break-all"; const commonClassName = "font-mono text-sm caret-white border-none outline-none w-full break-all";
@@ -66,6 +68,7 @@ export const SecretInput = forwardRef<HTMLTextAreaElement, Props>(
isDisabled, isDisabled,
isReadOnly, isReadOnly,
onFocus, onFocus,
canEditButNotView,
...props ...props
}, },
ref ref
@@ -93,7 +96,15 @@ export const SecretInput = forwardRef<HTMLTextAreaElement, Props>(
onFocus={(evt) => { onFocus={(evt) => {
onFocus?.(evt); onFocus?.(evt);
setIsSecretFocused.on(); setIsSecretFocused.on();
evt.currentTarget.select(); if (canEditButNotView && value === HIDDEN_SECRET_VALUE) {
evt.currentTarget.select();
}
}}
onMouseDown={(e) => {
if (canEditButNotView && value === HIDDEN_SECRET_VALUE) {
e.preventDefault();
e.currentTarget.select();
}
}} }}
disabled={isDisabled} disabled={isDisabled}
spellCheck={false} spellCheck={false}
@@ -0,0 +1,73 @@
const TABLE_PREFERENCES_KEY = "userTablePreferences";
export enum PreferenceKey {
PerPage = "perPage"
}
interface TableSpecificPreferences {
[preferenceKey: string]: any;
}
interface UserTablePreferences {
[tableName: string]: TableSpecificPreferences;
}
// Retrieves all table preferences from localStorage
const getAllTablePreferences = (): UserTablePreferences => {
try {
const preferencesString = localStorage.getItem(TABLE_PREFERENCES_KEY);
if (preferencesString) {
return JSON.parse(preferencesString) as UserTablePreferences;
}
} catch (error) {
console.error("Error reading user table preferences from localStorage:", error);
}
return {};
};
// Saves all table preferences to localStorage
const saveAllTablePreferences = (preferences: UserTablePreferences): void => {
try {
localStorage.setItem(TABLE_PREFERENCES_KEY, JSON.stringify(preferences));
} catch (error) {
console.error("Error saving user table preferences to localStorage:", error);
}
};
// Retrieves a specific preference for a given table
export const getUserTablePreference = <T>(
tableName: string,
preferenceKey: PreferenceKey,
defaultValue: T
): T => {
const preferences = getAllTablePreferences();
if (
preferences &&
typeof preferences === "object" &&
tableName in preferences &&
preferenceKey in preferences[tableName]
) {
const value = preferences[tableName][preferenceKey];
if (value !== undefined && value !== null) {
return value as T;
}
}
return defaultValue;
};
// Sets a specific preference for a given table and saves it to localStorage
export const setUserTablePreference = (
tableName: string,
preferenceKey: PreferenceKey,
value: any
): void => {
const preferences = getAllTablePreferences();
if (!preferences[tableName]) {
preferences[tableName] = {};
}
preferences[tableName][preferenceKey] = value;
saveAllTablePreferences(preferences);
};
@@ -70,10 +70,25 @@ export const SelectOrganizationSection = () => {
const handleSelectOrganization = useCallback( const handleSelectOrganization = useCallback(
async (organization: Organization) => { async (organization: Organization) => {
const canBypassOrgAuth = const isUserOrgAdmin = organization.userRole === OrgMembershipRole.Admin;
organization.bypassOrgAuthEnabled && const canBypassOrgAuth = organization.bypassOrgAuthEnabled && isUserOrgAdmin && isAdminLogin;
organization.userRole === OrgMembershipRole.Admin &&
isAdminLogin; if (isAdminLogin) {
if (!organization.bypassOrgAuthEnabled) {
createNotification({
text: "This organization does not have bypass org auth enabled",
type: "error"
});
return;
}
if (!isUserOrgAdmin) {
createNotification({
text: "Only organization admins can bypass org auth",
type: "error"
});
return;
}
}
if (organization.authEnforced && !canBypassOrgAuth) { if (organization.authEnforced && !canBypassOrgAuth) {
// org has an org-level auth method enabled (e.g. SAML) // org has an org-level auth method enabled (e.g. SAML)
@@ -43,6 +43,11 @@ import {
useSubscription, useSubscription,
useWorkspace useWorkspace
} from "@app/context"; } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
import { useGetKmipClientsByProjectId } from "@app/hooks/api/kmip"; import { useGetKmipClientsByProjectId } from "@app/hooks/api/kmip";
@@ -71,7 +76,14 @@ export const KmipClientTable = () => {
perPage, perPage,
page, page,
setPerPage setPerPage
} = usePagination(KmipClientOrderBy.Name); } = usePagination(KmipClientOrderBy.Name, {
initPerPage: getUserTablePreference("kmipClientTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("kmipClientTable", PreferenceKey.PerPage, newPerPage);
};
const { data, isPending, isFetching } = useGetKmipClientsByProjectId({ const { data, isPending, isFetching } = useGetKmipClientsByProjectId({
projectId, projectId,
@@ -290,7 +302,7 @@ export const KmipClientTable = () => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={(newPage) => setPage(newPage)} onChangePage={(newPage) => setPage(newPage)}
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && kmipClients.length === 0 && ( {!isPending && kmipClients.length === 0 && (
@@ -53,6 +53,11 @@ import {
useWorkspace useWorkspace
} from "@app/context"; } from "@app/context";
import { kmsKeyUsageOptions } from "@app/helpers/kms"; import { kmsKeyUsageOptions } from "@app/helpers/kms";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, usePopUp, useResetPageHelper, useTimedReset } from "@app/hooks"; import { usePagination, usePopUp, useResetPageHelper, useTimedReset } from "@app/hooks";
import { useGetCmeksByProjectId, useUpdateCmek } from "@app/hooks/api/cmeks"; import { useGetCmeksByProjectId, useUpdateCmek } from "@app/hooks/api/cmeks";
import { CmekOrderBy, KmsKeyUsage, TCmek } from "@app/hooks/api/cmeks/types"; import { CmekOrderBy, KmsKeyUsage, TCmek } from "@app/hooks/api/cmeks/types";
@@ -100,7 +105,14 @@ export const CmekTable = () => {
perPage, perPage,
page, page,
setPerPage setPerPage
} = usePagination(CmekOrderBy.Name); } = usePagination(CmekOrderBy.Name, {
initPerPage: getUserTablePreference("cmekClientTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("cmekClientTable", PreferenceKey.PerPage, newPerPage);
};
const { data, isPending, isFetching } = useGetCmeksByProjectId({ const { data, isPending, isFetching } = useGetCmeksByProjectId({
projectId, projectId,
@@ -508,7 +520,7 @@ export const CmekTable = () => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={(newPage) => setPage(newPage)} onChangePage={(newPage) => setPage(newPage)}
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && keys.length === 0 && ( {!isPending && keys.length === 0 && (
@@ -34,6 +34,11 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context"; import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetOrganizationGroups, useGetOrgRoles, useUpdateGroup } from "@app/hooks/api"; import { useGetOrganizationGroups, useGetOrgRoles, useUpdateGroup } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -103,7 +108,14 @@ export const OrgGroupsTable = ({ handlePopUpOpen }: Props) => {
setOrderBy, setOrderBy,
setOrderDirection, setOrderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination<GroupsOrderBy>(GroupsOrderBy.Name, { initPerPage: 20 }); } = usePagination<GroupsOrderBy>(GroupsOrderBy.Name, {
initPerPage: getUserTablePreference("orgGroupsTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("orgGroupsTable", PreferenceKey.PerPage, newPerPage);
};
const filteredGroups = useMemo(() => { const filteredGroups = useMemo(() => {
const filtered = search const filtered = search
@@ -376,7 +388,7 @@ export const OrgGroupsTable = ({ handlePopUpOpen }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredGroups?.length && ( {!isPending && !filteredGroups?.length && (
@@ -42,6 +42,11 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context"; import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetOrgRoles, useSearchIdentities, useUpdateIdentity } from "@app/hooks/api"; import { useGetOrgRoles, useSearchIdentities, useUpdateIdentity } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -76,7 +81,15 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
perPage, perPage,
page, page,
setPerPage setPerPage
} = usePagination<OrgIdentityOrderBy>(OrgIdentityOrderBy.Name); } = usePagination<OrgIdentityOrderBy>(OrgIdentityOrderBy.Name, {
initPerPage: getUserTablePreference("identityTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("identityTable", PreferenceKey.PerPage, newPerPage);
};
const [filteredRoles, setFilteredRoles] = useState<string[]>([]); const [filteredRoles, setFilteredRoles] = useState<string[]>([]);
const organizationId = currentOrg?.id || ""; const organizationId = currentOrg?.id || "";
@@ -379,7 +392,7 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={(newPage) => setPage(newPage)} onChangePage={(newPage) => setPage(newPage)}
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && data && data?.identities.length === 0 && ( {!isPending && data && data?.identities.length === 0 && (
@@ -42,6 +42,11 @@ import {
useSubscription, useSubscription,
useUser useUser
} from "@app/context"; } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { import {
useFetchServerStatus, useFetchServerStatus,
@@ -170,7 +175,14 @@ export const OrgMembersTable = ({ handlePopUpOpen, setCompleteInviteLinks }: Pro
setOrderBy, setOrderBy,
setOrderDirection, setOrderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination<OrgMembersOrderBy>(OrgMembersOrderBy.Name, { initPerPage: 20 }); } = usePagination<OrgMembersOrderBy>(OrgMembersOrderBy.Name, {
initPerPage: getUserTablePreference("orgMembersTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("orgMembersTable", PreferenceKey.PerPage, newPerPage);
};
const filteredUsers = useMemo( const filteredUsers = useMemo(
() => () =>
@@ -513,7 +525,7 @@ export const OrgMembersTable = ({ handlePopUpOpen, setCompleteInviteLinks }: Pro
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isMembersLoading && !filteredUsers?.length && ( {!isMembersLoading && !filteredUsers?.length && (
@@ -30,6 +30,11 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections"; import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { TAppConnection, useListAppConnections } from "@app/hooks/api/appConnections"; import { TAppConnection, useListAppConnections } from "@app/hooks/api/appConnections";
import { AppConnection } from "@app/hooks/api/appConnections/enums"; import { AppConnection } from "@app/hooks/api/appConnections/enums";
@@ -76,7 +81,14 @@ export const AppConnectionsTable = () => {
orderBy, orderBy,
setOrderDirection, setOrderDirection,
setOrderBy setOrderBy
} = usePagination<AppConnectionsOrderBy>(AppConnectionsOrderBy.App, { initPerPage: 20 }); } = usePagination<AppConnectionsOrderBy>(AppConnectionsOrderBy.App, {
initPerPage: getUserTablePreference("appConnectionsTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("appConnectionsTable", PreferenceKey.PerPage, newPerPage);
};
const filteredAppConnections = useMemo( const filteredAppConnections = useMemo(
() => () =>
@@ -282,7 +294,7 @@ export const AppConnectionsTable = () => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredAppConnections?.length && ( {!isPending && !filteredAppConnections?.length && (
@@ -25,6 +25,11 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context"; import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useListGroupUsers, useOidcManageGroupMembershipsEnabled } from "@app/hooks/api"; import { useListGroupUsers, useOidcManageGroupMembershipsEnabled } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -57,7 +62,14 @@ export const GroupMembersTable = ({ groupId, groupSlug, handlePopUpOpen }: Props
offset, offset,
orderDirection, orderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination(GroupMembersOrderBy.Name, { initPerPage: 10 }); } = usePagination(GroupMembersOrderBy.Name, {
initPerPage: getUserTablePreference("groupMembersTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("groupMembersTable", PreferenceKey.PerPage, newPerPage);
};
const { currentOrg } = useOrganization(); const { currentOrg } = useOrganization();
@@ -163,7 +175,7 @@ export const GroupMembersTable = ({ groupId, groupSlug, handlePopUpOpen }: Props
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredGroupMemberships?.length && ( {!isPending && !filteredGroupMemberships?.length && (
@@ -21,6 +21,11 @@ import {
THead, THead,
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetIdentityProjectMemberships } from "@app/hooks/api"; import { useGetIdentityProjectMemberships } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -53,7 +58,14 @@ export const IdentityProjectsTable = ({ identityId, handlePopUpOpen }: Props) =>
offset, offset,
orderDirection, orderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination(IdentityProjectsOrderBy.Name, { initPerPage: 10 }); } = usePagination(IdentityProjectsOrderBy.Name, {
initPerPage: getUserTablePreference("identityProjectsTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("identityProjectsTable", PreferenceKey.PerPage, newPerPage);
};
const filteredProjectMemberships = useMemo( const filteredProjectMemberships = useMemo(
() => () =>
@@ -132,7 +144,7 @@ export const IdentityProjectsTable = ({ identityId, handlePopUpOpen }: Props) =>
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredProjectMemberships?.length && ( {!isPending && !filteredProjectMemberships?.length && (
@@ -28,6 +28,11 @@ import {
} from "@app/components/v2"; } from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
import { getProjectHomePage } from "@app/helpers/project"; import { getProjectHomePage } from "@app/helpers/project";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { useRequestProjectAccess, useSearchProjects } from "@app/hooks/api"; import { useRequestProjectAccess, useSearchProjects } from "@app/hooks/api";
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types"; import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
@@ -104,7 +109,15 @@ export const AllProjectView = ({
limit, limit,
toggleOrderDirection, toggleOrderDirection,
orderDirection orderDirection
} = usePagination("name", { initPerPage: 50 }); } = usePagination("name", {
initPerPage: getUserTablePreference("allProjectsTable", PreferenceKey.PerPage, 50)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("allProjectsTable", PreferenceKey.PerPage, newPerPage);
};
const { popUp, handlePopUpToggle, handlePopUpOpen } = usePopUp([ const { popUp, handlePopUpToggle, handlePopUpOpen } = usePopUp([
"requestAccessConfirmation" "requestAccessConfirmation"
] as const); ] as const);
@@ -274,7 +287,7 @@ export const AllProjectView = ({
count={searchedProjects?.totalCount || 0} count={searchedProjects?.totalCount || 0}
page={page} page={page}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isProjectLoading && !searchedProjects?.totalCount && ( {!isProjectLoading && !searchedProjects?.totalCount && (
@@ -19,6 +19,11 @@ import { OrgPermissionCan } from "@app/components/permissions";
import { Button, IconButton, Input, Pagination, Skeleton, Tooltip } from "@app/components/v2"; import { Button, IconButton, Input, Pagination, Skeleton, Tooltip } from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context"; import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { getProjectHomePage } from "@app/helpers/project"; import { getProjectHomePage } from "@app/helpers/project";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetUserWorkspaces } from "@app/hooks/api"; import { useGetUserWorkspaces } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -63,7 +68,15 @@ export const MyProjectView = ({
limit, limit,
toggleOrderDirection, toggleOrderDirection,
orderDirection orderDirection
} = usePagination(ProjectOrderBy.Name, { initPerPage: 24 }); } = usePagination(ProjectOrderBy.Name, {
initPerPage: getUserTablePreference("myProjectsTable", PreferenceKey.PerPage, 24)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("myProjectsTable", PreferenceKey.PerPage, newPerPage);
};
const { data: projectFavorites, isPending: isProjectFavoritesLoading } = const { data: projectFavorites, isPending: isProjectFavoritesLoading } =
useGetUserProjectFavorites(currentOrg?.id); useGetUserProjectFavorites(currentOrg?.id);
@@ -415,7 +428,7 @@ export const MyProjectView = ({
count={filteredWorkspaces.length} count={filteredWorkspaces.length}
page={page} page={page}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{isWorkspaceEmpty && ( {isWorkspaceEmpty && (
@@ -13,6 +13,11 @@ import {
useOrganization, useOrganization,
useServerConfig useServerConfig
} from "@app/context"; } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { withPermission } from "@app/hoc"; import { withPermission } from "@app/hoc";
import { usePagination, usePopUp } from "@app/hooks"; import { usePagination, usePopUp } from "@app/hooks";
import { import {
@@ -28,8 +33,6 @@ import { SecretScanningFilter } from "./components/SecretScanningFilters";
import { SecretScanningFilterFormData, secretScanningFilterFormSchema } from "./components/types"; import { SecretScanningFilterFormData, secretScanningFilterFormSchema } from "./components/types";
import { SecretScanningLogsTable } from "./components"; import { SecretScanningLogsTable } from "./components";
const PER_PAGE_INIT = 25;
export const SecretScanningPage = withPermission( export const SecretScanningPage = withPermission(
() => { () => {
const queryParams = useSearch({ const queryParams = useSearch({
@@ -49,9 +52,14 @@ export const SecretScanningPage = withPermission(
const { offset, limit, orderBy, setPage, perPage, page, setPerPage } = usePagination( const { offset, limit, orderBy, setPage, perPage, page, setPerPage } = usePagination(
SecretScanningOrderBy.CreatedAt, SecretScanningOrderBy.CreatedAt,
{ initPerPage: PER_PAGE_INIT } { initPerPage: getUserTablePreference("secretScanningTable", PreferenceKey.PerPage, 20) }
); );
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("secretScanningTable", PreferenceKey.PerPage, newPerPage);
};
const repositoryNames = watch("repositoryNames"); const repositoryNames = watch("repositoryNames");
const resolvedStatus = watch("resolved"); const resolvedStatus = watch("resolved");
@@ -180,7 +188,7 @@ export const SecretScanningPage = withPermission(
</div> </div>
)} )}
</div> </div>
<div className="mt-8 space-y-3"> <div className="mt-8 space-y-2">
{integrationEnabled && ( {integrationEnabled && (
<div className="flex w-full items-center justify-end"> <div className="flex w-full items-center justify-end">
<SecretScanningFilter <SecretScanningFilter
@@ -191,18 +199,16 @@ export const SecretScanningPage = withPermission(
</div> </div>
)} )}
<SecretScanningLogsTable gitRisks={risksData?.risks} isPending={isPending} /> <SecretScanningLogsTable gitRisks={risksData?.risks} isPending={isPending} />
{!isPending && {!isPending && risksData?.totalCount !== undefined && risksData.totalCount >= 10 && (
risksData?.totalCount !== undefined && <Pagination
risksData.totalCount >= PER_PAGE_INIT && ( className="rounded-md"
<Pagination count={risksData.totalCount}
className="rounded-md" page={page}
count={risksData.totalCount} perPage={perPage}
page={page} onChangePage={(newPage) => setPage(newPage)}
perPage={perPage} onChangePerPage={handlePerPageChange}
onChangePage={(newPage) => setPage(newPage)} />
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} )}
/>
)}
</div> </div>
</div> </div>
</div> </div>
@@ -20,6 +20,11 @@ import {
THead, THead,
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
import { OrgUser } from "@app/hooks/api/types"; import { OrgUser } from "@app/hooks/api/types";
@@ -52,7 +57,14 @@ export const UserGroupsTable = ({ handlePopUpOpen, orgMembership }: Props) => {
offset, offset,
orderDirection, orderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination(UserGroupsOrderBy.Name, { initPerPage: 10 }); } = usePagination(UserGroupsOrderBy.Name, {
initPerPage: getUserTablePreference("userGroupsTable", PreferenceKey.PerPage, 10)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("userGroupsTable", PreferenceKey.PerPage, newPerPage);
};
const filteredGroupMemberships = useMemo( const filteredGroupMemberships = useMemo(
() => () =>
@@ -119,7 +131,7 @@ export const UserGroupsTable = ({ handlePopUpOpen, orgMembership }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredGroupMemberships?.length && ( {!isPending && !filteredGroupMemberships?.length && (
@@ -22,6 +22,11 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { useOrganization } from "@app/context"; import { useOrganization } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetOrgMembershipProjectMemberships } from "@app/hooks/api"; import { useGetOrgMembershipProjectMemberships } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -54,7 +59,14 @@ export const UserProjectsTable = ({ membershipId, handlePopUpOpen }: Props) => {
offset, offset,
orderDirection, orderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination(UserProjectsOrderBy.Name, { initPerPage: 10 }); } = usePagination(UserProjectsOrderBy.Name, {
initPerPage: getUserTablePreference("userProjectsTable", PreferenceKey.PerPage, 10)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("userProjectsTable", PreferenceKey.PerPage, newPerPage);
};
const { data: projectMemberships = [], isPending } = useGetOrgMembershipProjectMemberships( const { data: projectMemberships = [], isPending } = useGetOrgMembershipProjectMemberships(
orgId, orgId,
@@ -136,7 +148,7 @@ export const UserProjectsTable = ({ membershipId, handlePopUpOpen }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredProjectMemberships?.length && ( {!isPending && !filteredProjectMemberships?.length && (
@@ -27,6 +27,11 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useListWorkspaceGroups } from "@app/hooks/api"; import { useListWorkspaceGroups } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -62,7 +67,14 @@ export const GroupTable = ({ handlePopUpOpen }: Props) => {
orderDirection, orderDirection,
orderBy, orderBy,
toggleOrderDirection toggleOrderDirection
} = usePagination(GroupsOrderBy.Name, { initPerPage: 20 }); } = usePagination(GroupsOrderBy.Name, {
initPerPage: getUserTablePreference("projectGroupsTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("projectGroupsTable", PreferenceKey.PerPage, newPerPage);
};
const { data: groupMemberships = [], isPending } = useListWorkspaceGroups( const { data: groupMemberships = [], isPending } = useListWorkspaceGroups(
currentWorkspace?.id || "" currentWorkspace?.id || ""
@@ -183,7 +195,7 @@ export const GroupTable = ({ handlePopUpOpen }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredGroupMemberships?.length && ( {!isPending && !filteredGroupMemberships?.length && (
@@ -42,6 +42,11 @@ import {
} from "@app/components/v2"; } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { formatProjectRoleName } from "@app/helpers/roles"; import { formatProjectRoleName } from "@app/helpers/roles";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { withProjectPermission } from "@app/hoc"; import { withProjectPermission } from "@app/hoc";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useDeleteIdentityFromWorkspace, useGetWorkspaceIdentityMemberships } from "@app/hooks/api"; import { useDeleteIdentityFromWorkspace, useGetWorkspaceIdentityMemberships } from "@app/hooks/api";
@@ -72,7 +77,14 @@ export const IdentityTab = withProjectPermission(
perPage, perPage,
page, page,
setPerPage setPerPage
} = usePagination(ProjectIdentityOrderBy.Name); } = usePagination(ProjectIdentityOrderBy.Name, {
initPerPage: getUserTablePreference("projectIdentityTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("projectIdentityTable", PreferenceKey.PerPage, newPerPage);
};
const workspaceId = currentWorkspace?.id ?? ""; const workspaceId = currentWorkspace?.id ?? "";
@@ -403,7 +415,7 @@ export const IdentityTab = withProjectPermission(
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={(newPage) => setPage(newPage)} onChangePage={(newPage) => setPage(newPage)}
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && data && data?.identityMemberships.length === 0 && ( {!isPending && data && data?.identityMemberships.length === 0 && (
@@ -51,6 +51,11 @@ import {
useWorkspace useWorkspace
} from "@app/context"; } from "@app/context";
import { formatProjectRoleName } from "@app/helpers/roles"; import { formatProjectRoleName } from "@app/helpers/roles";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetProjectRoles, useGetWorkspaceUsers } from "@app/hooks/api"; import { useGetProjectRoles, useGetWorkspaceUsers } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -101,12 +106,12 @@ export const MembersTable = ({ handlePopUpOpen }: Props) => {
setOrderDirection, setOrderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination<MembersOrderBy>(MembersOrderBy.Name, { } = usePagination<MembersOrderBy>(MembersOrderBy.Name, {
initPerPage: parseInt(localStorage.getItem("PROJECT_MEMBERS_TABLE_PER_PAGE") || "20", 10) initPerPage: getUserTablePreference("projectMembersTable", PreferenceKey.PerPage, 20)
}); });
const handlePerPageChange = (newPerPage: number) => { const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage); setPerPage(newPerPage);
localStorage.setItem("PROJECT_MEMBERS_TABLE_PER_PAGE", newPerPage.toString()); setUserTablePreference("projectMembersTable", PreferenceKey.PerPage, newPerPage);
}; };
const { data: members = [], isPending: isMembersLoading } = useGetWorkspaceUsers( const { data: members = [], isPending: isMembersLoading } = useGetWorkspaceUsers(
@@ -32,6 +32,11 @@ import {
Tooltip, Tooltip,
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
import { useSyncIntegration } from "@app/hooks/api/integrations/queries"; import { useSyncIntegration } from "@app/hooks/api/integrations/queries";
@@ -110,7 +115,14 @@ export const IntegrationsTable = ({
orderBy, orderBy,
setOrderDirection, setOrderDirection,
setOrderBy setOrderBy
} = usePagination<IntegrationsOrderBy>(IntegrationsOrderBy.App, { initPerPage: 20 }); } = usePagination<IntegrationsOrderBy>(IntegrationsOrderBy.App, {
initPerPage: getUserTablePreference("integrationsTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("integrationsTable", PreferenceKey.PerPage, newPerPage);
};
useEffect(() => { useEffect(() => {
if (integrations?.some((integration) => integration.isSynced === false)) if (integrations?.some((integration) => integration.isSynced === false))
@@ -437,7 +449,7 @@ export const IntegrationsTable = ({
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isLoading && !filteredIntegrations?.length && ( {!isLoading && !filteredIntegrations?.length && (
@@ -38,6 +38,11 @@ import {
} from "@app/components/v2"; } from "@app/components/v2";
import { useWorkspace } from "@app/context"; import { useWorkspace } from "@app/context";
import { SECRET_SYNC_MAP } from "@app/helpers/secretSyncs"; import { SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
import { import {
@@ -119,7 +124,14 @@ export const SecretSyncsTable = ({ secretSyncs }: Props) => {
orderBy, orderBy,
setOrderDirection, setOrderDirection,
setOrderBy setOrderBy
} = usePagination<SecretSyncsOrderBy>(SecretSyncsOrderBy.Name, { initPerPage: 20 }); } = usePagination<SecretSyncsOrderBy>(SecretSyncsOrderBy.Name, {
initPerPage: getUserTablePreference("secretSyncTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("secretSyncTable", PreferenceKey.PerPage, newPerPage);
};
const filteredSecretSyncs = useMemo( const filteredSecretSyncs = useMemo(
() => () =>
@@ -465,7 +477,7 @@ export const SecretSyncsTable = ({ secretSyncs }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!filteredSecretSyncs?.length && ( {!filteredSecretSyncs?.length && (
@@ -64,6 +64,11 @@ import {
useWorkspace useWorkspace
} from "@app/context"; } from "@app/context";
import { ProjectPermissionSecretRotationActions } from "@app/context/ProjectPermissionContext/types"; import { ProjectPermissionSecretRotationActions } from "@app/context/ProjectPermissionContext/types";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { import {
useCreateFolder, useCreateFolder,
@@ -180,7 +185,14 @@ export const OverviewPage = () => {
page, page,
setPerPage, setPerPage,
orderBy orderBy
} = usePagination<DashboardSecretsOrderBy>(DashboardSecretsOrderBy.Name); } = usePagination<DashboardSecretsOrderBy>(DashboardSecretsOrderBy.Name, {
initPerPage: getUserTablePreference("secretOverviewTable", PreferenceKey.PerPage, 100)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("secretOverviewTable", PreferenceKey.PerPage, newPerPage);
};
const resetSelectedEntries = useCallback(() => { const resetSelectedEntries = useCallback(() => {
setSelectedEntries({ setSelectedEntries({
@@ -1416,7 +1428,7 @@ export const OverviewPage = () => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={(newPage) => setPage(newPage)} onChangePage={(newPage) => setPage(newPage)}
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} onChangePerPage={handlePerPageChange}
/> />
)} )}
</div> </div>
@@ -232,6 +232,7 @@ export const SecretEditRow = ({
environment={environment} environment={environment}
isImport={isImportedSecret} isImport={isImportedSecret}
defaultValue={secretValueHidden ? "" : undefined} defaultValue={secretValueHidden ? "" : undefined}
canEditButNotView={secretValueHidden && !isOverride}
/> />
)} )}
/> />
@@ -29,6 +29,11 @@ import {
ProjectPermissionSecretActions, ProjectPermissionSecretActions,
ProjectPermissionSecretRotationActions ProjectPermissionSecretRotationActions
} from "@app/context/ProjectPermissionContext/types"; } from "@app/context/ProjectPermissionContext/types";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { import {
useGetImportedSecretsSingleEnv, useGetImportedSecretsSingleEnv,
@@ -98,7 +103,14 @@ const Page = () => {
page, page,
setPerPage, setPerPage,
orderBy orderBy
} = usePagination<DashboardSecretsOrderBy>(DashboardSecretsOrderBy.Name); } = usePagination<DashboardSecretsOrderBy>(DashboardSecretsOrderBy.Name, {
initPerPage: getUserTablePreference("secretDashboardTable", PreferenceKey.PerPage, 100)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("secretDashboardTable", PreferenceKey.PerPage, newPerPage);
};
const [snapshotId, setSnapshotId] = useState<string | null>(null); const [snapshotId, setSnapshotId] = useState<string | null>(null);
const isRollbackMode = Boolean(snapshotId); const isRollbackMode = Boolean(snapshotId);
@@ -558,7 +570,7 @@ const Page = () => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={(newPage) => setPage(newPage)} onChangePage={(newPage) => setPage(newPage)}
onChangePerPage={(newPerPage) => setPerPage(newPerPage)} onChangePerPage={handlePerPageChange}
/> />
)} )}
<Modal <Modal
@@ -58,7 +58,7 @@ import {
} from "./SecretListView.utils"; } from "./SecretListView.utils";
import { CollapsibleSecretImports } from "./CollapsibleSecretImports"; import { CollapsibleSecretImports } from "./CollapsibleSecretImports";
const hiddenValue = "******"; export const HIDDEN_SECRET_VALUE = "******";
type Props = { type Props = {
secret: SecretV3RawSanitized; secret: SecretV3RawSanitized;
@@ -122,7 +122,7 @@ export const SecretItem = memo(
const getDefaultValue = () => { const getDefaultValue = () => {
if (secret.secretValueHidden) { if (secret.secretValueHidden) {
return canEditSecretValue ? hiddenValue : ""; return canEditSecretValue ? HIDDEN_SECRET_VALUE : "";
} }
return secret.valueOverride || secret.value || ""; return secret.valueOverride || secret.value || "";
}; };
@@ -366,10 +366,11 @@ export const SecretItem = memo(
isReadOnly={isReadOnly || isRotatedSecret} isReadOnly={isReadOnly || isRotatedSecret}
key="secret-value" key="secret-value"
isVisible={isVisible && !secretValueHidden} isVisible={isVisible && !secretValueHidden}
canEditButNotView={secretValueHidden && !isOverriden}
environment={environment} environment={environment}
secretPath={secretPath} secretPath={secretPath}
{...field} {...field}
defaultValue={secretValueHidden ? hiddenValue : undefined} defaultValue={secretValueHidden ? HIDDEN_SECRET_VALUE : undefined}
containerClassName="py-1.5 rounded-md transition-all" containerClassName="py-1.5 rounded-md transition-all"
/> />
)} )}
@@ -25,9 +25,14 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import {
getUserTablePreference,
PreferenceKey,
setUserTablePreference
} from "@app/helpers/userTablePreferences";
import { usePagination, useResetPageHelper } from "@app/hooks"; import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetWsTags } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types"; import { OrderByDirection } from "@app/hooks/api/generic/types";
import { useGetWsTags } from "@app/hooks/api/tags";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
type Props = { type Props = {
@@ -61,7 +66,14 @@ export const SecretTagsTable = ({ handlePopUpOpen }: Props) => {
offset, offset,
orderDirection, orderDirection,
toggleOrderDirection toggleOrderDirection
} = usePagination(TagsOrderBy.Slug, { initPerPage: 10 }); } = usePagination(TagsOrderBy.Slug, {
initPerPage: getUserTablePreference("secretTagsTable", PreferenceKey.PerPage, 20)
});
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
setUserTablePreference("secretTagsTable", PreferenceKey.PerPage, newPerPage);
};
const filteredTags = useMemo( const filteredTags = useMemo(
() => () =>
@@ -151,7 +163,7 @@ export const SecretTagsTable = ({ handlePopUpOpen }: Props) => {
page={page} page={page}
perPage={perPage} perPage={perPage}
onChangePage={setPage} onChangePage={setPage}
onChangePerPage={setPerPage} onChangePerPage={handlePerPageChange}
/> />
)} )}
{!isPending && !filteredTags?.length && ( {!isPending && !filteredTags?.length && (