diff --git a/app/common.js b/app/common.js index 2e08a62..56c8faa 100644 --- a/app/common.js +++ b/app/common.js @@ -1,174 +1,177 @@ -import { dasherize } from '@ember/string'; -import { languages } from 'monaco-editor/esm/vs/editor/editor.api.js'; +// import { dasherize } from '@ember/string'; +// // import { languages } from 'monaco-editor/esm/vs/editor/editor.api.js'; -const urlSettingsPrefix = 'https://docs.meilisearch.com/reference/api/settings'; +// const urlSettingsPrefix = 'https://docs.meilisearch.com/reference/api/settings'; -export const indexSettings = [ - { - 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]; +// export const indexSettings = [ +// { +// 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; -}); +// return item; +// }); -export const allIndexSettings = { - uri: urlSettingsPrefix, - fileMatch: [urlSettingsPrefix], - schema: { - $id: urlSettingsPrefix, - type: 'object', - properties: indexSettings.reduce((properties, item) => { - properties[item.name] = { - $ref: item.schema.$id, - }; +// const allSettings = { +// name: 'allSettings', +// uri: urlSettingsPrefix, +// fileMatch: [urlSettingsPrefix], +// schema: { +// $id: urlSettingsPrefix, +// type: 'object', +// properties: indexSettings.reduce((properties, item) => { +// properties[item.name] = { +// $ref: item.schema.$id, +// }; - return properties; - }, {}), - additionalProperties: false, - }, -}; +// return properties; +// }, {}), +// additionalProperties: false, +// }, +// }; -// TODO: do it async, not in main stream -languages.json.jsonDefaults.setDiagnosticsOptions({ - validate: true, - schemas: [...indexSettings, allIndexSettings], -}); +// indexSettings.unshift(allSettings); + +// // TODO: do it async, not in main stream +// // languages.json.jsonDefaults.setDiagnosticsOptions({ +// // validate: true, +// // schemas: indexSettings, +// // }); diff --git a/app/components/form/listbox.hbs b/app/components/form/listbox.hbs index f5016ff..3a991b3 100644 --- a/app/components/form/listbox.hbs +++ b/app/components/form/listbox.hbs @@ -9,8 +9,12 @@ - {{@listboxLabel}} - {{@value}} + {{#if (has-block)}} + {{yield @value}} + {{else}} + {{@listboxLabel}} + {{@value}} + {{/if}} - {{item}} + {{#if (has-block)}} + {{yield item}} + {{else}} + {{item}} + {{/if}} {{/each}} diff --git a/app/components/index-setting.hbs b/app/components/index-setting.hbs index 326b230..bada591 100644 --- a/app/components/index-setting.hbs +++ b/app/components/index-setting.hbs @@ -1,10 +1,15 @@ -
- {{!-- 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); - }); -});