mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
stash
This commit is contained in:
@@ -1007,6 +1007,102 @@ describe("#documents.list", () => {
|
||||
expect(body.data.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should allow advanced filtering", async () => {
|
||||
const user = await buildUser();
|
||||
await buildDocument({
|
||||
title: "First document",
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await buildDocument({
|
||||
title: "Second document",
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
const res = await server.post("/api/documents.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
filter: {
|
||||
field: "title",
|
||||
operator: "contains",
|
||||
value: "First",
|
||||
},
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.length).toEqual(1);
|
||||
expect(body.data[0].title).toEqual("First document");
|
||||
});
|
||||
|
||||
it("should allow advanced filtering with logical operators", async () => {
|
||||
const user = await buildUser();
|
||||
await buildDocument({
|
||||
title: "First document",
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await buildDocument({
|
||||
title: "Second document",
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
const res = await server.post("/api/documents.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
filter: {
|
||||
operator: "OR",
|
||||
filters: [
|
||||
{
|
||||
field: "title",
|
||||
operator: "eq",
|
||||
value: "First document",
|
||||
},
|
||||
{
|
||||
field: "title",
|
||||
operator: "eq",
|
||||
value: "Second document",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.length).toEqual(2);
|
||||
});
|
||||
|
||||
it("should allow filtering to include archived", async () => {
|
||||
const user = await buildUser();
|
||||
await buildDocument({
|
||||
title: "First document",
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await buildDocument({
|
||||
title: "Second document",
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
archivedAt: new Date(),
|
||||
});
|
||||
|
||||
const res = await server.post("/api/documents.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
filter: {
|
||||
field: "archivedAt",
|
||||
operator: "isNotNull",
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should allow filtering to private collection", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
|
||||
@@ -58,6 +58,7 @@ import { DocumentHelper } from "@server/models/helpers/DocumentHelper";
|
||||
import { ProsemirrorHelper } from "@server/models/helpers/ProsemirrorHelper";
|
||||
import SearchHelper from "@server/models/helpers/SearchHelper";
|
||||
import { TextHelper } from "@server/models/helpers/TextHelper";
|
||||
import { buildWhere } from "@server/models/filters/Filters";
|
||||
import { authorize, can, cannot } from "@server/policies";
|
||||
import {
|
||||
presentDocument,
|
||||
@@ -97,6 +98,7 @@ router.post(
|
||||
parentDocumentId,
|
||||
userId: createdById,
|
||||
statusFilter,
|
||||
filter,
|
||||
} = ctx.input.body;
|
||||
|
||||
// always filter by the current team
|
||||
@@ -114,8 +116,12 @@ router.post(
|
||||
],
|
||||
};
|
||||
|
||||
if (filter) {
|
||||
where[Op.and].push(buildWhere(filter));
|
||||
}
|
||||
|
||||
// Exclude archived docs by default
|
||||
if (!statusFilter) {
|
||||
if (!statusFilter && !filter) {
|
||||
where[Op.and].push({ archivedAt: { [Op.eq]: null } });
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DocumentPermission, StatusFilter } from "@shared/types";
|
||||
import { BaseSchema } from "@server/routes/api/schema";
|
||||
import { zodIconType, zodIdType, zodShareIdType } from "@server/utils/zod";
|
||||
import { ValidateColor } from "@server/validation";
|
||||
import { builderFilterSchema } from "@shared/helpers/FilterHelper";
|
||||
|
||||
const DocumentsSortParamsSchema = z.object({
|
||||
/** Specifies the attributes by which documents will be sorted in the list */
|
||||
@@ -69,6 +70,17 @@ const BaseIdSchema = z.object({
|
||||
id: zodIdType(),
|
||||
});
|
||||
|
||||
const filter = builderFilterSchema(
|
||||
z.enum([
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"archivedAt",
|
||||
"publishedAt",
|
||||
"title",
|
||||
"templateId",
|
||||
])
|
||||
);
|
||||
|
||||
export const DocumentsListSchema = BaseSchema.extend({
|
||||
body: DocumentsSortParamsSchema.extend({
|
||||
/** Id of the user who created the doc */
|
||||
@@ -94,6 +106,9 @@ export const DocumentsListSchema = BaseSchema.extend({
|
||||
|
||||
/** Document statuses to include in results */
|
||||
statusFilter: z.nativeEnum(StatusFilter).array().optional(),
|
||||
|
||||
/** Advanced filters */
|
||||
filter: filter.FilterSchema.optional(),
|
||||
}),
|
||||
// Maintains backwards compatibility
|
||||
}).transform((req) => {
|
||||
|
||||
Reference in New Issue
Block a user