Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
import { gql, useQuery } from "@apollo/client";
import { useQuery } from "@apollo/client";
import Select from "react-select";
import { UserQueryTopLevel } from "../utils/interfacesQuery";
import { useFilters } from "../context/FilterContext/FilterContext";
import { GET_USER_QUERY } from "../utils/queries";

const UserFilterBar = () => {
const { filters, updateFilters } = useFilters();
export interface UserFilterProps {
value: string;
onChange: (value: string) => void;
label?: string;
placeholder?: string;
isDisabled?: boolean;
}

const UserFilter = ({
value,
onChange,
label = "User",
placeholder = "Filter by User",
isDisabled = false,
}: UserFilterProps) => {
const { data, loading } = useQuery<UserQueryTopLevel>(GET_USER_QUERY);

const options = data?.users.edges.map((edge) => ({
value: edge.node.id,
label: edge.node.name,
})) || [];

const selectedOption = options.find((option) => option.value === filters.creatorId);
const selectedOption = options.find((option) => option.value === value);

return (
<div className="flex flex-col gap-1">
<label className="text-gray-700">User</label>
<label className="text-gray-700">{label}</label>
<Select
isDisabled={filters.isLocked || loading}
isDisabled={isDisabled || loading}
isLoading={loading}
isClearable
placeholder="Filter by Creator"
placeholder={placeholder}
options={options}
value={selectedOption}
onChange={(option) => {
updateFilters({ creatorId: option ? option.value : "" });
onChange(option ? option.value : "");
}}
/>
</div>
);
};

export default UserFilterBar;
export default UserFilter;
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type Filters = {
tomeFields: Array<FilterBarOption>,
tomeMultiSearch: string,
assetName: string,
creatorId: string,
userId: string,
}

const defaultFilters: Filters = {
Expand All @@ -33,7 +33,7 @@ const defaultFilters: Filters = {
tomeFields: [],
tomeMultiSearch: "",
assetName: "",
creatorId: ""
userId: ""
}

function isValidFilterBarOption(item: any): item is FilterBarOption {
Expand All @@ -60,7 +60,7 @@ function validateStoredFilters(data: any): Filters {
taskOutput: (v) => typeof v === 'string',
tomeMultiSearch: (v) => typeof v === 'string',
assetName: (v) => typeof v === 'string',
creatorId: (v) => typeof v === 'string',
userId: (v) => typeof v === 'string',
beaconFields: (v) => Array.isArray(v) && v.every(isValidFilterBarOption),
tomeFields: (v) => Array.isArray(v) && v.every(isValidFilterBarOption),
}
Expand Down Expand Up @@ -104,7 +104,7 @@ export function calculateFilterCount(filters: Filters, field: FilterFieldType):
case FilterFieldType.ASSET_NAME:
return filters.assetName !== "" ? 1 : 0;
case FilterFieldType.CREATOR:
return filters.creatorId !== "" ? 1 : 0;
return filters.userId !== "" ? 1 : 0;
case FilterFieldType.BEACON_FIELDS:
return filters.beaconFields.length;
case FilterFieldType.TOME_FIELDS:
Expand Down
11 changes: 9 additions & 2 deletions tavern/internal/www/src/context/FilterContext/FilterControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LockKeyhole, UnlockKeyhole } from "lucide-react";
import { TomeFilterBar } from "../../components/TomeFilterBar";
import { Tooltip } from "@chakra-ui/react";
import { useLocation } from "react-router-dom";
import UserFilterBar from "../../components/UserFilterBar";
import UserFilter from "../../components/UserFilter";

function getFilterFields(pathname: string): FilterFieldType[] | null {
if (pathname.startsWith('/hosts/')) {
Expand Down Expand Up @@ -123,7 +123,14 @@ export default function FilterControls() {
else if (field === FilterFieldType.CREATOR) {
return (
<div key={field}>
<UserFilterBar />
<UserFilter
key={field}
value={filters.userId}
onChange={(newValue) => updateFilters({ 'userId': newValue })}
label="User"
placeholder="Filter by Creator"
isDisabled={filters.isLocked}
/>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
});

Expand All @@ -50,7 +50,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: 'search-term',
assetName: '',
creatorId: '',
userId: '',
};

sessionStorage.setItem(STORAGE_KEY, JSON.stringify(storedFilters));
Expand All @@ -71,7 +71,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: 'search-term',
assetName: '',
creatorId: '',
userId: '',
};

sessionStorage.setItem(STORAGE_KEY, JSON.stringify(storedFilters));
Expand All @@ -88,7 +88,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
});

Expand All @@ -109,7 +109,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
expect(result.current.filterCount).toBe(0);
});
Expand All @@ -131,7 +131,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
});

Expand Down Expand Up @@ -184,7 +184,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
};

sessionStorage.setItem(STORAGE_KEY, JSON.stringify(validFilters));
Expand Down Expand Up @@ -298,7 +298,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
});

Expand Down Expand Up @@ -327,7 +327,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
});
});
Expand All @@ -347,7 +347,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: 'external-search',
assetName: '',
creatorId: '',
userId: '',
};

act(() => {
Expand Down Expand Up @@ -379,7 +379,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: 'external-search',
assetName: '',
creatorId: '',
userId: '',
};

act(() => {
Expand All @@ -399,7 +399,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
});
});

Expand Down Expand Up @@ -431,7 +431,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
};

it('should return 1 for non-empty questName', () => {
Expand Down Expand Up @@ -482,6 +482,24 @@ describe('FilterContext', () => {
};
expect(calculateFilterCount(filters, FilterFieldType.TOME_FIELDS)).toBe(1);
});

it('should return 1 for non-empty assetName', () => {
const filters = { ...baseFilters, assetName: 'asset' };
expect(calculateFilterCount(filters, FilterFieldType.ASSET_NAME)).toBe(1);
});

it('should return 0 for empty assetName', () => {
expect(calculateFilterCount(baseFilters, FilterFieldType.ASSET_NAME)).toBe(0);
});

it('should return 1 for non-empty userId', () => {
const filters = { ...baseFilters, userId: 'user1' };
expect(calculateFilterCount(filters, FilterFieldType.CREATOR)).toBe(1);
});

it('should return 0 for empty userId', () => {
expect(calculateFilterCount(baseFilters, FilterFieldType.CREATOR)).toBe(0);
});
});

describe('calculateTotalFilterCount', () => {
Expand All @@ -493,7 +511,7 @@ describe('FilterContext', () => {
tomeFields: [],
tomeMultiSearch: '',
assetName: '',
creatorId: '',
userId: '',
};

it('should return 0 when all filters are empty', () => {
Expand Down Expand Up @@ -530,7 +548,7 @@ describe('FilterContext', () => {
{ kind: 'tome', id: '1', name: 'T1' },
],
assetName: '',
creatorId: '',
userId: '',
};

const allFields = Object.values(FilterFieldType);
Expand Down
4 changes: 2 additions & 2 deletions tavern/internal/www/src/pages/assets/Assets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export const Assets = () => {
const rowLimit = 10;
const { filters } = useFilters();
const where: any = filters.assetName ? { nameContains: filters.assetName } : {};
if (filters.creatorId) {
where.hasCreatorWith = [{ id: filters.creatorId }];
if (filters.userId) {
where.hasCreatorWith = [{ id: filters.userId }];
}

const { assets, loading, error, totalCount, pageInfo, refetch, updateAssets, page, setPage } = useAssets(rowLimit, where);
Expand Down