feat: Show recent searches (#2868)
* stash * root hookup * recent searches UI * feat: Add search query deletion * simplify no results state * lint
This commit is contained in:
@@ -50,6 +50,8 @@ export default class BaseStore<T extends BaseModel> {
|
||||
|
||||
modelName: string;
|
||||
|
||||
apiEndpoint: string;
|
||||
|
||||
rootStore: RootStore;
|
||||
|
||||
actions = [
|
||||
@@ -65,6 +67,10 @@ export default class BaseStore<T extends BaseModel> {
|
||||
this.rootStore = rootStore;
|
||||
this.model = model;
|
||||
this.modelName = modelNameFromClassName(model.name);
|
||||
|
||||
if (!this.apiEndpoint) {
|
||||
this.apiEndpoint = `${this.modelName}s`;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -125,7 +131,7 @@ export default class BaseStore<T extends BaseModel> {
|
||||
this.isSaving = true;
|
||||
|
||||
try {
|
||||
const res = await client.post(`/${this.modelName}s.create`, {
|
||||
const res = await client.post(`/${this.apiEndpoint}.create`, {
|
||||
...params,
|
||||
...options,
|
||||
});
|
||||
@@ -150,7 +156,7 @@ export default class BaseStore<T extends BaseModel> {
|
||||
this.isSaving = true;
|
||||
|
||||
try {
|
||||
const res = await client.post(`/${this.modelName}s.update`, {
|
||||
const res = await client.post(`/${this.apiEndpoint}.update`, {
|
||||
...params,
|
||||
...options,
|
||||
});
|
||||
@@ -172,7 +178,7 @@ export default class BaseStore<T extends BaseModel> {
|
||||
this.isSaving = true;
|
||||
|
||||
try {
|
||||
await client.post(`/${this.modelName}s.delete`, {
|
||||
await client.post(`/${this.apiEndpoint}.delete`, {
|
||||
id: item.id,
|
||||
...options,
|
||||
});
|
||||
@@ -193,7 +199,7 @@ export default class BaseStore<T extends BaseModel> {
|
||||
this.isFetching = true;
|
||||
|
||||
try {
|
||||
const res = await client.post(`/${this.modelName}s.info`, {
|
||||
const res = await client.post(`/${this.apiEndpoint}.info`, {
|
||||
id,
|
||||
});
|
||||
invariant(res && res.data, "Data should be available");
|
||||
@@ -219,7 +225,7 @@ export default class BaseStore<T extends BaseModel> {
|
||||
this.isFetching = true;
|
||||
|
||||
try {
|
||||
const res = await client.post(`/${this.modelName}s.list`, params);
|
||||
const res = await client.post(`/${this.apiEndpoint}.list`, params);
|
||||
invariant(res && res.data, "Data not available");
|
||||
|
||||
runInAction(`list#${this.modelName}`, () => {
|
||||
|
||||
@@ -22,6 +22,16 @@ type FetchParams = PaginationParams & { collectionId: string };
|
||||
|
||||
type FetchPageParams = PaginationParams & { template?: boolean };
|
||||
|
||||
export type SearchParams = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
dateFilter?: DateFilter;
|
||||
includeArchived?: boolean;
|
||||
includeDrafts?: boolean;
|
||||
collectionId?: string;
|
||||
userId?: string;
|
||||
};
|
||||
|
||||
type ImportOptions = {
|
||||
publish?: boolean;
|
||||
};
|
||||
@@ -392,15 +402,7 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
@action
|
||||
search = async (
|
||||
query: string,
|
||||
options: {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
dateFilter?: DateFilter;
|
||||
includeArchived?: boolean;
|
||||
includeDrafts?: boolean;
|
||||
collectionId?: string;
|
||||
userId?: string;
|
||||
}
|
||||
options: SearchParams
|
||||
): Promise<SearchResult[]> => {
|
||||
const compactedOptions = omitBy(options, (o) => !o);
|
||||
const res = await client.get("/documents.search", {
|
||||
|
||||
@@ -14,6 +14,7 @@ import MembershipsStore from "./MembershipsStore";
|
||||
import NotificationSettingsStore from "./NotificationSettingsStore";
|
||||
import PoliciesStore from "./PoliciesStore";
|
||||
import RevisionsStore from "./RevisionsStore";
|
||||
import SearchesStore from "./SearchesStore";
|
||||
import SharesStore from "./SharesStore";
|
||||
import ToastsStore from "./ToastsStore";
|
||||
import UiStore from "./UiStore";
|
||||
@@ -36,6 +37,7 @@ export default class RootStore {
|
||||
presence: DocumentPresenceStore;
|
||||
policies: PoliciesStore;
|
||||
revisions: RevisionsStore;
|
||||
searches: SearchesStore;
|
||||
shares: SharesStore;
|
||||
ui: UiStore;
|
||||
users: UsersStore;
|
||||
@@ -60,6 +62,7 @@ export default class RootStore {
|
||||
this.notificationSettings = new NotificationSettingsStore(this);
|
||||
this.presence = new DocumentPresenceStore();
|
||||
this.revisions = new RevisionsStore(this);
|
||||
this.searches = new SearchesStore(this);
|
||||
this.shares = new SharesStore(this);
|
||||
this.ui = new UiStore();
|
||||
this.users = new UsersStore(this);
|
||||
@@ -83,6 +86,7 @@ export default class RootStore {
|
||||
this.presence.clear();
|
||||
this.policies.clear();
|
||||
this.revisions.clear();
|
||||
this.searches.clear();
|
||||
this.shares.clear();
|
||||
this.fileOperations.clear();
|
||||
// this.ui omitted to keep ui settings between sessions
|
||||
|
||||
20
app/stores/SearchesStore.ts
Normal file
20
app/stores/SearchesStore.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { uniqBy } from "lodash";
|
||||
import { computed } from "mobx";
|
||||
import SearchQuery from "~/models/SearchQuery";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
|
||||
export default class SearchesStore extends BaseStore<SearchQuery> {
|
||||
actions = [RPCAction.List, RPCAction.Delete];
|
||||
|
||||
apiEndpoint = "searches";
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, SearchQuery);
|
||||
}
|
||||
|
||||
@computed
|
||||
get recent(): SearchQuery[] {
|
||||
return uniqBy(this.orderedData, "query").slice(0, 8);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user