Skip to content

Commit

Permalink
Implement paired_or_unpaired collections...
Browse files Browse the repository at this point in the history
  • Loading branch information
jmchilton committed Dec 30, 2024
1 parent 2fa5320 commit 42e4995
Show file tree
Hide file tree
Showing 56 changed files with 3,229 additions and 217 deletions.
13 changes: 9 additions & 4 deletions client/src/api/datasetCollections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ export async function fetchElementsFromCollection(params: {
});
}

type CollectionElementIdentifiers = components["schemas"]["CollectionElementIdentifier"][];
type CreateNewCollectionPayload = components["schemas"]["CreateNewCollectionPayload"];
export type CollectionElementIdentifiers = components["schemas"]["CollectionElementIdentifier"][];
export type CreateNewCollectionPayload = components["schemas"]["CreateNewCollectionPayload"];

type NewCollectionOptions = {
export type NewCollectionOptions = {
name: string;
element_identifiers: CollectionElementIdentifiers;
collection_type: string;
Expand All @@ -104,13 +104,18 @@ export function createCollectionPayload(options: NewCollectionOptions): CreateNe
element_identifiers: options.element_identifiers,
collection_type: options.collection_type,
instance_type: "history",
fields: "auto",
copy_elements: options.copy_elements || true,
hide_source_items: options.hide_source_items || true,
};
}

export async function createHistoryDatasetCollectionInstance(options: NewCollectionOptions) {
export async function createHistoryDatasetCollectionInstanceSimple(options: NewCollectionOptions) {
const payload = createCollectionPayload(options);
return createHistoryDatasetCollectionInstanceFull(payload);
}

export async function createHistoryDatasetCollectionInstanceFull(payload: CreateNewCollectionPayload) {
const { data, error } = await GalaxyApi().POST("/api/dataset_collections", {
body: payload,
});
Expand Down
88 changes: 26 additions & 62 deletions client/src/components/Collections/CollectionCreatorModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BAlert, BLink, BModal } from "bootstrap-vue";
import { computed, ref, watch } from "vue";
import type { HDASummary, HistoryItemSummary, HistorySummary } from "@/api";
import { createDatasetCollection } from "@/components/History/model/queries";
import type { HistoryItemSummary } from "@/api";
import { createHistoryDatasetCollectionInstanceFull, type CreateNewCollectionPayload } from "@/api/datasetCollections";
import { useCollectionBuilderItemsStore } from "@/stores/collectionBuilderItemsStore";
import { useHistoryStore } from "@/stores/historyStore";
import localize from "@/utils/localization";
import { orList } from "@/utils/strings";
import type { CollectionType, DatasetPair } from "../History/adapters/buildCollectionModal";
import type { CollectionType } from "../History/adapters/buildCollectionModal";
import ListCollectionCreator from "./ListCollectionCreator.vue";
import PairCollectionCreator from "./PairCollectionCreator.vue";
import PairedListCollectionCreator from "./PairedListCollectionCreator.vue";
import PairedOrUnpairedListCollectionCreator from "./PairedOrUnpairedListCollectionCreator.vue";
import Heading from "@/components/Common/Heading.vue";
import GenericItem from "@/components/History/Content/GenericItem.vue";
import LoadingSpan from "@/components/LoadingSpan.vue";
Expand All @@ -30,6 +30,7 @@ interface Props {
fromRulesInput?: boolean;
hideModalOnCreate?: boolean;
filterText?: string;
useBetaComponents?: boolean;
}
const props = defineProps<Props>();
Expand Down Expand Up @@ -141,63 +142,11 @@ const modalTitle = computed(() => {
});
// Methods
function createListCollection(elements: HDASummary[], name: string, hideSourceItems: boolean) {
const returnedElems = elements.map((element) => ({
id: element.id,
name: element.name,
//TODO: this allows for list:list even if the implementation does not - reconcile
src: "src" in element ? element.src : element.history_content_type == "dataset" ? "hda" : "hdca",
}));
return createHDCA(returnedElems, "list", name, hideSourceItems);
}
function createListPairedCollection(elements: DatasetPair[], name: string, hideSourceItems: boolean) {
const returnedElems = elements.map((pair) => ({
collection_type: "paired",
src: "new_collection",
name: pair.name,
element_identifiers: [
{
name: "forward",
id: pair.forward.id,
src: "src" in pair.forward ? pair.forward.src : "hda",
},
{
name: "reverse",
id: pair.reverse.id,
src: "src" in pair.reverse ? pair.reverse.src : "hda",
},
],
}));
return createHDCA(returnedElems, "list:paired", name, hideSourceItems);
}
function createPairedCollection(elements: DatasetPair, name: string, hideSourceItems: boolean) {
const { forward, reverse } = elements;
const returnedElems = [
{ name: "forward", src: "src" in forward ? forward.src : "hda", id: forward.id },
{ name: "reverse", src: "src" in reverse ? reverse.src : "hda", id: reverse.id },
];
return createHDCA(returnedElems, "paired", name, hideSourceItems);
}
async function createHDCA(
element_identifiers: any[],
collection_type: CollectionType,
name: string,
hide_source_items: boolean,
options = {}
) {
async function createHDCA(payload: CreateNewCollectionPayload) {
try {
creatingCollection.value = true;
const collection = await createDatasetCollection(history.value as HistorySummary, {
collection_type,
name,
hide_source_items,
element_identifiers,
options,
});
const collection = await createHistoryDatasetCollectionInstanceFull(payload);
emit("created-collection", collection);
createdCollection.value = collection;
Expand Down Expand Up @@ -293,16 +242,30 @@ function resetModal() {
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
@on-create="createListCollection"
mode="modal"
@on-create="createHDCA"
@on-cancel="hideModal" />
<PairedListCollectionCreator
<PairedOrUnpairedListCollectionCreator
v-else-if="props.collectionType === 'list:paired'"
:history-id="props.historyId"
:initial-elements="creatorItems || []"
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
@on-create="createListPairedCollection"
collection-type="list:paired"
mode="modal"
@on-create="createHDCA"
@on-cancel="hideModal" />
<PairedOrUnpairedListCollectionCreator
v-else-if="props.collectionType === 'list:paired_or_unpaired'"
:history-id="props.historyId"
:initial-elements="creatorItems || []"
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
collection-type="list:paired_or_unpaired"
mode="modal"
@on-create="createHDCA"
@on-cancel="hideModal" />
<PairCollectionCreator
v-else-if="props.collectionType === 'paired'"
Expand All @@ -311,7 +274,8 @@ function resetModal() {
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
@clicked-create="createPairedCollection"
mode="modal"
@on-create="createHDCA"
@on-cancel="hideModal" />
</BModal>
</template>
Expand Down
38 changes: 30 additions & 8 deletions client/src/components/Collections/ListCollectionCreator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import { computed, ref, watch } from "vue";
import draggable from "vuedraggable";
import type { HDASummary, HistoryItemSummary } from "@/api";
import { type CollectionElementIdentifiers, type CreateNewCollectionPayload } from "@/api/datasetCollections";
import { useConfirmDialog } from "@/composables/confirmDialog";
import { Toast } from "@/composables/toast";
import localize from "@/utils/localization";
import { stripExtension } from "./common/stripExtension";
import { useCollectionCreator } from "./common/useCollectionCreator";
import { type Mode, useCollectionCreator } from "./common/useCollectionCreator";
import FormSelectMany from "../Form/Elements/FormSelectMany/FormSelectMany.vue";
import CollectionCreator from "@/components/Collections/common/CollectionCreator.vue";
Expand All @@ -28,14 +29,16 @@ interface Props {
defaultHideSourceItems?: boolean;
fromSelection?: boolean;
extensions?: string[];
showButtons?: boolean;
mode: Mode;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(e: "on-create", workingElements: HDASummary[], collectionName: string, hideSourceItems: boolean): void;
(e: "on-create", options: CreateNewCollectionPayload): void;
(e: "on-cancel"): void;
(e: "name", value: string): void;
(e: "input-valid", value: boolean): void;
}>();
const state = ref("build");
Expand Down Expand Up @@ -81,7 +84,16 @@ const allElementsAreInvalid = computed(() => {
/** If not `fromSelection`, the list of elements that will become the collection */
const inListElements = ref<HDASummary[]>([]);
const { removeExtensions, hideSourceItems, onUpdateHideSourceItems, isElementInvalid } = useCollectionCreator(props);
const {
removeExtensions,
hideSourceItems,
onUpdateHideSourceItems,
isElementInvalid,
collectionName,
onUpdateCollectionName,
onCollectionCreate,
showButtonsForModal,
} = useCollectionCreator(props, emit);
// ----------------------------------------------------------------------- process raw list
/** set up main data */
Expand Down Expand Up @@ -245,7 +257,7 @@ function clickSelectAll() {
}
const { confirm } = useConfirmDialog();
async function clickedCreate(collectionName: string) {
async function attemptCreate() {
checkForDuplicates();
const returnedElements = props.fromSelection ? workingElements.value : inListElements.value;
Expand All @@ -261,10 +273,18 @@ async function clickedCreate(collectionName: string) {
}
if (state.value !== "error" && (atLeastOneElement.value || confirmed)) {
emit("on-create", returnedElements, collectionName, hideSourceItems.value);
const identifiers = returnedElements.map((element) => ({
id: element.id,
name: element.name,
//TODO: this allows for list:list even if the implementation does not - reconcile
src: "src" in element ? element.src : element.history_content_type == "dataset" ? "hda" : "hdca",
})) as CollectionElementIdentifiers;
onCollectionCreate("list", identifiers);
}
}
defineExpose({ attemptCreate });
function checkForDuplicates() {
var valid = true;
var existingNames: { [key: string]: boolean } = {};
Expand Down Expand Up @@ -399,12 +419,14 @@ function renameElement(element: any, name: string) {
collection-type="list"
:no-items="props.initialElements.length == 0 && !props.fromSelection"
:show-upload="!fromSelection"
:show-buttons="showButtons"
:show-buttons="showButtonsForModal"
:collection-name="collectionName"
@on-update-collection-name="onUpdateCollectionName"
@add-uploaded-files="addUploadedFiles"
@on-update-datatype-toggle="changeDatatypeFilter"
@onUpdateHideSourceItems="onUpdateHideSourceItems"
@remove-extensions-toggle="removeExtensionsToggle"
@clicked-create="clickedCreate">
@clicked-create="attemptCreate">
<template v-slot:help-content>
<p>
{{
Expand Down
Loading

0 comments on commit 42e4995

Please sign in to comment.