Add stats to index page
This commit is contained in:
parent
87f2db24f9
commit
c9918ba879
13 changed files with 155 additions and 27 deletions
15
app/components/stat.hbs
Normal file
15
app/components/stat.hbs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<div
|
||||
class='px-4 py-5 bg-white shadow rounded-lg overflow-hidden sm:p-6'
|
||||
...attributes
|
||||
>
|
||||
<dt class='text-sm font-medium text-gray-500 truncate'>
|
||||
{{@title}}
|
||||
</dt>
|
||||
<dd class='mt-1 text-3xl font-semibold text-gray-900'>
|
||||
{{#if (has-block)}}
|
||||
{{yield}}
|
||||
{{else}}
|
||||
{{@value}}
|
||||
{{/if}}
|
||||
</dd>
|
||||
</div>
|
||||
11
app/helpers/date-time-format.js
Normal file
11
app/helpers/date-time-format.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { helper } from '@ember/component/helper';
|
||||
|
||||
export default helper(function dateTimeFormat([date], named) {
|
||||
if (typeof date === 'string') {
|
||||
date = new Date(date);
|
||||
}
|
||||
|
||||
const formatter = new Intl.DateTimeFormat(window.navigator.language, named);
|
||||
|
||||
return formatter.format(date);
|
||||
});
|
||||
11
app/helpers/format-bytes.js
Normal file
11
app/helpers/format-bytes.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { helper } from '@ember/component/helper';
|
||||
|
||||
export default helper(function formatBytes([bytes, decimals] /*, named*/) {
|
||||
if (bytes == 0) return '0 Bytes';
|
||||
let k = 1024,
|
||||
dm = decimals || 2,
|
||||
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
||||
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
});
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { hash } from 'rsvp';
|
||||
|
||||
export default class AdminRoute extends Route {
|
||||
@service meilisearch;
|
||||
|
|
@ -11,10 +10,6 @@ export default class AdminRoute extends Route {
|
|||
}
|
||||
|
||||
async model() {
|
||||
return hash({
|
||||
indexes: this.meilisearch.getIndexes(),
|
||||
health: this.meilisearch.getHealth(),
|
||||
version: this.meilisearch.getVersion(),
|
||||
});
|
||||
return this.meilisearch.getIndexes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
app/routes/admin/index.js
Normal file
16
app/routes/admin/index.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { hash } from 'rsvp';
|
||||
|
||||
export default class AdminIndexRoute extends Route {
|
||||
@service meilisearch;
|
||||
@service session;
|
||||
|
||||
async model() {
|
||||
return hash({
|
||||
health: this.meilisearch.getHealth(),
|
||||
version: this.meilisearch.getVersion(),
|
||||
stats: this.meilisearch.getStats(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,6 @@ export default class IndexRoute extends Route {
|
|||
@service router;
|
||||
|
||||
beforeModel() {
|
||||
this.router.transitionTo('admin.indexes');
|
||||
this.router.transitionTo('admin');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,8 @@ export default class MeilisearchService extends Service {
|
|||
getVersion() {
|
||||
return query('version');
|
||||
}
|
||||
|
||||
getStats() {
|
||||
return query('stats');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
}}
|
||||
<nav>
|
||||
<div class='px-4 py-2 text-sm text-gray'>Indexes</div>
|
||||
{{#each @model.indexes as |item|}}
|
||||
{{#each @model as |item|}}
|
||||
<LinkTo
|
||||
@route='admin.indexes.item'
|
||||
@model={{item}}
|
||||
|
|
@ -52,25 +52,6 @@
|
|||
><Icons::Logout class='mr-1' />Logout</button>
|
||||
</nav>
|
||||
{{/let}}
|
||||
<div class='flex flex-row items-center mt-auto px-4 pt-2'>
|
||||
<span
|
||||
class='mr-1 text-gray'
|
||||
title='The version of a running Meilisearch instance'
|
||||
>v{{@model.version.pkgVersion}}</span>
|
||||
{{#if (eq @model.health.status 'available')}}
|
||||
<Icons::CheckboxMarkedCircle
|
||||
class='text-green'
|
||||
@size={{18}}
|
||||
@title={{@model.health.status}}
|
||||
/>
|
||||
{{else}}
|
||||
<Icons::AlertCircle
|
||||
class='text-yellow'
|
||||
@size={{18}}
|
||||
@title={{@model.health.status}}
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
24
app/templates/admin/index.hbs
Normal file
24
app/templates/admin/index.hbs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<dl class='grid grid-cols-1 md:grid-cols-4 gap-5'>
|
||||
<Stat @title='Status'>
|
||||
<div class='flex items-center'>
|
||||
{{#if (eq @model.health.status 'available')}}
|
||||
<Icons::CheckboxMarkedCircle class='text-green mr-1' @size={{26}} />
|
||||
{{else}}
|
||||
<Icons::AlertCircle class='text-yellow mr-1' @size={{26}} />
|
||||
{{/if}}
|
||||
{{capitalize @model.health.status}}
|
||||
</div>
|
||||
</Stat>
|
||||
<Stat
|
||||
@title='Database size'
|
||||
@value={{format-bytes @model.stats.databaseSize}}
|
||||
/>
|
||||
<Stat
|
||||
@title='Last update'
|
||||
@value={{date-time-format @model.stats.lastUpdate}}
|
||||
/>
|
||||
<Stat
|
||||
@title='The version of the Meilisearch instance'
|
||||
@value={{@model.version.pkgVersion}}
|
||||
/>
|
||||
</dl>
|
||||
26
tests/integration/components/stat-test.js
Normal file
26
tests/integration/components/stat-test.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'meiliadmin/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Component | stat', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.set('myAction', function(val) { ... });
|
||||
|
||||
await render(hbs`<Stat />`);
|
||||
|
||||
assert.dom(this.element).hasText('');
|
||||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
<Stat>
|
||||
template block text
|
||||
</Stat>
|
||||
`);
|
||||
|
||||
assert.dom(this.element).hasText('template block text');
|
||||
});
|
||||
});
|
||||
17
tests/integration/helpers/date-time-format-test.js
Normal file
17
tests/integration/helpers/date-time-format-test.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'meiliadmin/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Helper | DateTimeFormat', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it renders', async function (assert) {
|
||||
this.set('inputValue', '1234');
|
||||
|
||||
await render(hbs`{{date-time-format this.inputValue}}`);
|
||||
|
||||
assert.dom(this.element).hasText('1234');
|
||||
});
|
||||
});
|
||||
17
tests/integration/helpers/format-bytes-test.js
Normal file
17
tests/integration/helpers/format-bytes-test.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'meiliadmin/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Helper | formatBytes', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it renders', async function (assert) {
|
||||
this.set('inputValue', '1234');
|
||||
|
||||
await render(hbs`{{format-bytes this.inputValue}}`);
|
||||
|
||||
assert.dom(this.element).hasText('1234');
|
||||
});
|
||||
});
|
||||
11
tests/unit/routes/admin/index-test.js
Normal file
11
tests/unit/routes/admin/index-test.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Route | admin/index', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:admin/index');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue