commit
222b5eaf8a
22 changed files with 312 additions and 45 deletions
26
app/controllers/admin/keys/key/delete.js
Normal file
26
app/controllers/admin/keys/key/delete.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class AdminKeysKeyDeleteController extends Controller {
|
||||
@service router;
|
||||
@service meilisearch;
|
||||
@service toasts;
|
||||
|
||||
@action
|
||||
delete() {
|
||||
return this.meilisearch.deleteKey(this.model.uid).then(() => {
|
||||
// TODO: add toast
|
||||
return this.router.transitionTo('admin.keys');
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
cancel() {
|
||||
const newRouteName = this.router.currentRouteName.replace(
|
||||
/\.(new|edit|delete)$/,
|
||||
''
|
||||
);
|
||||
this.router.transitionTo(newRouteName);
|
||||
}
|
||||
}
|
||||
49
app/controllers/admin/keys/key/edit.js
Normal file
49
app/controllers/admin/keys/key/edit.js
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import ActionInvoker from 'meiliadmin/lib/action-invoker';
|
||||
|
||||
export default class AdminKeysKeyEditController extends Controller {
|
||||
@service router;
|
||||
@service toasts;
|
||||
|
||||
@tracked error;
|
||||
@tracked isSaving;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
this.invoker = new ActionInvoker();
|
||||
}
|
||||
|
||||
@action
|
||||
async save(value) {
|
||||
this.error = null;
|
||||
|
||||
this.isSaving = true;
|
||||
|
||||
try {
|
||||
const key = await this.model.save(value);
|
||||
|
||||
if (this.router.isActive('admin.keys.key')) {
|
||||
await this.router.refresh('admin.keys.key', key.uid);
|
||||
}
|
||||
|
||||
await this.router.transitionTo('admin.keys.key.index', key.uid);
|
||||
} catch (error) {
|
||||
this.error = error.error || error;
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
cancel() {
|
||||
const newRouteName = this.router.currentRouteName.replace(
|
||||
/\.(new|edit|delete)$/,
|
||||
''
|
||||
);
|
||||
this.router.transitionTo(newRouteName);
|
||||
}
|
||||
}
|
||||
49
app/models/key.js
Normal file
49
app/models/key.js
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import query from '../utils/query';
|
||||
|
||||
export default class Key {
|
||||
actions = ['*'];
|
||||
indexes = ['*'];
|
||||
expiresAt = null;
|
||||
name = '';
|
||||
description = '';
|
||||
|
||||
constructor(data = {}) {
|
||||
for (const key in data) {
|
||||
this[key] = data[key];
|
||||
}
|
||||
}
|
||||
|
||||
get path() {
|
||||
return `keys/${this.uid}`;
|
||||
}
|
||||
|
||||
get isNew() {
|
||||
return Boolean(!this.uid);
|
||||
}
|
||||
|
||||
get editablePayload() {
|
||||
let keys = ['name', 'description'];
|
||||
|
||||
if (this.isNew) {
|
||||
keys = keys.concat(['actions', 'indexes', 'expiresAt', 'uid']);
|
||||
}
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries(this).filter(([key]) => keys.includes(key))
|
||||
);
|
||||
}
|
||||
|
||||
save(data) {
|
||||
const path = this.isNew ? 'keys' : this.path;
|
||||
const method = this.isNew ? 'POST' : 'PATCH';
|
||||
|
||||
if (typeof data === 'object') {
|
||||
data = JSON.stringify(data);
|
||||
}
|
||||
|
||||
return query(path, {
|
||||
method: method,
|
||||
body: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,11 @@ Router.map(function () {
|
|||
this.route('new');
|
||||
});
|
||||
this.route('keys', function () {
|
||||
this.route('key', { path: '/:uid' });
|
||||
this.route('key', { path: '/:uid' }, function () {
|
||||
this.route('edit');
|
||||
this.route('delete');
|
||||
});
|
||||
this.route('new');
|
||||
});
|
||||
this.route('tasks', function () {
|
||||
this.route('task', { path: '/:uid' });
|
||||
|
|
|
|||
3
app/routes/admin/keys/key/delete.js
Normal file
3
app/routes/admin/keys/key/delete.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class AdminKeysKeyDeleteRoute extends Route {}
|
||||
12
app/routes/admin/keys/key/edit.js
Normal file
12
app/routes/admin/keys/key/edit.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import Route from '@ember/routing/route';
|
||||
// import { hash } from 'rsvp';
|
||||
|
||||
export default class AdminKeysKeyEditRoute extends Route {
|
||||
// async model() {
|
||||
// const key = this.modelFor('admin.admin.keys.key');
|
||||
// return hash({
|
||||
// key,
|
||||
// // document:
|
||||
// });
|
||||
// }
|
||||
}
|
||||
3
app/routes/admin/keys/key/index.js
Normal file
3
app/routes/admin/keys/key/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class AdminKeysKeyIndexRoute extends Route {}
|
||||
11
app/routes/admin/keys/new.js
Normal file
11
app/routes/admin/keys/new.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import Key from 'meiliadmin/models/key';
|
||||
|
||||
export default class AdminKeysNewRoute extends Route {
|
||||
templateName = 'admin.keys.key.edit';
|
||||
controllerName = 'admin.keys.key.edit';
|
||||
|
||||
model() {
|
||||
return new Key();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import Service from '@ember/service';
|
||||
import Index from '../models/index';
|
||||
import Key from '../models/key';
|
||||
import Task from '../models/task';
|
||||
import query from '../utils/query';
|
||||
|
||||
|
|
@ -34,11 +35,20 @@ export default class MeilisearchService extends Service {
|
|||
}
|
||||
|
||||
getKeys() {
|
||||
return query('keys');
|
||||
return query('keys').then((data) => {
|
||||
data.results = data.results.map((item) => new Key(item));
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
getKey(uid) {
|
||||
return query(`keys/${uid}`);
|
||||
return query(`keys/${uid}`).then((item) => new Key(item));
|
||||
}
|
||||
|
||||
deleteKey(uid) {
|
||||
return query(`keys/${uid}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
getTasks(params, options = {}) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
<Headers::H1 @title='Keys' />
|
||||
|
||||
<LinkTo
|
||||
@route='admin.keys.new'
|
||||
class='inline-block mb-4'
|
||||
>
|
||||
Create new key
|
||||
</LinkTo>
|
||||
|
||||
<SimpleTable @data={{@model.results}} class='w-full' as |Column data|>
|
||||
<Column @prop='name'>
|
||||
<Column @name="Name or uid">
|
||||
<LinkTo @route='admin.keys.key' @model={{data.uid}}>
|
||||
{{data.name}}
|
||||
{{nu-co data.name data.uid}}
|
||||
</LinkTo>
|
||||
</Column>
|
||||
<Column @prop='actions' />
|
||||
<Column @prop='indexes' />
|
||||
<Column @prop='expiresAt' />
|
||||
</SimpleTable>
|
||||
|
|
|
|||
|
|
@ -1,40 +1,9 @@
|
|||
<Headers::H1 @title={{@model.name}} />
|
||||
<Headers::H1 @title={{nu-co @model.name @model.uid}} />
|
||||
|
||||
<Form::Element @label='description' @value={{@model.description}} />
|
||||
<Form::Element @label='key' @value={{@model.key}} />
|
||||
<Form::Element @label='uid' @value={{@model.uid}} />
|
||||
<Form::Element @label='actions' @value={{@model.actions}} />
|
||||
<Form::Element @label='indexes' @value={{@model.indexes}} />
|
||||
<Form::Element @label='expiresAt'>
|
||||
{{date-time-format
|
||||
@model.expiresAt
|
||||
year='numeric'
|
||||
month='numeric'
|
||||
day='numeric'
|
||||
hour='numeric'
|
||||
minute='numeric'
|
||||
second='numeric'
|
||||
}}
|
||||
</Form::Element>
|
||||
<Form::Element @label='createdAt'>
|
||||
{{date-time-format
|
||||
@model.createdAt
|
||||
year='numeric'
|
||||
month='numeric'
|
||||
day='numeric'
|
||||
hour='numeric'
|
||||
minute='numeric'
|
||||
second='numeric'
|
||||
}}
|
||||
</Form::Element>
|
||||
<Form::Element @label='updatedAt'>
|
||||
{{date-time-format
|
||||
@model.updatedAt
|
||||
year='numeric'
|
||||
month='numeric'
|
||||
day='numeric'
|
||||
hour='numeric'
|
||||
minute='numeric'
|
||||
second='numeric'
|
||||
}}
|
||||
</Form::Element>
|
||||
<Tabs>
|
||||
<Tab @route="admin.keys.key.index" @text="View" @model={{@model}} />
|
||||
<Tab @route="admin.keys.key.edit" @text="Edit" @model={{@model}} />
|
||||
<Tab @route="admin.keys.key.delete" @text="Delete" @model={{@model}} />
|
||||
</Tabs>
|
||||
|
||||
{{outlet}}
|
||||
|
|
|
|||
12
app/templates/admin/keys/key/delete.hbs
Normal file
12
app/templates/admin/keys/key/delete.hbs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<p>Are you sure you want to delete this key?</p>
|
||||
|
||||
<Button
|
||||
@text='Yes'
|
||||
@style='primary'
|
||||
@onClick={{this.delete}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
@text='No'
|
||||
@onClick={{this.cancel}}
|
||||
/>
|
||||
23
app/templates/admin/keys/key/edit.hbs
Normal file
23
app/templates/admin/keys/key/edit.hbs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{{#if @model.isNew}}
|
||||
<Headers::H1 @title='Create new key' />
|
||||
{{/if}}
|
||||
|
||||
<div class='mb-4'>
|
||||
<Form::Element @errors={{array this.error}}>
|
||||
<MonacoEditor
|
||||
@value={{json-stringify @model.editablePayload}}
|
||||
@language='json'
|
||||
@sendValue={{this.save}}
|
||||
@invoker={{this.invoker}}
|
||||
/>
|
||||
</Form::Element>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
@text='Save'
|
||||
@style='primary'
|
||||
@onClick={{fn this.invoker.invoke 'invokeSendValue'}}
|
||||
@state={{if this.isSaving 'pending'}}
|
||||
/>
|
||||
<Button @text='Cancel' @onClick={{this.cancel}} />
|
||||
</div>
|
||||
17
app/templates/admin/keys/key/index.hbs
Normal file
17
app/templates/admin/keys/key/index.hbs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{{#each
|
||||
(array
|
||||
'description'
|
||||
'key'
|
||||
'uid'
|
||||
'actions'
|
||||
'indexes'
|
||||
'expiresAt'
|
||||
'createdAt'
|
||||
'updatedAt'
|
||||
)
|
||||
as |key|
|
||||
}}
|
||||
{{#if (get @model key)}}
|
||||
<Form::Element @label={{key}} @value={{get @model key}} />
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
1
app/templates/admin/keys/new.hbs
Normal file
1
app/templates/admin/keys/new.hbs
Normal file
|
|
@ -0,0 +1 @@
|
|||
{{outlet}}
|
||||
|
|
@ -16,7 +16,9 @@ export default function query(path, options = {}) {
|
|||
);
|
||||
|
||||
return fetch(req).then((response) => {
|
||||
if (response.ok) {
|
||||
if (response.status === 204) {
|
||||
return;
|
||||
} else if (response.ok) {
|
||||
return response.json();
|
||||
} else {
|
||||
throw new Error('Network response was not OK');
|
||||
|
|
|
|||
12
tests/unit/controllers/admin/keys/key/delete-test.js
Normal file
12
tests/unit/controllers/admin/keys/key/delete-test.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Controller | admin/keys/key/delete', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup('controller:admin/keys/key/delete');
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
12
tests/unit/controllers/admin/keys/key/edit-test.js
Normal file
12
tests/unit/controllers/admin/keys/key/edit-test.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Controller | admin/keys/key/edit', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup('controller:admin/keys/key/edit');
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
11
tests/unit/routes/admin/keys/key/delete-test.js
Normal file
11
tests/unit/routes/admin/keys/key/delete-test.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Route | admin/keys/key/delete', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:admin/keys/key/delete');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
11
tests/unit/routes/admin/keys/key/edit-test.js
Normal file
11
tests/unit/routes/admin/keys/key/edit-test.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Route | admin/keys/key/edit', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:admin/keys/key/edit');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
11
tests/unit/routes/admin/keys/key/index-test.js
Normal file
11
tests/unit/routes/admin/keys/key/index-test.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Route | admin/keys/key/index', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:admin/keys/key/index');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
11
tests/unit/routes/admin/keys/new-test.js
Normal file
11
tests/unit/routes/admin/keys/new-test.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'meiliadmin/tests/helpers';
|
||||
|
||||
module('Unit | Route | admin/keys/new', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:admin/keys/new');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue