394 lines
12 KiB
Handlebars
394 lines
12 KiB
Handlebars
{{#if this.disallow}}
|
|
<h1>{{i18n "explorer.admins_only"}}</h1>
|
|
{{else}}
|
|
{{#unless this.validQueryPresent}}
|
|
<div class="query-list">
|
|
<TextField
|
|
@value={{this.search}}
|
|
@placeholderKey="explorer.search_placeholder"
|
|
@onChange={{this.updateSearch}}
|
|
/>
|
|
<DButton
|
|
@action={{this.displayCreate}}
|
|
@icon="plus"
|
|
class="no-text btn-right"
|
|
/>
|
|
<PickFilesButton
|
|
@label="explorer.import.label"
|
|
@icon="upload"
|
|
@acceptedFormatsOverride={{this.acceptedImportFileTypes}}
|
|
@showButton="true"
|
|
@onFilesPicked={{this.import}}
|
|
class="import-btn"
|
|
/>
|
|
</div>
|
|
|
|
{{#if this.showCreate}}
|
|
<div class="query-create">
|
|
<TextField
|
|
@value={{this.newQueryName}}
|
|
@placeholderKey="explorer.create_placeholder"
|
|
@onChange={{this.updateNewQueryName}}
|
|
/>
|
|
<DButton
|
|
@action={{this.create}}
|
|
@disabled={{this.createDisabled}}
|
|
@label="explorer.create"
|
|
@icon="plus"
|
|
/>
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#if this.othersDirty}}
|
|
<div class="warning">
|
|
{{d-icon "exclamation-triangle"}}
|
|
{{i18n "explorer.others_dirty"}}
|
|
</div>
|
|
{{/if}}
|
|
{{/unless}}
|
|
|
|
{{#if this.model.length}}
|
|
{{#unless this.selectedItem.fake}}
|
|
<div class="query-edit {{if this.editName 'editing'}}">
|
|
{{#if this.selectedItem}}
|
|
{{#if this.editingName}}
|
|
<div class="name">
|
|
<DButton
|
|
@action={{this.goHome}}
|
|
@icon="chevron-left"
|
|
class="previous"
|
|
/>
|
|
<DButton
|
|
@action={{this.exitEdit}}
|
|
@icon="times"
|
|
class="previous"
|
|
/>
|
|
<div class="name-text-field">
|
|
<TextField
|
|
@value={{this.selectedItem.name}}
|
|
@onChange={{this.setDirty}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="desc">
|
|
<DTextarea
|
|
@value={{this.selectedItem.description}}
|
|
@placeholder={{i18n "explorer.description_placeholder"}}
|
|
@input={{this.setDirty}}
|
|
/>
|
|
</div>
|
|
{{else}}
|
|
<div class="name">
|
|
<DButton
|
|
@action={{this.goHome}}
|
|
@icon="chevron-left"
|
|
class="previous"
|
|
/>
|
|
|
|
<h1>
|
|
{{this.selectedItem.name}}
|
|
{{#unless this.editDisabled}}
|
|
<a href {{action "editName"}} class="edit-query-name">
|
|
{{d-icon "pencil-alt"}}
|
|
</a>
|
|
{{/unless}}
|
|
</h1>
|
|
</div>
|
|
|
|
<div class="desc">
|
|
{{this.selectedItem.description}}
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#unless this.selectedItem.destroyed}}
|
|
<div class="pull-left">
|
|
<div class="groups">
|
|
<span class="label">{{i18n "explorer.allow_groups"}}</span>
|
|
<span>
|
|
<MultiSelect
|
|
@value={{this.selectedItem.group_ids}}
|
|
@content={{this.groupOptions}}
|
|
@options={{hash allowAny=false}}
|
|
@onChange={{this.updateGroupIds}}
|
|
/>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{{/unless}}
|
|
|
|
<div class="clear"></div>
|
|
|
|
{{#if this.editingQuery}}
|
|
<div class="query-editor {{if this.hideSchema 'no-schema'}}">
|
|
<div class="panels-flex">
|
|
<div class="editor-panel">
|
|
<AceEditor
|
|
{{on "click" this.setDirty}}
|
|
@content={{this.selectedItem.sql}}
|
|
@onChange={{fn (mut this.selectedItem.sql)}}
|
|
@mode="sql"
|
|
@disabled={{this.selectedItem.destroyed}}
|
|
@save={{this.save}}
|
|
@submit={{this.saveAndRun}}
|
|
/>
|
|
</div>
|
|
|
|
<div class="right-panel">
|
|
<ExplorerSchema
|
|
@schema={{this.schema}}
|
|
@hideSchema={{this.hideSchema}}
|
|
@updateHideSchema={{this.updateHideSchema}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="grippie"
|
|
{{draggable
|
|
didStartDrag=this.didStartDrag
|
|
didEndDrag=this.didEndDrag
|
|
dragMove=this.dragMove
|
|
}}
|
|
>
|
|
{{d-icon "discourse-expand"}}
|
|
</div>
|
|
|
|
<div class="clear"></div>
|
|
</div>
|
|
{{else}}
|
|
<div class="sql">
|
|
<CodeView
|
|
@value={{this.selectedItem.sql}}
|
|
@codeClass="sql"
|
|
@setDirty={{this.setDirty}}
|
|
/>
|
|
</div>
|
|
{{/if}}
|
|
|
|
<div class="clear"></div>
|
|
|
|
<div class="pull-left left-buttons">
|
|
{{#if this.editingQuery}}
|
|
<DButton
|
|
class="btn-save-query"
|
|
@action={{this.save}}
|
|
@label="explorer.save"
|
|
@disabled={{this.saveDisabled}}
|
|
/>
|
|
{{else}}
|
|
{{#unless this.editDisabled}}
|
|
<DButton
|
|
class="btn-edit-query"
|
|
@action={{this.editQuery}}
|
|
@label="explorer.edit"
|
|
@icon="pencil-alt"
|
|
/>
|
|
{{/unless}}
|
|
{{/if}}
|
|
|
|
<DButton
|
|
@action={{this.download}}
|
|
@label="explorer.export"
|
|
@disabled={{this.runDisabled}}
|
|
@icon="download"
|
|
/>
|
|
|
|
{{#if this.editingQuery}}
|
|
<DButton
|
|
@action={{this.showHelpModal}}
|
|
@label="explorer.help.label"
|
|
@icon="question-circle"
|
|
/>
|
|
{{/if}}
|
|
</div>
|
|
|
|
<div class="pull-right right-buttons">
|
|
{{#if this.selectedItem.destroyed}}
|
|
<DButton
|
|
@action={{this.recover}}
|
|
@icon="undo"
|
|
@label="explorer.recover"
|
|
/>
|
|
{{else}}
|
|
{{#if this.editingQuery}}
|
|
<DButton
|
|
@action={{this.discard}}
|
|
@icon="undo"
|
|
@label="explorer.undo"
|
|
@disabled={{this.saveDisabled}}
|
|
/>
|
|
{{/if}}
|
|
|
|
<DButton
|
|
@action={{this.destroyQuery}}
|
|
@icon="trash-alt"
|
|
@label="explorer.delete"
|
|
class="btn-danger"
|
|
/>
|
|
{{/if}}
|
|
</div>
|
|
|
|
<div class="clear"></div>
|
|
{{/if}}
|
|
</div>
|
|
|
|
<form class="query-run" {{on "submit" this.run}}>
|
|
{{#if this.selectedItem.hasParams}}
|
|
<ParamInputForm
|
|
@initialValues={{this.parsedParams}}
|
|
@paramInfo={{this.selectedItem.param_info}}
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
/>
|
|
{{/if}}
|
|
|
|
{{#if this.runDisabled}}
|
|
{{#if this.saveDisabled}}
|
|
<DButton
|
|
@label="explorer.run"
|
|
@disabled="true"
|
|
class="btn-primary"
|
|
/>
|
|
{{else}}
|
|
<DButton
|
|
@action={{this.saveAndRun}}
|
|
@icon="play"
|
|
@label="explorer.saverun"
|
|
class="btn-primary"
|
|
/>
|
|
{{/if}}
|
|
{{else}}
|
|
<DButton
|
|
@action={{this.run}}
|
|
@icon="play"
|
|
@label="explorer.run"
|
|
@disabled={{this.runDisabled}}
|
|
@type="submit"
|
|
class="btn-primary"
|
|
/>
|
|
{{/if}}
|
|
|
|
<label class="query-plan">
|
|
<Input @type="checkbox" @checked={{this.explain}} name="explain" />
|
|
{{i18n "explorer.explain_label"}}
|
|
</label>
|
|
</form>
|
|
<hr />
|
|
{{/unless}}
|
|
|
|
<ConditionalLoadingSpinner @condition={{this.loading}} />
|
|
|
|
{{#unless this.selectedItem.fake}}
|
|
<QueryResultsWrapper
|
|
@results={{this.results}}
|
|
@showResults={{this.showResults}}
|
|
@query={{this.selectedItem}}
|
|
@content={{this.results}}
|
|
/>
|
|
{{/unless}}
|
|
|
|
{{#unless this.validQueryPresent}}
|
|
<div class="container">
|
|
<table class="recent-queries">
|
|
<thead class="heading-container">
|
|
<th class="col heading name">
|
|
<div
|
|
role="button"
|
|
class="heading-toggle"
|
|
{{on "click" (fn this.updateSortProperty "name")}}
|
|
>
|
|
<TableHeaderToggle
|
|
@field="name"
|
|
@labelKey="explorer.query_name"
|
|
@order={{this.order}}
|
|
@asc={{not this.sortDescending}}
|
|
@automatic="true"
|
|
/>
|
|
</div>
|
|
</th>
|
|
<th class="col heading created-by">
|
|
<div
|
|
role="button"
|
|
class="heading-toggle"
|
|
{{on "click" (fn this.updateSortProperty "username")}}
|
|
>
|
|
<TableHeaderToggle
|
|
@field="username"
|
|
@labelKey="explorer.query_user"
|
|
@order={{this.order}}
|
|
@asc={{not this.sortDescending}}
|
|
@automatic="true"
|
|
/>
|
|
</div>
|
|
</th>
|
|
<th class="col heading group-names">
|
|
<div class="group-names-header">
|
|
{{i18n "explorer.query_groups"}}
|
|
</div>
|
|
</th>
|
|
<th class="col heading created-at">
|
|
<div
|
|
role="button"
|
|
class="heading-toggle"
|
|
{{on "click" (fn this.updateSortProperty "last_run_at")}}
|
|
>
|
|
<TableHeaderToggle
|
|
@field="last_run_at"
|
|
@labelKey="explorer.query_time"
|
|
@order={{this.order}}
|
|
@asc={{not this.sortDescending}}
|
|
@automatic="true"
|
|
/>
|
|
</div>
|
|
</th>
|
|
</thead>
|
|
<tbody>
|
|
{{#each this.filteredContent as |query|}}
|
|
<tr class="query-row">
|
|
<td>
|
|
<a
|
|
{{on "click" this.scrollTop}}
|
|
href="/admin/plugins/explorer/?id={{query.id}}"
|
|
>
|
|
<b class="query-name">{{query.name}}</b>
|
|
<medium class="query-desc">{{query.description}}</medium>
|
|
</a>
|
|
</td>
|
|
<td class="query-created-by">
|
|
{{#if query.username}}
|
|
<a href="/u/{{query.username}}/activity">
|
|
<medium>{{query.username}}</medium>
|
|
</a>
|
|
{{/if}}
|
|
</td>
|
|
<td class="query-group-names">
|
|
{{#each query.group_names as |group|}}
|
|
<ShareReport @group={{group}} @query={{query}} />
|
|
{{/each}}
|
|
</td>
|
|
<td class="query-created-at">
|
|
{{#if query.last_run_at}}
|
|
<medium>
|
|
{{bound-date query.last_run_at}}
|
|
</medium>
|
|
{{else if query.created_at}}
|
|
<medium>
|
|
{{bound-date query.created_at}}
|
|
</medium>
|
|
{{/if}}
|
|
</td>
|
|
</tr>
|
|
{{else}}
|
|
<br />
|
|
<em class="no-search-results">
|
|
{{i18n "explorer.no_search_results"}}
|
|
</em>
|
|
{{/each}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{/unless}}
|
|
|
|
<div class="explorer-pad-bottom"></div>
|
|
{{/if}}
|
|
{{/if}} |