Support for filter by parent document (#6850)
* Backend support for filter by parent document * parentDocumentId -> documentId
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
|||||||
EditIcon,
|
EditIcon,
|
||||||
PadlockIcon,
|
PadlockIcon,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
|
SearchIcon,
|
||||||
StarredIcon,
|
StarredIcon,
|
||||||
TrashIcon,
|
TrashIcon,
|
||||||
UnstarredIcon,
|
UnstarredIcon,
|
||||||
@@ -20,6 +21,7 @@ import { createAction } from "~/actions";
|
|||||||
import { CollectionSection } from "~/actions/sections";
|
import { CollectionSection } from "~/actions/sections";
|
||||||
import { setPersistedState } from "~/hooks/usePersistedState";
|
import { setPersistedState } from "~/hooks/usePersistedState";
|
||||||
import history from "~/utils/history";
|
import history from "~/utils/history";
|
||||||
|
import { searchPath } from "~/utils/routeHelpers";
|
||||||
|
|
||||||
const ColorCollectionIcon = ({ collection }: { collection: Collection }) => (
|
const ColorCollectionIcon = ({ collection }: { collection: Collection }) => (
|
||||||
<DynamicCollectionIcon collection={collection} />
|
<DynamicCollectionIcon collection={collection} />
|
||||||
@@ -111,6 +113,17 @@ export const editCollectionPermissions = createAction({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const searchInCollection = createAction({
|
||||||
|
name: ({ t }) => t("Search in collection"),
|
||||||
|
analyticsName: "Search collection",
|
||||||
|
section: CollectionSection,
|
||||||
|
icon: <SearchIcon />,
|
||||||
|
visible: ({ activeCollectionId }) => !!activeCollectionId,
|
||||||
|
perform: ({ activeCollectionId }) => {
|
||||||
|
history.push(searchPath(undefined, { collectionId: activeCollectionId }));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const starCollection = createAction({
|
export const starCollection = createAction({
|
||||||
name: ({ t }) => t("Star"),
|
name: ({ t }) => t("Star"),
|
||||||
analyticsName: "Star collection",
|
analyticsName: "Star collection",
|
||||||
|
|||||||
@@ -606,6 +606,17 @@ export const pinDocument = createAction({
|
|||||||
children: [pinDocumentToCollection, pinDocumentToHome],
|
children: [pinDocumentToCollection, pinDocumentToHome],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const searchInDocument = createAction({
|
||||||
|
name: ({ t }) => t("Search in document"),
|
||||||
|
analyticsName: "Search document",
|
||||||
|
section: DocumentSection,
|
||||||
|
icon: <SearchIcon />,
|
||||||
|
visible: ({ activeDocumentId }) => !!activeDocumentId,
|
||||||
|
perform: ({ activeDocumentId }) => {
|
||||||
|
history.push(searchPath(undefined, { documentId: activeDocumentId }));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const printDocument = createAction({
|
export const printDocument = createAction({
|
||||||
name: ({ t, isContextMenu }) =>
|
name: ({ t, isContextMenu }) =>
|
||||||
isContextMenu ? t("Print") : t("Print document"),
|
isContextMenu ? t("Print") : t("Print document"),
|
||||||
@@ -613,7 +624,7 @@ export const printDocument = createAction({
|
|||||||
section: DocumentSection,
|
section: DocumentSection,
|
||||||
icon: <PrintIcon />,
|
icon: <PrintIcon />,
|
||||||
visible: ({ activeDocumentId }) => !!(activeDocumentId && window.print),
|
visible: ({ activeDocumentId }) => !!(activeDocumentId && window.print),
|
||||||
perform: async () => {
|
perform: () => {
|
||||||
queueMicrotask(window.print);
|
queueMicrotask(window.print);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const FilterOptions = ({
|
|||||||
: "";
|
: "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<div>
|
||||||
<MenuButton {...menu}>
|
<MenuButton {...menu}>
|
||||||
{(props) => (
|
{(props) => (
|
||||||
<StyledButton {...props} className={className} neutral disclosure>
|
<StyledButton {...props} className={className} neutral disclosure>
|
||||||
@@ -76,7 +76,7 @@ const FilterOptions = ({
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</Wrapper>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ const LabelWithNote = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledButton = styled(Button)`
|
export const StyledButton = styled(Button)`
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
@@ -120,8 +120,4 @@ const Icon = styled.div`
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
|
||||||
margin-right: 8px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default FilterOptions;
|
export default FilterOptions;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default function useActionContext(
|
|||||||
isContextMenu: false,
|
isContextMenu: false,
|
||||||
isCommandBar: false,
|
isCommandBar: false,
|
||||||
isButton: false,
|
isButton: false,
|
||||||
activeCollectionId: stores.ui.activeCollectionId,
|
activeCollectionId: stores.ui.activeCollectionId ?? undefined,
|
||||||
activeDocumentId: stores.ui.activeDocumentId,
|
activeDocumentId: stores.ui.activeDocumentId,
|
||||||
currentUserId: stores.auth.user?.id,
|
currentUserId: stores.auth.user?.id,
|
||||||
currentTeamId: stores.auth.team?.id,
|
currentTeamId: stores.auth.team?.id,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
editCollectionPermissions,
|
editCollectionPermissions,
|
||||||
starCollection,
|
starCollection,
|
||||||
unstarCollection,
|
unstarCollection,
|
||||||
|
searchInCollection,
|
||||||
} from "~/actions/definitions/collections";
|
} from "~/actions/definitions/collections";
|
||||||
import useActionContext from "~/hooks/useActionContext";
|
import useActionContext from "~/hooks/useActionContext";
|
||||||
import useCurrentTeam from "~/hooks/useCurrentTeam";
|
import useCurrentTeam from "~/hooks/useCurrentTeam";
|
||||||
@@ -205,6 +206,7 @@ function CollectionMenu({
|
|||||||
onClick: handleExport,
|
onClick: handleExport,
|
||||||
icon: <ExportIcon />,
|
icon: <ExportIcon />,
|
||||||
},
|
},
|
||||||
|
actionToMenuItem(searchInCollection, context),
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: "separator",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import {
|
|||||||
createNestedDocument,
|
createNestedDocument,
|
||||||
shareDocument,
|
shareDocument,
|
||||||
copyDocument,
|
copyDocument,
|
||||||
|
searchInDocument,
|
||||||
} from "~/actions/definitions/documents";
|
} from "~/actions/definitions/documents";
|
||||||
import useActionContext from "~/hooks/useActionContext";
|
import useActionContext from "~/hooks/useActionContext";
|
||||||
import useCurrentUser from "~/hooks/useCurrentUser";
|
import useCurrentUser from "~/hooks/useCurrentUser";
|
||||||
@@ -94,7 +95,7 @@ function DocumentMenu({
|
|||||||
const context = useActionContext({
|
const context = useActionContext({
|
||||||
isContextMenu: true,
|
isContextMenu: true,
|
||||||
activeDocumentId: document.id,
|
activeDocumentId: document.id,
|
||||||
activeCollectionId: document.collectionId,
|
activeCollectionId: document.collectionId ?? undefined,
|
||||||
});
|
});
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isMobile = useMobile();
|
const isMobile = useMobile();
|
||||||
@@ -305,6 +306,7 @@ function DocumentMenu({
|
|||||||
actionToMenuItem(downloadDocument, context),
|
actionToMenuItem(downloadDocument, context),
|
||||||
actionToMenuItem(copyDocument, context),
|
actionToMenuItem(copyDocument, context),
|
||||||
actionToMenuItem(printDocument, context),
|
actionToMenuItem(printDocument, context),
|
||||||
|
actionToMenuItem(searchInDocument, context),
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: "separator",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { searchPath } from "~/utils/routeHelpers";
|
|||||||
import { decodeURIComponentSafe } from "~/utils/urls";
|
import { decodeURIComponentSafe } from "~/utils/urls";
|
||||||
import CollectionFilter from "./components/CollectionFilter";
|
import CollectionFilter from "./components/CollectionFilter";
|
||||||
import DateFilter from "./components/DateFilter";
|
import DateFilter from "./components/DateFilter";
|
||||||
|
import { DocumentFilter } from "./components/DocumentFilter";
|
||||||
import DocumentTypeFilter from "./components/DocumentTypeFilter";
|
import DocumentTypeFilter from "./components/DocumentTypeFilter";
|
||||||
import RecentSearches from "./components/RecentSearches";
|
import RecentSearches from "./components/RecentSearches";
|
||||||
import SearchInput from "./components/SearchInput";
|
import SearchInput from "./components/SearchInput";
|
||||||
@@ -59,11 +60,13 @@ function Search(props: Props) {
|
|||||||
const query = decodeURIComponentSafe(routeMatch.params.term ?? "");
|
const query = decodeURIComponentSafe(routeMatch.params.term ?? "");
|
||||||
const collectionId = params.get("collectionId") ?? undefined;
|
const collectionId = params.get("collectionId") ?? undefined;
|
||||||
const userId = params.get("userId") ?? undefined;
|
const userId = params.get("userId") ?? undefined;
|
||||||
|
const documentId = params.get("documentId") ?? undefined;
|
||||||
const dateFilter = (params.get("dateFilter") as TDateFilter) ?? undefined;
|
const dateFilter = (params.get("dateFilter") as TDateFilter) ?? undefined;
|
||||||
const statusFilter = params.getAll("statusFilter")?.length
|
const statusFilter = params.getAll("statusFilter")?.length
|
||||||
? (params.getAll("statusFilter") as TStatusFilter[])
|
? (params.getAll("statusFilter") as TStatusFilter[])
|
||||||
: [TStatusFilter.Published, TStatusFilter.Draft];
|
: [TStatusFilter.Published, TStatusFilter.Draft];
|
||||||
const titleFilter = params.get("titleFilter") === "true";
|
const titleFilter = params.get("titleFilter") === "true";
|
||||||
|
const hasFilters = !!(documentId || collectionId || userId || dateFilter);
|
||||||
|
|
||||||
const filters = React.useMemo(
|
const filters = React.useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -73,6 +76,7 @@ function Search(props: Props) {
|
|||||||
userId,
|
userId,
|
||||||
dateFilter,
|
dateFilter,
|
||||||
titleFilter,
|
titleFilter,
|
||||||
|
documentId,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
query,
|
query,
|
||||||
@@ -81,6 +85,7 @@ function Search(props: Props) {
|
|||||||
userId,
|
userId,
|
||||||
dateFilter,
|
dateFilter,
|
||||||
titleFilter,
|
titleFilter,
|
||||||
|
documentId,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -107,6 +112,8 @@ function Search(props: Props) {
|
|||||||
limit: Pagination.defaultLimit,
|
limit: Pagination.defaultLimit,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const document = documentId ? documents.get(documentId) : undefined;
|
||||||
|
|
||||||
const updateLocation = (query: string) => {
|
const updateLocation = (query: string) => {
|
||||||
history.replace({
|
history.replace({
|
||||||
pathname: searchPath(query),
|
pathname: searchPath(query),
|
||||||
@@ -118,6 +125,7 @@ function Search(props: Props) {
|
|||||||
// some complexity as the query string is the source of truth for the filters.
|
// some complexity as the query string is the source of truth for the filters.
|
||||||
const handleFilterChange = (search: {
|
const handleFilterChange = (search: {
|
||||||
collectionId?: string | undefined;
|
collectionId?: string | undefined;
|
||||||
|
documentId?: string | undefined;
|
||||||
userId?: string | undefined;
|
userId?: string | undefined;
|
||||||
dateFilter?: TDateFilter;
|
dateFilter?: TDateFilter;
|
||||||
statusFilter?: TStatusFilter[];
|
statusFilter?: TStatusFilter[];
|
||||||
@@ -206,44 +214,58 @@ function Search(props: Props) {
|
|||||||
<SearchInput
|
<SearchInput
|
||||||
key={query ? "search" : "recent"}
|
key={query ? "search" : "recent"}
|
||||||
ref={searchInputRef}
|
ref={searchInputRef}
|
||||||
placeholder={`${t("Search")}…`}
|
placeholder={`${
|
||||||
|
documentId
|
||||||
|
? t("Search in document")
|
||||||
|
: collectionId
|
||||||
|
? t("Search in collection")
|
||||||
|
: t("Search")
|
||||||
|
}…`}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
defaultValue={query}
|
defaultValue={query}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{(query || hasFilters) && (
|
||||||
|
<Filters>
|
||||||
|
{document && (
|
||||||
|
<DocumentFilter
|
||||||
|
document={document}
|
||||||
|
onClick={() => {
|
||||||
|
handleFilterChange({ documentId: undefined });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<DocumentTypeFilter
|
||||||
|
statusFilter={statusFilter}
|
||||||
|
onSelect={({ statusFilter }) =>
|
||||||
|
handleFilterChange({ statusFilter })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<CollectionFilter
|
||||||
|
collectionId={collectionId}
|
||||||
|
onSelect={(collectionId) => handleFilterChange({ collectionId })}
|
||||||
|
/>
|
||||||
|
<UserFilter
|
||||||
|
userId={userId}
|
||||||
|
onSelect={(userId) => handleFilterChange({ userId })}
|
||||||
|
/>
|
||||||
|
<DateFilter
|
||||||
|
dateFilter={dateFilter}
|
||||||
|
onSelect={(dateFilter) => handleFilterChange({ dateFilter })}
|
||||||
|
/>
|
||||||
|
<SearchTitlesFilter
|
||||||
|
width={26}
|
||||||
|
height={14}
|
||||||
|
label={t("Search titles only")}
|
||||||
|
onChange={(ev: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
handleFilterChange({ titleFilter: ev.target.checked });
|
||||||
|
}}
|
||||||
|
checked={titleFilter}
|
||||||
|
/>
|
||||||
|
</Filters>
|
||||||
|
)}
|
||||||
{query ? (
|
{query ? (
|
||||||
<>
|
<>
|
||||||
<Filters>
|
|
||||||
<DocumentTypeFilter
|
|
||||||
statusFilter={statusFilter}
|
|
||||||
onSelect={({ statusFilter }) =>
|
|
||||||
handleFilterChange({ statusFilter })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<CollectionFilter
|
|
||||||
collectionId={collectionId}
|
|
||||||
onSelect={(collectionId) =>
|
|
||||||
handleFilterChange({ collectionId })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<UserFilter
|
|
||||||
userId={userId}
|
|
||||||
onSelect={(userId) => handleFilterChange({ userId })}
|
|
||||||
/>
|
|
||||||
<DateFilter
|
|
||||||
dateFilter={dateFilter}
|
|
||||||
onSelect={(dateFilter) => handleFilterChange({ dateFilter })}
|
|
||||||
/>
|
|
||||||
<SearchTitlesFilter
|
|
||||||
width={26}
|
|
||||||
height={14}
|
|
||||||
label={t("Search titles only")}
|
|
||||||
onChange={(ev: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
handleFilterChange({ titleFilter: ev.target.checked });
|
|
||||||
}}
|
|
||||||
checked={titleFilter}
|
|
||||||
/>
|
|
||||||
</Filters>
|
|
||||||
{showEmpty && (
|
{showEmpty && (
|
||||||
<Fade>
|
<Fade>
|
||||||
<Centered column>
|
<Centered column>
|
||||||
@@ -282,7 +304,7 @@ function Search(props: Props) {
|
|||||||
/>
|
/>
|
||||||
</ResultList>
|
</ResultList>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : documentId || collectionId ? null : (
|
||||||
<RecentSearches
|
<RecentSearches
|
||||||
ref={recentSearchesCompositeRef}
|
ref={recentSearchesCompositeRef}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
@@ -323,6 +345,7 @@ const Filters = styled(Flex)`
|
|||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
|
gap: 8px;
|
||||||
${hideScrollbars()}
|
${hideScrollbars()}
|
||||||
|
|
||||||
${breakpoint("tablet")`
|
${breakpoint("tablet")`
|
||||||
|
|||||||
25
app/scenes/Search/components/DocumentFilter.tsx
Normal file
25
app/scenes/Search/components/DocumentFilter.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { CloseIcon } from "outline-icons";
|
||||||
|
import * as React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import Document from "~/models/Document";
|
||||||
|
import { StyledButton } from "~/components/FilterOptions";
|
||||||
|
import Tooltip from "~/components/Tooltip";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
document: Document;
|
||||||
|
onClick: React.MouseEventHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function DocumentFilter(props: Props) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Tooltip content={t("Remove document filter")} delay={350}>
|
||||||
|
<StyledButton onClick={props.onClick} icon={<CloseIcon />} neutral>
|
||||||
|
{props.document.title}
|
||||||
|
</StyledButton>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -83,7 +83,7 @@ export type ActionContext = {
|
|||||||
isCommandBar: boolean;
|
isCommandBar: boolean;
|
||||||
isButton: boolean;
|
isButton: boolean;
|
||||||
inStarredSection?: boolean;
|
inStarredSection?: boolean;
|
||||||
activeCollectionId?: string | null;
|
activeCollectionId?: string | undefined;
|
||||||
activeDocumentId: string | undefined;
|
activeDocumentId: string | undefined;
|
||||||
currentUserId: string | undefined;
|
currentUserId: string | undefined;
|
||||||
currentTeamId: string | undefined;
|
currentTeamId: string | undefined;
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ export function searchPath(
|
|||||||
query?: string,
|
query?: string,
|
||||||
params: {
|
params: {
|
||||||
collectionId?: string;
|
collectionId?: string;
|
||||||
|
documentId?: string;
|
||||||
ref?: string;
|
ref?: string;
|
||||||
} = {}
|
} = {}
|
||||||
): string {
|
): string {
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ type SearchOptions = {
|
|||||||
dateFilter?: DateFilter;
|
dateFilter?: DateFilter;
|
||||||
/** Status of the documents to return */
|
/** Status of the documents to return */
|
||||||
statusFilter?: StatusFilter[];
|
statusFilter?: StatusFilter[];
|
||||||
|
/** Limit results to a list of documents. */
|
||||||
|
documentIds?: string[];
|
||||||
/** Limit results to a list of users that collaborated on the document. */
|
/** Limit results to a list of users that collaborated on the document. */
|
||||||
collaboratorIds?: string[];
|
collaboratorIds?: string[];
|
||||||
/** The minimum number of words to be returned in the contextual snippet */
|
/** The minimum number of words to be returned in the contextual snippet */
|
||||||
@@ -367,6 +369,12 @@ export default class SearchHelper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.documentIds) {
|
||||||
|
where[Op.and].push({
|
||||||
|
id: options.documentIds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const statusQuery = [];
|
const statusQuery = [];
|
||||||
if (options.statusFilter?.includes(StatusFilter.Published)) {
|
if (options.statusFilter?.includes(StatusFilter.Published)) {
|
||||||
statusQuery.push({
|
statusQuery.push({
|
||||||
|
|||||||
@@ -785,6 +785,7 @@ router.post(
|
|||||||
const {
|
const {
|
||||||
query,
|
query,
|
||||||
collectionId,
|
collectionId,
|
||||||
|
documentId,
|
||||||
userId,
|
userId,
|
||||||
dateFilter,
|
dateFilter,
|
||||||
statusFilter = [],
|
statusFilter = [],
|
||||||
@@ -853,6 +854,18 @@ router.post(
|
|||||||
authorize(user, "readDocument", collection);
|
authorize(user, "readDocument", collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let documentIds = undefined;
|
||||||
|
if (documentId) {
|
||||||
|
const document = await Document.findByPk(documentId, {
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
authorize(user, "read", document);
|
||||||
|
documentIds = [
|
||||||
|
documentId,
|
||||||
|
...(await document.findAllChildDocumentIds()),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
let collaboratorIds = undefined;
|
let collaboratorIds = undefined;
|
||||||
|
|
||||||
if (userId) {
|
if (userId) {
|
||||||
@@ -862,6 +875,7 @@ router.post(
|
|||||||
response = await SearchHelper.searchForUser(user, query, {
|
response = await SearchHelper.searchForUser(user, query, {
|
||||||
collaboratorIds,
|
collaboratorIds,
|
||||||
collectionId,
|
collectionId,
|
||||||
|
documentIds,
|
||||||
dateFilter,
|
dateFilter,
|
||||||
statusFilter,
|
statusFilter,
|
||||||
offset,
|
offset,
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ export const DocumentsSearchSchema = BaseSchema.extend({
|
|||||||
/** Filter results based on user */
|
/** Filter results based on user */
|
||||||
userId: z.string().uuid().optional(),
|
userId: z.string().uuid().optional(),
|
||||||
|
|
||||||
|
/** Filter results based on content within a document and it's children */
|
||||||
|
documentId: z.string().uuid().optional(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to include archived documents in results
|
* Whether to include archived documents in results
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"Edit collection": "Edit collection",
|
"Edit collection": "Edit collection",
|
||||||
"Permissions": "Permissions",
|
"Permissions": "Permissions",
|
||||||
"Collection permissions": "Collection permissions",
|
"Collection permissions": "Collection permissions",
|
||||||
|
"Search in collection": "Search in collection",
|
||||||
"Star": "Star",
|
"Star": "Star",
|
||||||
"Unstar": "Unstar",
|
"Unstar": "Unstar",
|
||||||
"Delete": "Delete",
|
"Delete": "Delete",
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
"Pin to home": "Pin to home",
|
"Pin to home": "Pin to home",
|
||||||
"Pinned to home": "Pinned to home",
|
"Pinned to home": "Pinned to home",
|
||||||
"Pin": "Pin",
|
"Pin": "Pin",
|
||||||
|
"Search in document": "Search in document",
|
||||||
"Print": "Print",
|
"Print": "Print",
|
||||||
"Print document": "Print document",
|
"Print document": "Print document",
|
||||||
"Import document": "Import document",
|
"Import document": "Import document",
|
||||||
@@ -483,7 +485,6 @@
|
|||||||
"API token created": "API token created",
|
"API token created": "API token created",
|
||||||
"Name your token something that will help you to remember it's use in the future, for example \"local development\", \"production\", or \"continuous integration\".": "Name your token something that will help you to remember it's use in the future, for example \"local development\", \"production\", or \"continuous integration\".",
|
"Name your token something that will help you to remember it's use in the future, for example \"local development\", \"production\", or \"continuous integration\".": "Name your token something that will help you to remember it's use in the future, for example \"local development\", \"production\", or \"continuous integration\".",
|
||||||
"The document archive is empty at the moment.": "The document archive is empty at the moment.",
|
"The document archive is empty at the moment.": "The document archive is empty at the moment.",
|
||||||
"Search in collection": "Search in collection",
|
|
||||||
"This collection is only visible to those given access": "This collection is only visible to those given access",
|
"This collection is only visible to those given access": "This collection is only visible to those given access",
|
||||||
"Private": "Private",
|
"Private": "Private",
|
||||||
"Recently updated": "Recently updated",
|
"Recently updated": "Recently updated",
|
||||||
@@ -763,6 +764,7 @@
|
|||||||
"Past week": "Past week",
|
"Past week": "Past week",
|
||||||
"Past month": "Past month",
|
"Past month": "Past month",
|
||||||
"Past year": "Past year",
|
"Past year": "Past year",
|
||||||
|
"Remove document filter": "Remove document filter",
|
||||||
"Any status": "Any status",
|
"Any status": "Any status",
|
||||||
"Search Results": "Search Results",
|
"Search Results": "Search Results",
|
||||||
"Remove search": "Remove search",
|
"Remove search": "Remove search",
|
||||||
|
|||||||
Reference in New Issue
Block a user