Merge pull request #17818 from martenson/noexpand-private

[24.0] do not expand datasets that are known to be inaccessible
This commit is contained in:
Marius van den Beek
2024-05-25 15:53:03 +02:00
committed by GitHub
14 changed files with 168 additions and 22 deletions
+9 -5
View File
@@ -7,11 +7,15 @@ const inputFilePath = process.argv[2];
const localPath = new URL(inputFilePath, import.meta.url);
openapiTS(localPath, {
transform(schemaObject, metadata) {
if (
"const" in schemaObject &&
(typeof schemaObject.const === "string" || schemaObject.const instanceof String)
) {
return `"${schemaObject.const}"`;
if ("const" in schemaObject) {
const constType = typeof schemaObject.const;
switch (constType) {
case "number":
case "boolean":
return `${schemaObject.const}`;
default:
return `"${schemaObject.const}"`;
}
}
},
}).then((output) => console.log(output));
+10 -1
View File
@@ -89,6 +89,11 @@ export type DatasetSummary = components["schemas"]["HDASummary"];
*/
export type DatasetDetails = components["schemas"]["HDADetailed"];
/**
* Represents a HistoryDatasetAssociation that is inaccessible to the user.
*/
export type HDAInaccessible = components["schemas"]["HDAInaccessible"];
/**
* Contains storage (object store, quota, etc..) details for a dataset.
*/
@@ -97,7 +102,7 @@ export type DatasetStorageDetails = components["schemas"]["DatasetStorageDetails
/**
* Represents a HistoryDatasetAssociation with either summary or detailed information.
*/
export type DatasetEntry = DatasetSummary | DatasetDetails;
export type DatasetEntry = DatasetSummary | DatasetDetails | HDAInaccessible;
/**
* Contains summary information about a DCE (DatasetCollectionElement).
@@ -183,6 +188,10 @@ export function hasDetails(entry: DatasetEntry): entry is DatasetDetails {
return "peek" in entry;
}
export function isInaccessible(entry: DatasetEntry): entry is HDAInaccessible {
return "accessible" in entry && !entry.accessible;
}
/**
* Contains dataset metadata information.
*/
+97 -1
View File
@@ -5998,11 +5998,94 @@ export interface components {
*/
visible: boolean;
};
/**
* HDAInaccessible
* @description History Dataset Association information when the user can not access it.
*/
HDAInaccessible: {
/**
* Accessible
* @constant
*/
accessible: false;
/** Copied From Ldda Id */
copied_from_ldda_id?: string | null;
/**
* Create Time
* @description The time and date this item was created.
*/
create_time: string | null;
/**
* Deleted
* @description Whether this item is marked as deleted.
*/
deleted: boolean;
/**
* HID
* @description The index position of this item in the History.
*/
hid: number;
/**
* History Content Type
* @description This is always `dataset` for datasets.
* @constant
*/
history_content_type: "dataset";
/**
* History ID
* @example 0123456789ABCDEF
*/
history_id: string;
/**
* Id
* @example 0123456789ABCDEF
*/
id: string;
/**
* Name
* @description The name of the item.
*/
name: string | null;
/**
* State
* @description The current state of this dataset.
*/
state: components["schemas"]["DatasetState"];
tags: components["schemas"]["TagCollection"];
/**
* Type
* @description The type of this item.
*/
type: string;
/**
* Type - ID
* @description The type and the encoded ID of this item. Used for caching.
*/
type_id?: string | null;
/**
* Update Time
* @description The last time and date this item was updated.
*/
update_time: string | null;
/**
* URL
* @deprecated
* @description The relative URL to access this item.
*/
url: string;
/**
* Visible
* @description Whether this item is visible or hidden to the user by default.
*/
visible: boolean;
};
/**
* HDAObject
* @description History Dataset Association Object
*/
HDAObject: {
/** Accessible */
accessible?: boolean | null;
/** Copied From Ldda Id */
copied_from_ldda_id?: string | null;
/**
@@ -6925,6 +7008,7 @@ export interface components {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
)[];
@@ -6941,6 +7025,7 @@ export interface components {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
)[];
@@ -13533,6 +13618,7 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
)[];
@@ -13713,7 +13799,8 @@ export interface operations {
"application/json":
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"];
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"];
};
};
/** @description Validation Error */
@@ -16465,12 +16552,14 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
| (
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
)[];
@@ -17054,6 +17143,7 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"];
};
@@ -17105,6 +17195,7 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"];
};
@@ -17337,12 +17428,14 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
| (
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
)[];
@@ -17393,6 +17486,7 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"];
};
@@ -17443,6 +17537,7 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"];
};
@@ -17674,6 +17769,7 @@ export interface operations {
| components["schemas"]["HDACustom"]
| components["schemas"]["HDADetailed"]
| components["schemas"]["HDASummary"]
| components["schemas"]["HDAInaccessible"]
| components["schemas"]["HDCADetailed"]
| components["schemas"]["HDCASummary"]
)[];
@@ -91,7 +91,9 @@ const contentId = computed(() => {
const contentCls = computed(() => {
const status = contentState.value && contentState.value.status;
if (props.selected) {
if (props.item.accessible === false) {
return "alert-inaccessible";
} else if (props.selected) {
return "alert-info";
} else if (!status) {
return `alert-success`;
@@ -99,7 +101,6 @@ const contentCls = computed(() => {
return `alert-${status}`;
}
});
const contentState = computed(() => {
return STATES[state.value] && STATES[state.value];
});
@@ -116,6 +117,9 @@ const state = computed<keyof StateMap>(() => {
if (props.isPlaceholder) {
return "placeholder";
}
if (props.item.accessible === false) {
return "inaccessible";
}
if (props.item.populated_state === "failed") {
return "failed_populated_state";
}
@@ -135,7 +139,13 @@ const state = computed<keyof StateMap>(() => {
});
const dataState = computed(() => {
return state.value === "new_populated_state" ? "new" : state.value;
if (props.item.accessible === false) {
return "inaccessible";
} else if (state.value === "new_populated_state") {
return "new";
} else {
return state.value;
}
});
const tags = computed(() => {
@@ -334,7 +344,7 @@ function unexpandedClick(event: Event) {
:data-state="dataState"
tabindex="0"
role="button"
draggable
:draggable="props.item.accessible === false ? false : true"
@dragstart="onDragStart"
@dragend="onDragEnd"
@keydown="onKeyDown">
@@ -428,8 +438,9 @@ function unexpandedClick(event: Event) {
</span>
<!-- collections are not expandable, so we only need the DatasetDetails component here -->
<BCollapse :visible="expandDataset" class="px-2 pb-2">
<div v-if="item.accessible === false">You are not allowed to access this dataset</div>
<DatasetDetails
v-if="expandDataset && item.id"
v-else-if="expandDataset && item.id"
:id="item.id"
:writable="writable"
:show-highlight="(isHistoryItem && filterable) || addHighlightBtn"
@@ -2,6 +2,7 @@
import { BLink } from "bootstrap-vue";
import { computed } from "vue";
import { hasDetails } from "@/api";
import { STATES } from "@/components/History/Content/model/states";
import { useDatasetStore } from "@/stores/datasetStore";
@@ -26,6 +27,7 @@ const props = withDefaults(defineProps<Props>(), {
const emit = defineEmits<{
(e: "toggleHighlights"): void;
(e: "edit"): void;
}>();
const result = computed(() => datasetStore.getDataset(props.id));
@@ -40,7 +42,7 @@ function toggleHighlights() {
<template>
<div>
<div v-if="result && !isLoading" class="dataset">
<div v-if="result && !isLoading && hasDetails(result)" class="dataset">
<div class="details not-loading">
<div class="summary">
<div v-if="stateText" class="mb-1">{{ stateText }}</div>
@@ -2,7 +2,13 @@ import type { components } from "@/api/schema";
type DatasetState = components["schemas"]["DatasetState"];
// The 'failed' state is for the collection job state summary, not a dataset state.
type State = DatasetState | "failed" | "placeholder" | "failed_populated_state" | "new_populated_state";
type State =
| DatasetState
| "failed"
| "placeholder"
| "failed_populated_state"
| "new_populated_state"
| "inaccessible";
interface StateRepresentation {
status: "success" | "warning" | "info" | "danger" | "secondary";
@@ -120,6 +126,12 @@ export const STATES: StateMap = {
icon: "clock",
nonDb: true,
},
inaccessible: {
status: "warning",
text: "User not allowed to access this dataset.",
icon: "lock",
nonDb: true,
},
} as const satisfies StateMap;
/** We want to display a single state for a dataset collection whose elements may have mixed states.
@@ -76,7 +76,7 @@ function updateDsc(collection: any, fields: Object | undefined) {
}
function getItemKey(item: DCESummary) {
return item.id;
return `${item.element_type}-${item.id}`;
}
function onScroll(newOffset: number) {
@@ -45,7 +45,7 @@ const emit = defineEmits(["update:filter-text", "reloadContents"]);
const router = useRouter();
const { config } = useConfig();
const { currentUser } = storeToRefs(useUserStore());
const { currentUser, isAnonymous } = storeToRefs(useUserStore());
const { historySize, numItemsActive, numItemsDeleted, numItemsHidden } = useHistoryContentStats(
toRef(props, "history")
);
@@ -146,7 +146,7 @@ onMounted(() => {
<BButtonGroup v-if="currentUser">
<BButton
v-if="config && config.object_store_allows_id_selection"
v-if="config && config.object_store_allows_id_selection && !isAnonymous"
:id="`history-storage-${history.id}`"
title="Manage Preferred History Storage"
variant="link"
@@ -157,7 +157,7 @@ onMounted(() => {
</BButton>
<PreferredStorePopover
v-if="config && config.object_store_allows_id_selection"
v-if="config && config.object_store_allows_id_selection && !isAnonymous"
:history-id="history.id"
:history-preferred-object-store-id="historyPreferredObjectStoreId"
:user="currentUser">
@@ -425,7 +425,7 @@ function updateFilterValue(filterKey: string, newValue: any) {
}
function getItemKey(item: HistoryItem) {
return item.type_id;
return itemUniqueKey(item);
}
function itemUniqueKey(item: HistoryItem) {
@@ -150,6 +150,7 @@ function mockElement(collectionId: string, i: number): DCESummary {
hda_ldda: "hda",
history_id: "1",
tags: [],
accessible: true,
},
};
}
+4 -1
View File
@@ -1,7 +1,7 @@
import { defineStore } from "pinia";
import { computed, set } from "vue";
import type { DatasetDetails, DatasetEntry, HistoryContentItemBase } from "@/api";
import { type DatasetDetails, type DatasetEntry, type HistoryContentItemBase, isInaccessible } from "@/api";
import { fetchDataset } from "@/api/datasets";
import { ApiResponse } from "@/api/schema";
import { useKeyedCache } from "@/composables/keyedCache";
@@ -17,6 +17,9 @@ export const useDatasetStore = defineStore("datasetStore", () => {
if (!dataset) {
return true;
}
if (isInaccessible(dataset)) {
return false;
}
const isNotDetailed = !("peek" in dataset);
return isNotDetailed;
};
+2
View File
@@ -203,6 +203,7 @@ $galaxy-state-border: (
"deleted": darken($state-default-border, 30%),
"hidden": $state-default-border,
"setting_metadata": $state-warning-border,
"inaccessible": darken($state-default-border, 10%),
);
$galaxy-state-bg: (
@@ -216,6 +217,7 @@ $galaxy-state-bg: (
"deleted": darken($state-default-bg, 30%),
"hidden": $state-default-bg,
"setting_metadata": $state-warning-bg,
"inaccessible": darken($state-default-bg, 10%),
);
@each $state in map-keys($galaxy-state-border) {
+3 -2
View File
@@ -695,7 +695,7 @@ class HDASummary(HDACommon):
class HDAInaccessible(HDACommon):
"""History Dataset Association information when the user can not access it."""
accessible: bool = AccessibleField
accessible: Literal[False]
state: DatasetStateField
@@ -946,6 +946,7 @@ class HDAObject(Model, WithModelClass):
history_id: HistoryID
tags: List[str]
copied_from_ldda_id: Optional[EncodedDatabaseIdField] = None
accessible: Optional[bool] = None
model_config = ConfigDict(extra="allow")
@@ -3278,7 +3279,7 @@ class HDACustom(HDADetailed):
model_config = ConfigDict(extra="allow")
AnyHDA = Union[HDACustom, HDADetailed, HDASummary]
AnyHDA = Union[HDACustom, HDADetailed, HDASummary, HDAInaccessible]
AnyHDCA = Union[HDCADetailed, HDCASummary]
AnyHistoryContentItem = Annotated[
Union[
@@ -24,6 +24,7 @@ from galaxy.managers.collections_util import (
dictify_element_reference,
)
from galaxy.managers.context import ProvidesHistoryContext
from galaxy.managers.hdas import HDAManager
from galaxy.managers.hdcas import HDCAManager
from galaxy.managers.histories import HistoryManager
from galaxy.model import DatasetCollectionElement
@@ -94,12 +95,14 @@ class DatasetCollectionsService(ServiceBase, UsesLibraryMixinItems):
self,
security: IdEncodingHelper,
history_manager: HistoryManager,
hda_manager: HDAManager,
hdca_manager: HDCAManager,
collection_manager: DatasetCollectionManager,
datatypes_registry: Registry,
):
super().__init__(security)
self.history_manager = history_manager
self.hda_manager = hda_manager
self.hdca_manager = hdca_manager
self.collection_manager = collection_manager
self.datatypes_registry = datatypes_registry
@@ -270,6 +273,8 @@ class DatasetCollectionsService(ServiceBase, UsesLibraryMixinItems):
hdca_id=self.encode_id(hdca.id),
parent_id=self.encode_id(result["object"]["id"]),
)
else:
result["object"]["accessible"] = self.hda_manager.is_accessible(dsc_element.element_object, trans.user)
return result
rval = [serialize_element(el) for el in contents]