Skip to content

Commit

Permalink
Activity for rule builder imports.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmchilton committed Jan 8, 2025
1 parent dc25995 commit f7932e2
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 56 deletions.
59 changes: 55 additions & 4 deletions client/src/components/Collections/BuildFileSetWizard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { BCardGroup } from "bootstrap-vue";
import { computed, ref } from "vue";
import { getGalaxyInstance } from "@/app";
import { attemptCreate, type CollectionCreatorComponent } from "@/components/Collections/common/useCollectionCreator";
import { rawToTable } from "@/components/Collections/tables";
import { useWizard } from "@/components/Common/Wizard/useWizard";
import { useToolRouting } from "@/composables/route";
Expand All @@ -18,6 +20,7 @@ import SourceFromDatasetAsTable from "./wizard/SourceFromDatasetAsTable.vue";
import SourceFromPastedData from "./wizard/SourceFromPastedData.vue";
import SourceFromRemoteFiles from "./wizard/SourceFromRemoteFiles.vue";
import GenericWizard from "@/components/Common/Wizard/GenericWizard.vue";
import RuleCollectionBuilder from "@/components/RuleCollectionBuilder.vue";
const isBusy = ref<boolean>(false);
const { pasteData, tabularDatasetContents, uris, setRemoteFilesFolder, onFtp, setDatasetContents, setPasteTable } =
Expand All @@ -26,17 +29,20 @@ const { pasteData, tabularDatasetContents, uris, setRemoteFilesFolder, onFtp, se
interface Props {
fileSourcesConfigured: boolean;
ftpUploadSite?: string;
mode: "uploadModal" | "standalone";
}
const props = defineProps<Props>();
const ruleState = ref(false);
const creatingWhat = ref<RulesCreatingWhat>("datasets");
const creatingWhatTitle = computed(() => {
return creatingWhat.value == "datasets" ? "Datasets" : "Collections";
});
const sourceInstructions = computed(() => {
return `${creatingWhatTitle.value} can be created from a set or files, URIs, or existing datasets.`;
});
const collectionCreator = ref<CollectionCreatorComponent | undefined>();
const sourceFrom = ref<RulesSourceFrom>("remote_files");
Expand Down Expand Up @@ -65,7 +71,7 @@ const wizard = useWizard({
},
"paste-data": {
label: "Paste data",
instructions: "Paste data containing URIs and optional extra metadata.",
instructions: "Paste data (or drop file) containing URIs and optional extra metadata.",
isValid: () => sourceFrom.value === "pasted_table" && pasteData.value.length > 0,
isSkippable: () => sourceFrom.value !== "pasted_table",
},
Expand All @@ -75,6 +81,13 @@ const wizard = useWizard({
isValid: () => sourceFrom.value === "dataset_as_table" && tabularDatasetContents.value.length > 0,
isSkippable: () => sourceFrom.value !== "dataset_as_table",
},
"rule-builder": {
label: "Specify Rules",
instructions: "Use this form to describe rules for importing",
isValid: () => ruleState.value,
isSkippable: () => props.mode == "uploadModal",
width: "100%",
},
});
const importButtonLabel = computed(() => {
Expand All @@ -85,7 +98,7 @@ const importButtonLabel = computed(() => {
}
});
const emit = defineEmits(["dismiss"]);
const emit = defineEmits(["dismiss", "created"]);
type SelectionType = "raw" | "remote_files";
type ElementsType = RemoteFile[] | string[][];
Expand All @@ -101,8 +114,7 @@ interface Entry {
selectionType: SelectionType;
}
function launchRuleBuilder() {
const Galaxy = getGalaxyInstance();
const ruleBuilderModalEntryProps = computed(() => {
let elements: ElementsType | undefined = undefined;
let selectionType: SelectionType = "raw";
if (sourceFrom.value == "remote_files") {
Expand All @@ -119,12 +131,31 @@ function launchRuleBuilder() {
selectionType: selectionType,
elements: elements,
};
return entry;
});
const ruleBuilderElements = computed(() => {
const builderProps = ruleBuilderModalEntryProps.value;
let elements;
if (builderProps.elements) {
elements = builderProps.elements;
} else {
elements = rawToTable(builderProps.content || "");
}
return elements;
});
function launchRuleBuilder() {
const Galaxy = getGalaxyInstance();
const entry = ruleBuilderModalEntryProps.value;
Galaxy.currHistoryPanel.buildCollectionFromRules(entry, null, true);
}
function submit() {
if (sourceFrom.value == "collection") {
routeToTool("__APPLY_RULES__");
} else if (props.mode == "standalone") {
attemptCreate(collectionCreator);
} else {
launchRuleBuilder();
}
Expand All @@ -138,6 +169,15 @@ function setCreatingWhat(what: RulesCreatingWhat) {
function setSourceForm(newValue: RulesSourceFrom) {
sourceFrom.value = newValue;
}
function onRuleState(newRuleState: boolean) {
ruleState.value = newRuleState;
}
function onRuleCreate() {
// axios response data for job currently sent, not really used but wanted to document what is available.
emit("created");
}
</script>

<template>
Expand Down Expand Up @@ -165,5 +205,16 @@ function setSourceForm(newValue: RulesSourceFrom) {
<div v-else-if="wizard.isCurrent('select-dataset')">
<SelectDataset @onChange="setDatasetContents" />
</div>
<div v-else-if="wizard.isCurrent('rule-builder')" style="width: 100%">
<RuleCollectionBuilder
ref="collectionCreator"
grid-implementation="ag"
:import-type="creatingWhat"
:elements-type="ruleBuilderModalEntryProps.selectionType"
:initial-elements="ruleBuilderElements"
mode="wizard"
@onCreate="onRuleCreate"
@validInput="onRuleState" />
</div>
</GenericWizard>
</template>
35 changes: 7 additions & 28 deletions client/src/components/Collections/ListWizard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import { useCollectionBuilderItemSelection } from "@/stores/collectionBuilderIte
import { errorMessageAsString } from "@/utils/simple-error";
import { useCollectionCreation } from "./common/useCollectionCreation";
import { type SupportedPairedOrPairedBuilderCollectionTypes } from "./common/useCollectionCreator";
import {
attemptCreate,
type CollectionCreatorComponent,
type SupportedPairedOrPairedBuilderCollectionTypes,
} from "./common/useCollectionCreator";
import { type WhichListBuilder } from "./ListWizard/types";
import { autoPairWithCommonFilters } from "./pairing";
Expand All @@ -40,9 +44,6 @@ const creationError = ref<string | null>(null);
const collectionCreated = ref(false);
type InferrableBuilder = "list" | "list:paired";
type CollectionCreatorComponent =
| InstanceType<typeof ListCollectionCreator>
| InstanceType<typeof PairedOrUnpairedListCollectionCreator>;
const collectionCreator = ref<CollectionCreatorComponent>();
const { selectedItems } = storeToRefs(store);
Expand Down Expand Up @@ -155,26 +156,15 @@ const pairedListType = computed(() => {
return whichBuilder.value == "list:paired_or_unpaired" ? "list:paired_or_unpaired" : "list:paired";
});
async function attemptCreate(creator: CollectionCreatorComponent) {
// fight typing to workaround https://github.com/vuejs/core/issues/10077
interface HasAttemptCreate {
attemptCreate: () => Promise<void>;
}
(creator as unknown as HasAttemptCreate).attemptCreate();
}
async function submit() {
if (collectionCreator.value) {
attemptCreate(collectionCreator.value);
attemptCreate(collectionCreator);
}
}
async function onCreate(payload: CreateNewCollectionPayload) {
try {
const data = await createHistoryDatasetCollectionInstanceFull(payload);
console.log(data);
console.log("collection created!");
await createHistoryDatasetCollectionInstanceFull(payload);
collectionCreated.value = true;
} catch (e) {
creationError.value = errorMessageAsString(e);
Expand Down Expand Up @@ -213,18 +203,9 @@ function goToAutoPairing() {
wizard.goTo("auto-pairing");
}
function onRuleCreate() {
return 3;
}
function onRuleCancel() {
return 3;
}
const ruleState = ref(false);
function onRuleState(newRuleState: boolean) {
console.log("in on Rule state...");
ruleState.value = newRuleState;
}
</script>
Expand Down Expand Up @@ -288,8 +269,6 @@ function onRuleState(newRuleState: boolean) {
elements-type="datasets"
:initial-elements="selectedItems || []"
mode="wizard"
:oncreate="onRuleCreate"
:oncancel="onRuleCancel"
@onAttemptCreate="ruleOnAttemptCreate"
@validInput="onRuleState" />
</div>
Expand Down
35 changes: 35 additions & 0 deletions client/src/components/Collections/RulesStandalone.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { BAlert, BContainer, BRow } from "bootstrap-vue";
import { ref } from "vue";
import { useConfig } from "@/composables/config";
import BuildFileSetWizard from "./BuildFileSetWizard.vue";
import LoadingSpan from "@/components/LoadingSpan.vue";
const { config, isConfigLoaded } = useConfig();
const created = ref(false);
function onCreated() {
created.value = true;
}
</script>

<template>
<BContainer>
<LoadingSpan v-if="!isConfigLoaded" />
<BRow v-else-if="created">
<BAlert show variant="success" style="width: 100%">
Data imported and should be available in your history.
</BAlert>
</BRow>
<div v-else>
<BuildFileSetWizard
mode="standalone"
:file-sources-configured="config.file_sources_configured"
:ftp-upload-site="config.ftp_upload_site"
@created="onCreated" />
</div>
</BContainer>
</template>
22 changes: 21 additions & 1 deletion client/src/components/Collections/common/useCollectionCreator.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { computed, ref, watch } from "vue";
import { computed, type Ref, ref, unref, watch } from "vue";

import { type HistoryItemSummary } from "@/api";
import { type CollectionElementIdentifiers, type CreateNewCollectionPayload } from "@/api/datasetCollections";
import type RuleCollectionBuilder from "@/components/RuleCollectionBuilder.vue";
import STATES from "@/mvc/dataset/states";
import localize from "@/utils/localization";

import type ListCollectionCreator from "./ListCollectionCreator.vue";
import type PairedOrUnpairedListCollectionCreator from "./PairedOrUnpairedListCollectionCreator.vue";
import { useCollectionCreation } from "./useCollectionCreation";
import { useExtensionFiltering } from "./useExtensionFilter";

Expand All @@ -28,6 +31,23 @@ export type SupportedPairedOrPairedBuilderCollectionTypes =
| "list:list"
| "list:list:paired";

export type CollectionCreatorComponent =
| InstanceType<typeof ListCollectionCreator>
| InstanceType<typeof PairedOrUnpairedListCollectionCreator>
| InstanceType<typeof RuleCollectionBuilder>;

export async function attemptCreate(creator: CollectionCreatorComponent | Ref<CollectionCreatorComponent | undefined>) {
const creatorValue: CollectionCreatorComponent | undefined = unref(creator);
// fight typing to workaround https://github.com/vuejs/core/issues/10077
interface HasAttemptCreate {
attemptCreate: () => Promise<void>;
}

if (creatorValue) {
(creatorValue as unknown as HasAttemptCreate).attemptCreate();
}
}

export function useCollectionCreator(props: CommonCollectionBuilderProps, emit?: EmitsName) {
const removeExtensions = ref(true);
const hideSourceItems = ref(props.defaultHideSourceItems || false);
Expand Down
11 changes: 10 additions & 1 deletion client/src/components/Common/Wizard/GenericWizard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ const stepsGridColumnsTemplate = computed(() => {
.join(" ") + " max-content"
);
});
const bodyStyle = computed(() => {
const width = props.use.current.value.width;
if (width) {
return { width: width };
} else {
return {};
}
});
</script>

<template>
Expand Down Expand Up @@ -158,7 +167,7 @@ const stepsGridColumnsTemplate = computed(() => {
<div class="step-content">
<span class="h-md step-instructions" v-text="props.use.current.value.instructions" />

<div class="step-body">
<div class="step-body" :style="bodyStyle">
<slot>
<p>
Missing body for step <b>{{ props.use.current.value.label }}</b>
Expand Down
6 changes: 6 additions & 0 deletions client/src/components/Common/Wizard/useWizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export interface WizardStep {
* This is useful for optional or conditional steps.
*/
isSkippable: () => boolean;

/**
* Hack added by John, someone component in CSS should undo this or come up
* with an alternative that doesn't require this to be set.
*/
hackBodyWidth?: string;
}

/**
Expand Down
Loading

0 comments on commit f7932e2

Please sign in to comment.