- {{!-- TODO: add link to meilisearch's documentation --}}
+
+ {{! TODO: add link to meilisearch's documentation }}
-
+
diff --git a/app/components/index-setting.js b/app/components/index-setting.js
index 6fd6758..e555e38 100644
--- a/app/components/index-setting.js
+++ b/app/components/index-setting.js
@@ -14,8 +14,6 @@ export default class FormIndexSettingComponent extends Component {
super(...arguments);
this.invoker = new ActionInvoker();
-
- this.setInitialValue();
}
@action
@@ -32,7 +30,7 @@ export default class FormIndexSettingComponent extends Component {
}
@action
- async setInitialValue() {
+ async setValue() {
this.value = await this.args.index.getSetting(this.args.setting.name);
this.error = null;
}
diff --git a/app/components/monaco-editor.hbs b/app/components/monaco-editor.hbs
index 3ff2296..68d431f 100644
--- a/app/components/monaco-editor.hbs
+++ b/app/components/monaco-editor.hbs
@@ -1,6 +1,6 @@
diff --git a/app/components/monaco-editor.js b/app/components/monaco-editor.js
index 82cfacb..ac61fa0 100644
--- a/app/components/monaco-editor.js
+++ b/app/components/monaco-editor.js
@@ -1,6 +1,10 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
-import { Uri, editor } from 'monaco-editor/esm/vs/editor/editor.api.js';
+import {
+ Uri,
+ editor,
+ languages,
+} from 'monaco-editor/esm/vs/editor/editor.api.js';
import { registerDestructor } from '@ember/destroyable';
// This is needed because the SimpleWorker.js in monaco-editor has the following code:
@@ -13,6 +17,28 @@ window.requirejs.s = {
},
};
+function getModelUri(uri) {
+ return Uri.parse(uri);
+}
+
+function getModel(value, language, uri, schema) {
+ const modelUri = getModelUri(uri);
+ let model = editor.getModel(modelUri);
+
+ if (model === null) {
+ model = editor.createModel(value, language, modelUri);
+
+ if (language === 'json' && schema) {
+ languages.json.jsonDefaults.setDiagnosticsOptions({
+ validate: true,
+ schemas: [schema],
+ });
+ }
+ }
+
+ return model;
+}
+
export default class MonacoEditorComponent extends Component {
constructor(owner, args) {
super(owner, args);
@@ -20,21 +46,14 @@ export default class MonacoEditorComponent extends Component {
this.args.invoker?.subscribe(this);
}
- get modelUri() {
- return Uri.parse(this.args.uri);
- }
-
@action
initEditor(el) {
- let model = editor.getModel(this.modelUri);
-
- if (model === null) {
- model = editor.createModel(
- this.args.value,
- this.args.language,
- this.modelUri
- );
- }
+ const model = getModel(
+ this.args.value,
+ this.args.language,
+ this.args.uri,
+ this.args.schema
+ );
this.editor = editor.create(el, {
model,
@@ -50,13 +69,6 @@ export default class MonacoEditorComponent extends Component {
},
});
- // Add onChange event
- // if (this.args.onChange) {
- // this.editor.onDidChangeModelContent(() => {
- // this.args.onChange(this.editor.getValue());
- // });
- // }
-
// Autoresize height of element
const onDidContentSizeChangeHandler = this.editor.onDidContentSizeChange(
() => {
@@ -71,22 +83,32 @@ export default class MonacoEditorComponent extends Component {
);
registerDestructor(this, onDidContentSizeChangeHandler.dispose);
- const onDidChangeMarkersHandler = editor.onDidChangeMarkers((uris) => {
- const error = uris.find(
- (item) => item.toString() === this.modelUri.toString()
- );
+ // const onDidChangeMarkersHandler = editor.onDidChangeMarkers((uris) => {
+ // const error = uris.find((item) => item.toString() === this.args.uri);
- this.args.onDidChangeValidation?.(
- error ? 'Error: the value is invalid' : false
- );
- });
- registerDestructor(this, onDidChangeMarkersHandler.dispose);
+ // this.args.onDidChangeValidation?.(
+ // error ? 'Error: the value is invalid' : false
+ // );
+ // });
+ // registerDestructor(this, onDidChangeMarkersHandler.dispose);
}
@action
- updateValue(el, [value]) {
- if (value !== this.editor.getValue()) {
- this.editor?.setValue(value);
+ updateValue() {
+ const model = this.editor.getModel();
+
+ if (model.uri.toString() !== this.args.uri) {
+ const newModel = getModel(
+ this.args.value,
+ this.args.language,
+ this.args.uri,
+ this.args.schema
+ );
+
+ this.editor.setModel(newModel);
+ model.dispose();
+ } else {
+ this.editor.setValue(this.args.value);
}
}
@@ -96,7 +118,8 @@ export default class MonacoEditorComponent extends Component {
}
willDestroy() {
- this.editor?.dispose();
+ this.editor.getModel()?.dispose();
+ this.editor.dispose();
super.willDestroy(...arguments);
}
diff --git a/app/router.js b/app/router.js
index 3bb888c..1a7fc9c 100644
--- a/app/router.js
+++ b/app/router.js
@@ -10,9 +10,7 @@ Router.map(function () {
this.route('admin', function () {
this.route('indexes', function () {
this.route('item', { path: '/:index_uid' }, function () {
- this.route('settings', function () {
- this.route('specific');
- });
+ this.route('settings', function () {});
this.route('info');
this.route('edit');
this.route('documents', function () {
diff --git a/app/routes/admin/indexes/item/settings/index.js b/app/routes/admin/indexes/item/settings/index.js
index 3e3cc5e..416585b 100644
--- a/app/routes/admin/indexes/item/settings/index.js
+++ b/app/routes/admin/indexes/item/settings/index.js
@@ -1,3 +1,182 @@
import Route from '@ember/routing/route';
+import { dasherize } from '@ember/string';
-export default class AdminIndexesItemSettingsIndexRoute extends Route {}
+const urlSettingsPrefix = 'https://docs.meilisearch.com/reference/api/settings';
+
+export const settings = [
+ {
+ name: 'displayedAttributes',
+ schema: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ {
+ name: 'distinctAttribute',
+ schema: {
+ type: ['string', 'null'],
+ },
+ },
+ {
+ name: 'faceting',
+ schema: {
+ type: 'object',
+ properties: {
+ maxValuesPerFacet: {
+ type: 'integer',
+ },
+ },
+ required: ['maxValuesPerFacet'],
+ additionalProperties: false,
+ },
+ },
+ {
+ name: 'filterableAttributes',
+ schema: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ {
+ name: 'pagination',
+ schema: {
+ type: 'object',
+ properties: {
+ maxTotalHits: {
+ type: 'integer',
+ },
+ },
+ required: ['maxTotalHits'],
+ additionalProperties: false,
+ },
+ },
+ {
+ name: 'rankingRules',
+ schema: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ {
+ name: 'searchableAttributes',
+ schema: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ {
+ name: 'sortableAttributes',
+ schema: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ {
+ name: 'stopWords',
+ schema: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ {
+ name: 'synonyms',
+ schema: {
+ type: 'object',
+ additionalProperties: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ },
+ {
+ name: 'typoTolerance',
+ schema: {
+ type: 'object',
+ properties: {
+ enabled: {
+ type: 'boolean',
+ },
+ minWordSizeForTypos: {
+ type: 'object',
+ properties: {
+ oneTypo: { type: 'integer' },
+ twoTypos: { type: 'integer' },
+ },
+ additionalProperties: false,
+ },
+ disableOnWords: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ disableOnAttributes: {
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ uniqueItems: true,
+ },
+ },
+ additionalProperties: false,
+ },
+ },
+].map((item) => {
+ item.uri = item.schema.$id = `${urlSettingsPrefix}/${dasherize(item.name)}`;
+ item.fileMatch = [item.uri];
+
+ return item;
+});
+
+const allSettings = {
+ uri: urlSettingsPrefix,
+ fileMatch: [urlSettingsPrefix],
+ schema: {
+ $id: urlSettingsPrefix,
+ type: 'object',
+ properties: settings.reduce((properties, item) => {
+ properties[item.name] = item.schema;
+
+ return properties;
+ }, {}),
+ additionalProperties: false,
+ },
+};
+
+settings.unshift(allSettings);
+
+// TODO: do it async, not in main stream
+// languages.json.jsonDefaults.setDiagnosticsOptions({
+// validate: true,
+// schemas: indexSettings,
+// });
+
+export default class AdminIndexesItemSettingsIndexRoute extends Route {
+ model() {
+ const index = this.modelFor('admin.indexes.item');
+
+ return { index, settings, currentSetting: settings[0] };
+ }
+}
diff --git a/app/routes/admin/indexes/item/settings/specific.js b/app/routes/admin/indexes/item/settings/specific.js
deleted file mode 100644
index adba3b9..0000000
--- a/app/routes/admin/indexes/item/settings/specific.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Route from '@ember/routing/route';
-
-export default class AdminIndexesItemSettingsSpecificRoute extends Route {}
diff --git a/app/templates/admin/indexes/item/settings.hbs b/app/templates/admin/indexes/item/settings.hbs
index 4f6eb96..4ee6c39 100644
--- a/app/templates/admin/indexes/item/settings.hbs
+++ b/app/templates/admin/indexes/item/settings.hbs
@@ -1,6 +1,6 @@
-
+{{!--
-
+ --}}
{{outlet}}
diff --git a/app/templates/admin/indexes/item/settings/index.hbs b/app/templates/admin/indexes/item/settings/index.hbs
index 2af94a4..2d74990 100644
--- a/app/templates/admin/indexes/item/settings/index.hbs
+++ b/app/templates/admin/indexes/item/settings/index.hbs
@@ -1 +1,14 @@
-
+
+ {{if setting.name (namelize setting.name) 'All settings'}}
+
+
+
diff --git a/app/templates/admin/indexes/item/settings/specific.hbs b/app/templates/admin/indexes/item/settings/specific.hbs
deleted file mode 100644
index bd4d007..0000000
--- a/app/templates/admin/indexes/item/settings/specific.hbs
+++ /dev/null
@@ -1,7 +0,0 @@
-{{#each @model.settings as |setting|}}
-
-{{/each}}
diff --git a/tests/unit/routes/admin/indexes/item/settings/specific-test.js b/tests/unit/routes/admin/indexes/item/settings/specific-test.js
deleted file mode 100644
index b630eae..0000000
--- a/tests/unit/routes/admin/indexes/item/settings/specific-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'meiliadmin/tests/helpers';
-
-module('Unit | Route | admin/indexes/item/settings/specific', function (hooks) {
- setupTest(hooks);
-
- test('it exists', function (assert) {
- let route = this.owner.lookup('route:admin/indexes/item/settings/specific');
- assert.ok(route);
- });
-});