diff --git a/.changeset/filter-search-flow.md b/.changeset/filter-search-flow.md new file mode 100644 index 00000000..1da3302e --- /dev/null +++ b/.changeset/filter-search-flow.md @@ -0,0 +1,6 @@ +--- +"@developer-overheid-nl/api-register": patch +"@developer-overheid-nl/oss-register": patch +--- + +Zoeken maakt nu gebruik van de list/filter-endpoints zodat filter- en zoektermen gecombineerd gebruikt kunnen worden. diff --git a/.changeset/tough-swans-mate.md b/.changeset/tough-swans-mate.md new file mode 100644 index 00000000..f0911126 --- /dev/null +++ b/.changeset/tough-swans-mate.md @@ -0,0 +1,7 @@ +--- +"@developer-overheid-nl/don-register-components": minor +--- + +Hidden fields toegevoegd om bijv search- en filters in url te behouden. In: + - Search component + - Facet Filters component diff --git a/apps/api-register/src/components/FacetFiltersForm.tsx b/apps/api-register/src/components/FacetFiltersForm.tsx index 301545cc..9c57e5c9 100644 --- a/apps/api-register/src/components/FacetFiltersForm.tsx +++ b/apps/api-register/src/components/FacetFiltersForm.tsx @@ -19,11 +19,18 @@ interface FacetFiltersFormProps { filtersTitle: string; filterButtonLabel: string; }; + hiddenFields?: [string, string][]; } const FacetFiltersForm = (props: FacetFiltersFormProps) => { const formRef = useRef(null); - const { filters, action: formAction, method: formMethod, labels } = props; + const { + filters, + action: formAction, + method: formMethod, + labels, + hiddenFields = [], + } = props; const [{ data }, action, pending] = useActionState( withState(actions.getFilters), { @@ -55,6 +62,14 @@ const FacetFiltersForm = (props: FacetFiltersFormProps) => { action={formAction} method={formMethod} > + {hiddenFields.map(([name, value], index) => ( + + ))} key !== SEARCH_QUERY_KEY, +); +const filterHiddenFields: [string, string][] = routingObj.query[ + SEARCH_QUERY_KEY +] + ? [[SEARCH_QUERY_KEY, routingObj.query[SEARCH_QUERY_KEY] as string]] + : []; --- @@ -162,9 +170,10 @@ const labels = { > { facetfiltersError && ( diff --git a/apps/api-register/src/types/api-schema.prod.ts b/apps/api-register/src/types/api-schema.prod.ts index 9fb6da84..61cd048e 100644 --- a/apps/api-register/src/types/api-schema.prod.ts +++ b/apps/api-register/src/types/api-schema.prod.ts @@ -48,26 +48,6 @@ export interface paths { patch?: never; trace?: never; }; - "/apis/_search": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** - * Search APIs - * @description Returns a list of APIs matching the search query. - */ - get: operations["searchApis"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/lint-results": { parameters: { query?: never; @@ -427,6 +407,8 @@ export interface components { Page: number; /** @description Number of results per page. */ PerPage: number; + /** @description Search term to combine with API filters. Matches API title. */ + Search: string; /** @description Filter on organisation URI. */ Organisation: string; }; @@ -456,6 +438,8 @@ export interface operations { page?: components["parameters"]["Page"]; /** @description Number of results per page. */ perPage?: components["parameters"]["PerPage"]; + /** @description Search term to combine with API filters. Matches API title. */ + q?: components["parameters"]["Search"]; /** @description Filter on organisation URI. */ organisation?: components["parameters"]["Organisation"]; /** @description Comma-separated list of API IDs. */ @@ -522,6 +506,8 @@ export interface operations { listApiFilters: { parameters: { query?: { + /** @description Search term to combine with API filters. Matches API title. */ + q?: components["parameters"]["Search"]; /** @description Filter on organisation URI. */ organisation?: components["parameters"]["Organisation"]; /** @description Comma-separated list of API IDs. */ @@ -554,42 +540,6 @@ export interface operations { 400: components["responses"]["400"]; }; }; - searchApis: { - parameters: { - query: { - /** @description Page number (1-based). */ - page?: components["parameters"]["Page"]; - /** @description Number of results per page. */ - perPage?: components["parameters"]["PerPage"]; - /** @description Filter on organisation URI. */ - organisation?: components["parameters"]["Organisation"]; - /** @description Search term. */ - q: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - "API-Version": components["headers"]["ApiVersion"]; - Link: components["headers"]["Link"]; - "Total-Count": components["headers"]["TotalCount"]; - "Current-Page": components["headers"]["CurrentPage"]; - "Per-Page": components["headers"]["PerPage"]; - "Total-Pages": components["headers"]["TotalPages"]; - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ApiSummary"][]; - }; - }; - 400: components["responses"]["400"]; - }; - }; listLintResults: { parameters: { query?: never; @@ -823,7 +773,6 @@ export enum ApiPaths { listApis = "/apis", createApi = "/apis", listApiFilters = "/apis/filters", - searchApis = "/apis/_search", listLintResults = "/lint-results", retreiveApi = "/apis/{id}", updateApi = "/apis/{id}", diff --git a/apps/api-register/src/types/api-schema.test.ts b/apps/api-register/src/types/api-schema.test.ts index 5d37cf66..e3265ed9 100644 --- a/apps/api-register/src/types/api-schema.test.ts +++ b/apps/api-register/src/types/api-schema.test.ts @@ -48,26 +48,6 @@ export interface paths { patch?: never; trace?: never; }; - "/apis/_search": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** - * Search APIs - * @description Returns a list of APIs matching the search query. - */ - get: operations["searchApis"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/lint-results": { parameters: { query?: never; @@ -465,6 +445,8 @@ export interface components { Page: number; /** @description Number of results per page. */ PerPage: number; + /** @description Search term to combine with API filters. Matches API title. */ + Search: string; /** @description Filter on organisation URI. */ Organisation: string; /** @description Comma-separated list of API IDs. */ @@ -504,6 +486,8 @@ export interface operations { page?: components["parameters"]["Page"]; /** @description Number of results per page. */ perPage?: components["parameters"]["PerPage"]; + /** @description Search term to combine with API filters. Matches API title. */ + q?: components["parameters"]["Search"]; /** @description Filter on organisation URI. */ organisation?: components["parameters"]["Organisation"]; /** @description Comma-separated list of API IDs. */ @@ -570,6 +554,8 @@ export interface operations { listApiFilters: { parameters: { query?: { + /** @description Search term to combine with API filters. Matches API title. */ + q?: components["parameters"]["Search"]; /** @description Filter on organisation URI. */ organisation?: components["parameters"]["Organisation"]; /** @description Comma-separated list of API IDs. */ @@ -602,42 +588,6 @@ export interface operations { 400: components["responses"]["400"]; }; }; - searchApis: { - parameters: { - query: { - /** @description Page number (1-based). */ - page?: components["parameters"]["Page"]; - /** @description Number of results per page. */ - perPage?: components["parameters"]["PerPage"]; - /** @description Filter on organisation URI. */ - organisation?: components["parameters"]["Organisation"]; - /** @description Search term. */ - q: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - "API-Version": components["headers"]["ApiVersion"]; - Link: components["headers"]["Link"]; - "Total-Count": components["headers"]["TotalCount"]; - "Current-Page": components["headers"]["CurrentPage"]; - "Per-Page": components["headers"]["PerPage"]; - "Total-Pages": components["headers"]["TotalPages"]; - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ApiSummary"][]; - }; - }; - 400: components["responses"]["400"]; - }; - }; listLintResults: { parameters: { query?: never; @@ -871,7 +821,6 @@ export enum ApiPaths { listApis = "/apis", createApi = "/apis", listApiFilters = "/apis/filters", - searchApis = "/apis/_search", listLintResults = "/lint-results", retreiveApi = "/apis/{id}", updateApi = "/apis/{id}", diff --git a/apps/oss-register/src/components/FacetFiltersForm.tsx b/apps/oss-register/src/components/FacetFiltersForm.tsx index db8de4fb..827b4fa5 100644 --- a/apps/oss-register/src/components/FacetFiltersForm.tsx +++ b/apps/oss-register/src/components/FacetFiltersForm.tsx @@ -19,11 +19,18 @@ interface FacetFiltersFormProps { filtersTitle: string; filterButtonLabel: string; }; + hiddenFields?: [string, string][]; } const FacetFiltersForm = (props: FacetFiltersFormProps) => { const formRef = useRef(null); - const { filters, action: formAction, method: formMethod, labels } = props; + const { + filters, + action: formAction, + method: formMethod, + labels, + hiddenFields = [], + } = props; const [{ data, error }, action, pending] = useActionState( withState(actions.getFilters), { @@ -60,6 +67,14 @@ const FacetFiltersForm = (props: FacetFiltersFormProps) => { action={formAction} method={formMethod} > + {hiddenFields.map(([name, value], index) => ( + + ))} key !== SEARCH_QUERY_KEY, +); +const filterHiddenFields: [string, string][] = routingObj.query[ + SEARCH_QUERY_KEY +] + ? [[SEARCH_QUERY_KEY, routingObj.query[SEARCH_QUERY_KEY] as string]] + : []; --- @@ -159,9 +167,23 @@ const labels = { searchObject={searchObject} />
- + - + { facetfiltersError && ( {(facetfiltersError as unknown as any).message || (facetfiltersError as unknown as any).error_msg || `${facetfiltersStatus}: ${facetfiltersStatusText}` || t('components.fuzz-error')} @@ -302,4 +324,4 @@ const labels = { .orgLink { font-size: 0.875rem; } - \ No newline at end of file + diff --git a/apps/oss-register/src/types/api-schema.prod.ts b/apps/oss-register/src/types/api-schema.prod.ts index 3d0d4ec5..a49fcbbc 100644 --- a/apps/oss-register/src/types/api-schema.prod.ts +++ b/apps/oss-register/src/types/api-schema.prod.ts @@ -123,26 +123,6 @@ export interface paths { patch?: never; trace?: never; }; - "/repositories/_search": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** - * Search repositories - * @description Returns a list of OSS repositories included in the register. - */ - get: operations["searchRepositories"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; } export type webhooks = Record; export interface components { @@ -451,8 +431,8 @@ export interface components { LicenseFilter: string[]; /** @description Unique identifier of the resource. */ ResourceId: string; - /** @description Search term. */ - SearchQuery: string; + /** @description Search term to combine with repository filters. Matches repository name, short description, long description, publiccode.yml url and publiccode.yml landingURL. */ + SearchFilter: string; }; requestBodies: never; headers: { @@ -536,6 +516,8 @@ export interface operations { listRepositoryFilters: { parameters: { query?: { + /** @description Search term to combine with repository filters. Matches repository name, short description, long description, publiccode.yml url and publiccode.yml landingURL. */ + q?: components["parameters"]["SearchFilter"]; /** @description Filter by organisation URI. */ organisation?: components["parameters"]["OrganisationFilter"]; /** @description Filter on publiccode.yml presence. true: only repositories with a publiccode.yml URL. Omit or set false for all repositories. */ @@ -581,6 +563,8 @@ export interface operations { page?: components["parameters"]["Page"]; /** @description Number of results per page. */ perPage?: components["parameters"]["PerPage"]; + /** @description Search term to combine with repository filters. Matches repository name, short description, long description, publiccode.yml url and publiccode.yml landingURL. */ + q?: components["parameters"]["SearchFilter"]; /** @description Filter by organisation URI. */ organisation?: components["parameters"]["OrganisationFilter"]; /** @description Filter on publiccode.yml presence. true: only repositories with a publiccode.yml URL. Omit or set false for all repositories. */ @@ -763,42 +747,6 @@ export interface operations { 400: components["responses"]["BadRequest"]; }; }; - searchRepositories: { - parameters: { - query: { - /** @description Page number (1-based). */ - page?: components["parameters"]["Page"]; - /** @description Number of results per page. */ - perPage?: components["parameters"]["PerPage"]; - /** @description Filter by organisation URI. */ - organisation?: components["parameters"]["OrganisationFilter"]; - /** @description Search term. */ - q: components["parameters"]["SearchQuery"]; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - "API-Version": components["headers"]["APIVersion"]; - Link: components["headers"]["Link"]; - "Total-Count": components["headers"]["TotalCount"]; - "Current-Page": components["headers"]["CurrentPage"]; - "Per-Page": components["headers"]["PerPage"]; - "Total-Pages": components["headers"]["TotalPages"]; - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RepositorySummary"][]; - }; - }; - 400: components["responses"]["BadRequest"]; - }; - }; } export enum ApiPaths { listGitOrganisations = "/git-organisations", @@ -810,5 +758,4 @@ export enum ApiPaths { updateRepository = "/repositories/{id}", listOrganisations = "/organisations", createOrganisation = "/organisations", - searchRepositories = "/repositories/_search" } diff --git a/apps/oss-register/src/types/api-schema.test.ts b/apps/oss-register/src/types/api-schema.test.ts index 3d0d4ec5..a49fcbbc 100644 --- a/apps/oss-register/src/types/api-schema.test.ts +++ b/apps/oss-register/src/types/api-schema.test.ts @@ -123,26 +123,6 @@ export interface paths { patch?: never; trace?: never; }; - "/repositories/_search": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** - * Search repositories - * @description Returns a list of OSS repositories included in the register. - */ - get: operations["searchRepositories"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; } export type webhooks = Record; export interface components { @@ -451,8 +431,8 @@ export interface components { LicenseFilter: string[]; /** @description Unique identifier of the resource. */ ResourceId: string; - /** @description Search term. */ - SearchQuery: string; + /** @description Search term to combine with repository filters. Matches repository name, short description, long description, publiccode.yml url and publiccode.yml landingURL. */ + SearchFilter: string; }; requestBodies: never; headers: { @@ -536,6 +516,8 @@ export interface operations { listRepositoryFilters: { parameters: { query?: { + /** @description Search term to combine with repository filters. Matches repository name, short description, long description, publiccode.yml url and publiccode.yml landingURL. */ + q?: components["parameters"]["SearchFilter"]; /** @description Filter by organisation URI. */ organisation?: components["parameters"]["OrganisationFilter"]; /** @description Filter on publiccode.yml presence. true: only repositories with a publiccode.yml URL. Omit or set false for all repositories. */ @@ -581,6 +563,8 @@ export interface operations { page?: components["parameters"]["Page"]; /** @description Number of results per page. */ perPage?: components["parameters"]["PerPage"]; + /** @description Search term to combine with repository filters. Matches repository name, short description, long description, publiccode.yml url and publiccode.yml landingURL. */ + q?: components["parameters"]["SearchFilter"]; /** @description Filter by organisation URI. */ organisation?: components["parameters"]["OrganisationFilter"]; /** @description Filter on publiccode.yml presence. true: only repositories with a publiccode.yml URL. Omit or set false for all repositories. */ @@ -763,42 +747,6 @@ export interface operations { 400: components["responses"]["BadRequest"]; }; }; - searchRepositories: { - parameters: { - query: { - /** @description Page number (1-based). */ - page?: components["parameters"]["Page"]; - /** @description Number of results per page. */ - perPage?: components["parameters"]["PerPage"]; - /** @description Filter by organisation URI. */ - organisation?: components["parameters"]["OrganisationFilter"]; - /** @description Search term. */ - q: components["parameters"]["SearchQuery"]; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - "API-Version": components["headers"]["APIVersion"]; - Link: components["headers"]["Link"]; - "Total-Count": components["headers"]["TotalCount"]; - "Current-Page": components["headers"]["CurrentPage"]; - "Per-Page": components["headers"]["PerPage"]; - "Total-Pages": components["headers"]["TotalPages"]; - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RepositorySummary"][]; - }; - }; - 400: components["responses"]["BadRequest"]; - }; - }; } export enum ApiPaths { listGitOrganisations = "/git-organisations", @@ -810,5 +758,4 @@ export enum ApiPaths { updateRepository = "/repositories/{id}", listOrganisations = "/organisations", createOrganisation = "/organisations", - searchRepositories = "/repositories/_search" } diff --git a/packages/components/src/search/Search.tsx b/packages/components/src/search/Search.tsx index 9d014a05..9a7f7730 100644 --- a/packages/components/src/search/Search.tsx +++ b/packages/components/src/search/Search.tsx @@ -14,12 +14,19 @@ export interface SearchProps { searchUrl: string; searchKey?: string; searchTerm?: string; + hiddenFields?: [string, string][]; className?: string; } const Search = (props: SearchProps) => { const { t } = useTranslation(); - const { searchUrl, searchKey = "q", searchTerm, className } = props; + const { + searchUrl, + searchKey = "q", + searchTerm, + hiddenFields = [], + className, + } = props; return ( { {t("components.search")}
+ {hiddenFields.map(([name, value], index) => ( + + ))}