Merge pull request #23 from kaermorchen/feature/json-view

Add JSON view for documents
This commit is contained in:
Stanislav Romanov 2022-10-17 14:38:21 +03:00 committed by GitHub
commit f8dc680cbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 177 additions and 88 deletions

View file

@ -40,7 +40,7 @@ export default class ButtonComponent extends Component {
<this.icon
@spin={{this.isPending}}
@size={{get iconSizes this.size}}
class="mr-1"
class={{if this.text "mr-1"}}
/>
{{/if}}

View file

@ -48,17 +48,10 @@ export default class MonacoEditorComponent extends Component {
@action
initEditor(el) {
const model = getModel(
this.args.value,
this.args.language,
this.args.uri,
this.args.schema
);
this.editor = editor.create(el, {
model,
const options = {
// theme: 'vs-dark', //TODO: add checking global theme
readOnly: this.args.readOnly ?? false,
language: this.args.language,
// wordWrap: 'on',
// wrappingIndent: 'same',
lineNumbers: 'off',
@ -67,14 +60,39 @@ export default class MonacoEditorComponent extends Component {
minimap: {
enabled: false,
},
});
scrollbar: {
alwaysConsumeMouseWheel: false,
},
};
if (this.args.uri) {
options.model = getModel(
this.args.value,
this.args.language,
this.args.uri,
this.args.schema
);
} else if (this.args.value) {
options.value = this.args.value;
}
this.editor = editor.create(el, options);
if (Array.isArray(this.args.actions)) {
this.args.actions.forEach((item) => {
// assign because item can be a proxy object
this.editor.addAction(Object.assign({}, item));
});
}
const minHeight = this.args.minHeight ?? 160;
const maxHeight = this.args.maxHeight ?? 420;
// Autoresize height of element
const onDidContentSizeChangeHandler = this.editor.onDidContentSizeChange(
() => {
const contentHeight = Math.min(
Math.max(this.editor.getContentHeight(), 160),
420
Math.max(this.editor.getContentHeight(), minHeight),
maxHeight
);
el.style.height = `${contentHeight + 1}px`;

View file

@ -1,9 +1,12 @@
import Controller from '@ember/controller';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { Magnify, Table, MapOutline } from 'ember-mdi';
import { Magnify, Table, /* MapOutline, */ CodeJson } from 'ember-mdi';
import { inject as service } from '@ember/service';
export default class AdminIndexesItemDocumentsIndexController extends Controller {
@service router;
@tracked q = null;
@tracked limit = 20;
@tracked page = 1;
@ -19,7 +22,7 @@ export default class AdminIndexesItemDocumentsIndexController extends Controller
// key: view name, value: icon
views = {
table: Table,
map: MapOutline,
json: CodeJson,
};
get attributes() {
@ -65,6 +68,11 @@ export default class AdminIndexesItemDocumentsIndexController extends Controller
return result;
}
@action
goToPage(route, index, id) {
this.router.transitionTo(route, index, id);
}
@action
toggleAttribute(name) {
if (this.attributes.includes(name)) {

View file

@ -60,81 +60,144 @@
</div> --}}
{{#if (gt @model.data.estimatedTotalHits 0)}}
<SimpleTable
@data={{@model.data.hits}}
@sortingProp={{this.sort}}
@onSort={{this.onSort}}
class='w-full'
as |Column data|
>
{{#let
(array @model.index.uid (get data @model.index.primaryKey))
as |models|
}}
{{#each this.attributes as |field|}}
{{#if (not (includes field this.hiddenFields))}}
<Column
@name={{capitalize field}}
@prop={{field}}
@sortable={{includes field @model.sortableAttributes}}
>
{{#let (get data field) as |value|}}
{{#if (eq @model.index.primaryKey field)}}
<LinkTo
@route='admin.indexes.item.documents.document'
@models={{models}}
>{{value}}</LinkTo>
{{else if (eq (type-of value) 'object')}}
{{json-stringify value}}
{{else}}
{{value}}
{{/if}}
{{/let}}
</Column>
{{/if}}
{{/each}}
<Column class='relative'>
{{#let
'flex items-center px-4 py-2 text-inherit no-underline text-sm hover:bg-base-6 hover:text-base-1'
as |linkClasses|
}}
<Menu as |menu|>
<menu.Button class='inline-flex items-center'>
<Icons::DotsHorizontal />
</menu.Button>
<menu.Items
class='absolute z-dropdown right-0 w-28 mt-2 py-1 origin-top-right bg-base-7 border rounded shadow-sm outline-none'
<div class='flex items-center -space-x-px mb-4' role='group'>
{{#each-in this.views as |key icon|}}
<Button
@icon={{icon}}
@onClick={{set this 'dataView'}}
@value={{key}}
class='w-auto rounded-none first:rounded-l last:rounded-r
{{if (eq this.dataView key) "text-primary"}}'
/>
{{/each-in}}
</div>
{{#if (eq this.dataView 'table')}}
<SimpleTable
@data={{@model.data.hits}}
@sortingProp={{this.sort}}
@onSort={{this.onSort}}
class='w-full'
as |Column data|
>
{{#let
(array @model.index.uid (get data @model.index.primaryKey))
as |models|
}}
{{#each this.attributes as |field|}}
{{#if (not (includes field this.hiddenFields))}}
<Column
@name={{capitalize field}}
@prop={{field}}
@sortable={{includes field @model.sortableAttributes}}
>
<LinkTo
@route='admin.indexes.item.documents.document'
@models={{models}}
class={{linkClasses}}
{{#let (get data field) as |value|}}
{{#if (eq @model.index.primaryKey field)}}
<LinkTo
@route='admin.indexes.item.documents.document'
@models={{models}}
>{{value}}</LinkTo>
{{else if (eq (type-of value) 'object')}}
{{json-stringify value}}
{{else}}
{{value}}
{{/if}}
{{/let}}
</Column>
{{/if}}
{{/each}}
<Column class='relative'>
{{#let
'flex items-center px-4 py-2 text-inherit no-underline text-sm hover:bg-base-6 hover:text-base-1'
as |linkClasses|
}}
<Menu as |menu|>
<menu.Button class='inline-flex items-center'>
<Icons::DotsHorizontal />
</menu.Button>
<menu.Items
class='absolute z-dropdown right-0 w-28 mt-2 py-1 origin-top-right bg-base-7 border rounded shadow-sm outline-none'
>
<Icons::FileDocumentOutline @size={{18}} class='mr-1' />
View
</LinkTo>
<LinkTo
@route='admin.indexes.item.documents.document.edit'
@models={{models}}
class={{linkClasses}}
>
<Icons::PencilOutline @size={{18}} class='mr-1' />
Edit
</LinkTo>
<LinkTo
@route='admin.indexes.item.documents.document.delete'
@models={{models}}
class={{linkClasses}}
>
<Icons::TrashCanOutline @size={{18}} class='mr-1' />
Delete
</LinkTo>
</menu.Items>
</Menu>
{{/let}}
</Column>
{{/let}}
</SimpleTable>
<LinkTo
@route='admin.indexes.item.documents.document.index'
@models={{models}}
class={{linkClasses}}
>
<Icons::FileDocumentOutline @size={{18}} class='mr-1' />
View
</LinkTo>
<LinkTo
@route='admin.indexes.item.documents.document.edit'
@models={{models}}
class={{linkClasses}}
>
<Icons::PencilOutline @size={{18}} class='mr-1' />
Edit
</LinkTo>
<LinkTo
@route='admin.indexes.item.documents.document.delete'
@models={{models}}
class={{linkClasses}}
>
<Icons::TrashCanOutline @size={{18}} class='mr-1' />
Delete
</LinkTo>
</menu.Items>
</Menu>
{{/let}}
</Column>
{{/let}}
</SimpleTable>
{{else if (eq this.dataView 'json')}}
{{#each @model.data.hits as |data|}}
<MonacoEditor
@value={{json-stringify data}}
@language='json'
@readOnly={{true}}
@minHeight={{0}}
@actions={{array
(hash
label='Go to View page'
id='go-to-view-page'
contextMenuGroupId='navigation'
contextMenuOrder=1
run=(fn
this.goToPage
'admin.indexes.item.documents.document.index'
@model.index
(get data @model.index.primaryKey)
)
)
(hash
label='Go to Edit page'
id='go-to-edit-page'
contextMenuGroupId='navigation'
contextMenuOrder=2
run=(fn
this.goToPage
'admin.indexes.item.documents.document.edit'
@model.index
(get data @model.index.primaryKey)
)
)
(hash
label='Go to Delete page'
id='go-to-delete-page'
contextMenuGroupId='navigation'
contextMenuOrder=3
run=(fn
this.goToPage
'admin.indexes.item.documents.document.delete'
@model.index
(get data @model.index.primaryKey)
)
)
}}
class='mb-4'
/>
{{/each}}
{{/if}}
<div class='flex items-center'>
{{this.fromHits}}