Skip to content

Commit 235878a

Browse files
authored
Merge pull request #21231 from guerler/add_state_display
Consolidate Dataset State Display
2 parents 401eda7 + 84e8f89 commit 235878a

File tree

6 files changed

+89
-61
lines changed

6 files changed

+89
-61
lines changed

client/src/api/jobs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export type JobMessage =
1717

1818
export const NON_TERMINAL_STATES = ["new", "queued", "running", "waiting", "paused", "resubmitted", "stop"];
1919
export const ERROR_STATES = ["error", "deleted", "deleting"];
20-
export const TERMINAL_STATES = ["ok", "skipped", "stop", "stopping", "skipped"].concat(ERROR_STATES);
20+
export const TERMINAL_STATES = ["ok", "skipped", "stop", "stopping"].concat(ERROR_STATES);
2121

2222
interface JobDef {
2323
tool_id: string;

client/src/components/Dataset/DatasetDisplay.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<script setup lang="ts">
2+
import { faExclamationTriangle, faSpinner } from "@fortawesome/free-solid-svg-icons";
3+
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
24
import { BAlert } from "bootstrap-vue";
35
import { storeToRefs } from "pinia";
46
import { computed, ref, watch } from "vue";
57
68
import { useDatasetStore } from "@/stores/datasetStore";
79
import { useUserStore } from "@/stores/userStore";
10+
import STATES from "@/utils/datasetStates";
811
import { withPrefix } from "@/utils/redirect";
912
import { errorMessageAsString } from "@/utils/simple-error";
1013
import { bytesToString } from "@/utils/utils";
@@ -75,6 +78,14 @@ watch(
7578
{{ errorMessage }}
7679
</BAlert>
7780
<LoadingSpan v-else-if="isLoading || !dataset" message="Loading dataset content" />
81+
<BAlert v-else-if="STATES.PENDING_STATES.includes(dataset.state)" show variant="warning">
82+
<FontAwesomeIcon :icon="faSpinner" spin />
83+
<span>Waiting for dataset to become available. Please check the history panel for details.</span>
84+
</BAlert>
85+
<BAlert v-else-if="!STATES.OK_STATES.includes(dataset.state)" show variant="danger">
86+
<FontAwesomeIcon :icon="faExclamationTriangle" />
87+
<span>Dataset is unavailable. Please check the history panel for details.</span>
88+
</BAlert>
7889
<div v-else class="dataset-display h-100">
7990
<Alert v-if="sanitizedMessage" :dismissible="true" variant="warning" data-description="sanitization warning">
8091
{{ sanitizedMessage }}

client/src/components/Dataset/DatasetView.vue

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { usePersistentToggle } from "@/composables/persistentToggle";
88
import { useDatasetStore } from "@/stores/datasetStore";
99
import { useDatatypesMapperStore } from "@/stores/datatypesMapperStore";
1010
import { useDatatypeStore } from "@/stores/datatypeStore";
11+
import STATES from "@/utils/datasetStates";
1112
import { withPrefix } from "@/utils/redirect";
1213
import { bytesToString } from "@/utils/utils";
1314
@@ -41,6 +42,7 @@ const props = withDefaults(defineProps<Props>(), {
4142
const iframeLoading = ref(true);
4243
4344
const dataset = computed(() => datasetStore.getDataset(props.datasetId));
45+
const downloadUrl = computed(() => withPrefix(`/datasets/${props.datasetId}/display`));
4446
const headerState = computed(() => (headerCollapsed.value ? "closed" : "open"));
4547
4648
// Track datatype loading state
@@ -51,23 +53,16 @@ const isLoading = computed(() => {
5153
return datasetStore.isLoadingDataset(props.datasetId) || isDatatypeLoading.value || datatypesMapperStore.loading;
5254
});
5355
54-
const showError = computed(
55-
() => dataset.value && (dataset.value.state === "error" || dataset.value.state === "failed_metadata"),
56-
);
56+
// Match datatype variant
5757
const isAutoDownloadType = computed(
5858
() => dataset.value && datatypeStore.isDatatypeAutoDownload(dataset.value.file_ext),
5959
);
60-
const downloadUrl = computed(() => withPrefix(`/datasets/${props.datasetId}/display`));
61-
const preferredVisualization = computed(
62-
() => dataset.value && datatypeStore.getPreferredVisualization(dataset.value.file_ext),
63-
);
6460
const isBinaryDataset = computed(() => {
6561
if (!dataset.value?.file_ext || !datatypesMapperStore.datatypesMapper) {
6662
return false;
6763
}
6864
return datatypesMapperStore.datatypesMapper.isSubTypeOfAny(dataset.value.file_ext, ["galaxy.datatypes.binary"]);
6965
});
70-
7166
const isImageDataset = computed(() => {
7267
if (!dataset.value?.file_ext || !datatypesMapperStore.datatypesMapper) {
7368
return false;
@@ -76,11 +71,19 @@ const isImageDataset = computed(() => {
7671
"galaxy.datatypes.images.Image",
7772
]);
7873
});
79-
8074
const isPdfDataset = computed(() => {
8175
return dataset.value?.file_ext === "pdf";
8276
});
8377
78+
// Has a preferred visualization?
79+
const preferredVisualization = computed(
80+
() => dataset.value && datatypeStore.getPreferredVisualization(dataset.value.file_ext),
81+
);
82+
83+
// Match dataset state
84+
const showError = computed(() => dataset.value && STATES.ERROR === dataset.value.state);
85+
const showOk = computed(() => dataset.value && STATES.OK_STATES.includes(dataset.value.state));
86+
8487
// Watch for changes to the dataset to fetch datatype info
8588
watch(
8689
() => dataset.value?.file_ext,
@@ -149,20 +152,21 @@ watch(
149152
</header>
150153
<BNav v-if="!displayOnly" pills class="my-2 p-2 bg-light border-bottom">
151154
<BNavItem
155+
v-if="showOk"
152156
title="View a preview of the dataset contents"
153157
:active="tab === 'preview'"
154158
:to="`/datasets/${datasetId}/preview`">
155159
<FontAwesomeIcon :icon="faEye" class="mr-1" /> Preview
156160
</BNavItem>
157161
<BNavItem
158-
v-if="preferredVisualization"
162+
v-if="showOk && preferredVisualization"
159163
title="View raw dataset contents"
160164
:active="tab === 'raw'"
161165
:to="`/datasets/${datasetId}/raw`">
162166
<FontAwesomeIcon :icon="faFileAlt" class="mr-1" /> Raw
163167
</BNavItem>
164168
<BNavItem
165-
v-if="!showError"
169+
v-if="showOk"
166170
title="Explore available visualizations for this dataset"
167171
:active="tab === 'visualize'"
168172
:to="`/datasets/${datasetId}/visualize`">

client/src/components/History/Content/ContentItem.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { getGalaxyInstance } from "@/app";
1616
import type { ItemUrls } from "@/components/History/Content/Dataset/index";
1717
import { updateContentFields } from "@/components/History/model/queries";
1818
import { useEntryPointStore } from "@/stores/entryPointStore";
19+
import DATASET_STATES from "@/utils/datasetStates";
1920
import { clearDrag } from "@/utils/setDrag";
2021
2122
import { getContentItemState, type State, STATES } from "./model/states";
@@ -174,6 +175,8 @@ const itemUrls = computed<ItemUrls>(() => {
174175
let display = `/datasets/${id}`;
175176
if (props.item.extension == "tool_markdown") {
176177
display = `/datasets/${id}/report`;
178+
} else if (!DATASET_STATES.OK_STATES.includes(state.value)) {
179+
display = `/datasets/${id}/details`;
177180
}
178181
return {
179182
display: display,

client/src/utils/datasetStates.ts

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,70 @@
1-
//==============================================================================
2-
/** Map of possible HDA/collection/job states to their string equivalents.
3-
* A port of galaxy.model.Dataset.states.
4-
*/
5-
const RAW_STATES = {
6-
// NOT ready states
7-
/** is uploading and not ready */
8-
UPLOAD: "upload",
9-
/** the job that will produce the dataset queued in the runner */
10-
QUEUED: "queued",
11-
/** the job that will produce the dataset is running */
12-
RUNNING: "running",
13-
/** metadata for the dataset is being discovered/set */
14-
SETTING_METADATA: "setting_metadata",
15-
16-
// ready states
17-
/** was created without a tool */
18-
NEW: "new",
19-
/** has no data */
20-
EMPTY: "empty",
21-
/** has successfully completed running */
22-
OK: "ok",
23-
24-
/** the job that will produce the dataset paused */
25-
PAUSED: "paused",
26-
/** metadata discovery/setting failed or errored (but otherwise ok) */
27-
FAILED_METADATA: "failed_metadata",
28-
//TODO: not in trans.app.model.Dataset.states - is in database
29-
/** not accessible to the current user (i.e. due to permissions) */
30-
NOT_VIEWABLE: "noPermission",
1+
const STATES = {
312
/** deleted while uploading */
323
DISCARDED: "discarded",
334
/** remote dataset not ingested yet */
345
DEFERRED: "deferred",
6+
/** dataset has been deleted */
7+
DELETED: "deleted",
8+
/** dataset is being been deleted */
9+
DELETING: "deleting",
10+
/** has no data */
11+
EMPTY: "empty",
3512
/** the tool producing this dataset failed */
3613
ERROR: "error",
14+
/** metadata discovery/setting failed or errored (but otherwise ok) */
15+
FAILED_METADATA: "failed_metadata",
16+
/** was created without a tool */
17+
NEW: "new",
18+
/** not accessible to the current user (i.e. due to permissions) */
19+
NOT_VIEWABLE: "noPermission",
20+
/** has successfully completed running */
21+
OK: "ok",
22+
/** the job that will produce the dataset paused */
23+
PAUSED: "paused",
24+
/** the job that will produce the dataset queued in the runner */
25+
QUEUED: "queued",
26+
/** the job that will produce the dataset is running */
27+
RUNNING: "running",
28+
/** the job has been resubmitted */
29+
RESUBMITTED: "resubmitted",
30+
/** metadata for the dataset is being discovered/set */
31+
SETTING_METADATA: "setting_metadata",
32+
/** the job has been skipped */
33+
SKIPPED: "skipped",
34+
/** the job has been stopped */
35+
STOP: "stop",
36+
/** the job is stopping */
37+
STOPPING: "stopping",
38+
/** is uploading and not ready */
39+
UPLOAD: "upload",
40+
/** the job is waiting */
41+
WAITING: "waiting",
3742
};
3843

39-
const STATES = {
40-
...RAW_STATES,
44+
export default {
45+
...STATES,
46+
OK_STATES: [STATES.OK, STATES.DEFERRED, STATES.FAILED_METADATA],
4147
READY_STATES: [
42-
RAW_STATES.OK,
43-
RAW_STATES.EMPTY,
44-
RAW_STATES.PAUSED,
45-
RAW_STATES.FAILED_METADATA,
46-
RAW_STATES.NOT_VIEWABLE,
47-
RAW_STATES.DEFERRED,
48-
RAW_STATES.DISCARDED,
49-
RAW_STATES.ERROR,
48+
STATES.DEFERRED,
49+
STATES.DISCARDED,
50+
STATES.EMPTY,
51+
STATES.ERROR,
52+
STATES.FAILED_METADATA,
53+
STATES.NOT_VIEWABLE,
54+
STATES.OK,
55+
STATES.PAUSED,
56+
STATES.SKIPPED,
57+
STATES.STOP,
58+
STATES.STOPPING,
5059
],
51-
NOT_READY_STATES: [
52-
RAW_STATES.UPLOAD,
53-
RAW_STATES.QUEUED,
54-
RAW_STATES.RUNNING,
55-
RAW_STATES.SETTING_METADATA,
56-
RAW_STATES.NEW,
60+
PENDING_STATES: [
61+
STATES.NEW,
62+
STATES.QUEUED,
63+
STATES.RESUBMITTED,
64+
STATES.RUNNING,
65+
STATES.SETTING_METADATA,
66+
STATES.UPLOAD,
67+
STATES.WAITING,
5768
],
69+
ERROR_STATES: [STATES.DELETED, STATES.DELETING, STATES.ERROR],
5870
};
59-
60-
//==============================================================================
61-
export default STATES;

lib/galaxy/webapps/galaxy/buildapp.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ def app_pair(global_conf, load_app_kwds=None, wsgi_preflight=True, **kwargs):
284284
webapp.add_client_route("/datasets/{dataset_id}/error")
285285
webapp.add_client_route("/datasets/{dataset_id}/details")
286286
webapp.add_client_route("/datasets/{dataset_id}/preview")
287+
webapp.add_client_route("/datasets/{dataset_id}/raw")
287288
webapp.add_client_route("/datasets/{dataset_id}/report")
288289
webapp.add_client_route("/datasets/{dataset_id}/show_params")
289290
webapp.add_client_route("/datasets/{dataset_id}/visualize")

0 commit comments

Comments
 (0)