mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 05:19:49 +00:00
address feedback suggestions
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
export enum OrderByDirection {
|
||||
ASC = "asc",
|
||||
DESC = "desc"
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useMutation, useQuery, useQueryClient, UseQueryOptions } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
|
||||
import { TGroupOrgMembership } from "../groups/types";
|
||||
import {
|
||||
@@ -8,6 +9,7 @@ import {
|
||||
Invoice,
|
||||
License,
|
||||
Organization,
|
||||
OrgIdentityOrderBy,
|
||||
OrgPlanTable,
|
||||
PlanBillingInfo,
|
||||
PmtMethod,
|
||||
@@ -372,9 +374,9 @@ export const useGetIdentityMembershipOrgs = (
|
||||
organizationId,
|
||||
offset = 0,
|
||||
limit = 100,
|
||||
orderBy = "name",
|
||||
direction = "asc",
|
||||
textFilter = ""
|
||||
orderBy = OrgIdentityOrderBy.Name,
|
||||
orderDirection = OrderByDirection.ASC,
|
||||
search = ""
|
||||
}: TListOrgIdentitiesDTO,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
@@ -390,8 +392,8 @@ export const useGetIdentityMembershipOrgs = (
|
||||
offset: String(offset),
|
||||
limit: String(limit),
|
||||
orderBy: String(orderBy),
|
||||
direction: String(direction),
|
||||
textFilter: String(textFilter)
|
||||
orderDirection: String(orderDirection),
|
||||
search: String(search)
|
||||
});
|
||||
return useQuery({
|
||||
queryKey: organizationKeys.getOrgIdentityMembershipsWithParams({
|
||||
@@ -399,8 +401,8 @@ export const useGetIdentityMembershipOrgs = (
|
||||
offset,
|
||||
limit,
|
||||
orderBy,
|
||||
direction,
|
||||
textFilter
|
||||
orderDirection,
|
||||
search
|
||||
}),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<TOrgIdentitiesList>(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { IdentityMembershipOrg } from "@app/hooks/api/identities/types";
|
||||
|
||||
export type Organization = {
|
||||
@@ -109,12 +110,17 @@ export type TListOrgIdentitiesDTO = {
|
||||
organizationId: string;
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
orderBy?: string;
|
||||
direction?: string;
|
||||
textFilter?: string;
|
||||
orderBy?: OrgIdentityOrderBy;
|
||||
orderDirection?: OrderByDirection;
|
||||
search?: string;
|
||||
};
|
||||
|
||||
export type TOrgIdentitiesList = {
|
||||
identityMemberships: IdentityMembershipOrg[];
|
||||
totalCount: number;
|
||||
};
|
||||
|
||||
export enum OrgIdentityOrderBy {
|
||||
Name = "name",
|
||||
Role = "role"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useMutation, useQuery, useQueryClient, UseQueryOptions } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
|
||||
import { CaStatus } from "../ca/enums";
|
||||
import { TCertificateAuthority } from "../ca/types";
|
||||
@@ -23,6 +24,7 @@ import {
|
||||
DeleteEnvironmentDTO,
|
||||
DeleteWorkspaceDTO,
|
||||
NameWorkspaceSecretsDTO,
|
||||
ProjectIdentityOrderBy,
|
||||
RenameWorkspaceDTO,
|
||||
TGetUpgradeProjectStatusDTO,
|
||||
TListProjectIdentitiesDTO,
|
||||
@@ -538,9 +540,9 @@ export const useGetWorkspaceIdentityMemberships = (
|
||||
workspaceId,
|
||||
offset = 0,
|
||||
limit = 100,
|
||||
orderBy = "name",
|
||||
direction = "asc",
|
||||
textFilter = ""
|
||||
orderBy = ProjectIdentityOrderBy.Name,
|
||||
orderDirection = OrderByDirection.ASC,
|
||||
search = ""
|
||||
}: TListProjectIdentitiesDTO,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
@@ -558,16 +560,16 @@ export const useGetWorkspaceIdentityMemberships = (
|
||||
offset,
|
||||
limit,
|
||||
orderBy,
|
||||
direction,
|
||||
textFilter
|
||||
orderDirection,
|
||||
search
|
||||
}),
|
||||
queryFn: async () => {
|
||||
const params = new URLSearchParams({
|
||||
offset: String(offset),
|
||||
limit: String(limit),
|
||||
orderBy: String(orderBy),
|
||||
direction: String(direction),
|
||||
textFilter: String(textFilter)
|
||||
orderDirection: String(orderDirection),
|
||||
search: String(search)
|
||||
});
|
||||
|
||||
const { data } = await apiRequest.get<TProjectIdentitiesList>(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
|
||||
import { TProjectRole } from "../roles/types";
|
||||
|
||||
export enum ProjectVersion {
|
||||
@@ -146,7 +148,11 @@ export type TListProjectIdentitiesDTO = {
|
||||
workspaceId: string;
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
orderBy?: string;
|
||||
direction?: string;
|
||||
textFilter?: string;
|
||||
orderBy?: ProjectIdentityOrderBy;
|
||||
orderDirection?: OrderByDirection;
|
||||
search?: string;
|
||||
};
|
||||
|
||||
export enum ProjectIdentityOrderBy {
|
||||
Name = "name"
|
||||
}
|
||||
|
||||
+32
-18
@@ -36,6 +36,8 @@ import {
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||
import { useDebounce } from "@app/hooks";
|
||||
import { useGetIdentityMembershipOrgs, useGetOrgRoles, useUpdateIdentity } from "@app/hooks/api";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { OrgIdentityOrderBy } from "@app/hooks/api/organization/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
type Props = {
|
||||
@@ -55,10 +57,10 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const [page, setPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(INIT_PER_PAGE);
|
||||
const [direction, setDirection] = useState("asc");
|
||||
const [orderBy, setOrderBy] = useState("name");
|
||||
const [textFilter, setTextFilter] = useState("");
|
||||
const debouncedTextFilter = useDebounce(textFilter);
|
||||
const [orderDirection, setOrderDirection] = useState(OrderByDirection.ASC);
|
||||
const [orderBy, setOrderBy] = useState(OrgIdentityOrderBy.Name);
|
||||
const [search, setSearch] = useState("");
|
||||
const debouncedSearch = useDebounce(search);
|
||||
|
||||
const organizationId = currentOrg?.id || "";
|
||||
|
||||
@@ -70,9 +72,9 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
organizationId,
|
||||
offset,
|
||||
limit: perPage,
|
||||
direction,
|
||||
orderDirection,
|
||||
orderBy,
|
||||
textFilter: debouncedTextFilter
|
||||
search: debouncedSearch
|
||||
},
|
||||
{ keepPreviousData: true }
|
||||
);
|
||||
@@ -84,14 +86,16 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
|
||||
const { data: roles } = useGetOrgRoles(organizationId);
|
||||
|
||||
const handleSort = (column: string) => {
|
||||
const handleSort = (column: OrgIdentityOrderBy) => {
|
||||
if (column === orderBy) {
|
||||
setDirection((prev) => (prev === "asc" ? "desc" : "asc"));
|
||||
setOrderDirection((prev) =>
|
||||
prev === OrderByDirection.ASC ? OrderByDirection.DESC : OrderByDirection.ASC
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setOrderBy(column);
|
||||
setDirection("asc");
|
||||
setOrderDirection(OrderByDirection.ASC);
|
||||
};
|
||||
|
||||
const handleChangeRole = async ({ identityId, role }: { identityId: string; role: string }) => {
|
||||
@@ -122,8 +126,8 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
<div>
|
||||
<Input
|
||||
containerClassName="mb-4"
|
||||
value={textFilter}
|
||||
onChange={(e) => setTextFilter(e.target.value)}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
||||
placeholder="Search identities by name..."
|
||||
/>
|
||||
@@ -136,12 +140,17 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
Name
|
||||
<IconButton
|
||||
variant="plain"
|
||||
className={`ml-2 ${orderBy === "name" ? "" : "opacity-30"}`}
|
||||
className={`ml-2 ${orderBy === OrgIdentityOrderBy.Name ? "" : "opacity-30"}`}
|
||||
ariaLabel="sort"
|
||||
onClick={() => handleSort("name")}
|
||||
onClick={() => handleSort(OrgIdentityOrderBy.Name)}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={direction === "desc" && orderBy === "name" ? faArrowUp : faArrowDown}
|
||||
icon={
|
||||
orderDirection === OrderByDirection.DESC &&
|
||||
orderBy === OrgIdentityOrderBy.Name
|
||||
? faArrowUp
|
||||
: faArrowDown
|
||||
}
|
||||
/>
|
||||
</IconButton>
|
||||
</div>
|
||||
@@ -151,12 +160,17 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
Role
|
||||
<IconButton
|
||||
variant="plain"
|
||||
className={`ml-2 ${orderBy === "role" ? "" : "opacity-30"}`}
|
||||
className={`ml-2 ${orderBy === OrgIdentityOrderBy.Role ? "" : "opacity-30"}`}
|
||||
ariaLabel="sort"
|
||||
onClick={() => handleSort("role")}
|
||||
onClick={() => handleSort(OrgIdentityOrderBy.Role)}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={direction === "desc" && orderBy === "role" ? faArrowUp : faArrowDown}
|
||||
icon={
|
||||
orderDirection === OrderByDirection.DESC &&
|
||||
orderBy === OrgIdentityOrderBy.Role
|
||||
? faArrowUp
|
||||
: faArrowDown
|
||||
}
|
||||
/>
|
||||
</IconButton>
|
||||
</div>
|
||||
@@ -275,7 +289,7 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
{!isLoading && data && data?.identityMemberships.length === 0 && (
|
||||
<EmptyState
|
||||
title={
|
||||
debouncedTextFilter.trim().length > 0
|
||||
debouncedSearch.trim().length > 0
|
||||
? "No identities match search filter"
|
||||
: "No identities have been created in this organization"
|
||||
}
|
||||
|
||||
@@ -46,8 +46,10 @@ import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@a
|
||||
import { withProjectPermission } from "@app/hoc";
|
||||
import { useDebounce } from "@app/hooks";
|
||||
import { useDeleteIdentityFromWorkspace, useGetWorkspaceIdentityMemberships } from "@app/hooks/api";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { IdentityMembership } from "@app/hooks/api/identities/types";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { ProjectIdentityOrderBy } from "@app/hooks/api/workspace/types";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
import { IdentityModal } from "./components/IdentityModal";
|
||||
@@ -67,10 +69,10 @@ export const IdentityTab = withProjectPermission(
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(INIT_PER_PAGE);
|
||||
const [direction, setDirection] = useState("asc");
|
||||
const [orderBy, setOrderBy] = useState("name");
|
||||
const [textFilter, setTextFilter] = useState("");
|
||||
const debouncedTextFilter = useDebounce(textFilter);
|
||||
const [orderDirection, setOrderDirection] = useState(OrderByDirection.ASC);
|
||||
const [orderBy, setOrderBy] = useState(ProjectIdentityOrderBy.Name);
|
||||
const [search, setSearch] = useState("");
|
||||
const debouncedSearch = useDebounce(search);
|
||||
|
||||
const workspaceId = currentWorkspace?.id ?? "";
|
||||
|
||||
@@ -80,9 +82,9 @@ export const IdentityTab = withProjectPermission(
|
||||
workspaceId: currentWorkspace?.id || "",
|
||||
offset,
|
||||
limit: perPage,
|
||||
direction,
|
||||
orderDirection,
|
||||
orderBy,
|
||||
textFilter: debouncedTextFilter
|
||||
search: debouncedSearch
|
||||
},
|
||||
{ keepPreviousData: true }
|
||||
);
|
||||
@@ -125,14 +127,16 @@ export const IdentityTab = withProjectPermission(
|
||||
if (data && data.totalCount < offset) setPage(1);
|
||||
}, [data?.totalCount]);
|
||||
|
||||
const handleSort = (column: string) => {
|
||||
const handleSort = (column: ProjectIdentityOrderBy) => {
|
||||
if (column === orderBy) {
|
||||
setDirection((prev) => (prev === "asc" ? "desc" : "asc"));
|
||||
setOrderDirection((prev) =>
|
||||
prev === OrderByDirection.ASC ? OrderByDirection.DESC : OrderByDirection.ASC
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setOrderBy(column);
|
||||
setDirection("asc");
|
||||
setOrderDirection(OrderByDirection.ASC);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -176,8 +180,8 @@ export const IdentityTab = withProjectPermission(
|
||||
</div>
|
||||
<Input
|
||||
containerClassName="mb-4"
|
||||
value={textFilter}
|
||||
onChange={(e) => setTextFilter(e.target.value)}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
||||
placeholder="Search identities by name..."
|
||||
/>
|
||||
@@ -190,13 +194,18 @@ export const IdentityTab = withProjectPermission(
|
||||
Name
|
||||
<IconButton
|
||||
variant="plain"
|
||||
className={`ml-2 ${orderBy === "name" ? "" : "opacity-30"}`}
|
||||
className={`ml-2 ${
|
||||
orderBy === ProjectIdentityOrderBy.Name ? "" : "opacity-30"
|
||||
}`}
|
||||
ariaLabel="sort"
|
||||
onClick={() => handleSort("name")}
|
||||
onClick={() => handleSort(ProjectIdentityOrderBy.Name)}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={
|
||||
direction === "desc" && orderBy === "name" ? faArrowUp : faArrowDown
|
||||
orderDirection === OrderByDirection.DESC &&
|
||||
orderBy === ProjectIdentityOrderBy.Name
|
||||
? faArrowUp
|
||||
: faArrowDown
|
||||
}
|
||||
/>
|
||||
</IconButton>
|
||||
@@ -372,7 +381,7 @@ export const IdentityTab = withProjectPermission(
|
||||
{!isLoading && data && data?.identityMemberships.length === 0 && (
|
||||
<EmptyState
|
||||
title={
|
||||
debouncedTextFilter.trim().length > 0
|
||||
debouncedSearch.trim().length > 0
|
||||
? "No identities match search filter"
|
||||
: "No identities have been added to this project"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user