Skip to content

Commit

Permalink
Merge pull request #295 from Southclaws/datagraph-search-filters
Browse files Browse the repository at this point in the history
Datagraph-search-filters
  • Loading branch information
Southclaws authored Nov 12, 2024
2 parents 8c3c928 + 5b55611 commit e182243
Show file tree
Hide file tree
Showing 26 changed files with 1,005 additions and 477 deletions.
12 changes: 11 additions & 1 deletion api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1699,7 +1699,7 @@ paths:
description: Query and search content.
tags: [datagraph]
parameters:
- $ref: "#/components/parameters/SearchQuery"
- $ref: "#/components/parameters/RequiredSearchQuery"
- $ref: "#/components/parameters/DatagraphKindQuery"
- $ref: "#/components/parameters/PaginationQuery"
responses:
Expand Down Expand Up @@ -1997,6 +1997,16 @@ components:
type: string
minLength: 0

RequiredSearchQuery:
description: Search query string.
name: q
in: query
required: true
allowEmptyValue: true
schema:
type: string
minLength: 0

DatagraphKindQuery:
description: Datagraph item kind query.
name: kind
Expand Down
9 changes: 7 additions & 2 deletions app/services/search/simplesearch/simple_searcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func NewParallelSearcher(
) *ParallelSearcher {
return &ParallelSearcher{
searchers: map[datagraph.Kind]searcher.SingleKindSearcher{
datagraph.KindPost: &postSearcher{post_searcher},
datagraph.KindNode: &nodeSearcher{node_searcher},
datagraph.KindThread: &postSearcher{post_searcher},
datagraph.KindNode: &nodeSearcher{node_searcher},
},
}
}
Expand All @@ -53,6 +53,11 @@ func (s *ParallelSearcher) Search(ctx context.Context, q string, p pagination.Pa
searchers = lo.Values(s.searchers)
}

if len(searchers) == 0 {
results := pagination.NewPageResult(p, 0, []datagraph.Item{})
return &results, nil
}

// Earch searcher receives a smaller page size
subsearchPageSize := uint(p.Size() / len(searchers))
subsearchParams := pagination.NewPageParams(uint(p.PageOneIndexed()), subsearchPageSize)
Expand Down
6 changes: 1 addition & 5 deletions app/transports/http/bindings/datagraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ func NewDatagraph(
const datagraphSearchPageSize = 50

func (d Datagraph) DatagraphSearch(ctx context.Context, request openapi.DatagraphSearchRequestObject) (openapi.DatagraphSearchResponseObject, error) {
if request.Params.Q == nil {
return nil, fault.New("missing query")
}

pp := deserialisePageParams(request.Params.Page, datagraphSearchPageSize)

kindFilter, err := opt.MapErr(opt.NewPtr(request.Params.Kind), deserialiseDatagraphKindList)
Expand All @@ -49,7 +45,7 @@ func (d Datagraph) DatagraphSearch(ctx context.Context, request openapi.Datagrap
Kinds: kindFilter,
}

r, err := d.searcher.Search(ctx, *request.Params.Q, pp, opts)
r, err := d.searcher.Search(ctx, request.Params.Q, pp, opts)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}
Expand Down
726 changes: 363 additions & 363 deletions app/transports/http/openapi/server_gen.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/semdex/semdex_weaviate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func TestSemdexWeaviate(t *testing.T) {
query := "outage"

search1, err := cl.DatagraphSearchWithResponse(ctx, &openapi.DatagraphSearchParams{
Q: &query,
Q: query,
}, e2e.WithSession(ctx, cj))
r.NoError(err)
r.Equal(http.StatusOK, search1.StatusCode())
Expand Down
4 changes: 4 additions & 0 deletions web/panda.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { richCard } from "@/recipes/rich-card";
import { select } from "@/recipes/select";
import { table } from "@/recipes/table";
import { tagsInput } from "@/recipes/tags-input";
import { toggleGroup } from "@/recipes/toggle-group";
import { tooltip } from "@/recipes/tooltip";
import { treeView } from "@/recipes/tree-view";
import { typographyHeading } from "@/recipes/typography-heading";

Expand Down Expand Up @@ -295,6 +297,8 @@ export default defineConfig({
table: table,
tagsInput: tagsInput,
treeView: treeView,
toggleGroup: toggleGroup,
tooltip: tooltip,
},
semanticTokens,
tokens: defineTokens({
Expand Down
6 changes: 3 additions & 3 deletions web/src/api/openapi-client/datagraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ import type {
/**
* Query and search content.
*/
export const datagraphSearch = (params?: DatagraphSearchParams) => {
export const datagraphSearch = (params: DatagraphSearchParams) => {
return fetcher<DatagraphSearchOKResponse>({
url: `/datagraph`,
method: "GET",
params,
});
};

export const getDatagraphSearchKey = (params?: DatagraphSearchParams) =>
export const getDatagraphSearchKey = (params: DatagraphSearchParams) =>
[`/datagraph`, ...(params ? [params] : [])] as const;

export type DatagraphSearchQueryResult = NonNullable<
Expand All @@ -47,7 +47,7 @@ export const useDatagraphSearch = <
| NotFoundResponse
| InternalServerErrorResponse,
>(
params?: DatagraphSearchParams,
params: DatagraphSearchParams,
options?: {
swr?: SWRConfiguration<
Awaited<ReturnType<typeof datagraphSearch>>,
Expand Down
4 changes: 2 additions & 2 deletions web/src/api/openapi-schema/datagraphSearchParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ The Storyden API does not adhere to semantic versioning but instead applies a ro
*/
import type { DatagraphKindQueryParameter } from "./datagraphKindQueryParameter";
import type { PaginationQueryParameter } from "./paginationQueryParameter";
import type { SearchQueryParameter } from "./searchQueryParameter";
import type { RequiredSearchQueryParameter } from "./requiredSearchQueryParameter";

export type DatagraphSearchParams = {
/**
* Search query string.
*/
q?: SearchQueryParameter;
q: RequiredSearchQueryParameter;
/**
* Datagraph item kind query.
*/
Expand Down
1 change: 1 addition & 0 deletions web/src/api/openapi-schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ export * from "./replyInitialProps";
export * from "./replyList";
export * from "./replyProps";
export * from "./replyStatus";
export * from "./requiredSearchQueryParameter";
export * from "./residentKeyRequirement";
export * from "./role";
export * from "./roleCreateBody";
Expand Down
14 changes: 14 additions & 0 deletions web/src/api/openapi-schema/requiredSearchQueryParameter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Generated by orval v7.2.0 🍺
* Do not edit manually.
* storyden
* Storyden social API for building community driven platforms.
The Storyden API does not adhere to semantic versioning but instead applies a rolling strategy with deprecations and minimal breaking changes. This has been done mainly for a simpler development process and it may be changed to a more fixed versioning strategy in the future. Ultimately, the primary way Storyden tracks versions is dates, there are no set release tags currently.
* OpenAPI spec version: rolling
*/

/**
* Search query string.
*/
export type RequiredSearchQueryParameter = string;
4 changes: 2 additions & 2 deletions web/src/api/openapi-server/datagraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type datagraphSearchResponse = {
status: number;
};

export const getDatagraphSearchUrl = (params?: DatagraphSearchParams) => {
export const getDatagraphSearchUrl = (params: DatagraphSearchParams) => {
const normalizedParams = new URLSearchParams();

Object.entries(params || {}).forEach(([key, value]) => {
Expand All @@ -45,7 +45,7 @@ export const getDatagraphSearchUrl = (params?: DatagraphSearchParams) => {
};

export const datagraphSearch = async (
params?: DatagraphSearchParams,
params: DatagraphSearchParams,
options?: RequestInit,
): Promise<datagraphSearchResponse> => {
return fetcher<Promise<datagraphSearchResponse>>(
Expand Down
36 changes: 24 additions & 12 deletions web/src/app/(dashboard)/search/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import { z } from "zod";

import { EmptyState } from "src/components/site/EmptyState";
import { SearchScreen } from "src/screens/search/SearchScreen";

import { datagraphSearch } from "@/api/openapi-server/datagraph";
import { UnreadyBanner } from "@/components/site/Unready";
import { DatagraphKindSchema } from "@/lib/datagraph/schema";

type Props = {
searchParams: Promise<Query>;
};

export const dynamic = "force-dynamic";

const QuerySchema = z.object({
q: z.string().optional(),
page: z
.string()
.transform((v) => parseInt(v, 10))
.optional(),
kind: z
.preprocess((arg: unknown) => {
if (typeof arg === "string") {
return [arg];
}

return arg;
}, z.array(DatagraphKindSchema))
.optional(),
});

type Query = z.infer<typeof QuerySchema>;
Expand All @@ -26,20 +37,21 @@ export default async function Page(props: Props) {

const params = QuerySchema.parse(searchParams);

if (!params.q) {
return (
<EmptyState>
<p>Search anything.</p>
</EmptyState>
);
}

const { data } = await datagraphSearch({ q: params.q });
const { data } = params.q
? await datagraphSearch({
q: params.q,
page: params.page?.toString(),
kind: params.kind,
})
: {
data: undefined,
};

return (
<SearchScreen
query={params.q}
page={params.page ?? 1}
initialQuery={params.q ?? ""}
initialPage={params.page ?? 1}
initialKind={params.kind ?? []}
initialResults={data}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/search/Search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function Search(props: Props) {
<styled.form
display="flex"
w="full"
onSubmit={handlers.handleSearch}
// onSubmit={handlers.handleSearch}
action="/search"
>
<Input
Expand Down
33 changes: 33 additions & 0 deletions web/src/components/site/Navigation/Anchors/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { SearchIcon } from "@/components/ui/icons/Search";
import { LinkButtonStyleProps } from "@/components/ui/link-button";

import { Anchor, AnchorProps, MenuItem } from "./Anchor";

export const SearchID = "search";
export const SearchRoute = "/search";
export const SearchLabel = "Search";

type Props = AnchorProps & LinkButtonStyleProps;

export function SearchAnchor(props: Props) {
return (
<Anchor
id={SearchID}
route={SearchRoute}
label={SearchLabel}
icon={<SearchIcon />}
{...props}
/>
);
}

export function SearchMenuItem() {
return (
<MenuItem
id={SearchID}
route={SearchRoute}
label={SearchLabel}
icon={<SearchIcon />}
/>
);
}
5 changes: 2 additions & 3 deletions web/src/components/site/Navigation/DesktopCommandBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { cx } from "@/styled-system/css";
import { HStack } from "@/styled-system/jsx";
import { Floating } from "@/styled-system/patterns";

import { Search } from "../../search/Search/Search";

import styles from "./navigation.module.css";

import { SearchAnchor } from "./Anchors/Search";
import { MemberActions } from "./MemberActions";
import { SidebarToggle } from "./NavigationPane/SidebarToggle";
import { getServerSidebarState } from "./NavigationPane/server";
Expand All @@ -29,7 +28,7 @@ export async function DesktopCommandBar() {
>
<HStack className={styles["topbar-left"]}>
<SidebarToggle initialValue={initialSidebarState} />
<Search />
<SearchAnchor />
</HStack>

<HStack className={styles["topbar-middle"]} justify="space-around">
Expand Down
77 changes: 77 additions & 0 deletions web/src/components/ui/form/DatagraphKindFilterField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Portal, ToggleGroupValueChangeDetails } from "@ark-ui/react";
import { JSX } from "react";
import { Controller, ControllerProps, FieldValues } from "react-hook-form";

import * as ToggleGroup from "@/components/ui/toggle-group";
import * as Tooltip from "@/components/ui/tooltip";
import { HStack } from "@/styled-system/jsx";

type CollectionItem = {
label: string;
icon: JSX.Element;
description: string;
value: string;
};

type Props<T extends FieldValues> = Omit<ControllerProps<T>, "render"> & {
items: CollectionItem[];
};

export function DatagraphKindFilterField<T extends FieldValues>({
items,
...props
}: Props<T>) {
return (
<Controller<T>
{...props}
render={({ formState, field }) => {
function handleChangeFilter({ value }: ToggleGroupValueChangeDetails) {
field.onChange(value);
}

return (
<ToggleGroup.Root
multiple
size="xs"
onValueChange={handleChangeFilter}
defaultValue={formState.defaultValues?.[props.name]}
>
{items.map((item) => (
<ToggleGroup.Item
key={item.value}
value={item.value}
aria-label={item.description}
>
<Tooltip.Root
lazyMount
openDelay={0}
positioning={{
slide: true,
shift: -48,
placement: "right-end",
}}
>
<Tooltip.Trigger asChild>
<HStack gap="1">
{item.icon} {item.label}
</HStack>
</Tooltip.Trigger>

<Portal>
<Tooltip.Positioner>
<Tooltip.Arrow>
<Tooltip.ArrowTip />
</Tooltip.Arrow>

<Tooltip.Content>{item.description}</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
</ToggleGroup.Item>
))}
</ToggleGroup.Root>
);
}}
/>
);
}
Loading

0 comments on commit e182243

Please sign in to comment.