Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(file): implement new alexandria search endpoint #1025

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions addon/adapters/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,5 @@ export default function (BaseClass) {

return ajaxOptions;
}

// Overwrite and replicate the query function,
// because ember doesnt pass adapterOptions to urlForQuery
query(_, type, query, __, options) {
let url = this.buildURL(type.modelName, null, null, "query", query);

if (options?.adapterOptions?.customEndpoint) {
url = `${this.buildURL()}/${options.adapterOptions.customEndpoint}`;
}

return this.ajax(url, "GET", { data: query });
}
};
}
15 changes: 15 additions & 0 deletions addon/adapters/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default function (BaseClass) {
return class SearchResultAdapter extends BaseClass {
// Overwrite and replicate the query function,
// because ember doesnt pass adapterOptions to urlForQuery
query(_, type, query, __, options) {
let url = this.buildURL(type.modelName, null, null, "query", query);

if (options?.adapterOptions?.customEndpoint) {
url = `${this.buildURL()}/${options.adapterOptions.customEndpoint}`;
}

return this.ajax(url, "GET", { data: query });
}
};
}
1 change: 0 additions & 1 deletion addon/components/document-view.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
>
<div
class="document-view"
{{did-insert (perform this.initialiseDocumentSelection)}}
>
{{! List & Grid View }}
{{#if this.listView}}
Expand Down
45 changes: 34 additions & 11 deletions addon/components/document-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,51 @@ export default class DocumentViewComponent extends Component {

@task
*fetchDocuments() {
const documents = yield this.store.query("document", {
include: "category,files,tags",
filter: this.args.filters || {},
sort: this.sort ? `${this.sortDirection}${this.sort}` : "",
});
let documents = [];
const filter = this.args.filters || {};
if (filter.query) {
filter.only_newest = true;
const searchResult = yield this.store.query(
"search-result",
{
include: "document,matched_file",
filter,
page: { number: 1 },
},
{
adapterOptions: {
customEndpoint: "search",
},
},
);

documents = searchResult.reduce((acc, result) => {
if (!acc.some((doc) => doc.id === result.document.id)) {
acc.push(result.document);
}
return acc;
}, []);
} else {
documents = yield this.store.query("document", {
include: "category,files,tags",
filter,
sort: this.sort ? `${this.sortDirection}${this.sort}` : "",
});
}

this.initialiseDocumentSelection(documents);

return yield this.config.documentsPostProcess(documents);
}

@task
*initialiseDocumentSelection() {
initialiseDocumentSelection(docs) {
let docIds = [];
if (this.router.externalRouter.currentRoute?.queryParams?.document) {
docIds = decodeURIComponent(
this.router.externalRouter.currentRoute.queryParams.document,
).split(",");
}
if (docIds.length !== 0) {
const docs = yield this.store.query("document", {
filter: this.args.filters || {},
sort: this.sort ? `${this.sortDirection}${this.sort}` : "",
});
const selectedDocs = [...docs].filter((doc) => docIds.includes(doc.id));
selectedDocs.forEach((doc) => this.documents.selectDocument(doc));
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { tracked } from "@glimmer/tracking";
import { task } from "ember-concurrency";
import { trackedFunction } from "reactiveweb/function";

export default class DocumentViewComponent extends Component {
export default class SearchViewComponent extends Component {
@service store;
@service("alexandria-config") config;
@service("alexandria-documents") documents;
Expand All @@ -22,10 +22,10 @@ export default class DocumentViewComponent extends Component {
return [];
}

const files = await this.store.query(
"file",
const search = await this.store.query(
"search-result",
{
include: "document,renderings",
include: "document,matched_file",
filter: this.args.filters || {},
page: { number: 1 },
},
Expand All @@ -36,14 +36,7 @@ export default class DocumentViewComponent extends Component {
},
);

const documents = Array.from(
new Map(
files.map((file) => [
file.document.id,
this.store.peekRecord("document", file.document.id),
]),
).values(),
);
const documents = search.map((result) => result.document);

return await this.config.documentsPostProcess(documents);
});
Expand Down
10 changes: 9 additions & 1 deletion addon/components/search.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class="uk-background-default uk-search uk-search-default uk-width-1"
{{on "submit" this.onSubmit}}
>
<span uk-search-icon />
<span uk-search-icon></span>
<input
type="search"
class="uk-search-input uk-background-default"
Expand All @@ -13,5 +13,13 @@
data-test-search-input
{{on "input" this.updateSearch.perform}}
/>
{{!<button class="uk-form-icon uk-form-icon-flip"><UkIcon @icon="close" /></button>}}
<a
class="uk-form-icon uk-form-icon-flip"
href="#"
uk-tooltip={{t "alexandria.search-clear"}}
{{on "click" this.resetSearch}}
data-test-search-clear
><UkIcon @icon="close" /></a>
</form>
</div>
10 changes: 9 additions & 1 deletion addon/components/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,16 @@ export default class SearchComponent extends Component {
}

this.router.transitionTo(this.router.currentRouteName, {
queryParams: { search: search || undefined, category: undefined },
queryParams: { search: search || undefined },
});
},
);

@action
resetSearch(event) {
event.preventDefault();
this.router.transitionTo(this.router.currentRouteName, {
queryParams: { search: undefined },
});
}
}
4 changes: 2 additions & 2 deletions addon/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export default class IndexController extends Controller {

get documentFilters() {
let filters = {
category: this.category,
categories: this.category,
tags: this.tags.length ? this.tags.join(",") : undefined,
marks: this.marks.length ? this.marks.join(",") : undefined,
search: this.search,
query: this.search,
activeGroup: this.activeGroup,
};

Expand Down
1 change: 1 addition & 0 deletions addon/controllers/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class SearchController extends Controller {

get filters() {
const filters = {
onlyNewest: true,
query: this.search,
};

Expand Down
11 changes: 11 additions & 0 deletions addon/models/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Model, { attr, belongsTo } from "@ember-data/model";

export default class SearchResultModel extends Model {
@attr searchRank;
@attr searchContext;
@attr fileName;
@attr documentName;

@belongsTo("document", { inverse: null, async: false }) document;
@belongsTo("matched-file", { inverse: null, async: false }) file;
}
3 changes: 3 additions & 0 deletions addon/serializers/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { LocalizedSerializer } from "ember-localized-model";

export default class SearchResultSerializer extends LocalizedSerializer {}
2 changes: 1 addition & 1 deletion addon/templates/search.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div
class="alexandria-container uk-flex uk-flex-1 uk-height-1-1 uk-border uk-background-default uk-width-1 uk-flex-column uk-overflow-hidden"
>
<FileSearch
<SearchView
@filters={{this.filters}}
class="uk-border-top"
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ApplicationAdapter from "./application";

import adapterFactory from "ember-alexandria/adapters/search-result";

export default adapterFactory(ApplicationAdapter);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ember-alexandria/models/search-result";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ember-alexandria/serializers/search-result";
5 changes: 5 additions & 0 deletions tests/dummy/app/adapters/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ApplicationAdapter from "./application";

import adapterFactory from "ember-alexandria/adapters/search-result";

export default adapterFactory(ApplicationAdapter);
1 change: 1 addition & 0 deletions tests/dummy/app/models/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ember-alexandria/models/search-result";
1 change: 1 addition & 0 deletions tests/dummy/app/serializers/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ember-alexandria/serializers/search-result";
9 changes: 9 additions & 0 deletions tests/dummy/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ export default function makeServer(config) {
});

this.get("/files/multi", () => new Response(200, {}, {}));

this.get("/search", function (schema) {
const res = schema.searchResults.create({
document: schema.documents.create(),
});
const serialized = this.serialize(res);
serialized.data = [serialized.data];
return serialized;
});
},
});
}
1 change: 0 additions & 1 deletion tests/dummy/mirage/factories/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ export default Factory.extend({
name: () => faker.system.fileName(),
variant: "original",
downloadUrl: () => faker.internet.url(),
checksum: () => `sha256:${faker.git.commitSha({ length: 64 })}`,
});
16 changes: 16 additions & 0 deletions tests/dummy/mirage/factories/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { faker } from "@faker-js/faker";
import { Factory } from "miragejs";

export default Factory.extend({
fileName: () => faker.system.fileName(),
documentName: () => faker.system.fileName(),
searchRank: () => faker.number.int(),
searchContext: () => faker.word.adjective(),

afterCreate(result, server) {
result.update({
document: server.schema.documents.create(),
matchedFile: server.schema.files.create(),
});
},
});
6 changes: 6 additions & 0 deletions tests/dummy/mirage/models/search-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Model, belongsTo } from "miragejs";

export default Model.extend({
document: belongsTo(),
matchedFile: belongsTo(),
});
31 changes: 28 additions & 3 deletions tests/integration/components/search-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, fillIn } from "@ember/test-helpers";
import { render, fillIn, click } from "@ember/test-helpers";
import { setupRenderingTest } from "dummy/tests/helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
Expand All @@ -7,7 +7,7 @@ import { fake, stub } from "sinon";
module("Integration | Component | search", function (hooks) {
setupRenderingTest(hooks);

test("it renders", async function (assert) {
test("it searches", async function (assert) {
const router = this.engine.lookup("service:router");

stub(router, "currentRouteName").get(() => null);
Expand All @@ -25,7 +25,32 @@ module("Integration | Component | search", function (hooks) {
[
null,
{
queryParams: { search: "new search", category: undefined },
queryParams: { search: "new search" },
},
],
"transitionTo was called with the correct arguments",
);
});

test("it clears search", async function (assert) {
const router = this.engine.lookup("service:router");

stub(router, "currentRouteName").get(() => null);
router.transitionTo = fake();

await render(hbs`<Search @search="test"/>`, { owner: this.engine });

assert.dom("[data-test-search-input]").hasValue("test");

await click("[data-test-search-clear]");

assert.ok(router.transitionTo.called, "transitionTo was called");
assert.deepEqual(
router.transitionTo.firstCall.args,
[
null,
{
queryParams: { search: undefined },
},
],
"transitionTo was called with the correct arguments",
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/controllers/application-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ module("Unit | Controller | index", function (hooks) {

assert.deepEqual(controller.documentFilters, {
activeGroup: "group",
category: 1,
categories: 1,
metainfo: JSON.stringify([{ key: "instance_id", value: "1" }]),
search: "test",
query: "test",
tags: undefined,
marks: undefined,
});
Expand Down
1 change: 1 addition & 0 deletions translations/de.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
alexandria:
loading: "Lädt..."
search: "Suchen..."
search-clear: "Suche löschen"
nothing-found: "Wir haben nichts gefunden..."
delete: "Löschen"
upload-file: "Datei hochladen"
Expand Down
1 change: 1 addition & 0 deletions translations/en.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
alexandria:
loading: "Loading..."
search: "Search..."
search-clear: "Clear search"
nothing-found: "We found nothing..."
delete: "Delete"
upload-file: "Upload file"
Expand Down
1 change: 1 addition & 0 deletions translations/it.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
alexandria:
loading: "Sto caricando i risultati..."
search: "Cerca..."
search-clear: "Ricerca chiara"
nothing-found: "Nessun risultato trovato..."
delete: "Elimina"
upload-file: "Carica file"
Expand Down
Loading