Refactor export wizards for more shared code

This commit is contained in:
mvdbeek
2026-01-21 12:21:11 +01:00
parent 93296316d7
commit c3f5a46400
10 changed files with 355 additions and 220 deletions
+4
View File
@@ -2,6 +2,10 @@ import { GalaxyApi, type ObjectExportTaskResponse } from "@/api";
import { ExportRecordModel } from "@/components/Common/models/exportRecordModel";
import { rethrowSimple } from "@/utils/simple-error";
import type { components } from "./schema";
export type WriteStoreToPayload = components["schemas"]["WriteStoreToPayload"];
/**
* Gets a list of recent export records for the current user.
* This includes exports to remote file sources (not short-term storage downloads).
@@ -0,0 +1,73 @@
<script setup lang="ts">
import { BCard, BCardGroup, BCardImg, BCardTitle } from "bootstrap-vue";
import { borderVariant } from "@/components/Common/Wizard/utils";
import type { ExportPlugin } from "@/components/Workflow/Invocation/Export/Plugins";
import { useMarkdown } from "@/composables/markdown";
import ExternalLink from "@/components/ExternalLink.vue";
const { renderMarkdown } = useMarkdown({ openLinksInNewPage: true });
interface Props {
plugins: ExportPlugin[];
modelValue: string;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(e: "update:model-value", value: string): void;
}>();
function selectPlugin(plugin: ExportPlugin) {
emit("update:model-value", plugin.exportParams.modelStoreFormat);
}
function isSelected(plugin: ExportPlugin): boolean {
return props.modelValue === plugin.exportParams.modelStoreFormat;
}
</script>
<template>
<BCardGroup deck>
<BCard
v-for="plugin in plugins"
:key="plugin.id"
:data-export-format="plugin.exportParams.modelStoreFormat"
class="export-format-card"
:border-variant="borderVariant(isSelected(plugin))"
@click="selectPlugin(plugin)">
<BCardTitle>
<b>{{ plugin.title }}</b>
</BCardTitle>
<div v-if="plugin.img">
<BCardImg :src="plugin.img" :alt="plugin.title" class="export-format-img" />
<br />
<ExternalLink v-if="plugin.url" :href="plugin.url">
<b>Learn more</b>
</ExternalLink>
</div>
<div v-else v-html="renderMarkdown(plugin.markdownDescription)" />
</BCard>
</BCardGroup>
</template>
<style scoped lang="scss">
.export-format-card {
cursor: pointer;
transition: border-color 0.15s ease-in-out;
&:hover {
border-color: var(--bs-primary);
}
}
.export-format-img {
height: auto;
width: auto;
max-height: 100px;
max-width: 100%;
max-inline-size: -webkit-fill-available;
}
</style>
@@ -0,0 +1,51 @@
<script setup lang="ts">
import { BFormCheckbox, BFormGroup } from "bootstrap-vue";
interface Props {
includeFiles: boolean;
includeDeleted: boolean;
includeHidden: boolean;
disabled?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
disabled: false,
});
const emit = defineEmits<{
(e: "update:includeFiles", value: boolean): void;
(e: "update:includeDeleted", value: boolean): void;
(e: "update:includeHidden", value: boolean): void;
}>();
</script>
<template>
<BFormGroup label="Dataset files included in the export:">
<BFormCheckbox
:checked="props.includeFiles"
:disabled="props.disabled"
switch
data-test-id="include-files-checkbox"
@change="emit('update:includeFiles', $event)">
Include Active Files
</BFormCheckbox>
<BFormCheckbox
:checked="props.includeDeleted"
:disabled="props.disabled"
switch
data-test-id="include-deleted-checkbox"
@change="emit('update:includeDeleted', $event)">
Include Deleted (not purged)
</BFormCheckbox>
<BFormCheckbox
:checked="props.includeHidden"
:disabled="props.disabled"
switch
data-test-id="include-hidden-checkbox"
@change="emit('update:includeHidden', $event)">
Include Hidden
</BFormCheckbox>
</BFormGroup>
</template>
@@ -0,0 +1,74 @@
<script setup lang="ts">
import { BFormGroup, BFormInput } from "bootstrap-vue";
import type { FilterFileSourcesOptions } from "@/api/remoteFiles";
import { useFileSources } from "@/composables/fileSources";
import localize from "@/utils/localization";
import FilesInput from "@/components/FilesDialog/FilesInput.vue";
interface Props {
directory: string;
fileName?: string;
fileExtension?: string;
resourceName?: string;
filterOptions?: FilterFileSourcesOptions;
showFileName?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
fileName: "",
fileExtension: "",
resourceName: "data",
filterOptions: () => ({ exclude: ["rdm"] }),
showFileName: false,
});
const emit = defineEmits<{
(e: "update:directory", value: string): void;
(e: "update:fileName", value: string): void;
}>();
const { hasWritable: hasWritableFileSources } = useFileSources(props.filterOptions);
const directoryDescription = localize(`Select a 'repository' to export ${props.resourceName} to.`);
const fileNameDescription = localize("Give the exported file a name.");
</script>
<template>
<div>
<p v-if="!hasWritableFileSources" class="text-warning">
No writable file sources are configured. Please contact your administrator.
</p>
<template v-else>
<BFormGroup id="fieldset-directory" label-for="directory" :description="directoryDescription" class="mt-3">
<FilesInput
id="directory"
:value="props.directory"
mode="directory"
:require-writable="true"
:filter-options="props.filterOptions"
data-test-id="export-destination-input"
@input="emit('update:directory', $event)" />
</BFormGroup>
<BFormGroup
v-if="props.showFileName"
id="fieldset-name"
label-for="name"
:description="fileNameDescription"
class="mt-3">
<div class="d-flex align-items-center">
<BFormInput
id="name"
:value="props.fileName"
placeholder="Name"
required
data-test-id="export-file-name-input"
@input="emit('update:fileName', $event)" />
<span v-if="props.fileExtension" class="ml-2 text-muted">.{{ props.fileExtension }}</span>
</div>
</BFormGroup>
</template>
</div>
</template>
@@ -1,21 +1,23 @@
<script setup lang="ts">
import { BAlert, BCard, BCardGroup, BCardTitle, BFormCheckbox, BFormGroup, BFormInput } from "bootstrap-vue";
import { BAlert, BCard, BCardGroup, BFormGroup, BFormInput } from "bootstrap-vue";
import { computed, reactive, ref, watch } from "vue";
import { AVAILABLE_EXPORT_FORMATS } from "@/api/histories.export";
import type { ModelStoreFormat } from "@/api";
import { useWizard } from "@/components/Common/Wizard/useWizard";
import { borderVariant } from "@/components/Common/Wizard/utils";
import type { ExportPlugin } from "@/components/Workflow/Invocation/Export/Plugins";
import { useFileSources } from "@/composables/fileSources";
import { useMarkdown } from "@/composables/markdown";
import { DEFAULT_EXPORT_PARAMS } from "@/composables/shortTermStorage";
import type { HistoryExportData, HistoryExportDestination } from "./types";
import ExportFormatSelector from "@/components/Common/ExportFormatSelector.vue";
import ExportIncludeOptions from "@/components/Common/ExportIncludeOptions.vue";
import ExportRemoteSourceSelector from "@/components/Common/ExportRemoteSourceSelector.vue";
import RDMCredentialsInfo from "@/components/Common/RDMCredentialsInfo.vue";
import RDMDestinationSelector from "@/components/Common/RDMDestinationSelector.vue";
import GenericWizard from "@/components/Common/Wizard/GenericWizard.vue";
import ExternalLink from "@/components/ExternalLink.vue";
import FilesInput from "@/components/FilesDialog/FilesInput.vue";
import FileSourceNameSpan from "@/components/FileSources/FileSourceNameSpan.vue";
const { renderMarkdown } = useMarkdown({ openLinksInNewPage: true });
@@ -30,6 +32,34 @@ const {
const resource = "history";
// History-specific export plugins
const historyExportPlugins: ExportPlugin[] = [
{
id: "ro-crate",
title: "RO-Crate",
img: "https://www.researchobject.org/ro-crate/assets/img/ro-crate-wide.svg",
url: "https://www.researchobject.org/ro-crate/",
markdownDescription: `RO-Crate is a community effort to establish a lightweight approach to packaging research data with their metadata. It makes use of schema.org annotations in JSON-LD format.`,
exportParams: {
modelStoreFormat: "rocrate.zip",
includeFiles: true,
includeDeleted: false,
includeHidden: false,
},
},
{
id: "tar-gz",
title: "Compressed TGZ",
markdownDescription: `A compressed tar.gz archive containing the history and its metadata.`,
exportParams: {
modelStoreFormat: "tar.gz" as ModelStoreFormat,
includeFiles: true,
includeDeleted: false,
includeHidden: false,
},
},
];
interface ExportDestinationInfo {
destination: HistoryExportDestination;
label: string;
@@ -84,12 +114,13 @@ const exportDestinationSummary = computed(() => {
const exportDestinationTargets = computed(initializeExportDestinations);
const exportFormats = computed(() => AVAILABLE_EXPORT_FORMATS);
const selectedPlugin = computed(
() =>
historyExportPlugins.find((p) => p.exportParams.modelStoreFormat === exportData.modelStoreFormat) ||
historyExportPlugins[0],
);
const exportFormatName = computed(() => {
const format = exportFormats.value.find((f) => f.id === exportData.modelStoreFormat);
return format ? format.name : "";
});
const exportFormatName = computed(() => selectedPlugin.value?.title ?? "");
const zenodoSource = computed(() => getZenodoSource());
@@ -155,6 +186,13 @@ function onRecordSelected(recordUri: string) {
exportData.remoteUri = recordUri;
}
function onFormatSelected(formatId: string) {
const plugin = historyExportPlugins.find((p) => p.exportParams.modelStoreFormat === formatId);
if (plugin) {
exportData.modelStoreFormat = plugin.exportParams.modelStoreFormat;
}
}
async function exportHistory() {
emit("onExport", exportData);
}
@@ -232,36 +270,10 @@ function resetWizard() {
:is-busy="isBusy"
@submit="exportHistory">
<div v-if="wizard.isCurrent('select-format')">
<BCardGroup deck>
<BCard
v-for="format in exportFormats"
:key="format.id"
:data-history-export-format="format.id"
class="wizard-selection-card"
:border-variant="borderVariant(exportData.modelStoreFormat == format.id)"
@click="exportData.modelStoreFormat = format.id">
<BCardTitle>
<b>{{ format.name }}</b>
</BCardTitle>
<div v-if="format.id === 'rocrate.zip'">
<p>
RO-Crate is a community effort to establish a lightweight approach to packaging research
data with their metadata. It makes use of schema.org annotations in JSON-LD format.
</p>
<img
class="card-img"
src="https://www.researchobject.org/ro-crate/assets/img/ro-crate-wide.svg"
alt="RO-Crate Logo" />
<br />
<ExternalLink href="https://www.researchobject.org/ro-crate/">
<b>Learn more</b>
</ExternalLink>
</div>
<div v-else>
<p>A compressed tar.gz archive containing the history and its metadata.</p>
</div>
</BCard>
</BCardGroup>
<ExportFormatSelector
:model-value="exportData.modelStoreFormat"
:plugins="historyExportPlugins"
@update:model-value="onFormatSelected" />
</div>
<div v-if="wizard.isCurrent('select-destination')">
@@ -283,18 +295,10 @@ function resetWizard() {
</div>
<div v-if="wizard.isCurrent('setup-remote')">
<BFormGroup
id="fieldset-directory"
label-for="directory"
:description="`Select a 'repository' to export ${resource} to.`"
class="mt-3">
<FilesInput
id="directory"
v-model="exportData.remoteUri"
mode="directory"
:require-writable="true"
:filter-options="{ exclude: ['rdm'] }" />
</BFormGroup>
<ExportRemoteSourceSelector
:directory="exportData.remoteUri"
:resource-name="resource"
@update:directory="exportData.remoteUri = $event" />
</div>
<div v-if="wizard.isCurrent('setup-rdm')">
@@ -337,15 +341,13 @@ function resetWizard() {
required />
</BFormGroup>
<BFormGroup label="Dataset files included in the package:">
<BFormCheckbox v-model="exportData.includeFiles" switch> Include Active Files </BFormCheckbox>
<BFormCheckbox v-model="exportData.includeDeleted" switch>
Include Deleted (not purged)
</BFormCheckbox>
<BFormCheckbox v-model="exportData.includeHidden" switch> Include Hidden </BFormCheckbox>
</BFormGroup>
<ExportIncludeOptions
:include-files="exportData.includeFiles"
:include-deleted="exportData.includeDeleted"
:include-hidden="exportData.includeHidden"
@update:include-files="exportData.includeFiles = $event"
@update:include-deleted="exportData.includeDeleted = $event"
@update:include-hidden="exportData.includeHidden = $event" />
<br />
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { BAlert, BCard, BCardGroup, BCardImg, BCardTitle, BFormCheckbox, BFormGroup, BFormInput } from "bootstrap-vue";
import { BAlert, BCard, BCardGroup, BFormGroup, BFormInput } from "bootstrap-vue";
import { computed, onUnmounted, reactive, ref, watch } from "vue";
import { GalaxyApi } from "@/api";
@@ -21,11 +21,13 @@ import { useShortTermStorageMonitor } from "@/composables/shortTermStorageMonito
import { useTaskMonitor } from "@/composables/taskMonitor";
import { errorMessageAsString } from "@/utils/simple-error";
import ExportFormatSelector from "@/components/Common/ExportFormatSelector.vue";
import ExportIncludeOptions from "@/components/Common/ExportIncludeOptions.vue";
import ExportRemoteSourceSelector from "@/components/Common/ExportRemoteSourceSelector.vue";
import RDMCredentialsInfo from "@/components/Common/RDMCredentialsInfo.vue";
import RDMDestinationSelector from "@/components/Common/RDMDestinationSelector.vue";
import GenericWizard from "@/components/Common/Wizard/GenericWizard.vue";
import ExternalLink from "@/components/ExternalLink.vue";
import FilesInput from "@/components/FilesDialog/FilesInput.vue";
import FileSourceNameSpan from "@/components/FileSources/FileSourceNameSpan.vue";
import ExistingInvocationExportProgressCard from "@/components/Workflow/Invocation/Export/ExistingInvocationExportProgressCard.vue";
@@ -323,6 +325,14 @@ function initializeExportData(): InvocationExportData {
};
}
function onFormatSelected(formatId: string) {
// Find the plugin that uses this format
const plugin = exportPlugins.value.find((p) => p.exportParams.modelStoreFormat === formatId);
if (plugin) {
exportData.exportPluginFormat = plugin.id;
}
}
function resetWizard() {
const initialExportData = initializeExportData();
Object.assign(exportData, initialExportData);
@@ -374,27 +384,10 @@ onUnmounted(() => {
:is-busy="isWizardBusy"
@submit="exportInvocation">
<div v-if="wizard.isCurrent('select-format')">
<BCardGroup deck>
<BCard
v-for="plugin in exportPlugins"
:key="plugin.id"
:data-invocation-export-type="plugin.id"
class="wizard-selection-card"
:border-variant="borderVariant(exportData.exportPluginFormat == plugin.id)"
@click="exportData.exportPluginFormat = plugin.id">
<BCardTitle>
<b>{{ plugin.title }}</b>
</BCardTitle>
<div v-if="plugin.img">
<BCardImg :src="plugin.img" :alt="plugin.title" />
<br />
<ExternalLink v-if="plugin.url" :href="plugin.url">
<b>Learn more</b>
</ExternalLink>
</div>
<div v-else v-html="renderMarkdown(plugin.markdownDescription)" />
</BCard>
</BCardGroup>
<ExportFormatSelector
:plugins="exportPlugins"
:model-value="selectedExportPlugin.exportParams.modelStoreFormat"
@update:model-value="onFormatSelected" />
</div>
<div v-if="wizard.isCurrent('select-destination')">
@@ -415,18 +408,11 @@ onUnmounted(() => {
</div>
<div v-if="wizard.isCurrent('setup-remote')">
<BFormGroup
id="fieldset-directory"
label-for="directory"
:description="`Select a 'repository' to export ${resource} to.`"
class="mt-3">
<FilesInput
id="directory"
v-model="exportData.remoteUri"
mode="directory"
:require-writable="true"
:filter-options="{ exclude: ['rdm'] }" />
</BFormGroup>
<ExportRemoteSourceSelector
:directory="exportData.remoteUri"
:resource-name="resource"
:filter-options="{ exclude: ['rdm'] }"
@update:directory="exportData.remoteUri = $event" />
</div>
<div v-if="wizard.isCurrent('setup-rdm')">
@@ -495,15 +481,14 @@ onUnmounted(() => {
required />
</BFormGroup>
<BFormGroup v-if="canIncludeData" label="Dataset files included in the package:">
<BFormCheckbox v-model="exportData.includeFiles" switch> Include Active Files </BFormCheckbox>
<BFormCheckbox v-model="exportData.includeDeleted" switch>
Include Deleted (not purged)
</BFormCheckbox>
<BFormCheckbox v-model="exportData.includeHidden" switch> Include Hidden </BFormCheckbox>
</BFormGroup>
<ExportIncludeOptions
v-if="canIncludeData"
:include-files="exportData.includeFiles"
:include-deleted="exportData.includeDeleted"
:include-hidden="exportData.includeHidden"
@update:include-files="exportData.includeFiles = $event"
@update:include-deleted="exportData.includeDeleted = $event"
@update:include-hidden="exportData.includeHidden = $event" />
<br />
@@ -531,13 +516,3 @@ onUnmounted(() => {
</BAlert>
</div>
</template>
<style scoped lang="scss">
.card-img {
height: auto;
width: auto;
max-height: 100px;
max-width: 100%;
max-inline-size: -webkit-fill-available;
}
</style>
@@ -23,11 +23,11 @@ export function getInvocationExportPluginByType(pluginType: InvocationExportPlug
}
/**
* Defines a UI plugin that can export a workflow invocation to a particular format.
* Generic base interface for export plugins that can be used across different export wizards.
*/
export interface InvocationExportPlugin {
export interface ExportPlugin {
/** The unique identifier for the plugin. */
id: InvocationExportPluginType;
id: string;
/** The title of the plugin. */
title: string;
/** The image URL to display for the plugin. Usually a logo. */
@@ -36,10 +36,18 @@ export interface InvocationExportPlugin {
url?: string;
/** A markdown description of the plugin. */
markdownDescription: string;
/** The parameters to use when exporting the invocation. */
/** The parameters to use when exporting. */
exportParams: ExportParams;
}
/**
* Defines a UI plugin that can export a workflow invocation to a particular format.
*/
export interface InvocationExportPlugin extends ExportPlugin {
/** The unique identifier for the plugin. */
id: InvocationExportPluginType;
}
/**
* Defines an action that can be taken in addition to the main export action.
*/
@@ -1,28 +1,21 @@
<script setup lang="ts">
import { BButton, BCard, BCardGroup, BCardTitle, BFormCheckbox, BFormGroup, BFormInput } from "bootstrap-vue";
import { BButton } from "bootstrap-vue";
import { computed, ref } from "vue";
import type { FilterFileSourcesOptions } from "@/api/remoteFiles";
import type { components } from "@/api/schema";
import type { ModelStoreFormat } from "@/api";
import type { WriteStoreToPayload } from "@/api/exports";
import { useWizard } from "@/components/Common/Wizard/useWizard";
import { borderVariant } from "@/components/Common/Wizard/utils";
import {
AVAILABLE_INVOCATION_EXPORT_PLUGINS,
type InvocationExportPlugin,
} from "@/components/Workflow/Invocation/Export/Plugins";
import { useFileSources } from "@/composables/fileSources";
import { useMarkdown } from "@/composables/markdown";
import localize from "@/utils/localization";
import ExportFormatSelector from "@/components/Common/ExportFormatSelector.vue";
import ExportIncludeOptions from "@/components/Common/ExportIncludeOptions.vue";
import ExportRemoteSourceSelector from "@/components/Common/ExportRemoteSourceSelector.vue";
import GenericWizard from "@/components/Common/Wizard/GenericWizard.vue";
import FilesInput from "@/components/FilesDialog/FilesInput.vue";
import FileSourceNameSpan from "@/components/FileSources/FileSourceNameSpan.vue";
const { renderMarkdown } = useMarkdown({ openLinksInNewPage: true });
export type WriteStoreToPayload = components["schemas"]["WriteStoreToPayload"];
type ModelStoreFormat = components["schemas"]["ModelStoreFormat"];
interface Props {
initialConfig?: Partial<WriteStoreToPayload> & { fileName?: string; directory?: string };
}
@@ -36,9 +29,6 @@ const emit = defineEmits<{
(e: "cancel"): void;
}>();
const defaultExportFilterOptions: FilterFileSourcesOptions = { exclude: ["rdm"] };
const { hasWritable: hasWritableFileSources } = useFileSources(defaultExportFilterOptions);
// Internal state for the wizard UI
const directory = ref(props.initialConfig.directory || "");
const fileName = ref(props.initialConfig.fileName || "galaxy-workflow-export");
@@ -57,9 +47,6 @@ const selectedPlugin = computed(
() => exportPlugins.find((p) => p.exportParams.modelStoreFormat === modelStoreFormat.value) || exportPlugins[0],
);
const directoryDescription = computed(() => localize("Select a 'repository' to export the workflow results to."));
const nameDescription = computed(() => localize("Give the exported file a name."));
const wizard = useWizard({
"select-format": {
label: "Select format",
@@ -98,6 +85,10 @@ function onSubmit() {
function onCancel() {
emit("cancel");
}
function onFormatChange(format: string) {
modelStoreFormat.value = format as ModelStoreFormat;
}
</script>
<template>
@@ -109,69 +100,31 @@ function onCancel() {
container-component="div"
@submit="onSubmit">
<div v-if="wizard.isCurrent('select-format')">
<BCardGroup deck>
<BCard
v-for="plugin in exportPlugins"
:key="plugin.id"
:data-export-format="plugin.exportParams.modelStoreFormat"
class="wizard-selection-card"
:border-variant="borderVariant(modelStoreFormat === plugin.exportParams.modelStoreFormat)"
@click="modelStoreFormat = plugin.exportParams.modelStoreFormat">
<BCardTitle>
<b>{{ plugin.title }}</b>
</BCardTitle>
<div v-html="renderMarkdown(plugin.markdownDescription)" />
</BCard>
</BCardGroup>
<ExportFormatSelector
:model-value="modelStoreFormat"
:plugins="exportPlugins"
@update:model-value="onFormatChange" />
</div>
<div v-if="wizard.isCurrent('select-destination')">
<p v-if="!hasWritableFileSources" class="text-warning">
No writable file sources are configured. Please contact your administrator.
</p>
<template v-else>
<BFormGroup
id="fieldset-directory"
label-for="directory"
:description="directoryDescription"
class="mt-3">
<FilesInput
id="directory"
v-model="directory"
mode="directory"
:require-writable="true"
:filter-options="defaultExportFilterOptions"
data-test-id="export-destination-input" />
</BFormGroup>
<BFormGroup id="fieldset-name" label-for="name" :description="nameDescription" class="mt-3">
<div class="d-flex align-items-center">
<BFormInput
id="name"
v-model="fileName"
placeholder="Name"
required
data-test-id="export-file-name-input" />
<span class="ml-2 text-muted">.{{ modelStoreFormat }}</span>
</div>
</BFormGroup>
</template>
<ExportRemoteSourceSelector
:directory="directory"
:file-name="fileName"
:file-extension="modelStoreFormat"
resource-name="workflow results"
:show-file-name="true"
@update:directory="directory = $event"
@update:file-name="fileName = $event" />
</div>
<div v-if="wizard.isCurrent('configure-options')">
<BFormGroup label="Dataset files included in the export:">
<BFormCheckbox v-model="includeFiles" switch data-test-id="include-files-checkbox">
Include Active Files
</BFormCheckbox>
<BFormCheckbox v-model="includeDeleted" switch data-test-id="include-deleted-checkbox">
Include Deleted (not purged)
</BFormCheckbox>
<BFormCheckbox v-model="includeHidden" switch data-test-id="include-hidden-checkbox">
Include Hidden
</BFormCheckbox>
</BFormGroup>
<ExportIncludeOptions
:include-files="includeFiles"
:include-deleted="includeDeleted"
:include-hidden="includeHidden"
@update:include-files="includeFiles = $event"
@update:include-deleted="includeDeleted = $event"
@update:include-hidden="includeHidden = $event" />
<hr />
@@ -200,15 +153,6 @@ function onCancel() {
</template>
<style scoped lang="scss">
.wizard-selection-card {
cursor: pointer;
transition: border-color 0.15s ease-in-out;
&:hover {
border-color: var(--bs-primary);
}
}
.summary {
background-color: var(--bs-light);
padding: 1rem;
@@ -2,10 +2,11 @@
import { BButton, BFormCheckbox, BFormGroup, BModal } from "bootstrap-vue";
import { computed, reactive, ref, watch } from "vue";
import type { WriteStoreToPayload } from "@/api/exports";
import { useConfig } from "@/composables/config";
import { useFileSources } from "@/composables/fileSources";
import ExportOnCompleteWizard, { type WriteStoreToPayload } from "./ExportOnCompleteWizard.vue";
import ExportOnCompleteWizard from "./ExportOnCompleteWizard.vue";
import FileSourceNameSpan from "@/components/FileSources/FileSourceNameSpan.vue";
import FormCard from "@/components/Form/FormCard.vue";
@@ -14,6 +15,12 @@ interface OnCompleteAction {
export_to_file_source?: WriteStoreToPayload;
}
interface ComponentState {
sendNotification: boolean;
exportEnabled: boolean;
exportConfig: WriteStoreToPayload;
}
interface Props {
value: OnCompleteAction[];
}
@@ -32,16 +39,18 @@ const notificationSystemEnabled = computed(
const showExportWizard = ref(false);
const state = reactive({
const defaultExportConfig: WriteStoreToPayload = {
target_uri: "",
model_store_format: "rocrate.zip",
include_files: true,
include_hidden: false,
include_deleted: false,
};
const state = reactive<ComponentState>({
sendNotification: false,
exportEnabled: false,
exportConfig: {
target_uri: "",
model_store_format: "rocrate.zip",
include_files: true,
include_hidden: false,
include_deleted: false,
} as WriteStoreToPayload,
exportConfig: { ...defaultExportConfig },
});
// Initialize state from value prop (Vue 2 style v-model)
@@ -92,13 +101,7 @@ function openExportWizard() {
function clearExport() {
state.exportEnabled = false;
state.exportConfig = {
target_uri: "",
model_store_format: "rocrate.zip",
include_files: true,
include_hidden: false,
include_deleted: false,
};
state.exportConfig = { ...defaultExportConfig };
}
const exportSummary = computed(() => {
@@ -6,6 +6,7 @@ import { BAlert, BFormInput, BModal, BOverlay } from "bootstrap-vue";
import { storeToRefs } from "pinia";
import { computed, onBeforeMount, ref, watch } from "vue";
import type { WriteStoreToPayload } from "@/api/exports";
import type { WorkflowInvocationRequestInputs } from "@/api/invocations";
import type { ToolIdentifier } from "@/api/tools";
import type { DataOption } from "@/components/Form/Elements/FormData/types";
@@ -27,7 +28,7 @@ import { invokeWorkflow } from "./services";
import WorkflowAnnotation from "../WorkflowAnnotation.vue";
import WorkflowNavigationTitle from "../WorkflowNavigationTitle.vue";
import ExportOnCompleteWizard, { type WriteStoreToPayload } from "./ExportOnCompleteWizard.vue";
import ExportOnCompleteWizard from "./ExportOnCompleteWizard.vue";
import WorkflowHelpDisplay from "./WorkflowHelpDisplay.vue";
import WorkflowRunGraph from "./WorkflowRunGraph.vue";
import WorkflowStorageConfiguration from "./WorkflowStorageConfiguration.vue";