mirror of
https://github.com/docmost/docmost.git
synced 2026-08-25 15:57:11 +08:00
feat: show secondary search filters only when applied
Created by and Labels now stay hidden until they hold a value; a Filter button at the right end of the bar lists the hidden ones and opens the picked filter's dropdown immediately.
This commit is contained in:
@@ -21,6 +21,8 @@ type CreatorFilterMenuProps = {
|
||||
| "top-end"
|
||||
| "top";
|
||||
zIndex?: number;
|
||||
opened?: boolean;
|
||||
onOpenChange?: (opened: boolean) => void;
|
||||
};
|
||||
|
||||
export function CreatorFilterMenu({
|
||||
@@ -30,6 +32,8 @@ export function CreatorFilterMenu({
|
||||
width = 280,
|
||||
position = "bottom-end",
|
||||
zIndex,
|
||||
opened,
|
||||
onOpenChange,
|
||||
}: CreatorFilterMenuProps) {
|
||||
const { t } = useTranslation();
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
@@ -46,7 +50,14 @@ export function CreatorFilterMenu({
|
||||
const users: IUser[] = (suggestion?.users as IUser[]) ?? [];
|
||||
|
||||
return (
|
||||
<Menu shadow="md" width={width} position={position} zIndex={zIndex}>
|
||||
<Menu
|
||||
shadow="md"
|
||||
width={width}
|
||||
position={position}
|
||||
zIndex={zIndex}
|
||||
opened={opened}
|
||||
onChange={onOpenChange}
|
||||
>
|
||||
<Menu.Target>{children}</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<TextInput
|
||||
|
||||
@@ -27,6 +27,8 @@ type LabelFilterMenuProps = {
|
||||
| "top-end"
|
||||
| "top";
|
||||
zIndex?: number;
|
||||
opened?: boolean;
|
||||
onOpenChange?: (opened: boolean) => void;
|
||||
};
|
||||
|
||||
export function LabelFilterMenu({
|
||||
@@ -36,6 +38,8 @@ export function LabelFilterMenu({
|
||||
width = 280,
|
||||
position = "bottom-end",
|
||||
zIndex,
|
||||
opened,
|
||||
onOpenChange,
|
||||
}: LabelFilterMenuProps) {
|
||||
const { t } = useTranslation();
|
||||
const scheme = useComputedColorScheme("light");
|
||||
@@ -61,6 +65,8 @@ export function LabelFilterMenu({
|
||||
width={width}
|
||||
position={position}
|
||||
zIndex={zIndex}
|
||||
opened={opened}
|
||||
onChange={onOpenChange}
|
||||
closeOnItemClick={false}
|
||||
>
|
||||
<Menu.Target>{children}</Menu.Target>
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconBuilding,
|
||||
IconPlus,
|
||||
IconFileDescription,
|
||||
IconCheck,
|
||||
IconUser,
|
||||
@@ -52,6 +53,7 @@ export function SearchSpotlightFilters({
|
||||
null
|
||||
);
|
||||
const [selectedLabelIds, setSelectedLabelIds] = useState<string[]>([]);
|
||||
const [openedFilter, setOpenedFilter] = useState<string | null>(null);
|
||||
const [workspace] = useAtom(workspaceAtom);
|
||||
|
||||
const { data: spacesData } = useGetSpacesQuery({ limit: 100 });
|
||||
@@ -104,6 +106,24 @@ export function SearchSpotlightFilters({
|
||||
}
|
||||
};
|
||||
|
||||
const showCreatorFilter = !!selectedCreatorId || openedFilter === "creator";
|
||||
const showLabelFilter =
|
||||
contentType !== "attachment" &&
|
||||
(selectedLabelIds.length > 0 || openedFilter === "labels");
|
||||
|
||||
const addableFilters: { key: string; label: string; icon: typeof IconUser }[] =
|
||||
[];
|
||||
if (!showCreatorFilter) {
|
||||
addableFilters.push({
|
||||
key: "creator",
|
||||
label: t("Created by"),
|
||||
icon: IconUser,
|
||||
});
|
||||
}
|
||||
if (contentType !== "attachment" && !showLabelFilter) {
|
||||
addableFilters.push({ key: "labels", label: t("Labels"), icon: IconTag });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.filtersContainer}>
|
||||
{workspace?.settings?.ai?.search === true && (
|
||||
@@ -219,35 +239,41 @@ export function SearchSpotlightFilters({
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
|
||||
<CreatorFilterMenu
|
||||
value={selectedCreatorId}
|
||||
onChange={handleCreatorSelect}
|
||||
position="bottom-start"
|
||||
width={250}
|
||||
zIndex={getDefaultZIndex("max")}
|
||||
>
|
||||
<Button
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size="sm"
|
||||
rightSection={<IconChevronDown size={14} />}
|
||||
leftSection={<IconUser size={16} />}
|
||||
className={classes.filterButton}
|
||||
fw={500}
|
||||
{showCreatorFilter && (
|
||||
<CreatorFilterMenu
|
||||
value={selectedCreatorId}
|
||||
onChange={handleCreatorSelect}
|
||||
position="bottom-start"
|
||||
width={250}
|
||||
zIndex={getDefaultZIndex("max")}
|
||||
opened={openedFilter === "creator"}
|
||||
onOpenChange={(opened) => setOpenedFilter(opened ? "creator" : null)}
|
||||
>
|
||||
{selectedCreatorId
|
||||
? `${t("Created by")}: ${selectedCreatorName || t("Unknown")}`
|
||||
: `${t("Created by")}: ${t("Anyone")}`}
|
||||
</Button>
|
||||
</CreatorFilterMenu>
|
||||
<Button
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size="sm"
|
||||
rightSection={<IconChevronDown size={14} />}
|
||||
leftSection={<IconUser size={16} />}
|
||||
className={classes.filterButton}
|
||||
fw={500}
|
||||
>
|
||||
{selectedCreatorId
|
||||
? `${t("Created by")}: ${selectedCreatorName || t("Unknown")}`
|
||||
: `${t("Created by")}: ${t("Anyone")}`}
|
||||
</Button>
|
||||
</CreatorFilterMenu>
|
||||
)}
|
||||
|
||||
{contentType !== "attachment" && (
|
||||
{showLabelFilter && (
|
||||
<LabelFilterMenu
|
||||
value={selectedLabelIds}
|
||||
onChange={handleLabelsSelect}
|
||||
position="bottom-start"
|
||||
width={250}
|
||||
zIndex={getDefaultZIndex("max")}
|
||||
opened={openedFilter === "labels"}
|
||||
onOpenChange={(opened) => setOpenedFilter(opened ? "labels" : null)}
|
||||
>
|
||||
<Button
|
||||
variant="subtle"
|
||||
@@ -264,6 +290,40 @@ export function SearchSpotlightFilters({
|
||||
</Button>
|
||||
</LabelFilterMenu>
|
||||
)}
|
||||
|
||||
{addableFilters.length > 0 && (
|
||||
<Menu
|
||||
shadow="md"
|
||||
width={200}
|
||||
position="bottom-end"
|
||||
zIndex={getDefaultZIndex("max")}
|
||||
>
|
||||
<Menu.Target>
|
||||
<Button
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size="sm"
|
||||
leftSection={<IconPlus size={16} />}
|
||||
className={classes.filterButton}
|
||||
style={{ marginLeft: "auto" }}
|
||||
fw={500}
|
||||
>
|
||||
{t("Filter")}
|
||||
</Button>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
{addableFilters.map((filter) => (
|
||||
<Menu.Item
|
||||
key={filter.key}
|
||||
leftSection={<filter.icon size={16} />}
|
||||
onClick={() => setOpenedFilter(filter.key)}
|
||||
>
|
||||
{filter.label}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user