Skip to content

Commit

Permalink
add filter and buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhamraj-git committed Nov 20, 2024
1 parent 43b63d6 commit f1a05bb
Showing 1 changed file with 171 additions and 3 deletions.
174 changes: 171 additions & 3 deletions airflow/ui/src/pages/Variables/Variables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Box } from "@chakra-ui/react";
import {
Box,
Button,
createListCollection,
HStack,
Input,
} from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import { useState, useEffect } from "react";
import { FiUpload, FiFilter } from "react-icons/fi";
import { IoAddCircleOutline } from "react-icons/io5";

import { useVariableServiceGetVariables } from "openapi/queries";
import type { VariableResponse } from "openapi/requests/types.gen";
import { DataTable } from "src/components/DataTable";
import { useTableURLState } from "src/components/DataTable/useTableUrlState";
import { ErrorAlert } from "src/components/ErrorAlert";
import { CloseButton, Select } from "src/components/ui";

const variablesColumn = (): Array<ColumnDef<VariableResponse>> => [
{
Expand Down Expand Up @@ -52,6 +62,24 @@ const variablesColumn = (): Array<ColumnDef<VariableResponse>> => [
},
];

const filterOptions = createListCollection({
items: [
{ label: "Key", value: "key" },
{ label: "Value", value: "value" },
],
});

const filterOperatorOptions = createListCollection({
items: [
{ label: "Starts With", value: "starts_with" },
{ label: "Ends With", value: "ends_with" },
{ label: "Contains", value: "contains" },
{ label: "Equals", value: "equals" },
{ label: "Not Starts With", value: "not_starts_with" },
{ label: "Not Ends With", value: "not_ends_with" },
],
});

export const Variables = () => {
const { setTableURLState, tableURLState } = useTableURLState({
sorting: [{ desc: true, id: "key" }],
Expand All @@ -61,6 +89,12 @@ export const Variables = () => {

const orderBy = sort ? `${sort.desc ? "-" : ""}${sort.id}` : undefined;

const [filterType, setFilterType] = useState<string | undefined>(undefined);
const [filterOperator, setFilterOperator] = useState<string | undefined>(
undefined,
);
const [filterText, setFilterText] = useState<string>("");

const {
data,
error: VariableError,
Expand All @@ -72,20 +106,154 @@ export const Variables = () => {
orderBy,
});

const [filteredData, setFilteredData] = useState<Array<VariableResponse>>([]);

useEffect(() => {
if (data?.variables) {
let filtered = data.variables;

if (filterText.trim()) {
filtered = filtered.filter((item) => {
const valueToFilter =
filterType === "key" ? item.key : (item.value ?? "");

switch (filterOperator) {
case "contains":
return valueToFilter.includes(filterText);
case "ends_with":
return valueToFilter.endsWith(filterText);
case "equals":
return valueToFilter === filterText;
case "not_ends_with":
return !valueToFilter.endsWith(filterText);
case "not_starts_with":
return !valueToFilter.startsWith(filterText);
case "starts_with":
return valueToFilter.startsWith(filterText);
default:
return true;
}
});
}

setFilteredData(filtered);
} else {
setFilteredData([]);
}

// Reset pagination when filter changes
setTableURLState({
pagination: { ...pagination, pageIndex: 0 },
sorting,
});
}, [
filterText,
filterType,
filterOperator,
data,
pagination,
sorting,
setTableURLState,
]);

return (
<Box>
<HStack justifyContent="space-between">
<Box
alignItems="center"
border="1px solid"
borderColor="gray.800"
borderRadius="md"
color="gray.400"
display="flex"
gap={2}
p={1}
pl={2}
position="relative"
>
<FiFilter />
<Select.Root
collection={filterOptions}
onValueChange={(event) => setFilterType(event.value[0])}
size="xs"
value={[filterType ?? ""]}
width="90px"
>
<Select.Trigger>
<Select.ValueText placeholder="Filter by" />
</Select.Trigger>
<Select.Content>
{filterOptions.items.map((option) => (
<Select.Item item={option} key={option.value}>
{option.label}
</Select.Item>
))}
</Select.Content>
</Select.Root>
<Select.Root
collection={filterOperatorOptions}
onValueChange={(event) => setFilterOperator(event.value[0])}
size="xs"
value={[filterOperator ?? ""]}
width="140px"
>
<Select.Trigger>
<Select.ValueText placeholder="Filter operator" />
</Select.Trigger>
<Select.Content>
{filterOperatorOptions.items.map((option) => (
<Select.Item item={option} key={option.value}>
{option.label}
</Select.Item>
))}
</Select.Content>
</Select.Root>
<Input
border="0px"
onChange={(event) => setFilterText(event.target.value)}
outline="none"
placeholder="Filter text"
size="xs"
value={filterText}
width="200px"
/>
{filterText === "" ? undefined : (
<CloseButton
aria-label="Clear search"
colorPalette="gray"
data-testid="clear-search"
onClick={() => {
setFilterText("");
}}
size="xs"
/>
)}
</Box>

<HStack>
<Button colorPalette="blue">
<FiUpload />
Import Variables
</Button>
<Button colorPalette="blue">
<IoAddCircleOutline />
Add Variable
</Button>
</HStack>
</HStack>

<ErrorAlert error={VariableError} />
<DataTable
columns={variablesColumn()}
data={data ? data.variables : []}
data={filteredData}
displayMode="table"
initialState={tableURLState}
isFetching={isFetching}
isLoading={isLoading}
modelName="Variable"
onStateChange={setTableURLState}
skeletonCount={undefined}
total={data ? data.total_entries : 0}
total={filteredData.length}
/>
</Box>
);
Expand Down

0 comments on commit f1a05bb

Please sign in to comment.