Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show backend search errors in hist panel #15874

Merged
Merged
Expand Up @@ -51,7 +51,13 @@
<b-form-input v-model="filterSettings['tag:']" size="sm" placeholder="any tag" />
<small class="mt-1">Filter by state:</small>
<b-input-group>
<b-form-input v-model="filterSettings['state:']" size="sm" placeholder="any state" list="stateSelect" />
<b-form-input
v-model="filterSettings['state:']"
v-b-tooltip.focus.v-danger="hasError('state:')"
:class="hasError('state:') && 'ui-input-error'"
size="sm"
placeholder="any state"
list="stateSelect" />
<b-form-datalist id="stateSelect" :options="states"></b-form-datalist>
<b-input-group-append>
<b-button title="States Help" size="sm" @click="showHelp = true">
Expand All @@ -63,22 +69,47 @@
<small>Filter by database:</small>
<b-form-input v-model="filterSettings['genome_build:']" size="sm" placeholder="any database" />
<small class="mt-1">Filter by related to item index:</small>
<b-form-input v-model="filterSettings['related:']" size="sm" placeholder="index equals" />
<b-form-input
v-model="filterSettings['related:']"
v-b-tooltip.focus.v-danger="hasError('related:')"
:class="hasError('related:') && 'ui-input-error'"
size="sm"
placeholder="index equals" />
<small class="mt-1">Filter by item index:</small>
<b-form-group class="m-0">
<b-input-group>
<b-form-input v-model="filterSettings['hid>']" size="sm" placeholder="index greater" />
<b-form-input v-model="filterSettings['hid<']" size="sm" placeholder="index lower" />
<b-form-input
v-model="filterSettings['hid>']"
v-b-tooltip.focus.v-danger="hasError('hid>')"
:class="hasError('hid>') && 'ui-input-error'"
size="sm"
placeholder="index greater" />
<b-form-input
v-model="filterSettings['hid<']"
v-b-tooltip.focus.v-danger="hasError('hid<')"
:class="hasError('hid<') && 'ui-input-error'"
size="sm"
placeholder="index lower" />
</b-input-group>
</b-form-group>
<small class="mt-1">Filter by creation time:</small>
<b-form-group class="m-0">
<b-input-group>
<b-form-input v-model="create_time_gt" size="sm" placeholder="created after" />
<b-form-input
v-model="create_time_gt"
v-b-tooltip.focus.v-danger="hasError('create_time>')"
:class="hasError('create_time>') && 'ui-input-error'"
size="sm"
placeholder="created after" />
<b-input-group-append>
<b-form-datepicker v-model="create_time_gt" reset-button button-only size="sm" />
</b-input-group-append>
<b-form-input v-model="create_time_lt" size="sm" placeholder="created before" />
<b-form-input
v-model="create_time_lt"
v-b-tooltip.focus.v-danger="hasError('create_time<')"
:class="hasError('create_time<') && 'ui-input-error'"
size="sm"
placeholder="created before" />
<b-input-group-append>
<b-form-datepicker v-model="create_time_lt" reset-button button-only size="sm" />
</b-input-group-append>
Expand Down Expand Up @@ -115,6 +146,7 @@ export default {
props: {
filterText: { type: String, default: null },
showAdvanced: { type: Boolean, default: false },
searchError: { type: Object, default: null },
},
data() {
return {
Expand Down Expand Up @@ -147,8 +179,17 @@ export default {
this.create_time_gt = this.filterSettings["create_time>"];
this.create_time_lt = this.filterSettings["create_time<"];
},
showAdvanced(newVal) {
this.showHelp = !newVal ? false : this.showHelp;
},
},
methods: {
hasError(field) {
if (this.searchError && this.searchError.filter == field) {
return this.searchError.typeError || this.searchError.msg;
}
return "";
},
onOption(name, value) {
this.filterSettings[name] = value;
},
Expand Down
39 changes: 34 additions & 5 deletions client/src/components/History/CurrentHistory/HistoryPanel.vue
Expand Up @@ -31,7 +31,8 @@
v-if="showControls"
class="content-operations-filters mx-3"
:filter-text.sync="filterText"
:show-advanced.sync="showAdvanced" />
:show-advanced.sync="showAdvanced"
:search-error="formattedSearchError" />
<section v-if="!showAdvanced">
<HistoryDetails
:history="history"
Expand Down Expand Up @@ -93,6 +94,12 @@
</b-alert>
<div v-else-if="itemsLoaded.length === 0">
<HistoryEmpty v-if="queryDefault" class="m-2" />
<b-alert v-else-if="formattedSearchError" class="m-2" variant="danger" show>
Error in filter:
<a href="javascript:void(0)" @click="showAdvanced = true">
{{ formattedSearchError.filter }}'{{ formattedSearchError.value }}'
</a>
</b-alert>
<b-alert v-else class="m-2" variant="info" show>
No data found for selected filter.
</b-alert>
Expand Down Expand Up @@ -153,6 +160,7 @@ import HistoryDetails from "./HistoryDetails";
import HistoryDropZone from "./HistoryDropZone";
import HistoryEmpty from "./HistoryEmpty";
import HistoryFilters from "./HistoryFilters/HistoryFilters";
import { getOperatorForAlias } from "utils/filtering";
import HistoryMessages from "./HistoryMessages";
import HistorySelectionOperations from "./HistoryOperations/SelectionOperations";
import HistorySelectionStatus from "./HistoryOperations/SelectionStatus";
Expand Down Expand Up @@ -190,12 +198,12 @@ export default {
},
data() {
return {
error: null,
filterText: "",
highlightsKey: null,
invisible: {},
loading: false,
offset: 0,
searchError: null,
showAdvanced: false,
showDropZone: false,
operationRunning: null,
Expand Down Expand Up @@ -248,6 +256,23 @@ export default {
const { getWatchingVisibility } = storeToRefs(useHistoryItemsStore());
return getWatchingVisibility.value;
},
/** @returns {Object} */
formattedSearchError() {
if (this.searchError) {
const { column, col, operation, op, value, val, err_msg, ValueError } = this.searchError;
const alias = operation || op;
const operator = alias ? getOperatorForAlias(alias) : ":";
const formatted = {
filter: `${column || col}${operator}`,
value: value || val,
msg: err_msg,
typeError: ValueError,
};
return formatted;
} else {
return null;
}
},
/** @returns {String} */
storeFilterText() {
const { currentFilterText } = storeToRefs(useHistoryStore());
Expand Down Expand Up @@ -316,11 +341,15 @@ export default {
this.loading = true;
try {
await this.fetchHistoryItems(this.historyId, this.filterText, this.offset);
this.error = null;
this.searchError = null;
this.loading = false;
} catch (error) {
console.debug("HistoryPanel - Load error.", error);
this.error = error;
if (error.response && error.response.data && error.response.data.err_msg) {
console.debug("HistoryPanel - Load items error:", error.response.data.err_msg);
this.searchError = error.response.data;
} else {
console.debug("HistoryPanel - Load items error.", error);
}
this.loading = false;
}
},
Expand Down
2 changes: 1 addition & 1 deletion client/src/stores/history/historyItemsStore.js
Expand Up @@ -67,7 +67,7 @@ export const useHistoryItemsStore = defineStore("historyItemsStore", {
const params = `v=dev&order=hid&offset=${offset}&limit=${limit}`;
const url = `/api/histories/${historyId}/contents?${params}&${queryString}`;
const headers = { accept: "application/vnd.galaxy.history.contents.stats+json" };
await queue.enqueue(urlData, { url, headers }, historyId).then((data) => {
return await queue.enqueue(urlData, { url, headers, errorSimplify: false }, historyId).then((data) => {
const stats = data.stats;
this.totalMatchesCount = stats.total_matches;
const payload = data.contents;
Expand Down
4 changes: 4 additions & 0 deletions client/src/style/scss/ui.scss
Expand Up @@ -213,6 +213,10 @@ $ui-margin-horizontal-large: $margin-v * 2;
}
}

.ui-input-error {
border-color: $brand-danger;
}

.ui-textarea {
@extend .ui-input;
height: 100px !important;
Expand Down
8 changes: 6 additions & 2 deletions client/src/utils/url.js
Expand Up @@ -2,14 +2,18 @@ import axios from "axios";
import { withPrefix } from "utils/redirect";
import { rethrowSimple } from "utils/simple-error";

export async function urlData({ url, headers, params }) {
export async function urlData({ url, headers, params, errorSimplify = true }) {
try {
headers = headers || {};
params = params || {};
const { data } = await axios.get(withPrefix(url), { headers, params });
return data;
} catch (e) {
rethrowSimple(e);
if (errorSimplify) {
rethrowSimple(e);
} else {
throw e;
}
}
}

Expand Down