The code for listing all of the defined queries is mixed together with the code for editing a single query. Notably, this results in large amounts of unnecessary data being loaded for the list view, which causes substantial rendering slowdowns. To address this issue, we now only load the necessary data for the list view, and load the full data when it's actually needed (any endpoint that returns a single query). The primary changes that achieve this are: - Create a new `QueryDetailsSerializer` serialiser, which includes all of the query info, and change the existing `QuerySerializer` serialiser to only include the necessary attributes of each query for generating a list of them all. - Split the monolith `/plugins/explorer` route into `/plugins/explorer` for showing just the list of queries, and `/plugins/explorer/queries/:query_id`, for showing/editing/running a specific query.
166 lines
5.2 KiB
Handlebars
166 lines
5.2 KiB
Handlebars
{{#if this.disallow}}
|
|
<h1>{{i18n "explorer.admins_only"}}</h1>
|
|
{{else}}
|
|
<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 "triangle-exclamation"}}
|
|
{{i18n "explorer.others_dirty"}}
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#if this.model.length}}
|
|
<ConditionalLoadingSpinner @condition={{this.loading}} />
|
|
|
|
<div class="container">
|
|
<table class="d-admin-table 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="d-admin-row__content query-row">
|
|
<td class="d-admin-row__overview">
|
|
<a
|
|
{{on "click" this.scrollTop}}
|
|
href="/admin/plugins/explorer/queries/{{query.id}}"
|
|
>
|
|
<b class="query-name">{{query.name}}</b>
|
|
<medium class="query-desc">{{query.description}}</medium>
|
|
</a>
|
|
</td>
|
|
<td class="d-admin-row__detail query-created-by">
|
|
<div class="d-admin-row__mobile-label">
|
|
{{i18n "explorer.query_user"}}
|
|
</div>
|
|
{{#if query.username}}
|
|
<div>
|
|
<a href="/u/{{query.username}}/activity">
|
|
<medium>{{query.username}}</medium>
|
|
</a>
|
|
</div>
|
|
{{/if}}
|
|
</td>
|
|
<td class="d-admin-row__detail query-group-names">
|
|
<div class="d-admin-row__mobile-label">
|
|
{{i18n "explorer.query_groups"}}
|
|
</div>
|
|
<div class="group-names">
|
|
{{#each query.group_names as |group|}}
|
|
<ShareReport @group={{group}} @query={{query}} />
|
|
{{/each}}
|
|
</div>
|
|
</td>
|
|
<td class="d-admin-row__detail query-created-at">
|
|
<div class="d-admin-row__mobile-label">
|
|
{{i18n "explorer.query_time"}}
|
|
</div>
|
|
{{#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>
|
|
|
|
<div class="explorer-pad-bottom"></div>
|
|
{{/if}}
|
|
{{/if}} |