improv: use statusFilter instead of includeArchive,includeDrafts for document search (#6537)

* improv: use statusFilter instead of includeArchive,includeDrafts for document search

* improv: update FilterComponent to add support for multiple selected items

* feat: update document type search ui

* fix test

* Restore support for old parameters to avoid breaking change

---------

Co-authored-by: Tom Moor <tom.moor@gmail.com>
This commit is contained in:
Pranav Joglekar
2024-02-25 00:32:19 +05:30
committed by GitHub
parent b7f0af9b85
commit 50b90b8878
15 changed files with 426 additions and 191 deletions

View File

@@ -1,6 +1,10 @@
import { faker } from "@faker-js/faker";
import { addMinutes, subDays } from "date-fns";
import { CollectionPermission, DocumentPermission } from "@shared/types";
import {
CollectionPermission,
DocumentPermission,
StatusFilter,
} from "@shared/types";
import {
Document,
View,
@@ -1104,7 +1108,7 @@ describe("#documents.search_titles", () => {
body: {
token: member.getJwtToken(),
query: "title",
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
},
});
const body = await res.json();
@@ -1215,7 +1219,7 @@ describe("#documents.search_titles", () => {
body: {
token: user.getJwtToken(),
query: "SECRET",
includeArchived: true,
statusFilter: [StatusFilter.Archived],
},
});
const body = await res.json();
@@ -1235,7 +1239,7 @@ describe("#documents.search_titles", () => {
body: {
token: user.getJwtToken(),
query: "SECRET",
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
},
});
const body = await res.json();
@@ -1282,6 +1286,7 @@ describe("#documents.search_titles", () => {
body: {
token: user.getJwtToken(),
query: "SECRET",
statusFilter: [StatusFilter.Published, StatusFilter.Draft],
},
});
const body = await res.json();
@@ -1371,7 +1376,7 @@ describe("#documents.search", () => {
body: {
token: user.getJwtToken(),
shareId: share.id,
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
query: "test",
},
});
@@ -1540,6 +1545,7 @@ describe("#documents.search", () => {
body: {
token: user.getJwtToken(),
query: "search term",
statusFilter: [StatusFilter.Published, StatusFilter.Archived],
},
});
const body = await res.json();
@@ -1574,7 +1580,7 @@ describe("#documents.search", () => {
body: {
token: user.getJwtToken(),
query: "search term",
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
},
});
const body = await res.json();
@@ -1595,7 +1601,7 @@ describe("#documents.search", () => {
const res = await server.post("/api/documents.search", {
body: {
token: user.getJwtToken(),
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
query: "text",
},
});
@@ -1616,7 +1622,7 @@ describe("#documents.search", () => {
body: {
token: user.getJwtToken(),
query: "search term",
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
},
});
const body = await res.json();
@@ -1636,6 +1642,7 @@ describe("#documents.search", () => {
body: {
token: user.getJwtToken(),
query: "search term",
statusFilter: [StatusFilter.Published, StatusFilter.Draft],
},
});
const body = await res.json();
@@ -1655,7 +1662,7 @@ describe("#documents.search", () => {
body: {
token: user.getJwtToken(),
query: "search term",
includeArchived: true,
statusFilter: [StatusFilter.Archived],
},
});
const body = await res.json();
@@ -1899,7 +1906,7 @@ describe("#documents.search", () => {
body: {
token: member.getJwtToken(),
query: "title",
includeDrafts: true,
statusFilter: [StatusFilter.Draft],
},
});
const body = await res.json();

View File

@@ -7,7 +7,7 @@ import Router from "koa-router";
import escapeRegExp from "lodash/escapeRegExp";
import mime from "mime-types";
import { Op, ScopeOptions, Sequelize, WhereOptions } from "sequelize";
import { TeamPreference } from "@shared/types";
import { StatusFilter, TeamPreference } from "@shared/types";
import { subtractDate } from "@shared/utils/date";
import slugify from "@shared/utils/slugify";
import documentCreator from "@server/commands/documentCreator";
@@ -732,14 +732,8 @@ router.post(
rateLimiter(RateLimiterStrategy.OneHundredPerMinute),
validate(T.DocumentsSearchSchema),
async (ctx: APIContext<T.DocumentsSearchReq>) => {
const {
query,
includeArchived,
includeDrafts,
dateFilter,
collectionId,
userId,
} = ctx.input.body;
const { query, statusFilter, dateFilter, collectionId, userId } =
ctx.input.body;
const { offset, limit } = ctx.state.pagination;
const { user } = ctx.state.auth;
let collaboratorIds = undefined;
@@ -756,9 +750,8 @@ router.post(
}
const documents = await SearchHelper.searchTitlesForUser(user, query, {
includeArchived,
includeDrafts,
dateFilter,
statusFilter,
collectionId,
collaboratorIds,
offset,
@@ -786,11 +779,12 @@ router.post(
async (ctx: APIContext<T.DocumentsSearchReq>) => {
const {
query,
includeArchived,
includeDrafts,
collectionId,
userId,
dateFilter,
statusFilter = [],
includeArchived,
includeDrafts,
shareId,
snippetMinWords,
snippetMaxWords,
@@ -800,6 +794,14 @@ router.post(
// Unfortunately, this still doesn't adequately handle cases when auth is optional
const { user } = ctx.state.auth;
// TODO: Deprecated filter options, remove in a few versions
if (includeArchived && !statusFilter.includes(StatusFilter.Archived)) {
statusFilter.push(StatusFilter.Archived);
}
if (includeDrafts && !statusFilter.includes(StatusFilter.Draft)) {
statusFilter.push(StatusFilter.Draft);
}
let teamId;
let response;
let share;
@@ -823,11 +825,10 @@ router.post(
invariant(team, "Share must belong to a team");
response = await SearchHelper.searchForTeam(team, query, {
includeArchived,
includeDrafts,
collectionId: document.collectionId,
share,
dateFilter,
statusFilter,
offset,
limit,
snippetMinWords,
@@ -854,11 +855,10 @@ router.post(
}
response = await SearchHelper.searchForUser(user, query, {
includeArchived,
includeDrafts,
collaboratorIds,
collectionId,
dateFilter,
statusFilter,
offset,
limit,
snippetMinWords,

View File

@@ -3,7 +3,7 @@ import formidable from "formidable";
import isEmpty from "lodash/isEmpty";
import isUUID from "validator/lib/isUUID";
import { z } from "zod";
import { DocumentPermission } from "@shared/types";
import { DocumentPermission, StatusFilter } from "@shared/types";
import { SHARE_URL_SLUG_REGEX } from "@shared/utils/urlHelpers";
import { BaseSchema } from "@server/routes/api/schema";
@@ -147,18 +147,29 @@ export type DocumentsRestoreReq = z.infer<typeof DocumentsRestoreSchema>;
export const DocumentsSearchSchema = BaseSchema.extend({
body: SearchQuerySchema.merge(DateFilterSchema).extend({
/** Whether to include archived docs in results */
includeArchived: z.boolean().optional(),
/** Whether to include drafts in results */
includeDrafts: z.boolean().optional(),
/** Filter results for team based on the collection */
collectionId: z.string().uuid().optional(),
/** Filter results based on user */
userId: z.string().uuid().optional(),
/**
* Whether to include archived documents in results
*
* @deprecated Use `statusFilter` instead
*/
includeArchived: z.boolean().optional(),
/**
* Whether to include draft documents in results
*
* @deprecated Use `statusFilter` instead
*/
includeDrafts: z.boolean().optional(),
/** Document statuses to include in results */
statusFilter: z.nativeEnum(StatusFilter).array().optional(),
/** Filter results for the team derived from shareId */
shareId: z
.string()