Merge branch 'release_24.2' into merge_24.2_into_dev

This commit is contained in:
John Chilton
2024-12-05 09:44:25 -05:00
9 changed files with 699 additions and 717 deletions
@@ -260,9 +260,6 @@ function resetModal() {
<BAlert v-else-if="!fromSelection && historyItemsError" variant="danger" show>
{{ historyItemsError }}
</BAlert>
<BAlert v-else-if="!creatorItems?.length" variant="info" show>
{{ localize("No items available to create a collection.") }}
</BAlert>
<BAlert v-else-if="creatingCollection" variant="info" show>
<LoadingSpan :message="localize('Creating collection')" />
</BAlert>
@@ -289,7 +286,7 @@ function resetModal() {
<ListCollectionCreator
v-else-if="props.collectionType === 'list'"
:history-id="props.historyId"
:initial-elements="creatorItems"
:initial-elements="creatorItems || []"
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
@@ -298,7 +295,7 @@ function resetModal() {
<PairedListCollectionCreator
v-else-if="props.collectionType === 'list:paired'"
:history-id="props.historyId"
:initial-elements="creatorItems"
:initial-elements="creatorItems || []"
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
@@ -307,7 +304,7 @@ function resetModal() {
<PairCollectionCreator
v-else-if="props.collectionType === 'paired'"
:history-id="props.historyId"
:initial-elements="creatorItems"
:initial-elements="creatorItems || []"
:default-hide-source-items="props.defaultHideSourceItems"
:from-selection="fromSelection"
:extensions="props.extensions"
@@ -359,287 +359,273 @@ function renameElement(element: any, name: string) {
</BAlert>
</div>
<div v-else>
<div v-if="noInitialElements">
<div v-if="fromSelection && returnInvalidElementsLength">
<BAlert show variant="warning" dismissible>
{{ localize("No datasets were selected") }}
{{ localize("At least one element is needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements.") }}
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ localize("Cancel") }}
</button>
</div>
</div>
<div v-else-if="allElementsAreInvalid">
<BAlert v-if="!fromSelection" show variant="warning">
{{
localize(
"No elements in your history are valid for this list. You may need to switch to a different history."
)
}}
<span v-if="extensions?.length">
{{ localize("The following extensions are required for this list: ") }}
<ul>
<li v-for="extension in extensions" :key="extension">
{{ extension }}
</li>
</ul>
</span>
</BAlert>
<BAlert v-else show variant="warning" dismissible>
{{ localize("The following selections could not be included due to problems:") }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
{{ localize("At least one element is needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements.") }}
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ localize("Cancel") }}
</button>
</div>
</div>
<div v-else>
<div v-if="fromSelection && returnInvalidElementsLength">
<BAlert show variant="warning" dismissible>
{{ localize("The following selections could not be included due to problems:") }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
</BAlert>
</div>
<div v-if="showDuplicateError">
<BAlert show variant="danger">
<div v-if="showDuplicateError">
<BAlert show variant="danger">
{{
localize("Collections cannot have duplicated names. The following list names are duplicated: ")
}}
<ol>
<li v-for="name in duplicateNames" :key="name">{{ name }}</li>
</ol>
{{ localize("Please fix these duplicates and try again.") }}
</BAlert>
</div>
<CollectionCreator
:oncancel="() => emit('on-cancel')"
:history-id="props.historyId"
:hide-source-items="hideSourceItems"
:extensions="extensions"
:no-items="props.initialElements.length == 0 && !props.fromSelection"
@add-uploaded-files="addUploadedFiles"
@on-update-datatype-toggle="changeDatatypeFilter"
@onUpdateHideSourceItems="onUpdateHideSourceItems"
@clicked-create="clickedCreate">
<template v-slot:help-content>
<!-- TODO: Update help content for case where `fromSelection` is false -->
<p>
{{
localize(
"Collections cannot have duplicated names. The following list names are duplicated: "
[
"Collections of datasets are permanent, ordered lists of datasets that can be passed to tools ",
"and workflows in order to have analyses done on each member of the entire group. This interface allows ",
"you to create a collection and re-order the final collection.",
].join("")
)
}}
<ol>
<li v-for="name in duplicateNames" :key="name">{{ name }}</li>
</ol>
{{ localize("Please fix these duplicates and try again.") }}
</BAlert>
</div>
</p>
<CollectionCreator
:oncancel="() => emit('on-cancel')"
:history-id="props.historyId"
:hide-source-items="hideSourceItems"
:extensions="extensions"
@add-uploaded-files="addUploadedFiles"
@on-update-datatype-toggle="changeDatatypeFilter"
@onUpdateHideSourceItems="onUpdateHideSourceItems"
@clicked-create="clickedCreate">
<template v-slot:help-content>
<!-- TODO: Update help content for case where `fromSelection` is false -->
<p>
{{
localize(
[
"Collections of datasets are permanent, ordered lists of datasets that can be passed to tools ",
"and workflows in order to have analyses done on each member of the entire group. This interface allows ",
"you to create a collection and re-order the final collection.",
].join("")
)
}}
</p>
<ul>
<li>
{{ localize("Rename elements in the list by clicking on") }}
<i data-target=".collection-element .name">
{{ localize("the existing name") }}
</i>
{{ localize(".") }}
</li>
<li>
{{ localize("Discard elements from the final created list by clicking on the ") }}
<i data-target=".collection-element .discard">
{{ localize("Discard") }}
</i>
{{ localize("button.") }}
</li>
<li>
{{
localize(
"Reorder the list by clicking and dragging elements. Select multiple elements by clicking on"
)
}}
<i data-target=".collection-element">
{{ localize("them") }}
</i>
{{
localize(
"and you can then move those selected by dragging the entire group. Deselect them by clicking them again or by clicking the"
)
}}
<i data-target=".clear-selected">
{{ localize("Clear selected") }}
</i>
{{ localize("link.") }}
</li>
<li>
{{ localize("Click ") }}
<i data-target=".reset">
<FontAwesomeIcon :icon="faUndo" />
</i>
{{ localize("to begin again as if you had just opened the interface.") }}
</li>
<li>
{{ localize("Click ") }}
<i data-target=".sort-items">
<FontAwesomeIcon :icon="faSortAlphaDown" />
</i>
{{ localize("to sort datasets alphabetically.") }}
</li>
<li>
{{ localize("Click the") }}
<i data-target=".cancel-create">
{{ localize("Cancel") }}
</i>
{{ localize("button to exit the interface.") }}
</li>
</ul>
<br />
<p>
{{ localize("Once your collection is complete, enter a ") }}
<i data-target=".collection-name">
{{ localize("name") }}
</i>
{{ localize("and click") }}
<i data-target=".create-collection">
{{ localize("Create list") }}
<ul>
<li>
{{ localize("Rename elements in the list by clicking on") }}
<i data-target=".collection-element .name">
{{ localize("the existing name") }}
</i>
{{ localize(".") }}
</p>
</template>
</li>
<template v-slot:middle-content>
<div v-if="fromSelection">
<div class="collection-elements-controls">
<div>
<BButton
class="reset"
:title="localize('Reset to original state')"
size="sm"
@click="reset">
<FontAwesomeIcon :icon="faUndo" fixed-width />
{{ localize("Reset") }}
</BButton>
<BButton
class="sort-items"
:title="localize('Sort datasets by name')"
size="sm"
@click="sortByName">
<FontAwesomeIcon :icon="faSortAlphaDown" />
</BButton>
</div>
<li>
{{ localize("Discard elements from the final created list by clicking on the ") }}
<i data-target=".collection-element .discard">
{{ localize("Discard") }}
</i>
{{ localize("button.") }}
</li>
<div class="center-text">
<u>{{ workingElements.length }}</u> {{ localize("elements in list") }}
</div>
<li>
{{
localize(
"Reorder the list by clicking and dragging elements. Select multiple elements by clicking on"
)
}}
<i data-target=".collection-element">
{{ localize("them") }}
</i>
{{
localize(
"and you can then move those selected by dragging the entire group. Deselect them by clicking them again or by clicking the"
)
}}
<i data-target=".clear-selected">
{{ localize("Clear selected") }}
</i>
{{ localize("link.") }}
</li>
<div>
<span v-if="atLeastOneDatasetIsSelected"
>{{ localize("For selection") }} ({{ selectedDatasetElements.length }}):</span
>
<BButtonGroup class="" size="sm">
<BButton
v-if="atLeastOneDatasetIsSelected"
:title="localize('Remove selected datasets from the list')"
@click="clickRemoveSelected">
<FontAwesomeIcon :icon="faMinus" fixed-width />
{{ localize("Remove") }}
</BButton>
<BButton
v-if="
!atLeastOneDatasetIsSelected ||
selectedDatasetElements.length < workingElements.length
"
:title="localize('Select all datasets')"
size="sm"
@click="clickSelectAll">
<FontAwesomeIcon :icon="faSquare" fixed-width />
{{ localize("Select all") }}
</BButton>
<BButton
v-if="atLeastOneDatasetIsSelected"
class="clear-selected"
:title="localize('De-select all selected datasets')"
@click="clickClearAll">
<FontAwesomeIcon :icon="faTimes" fixed-width />
{{ localize("Clear") }}
</BButton>
</BButtonGroup>
</div>
<li>
{{ localize("Click ") }}
<i data-target=".reset">
<FontAwesomeIcon :icon="faUndo" />
</i>
{{ localize("to begin again as if you had just opened the interface.") }}
</li>
<li>
{{ localize("Click ") }}
<i data-target=".sort-items">
<FontAwesomeIcon :icon="faSortAlphaDown" />
</i>
{{ localize("to sort datasets alphabetically.") }}
</li>
<li>
{{ localize("Click the") }}
<i data-target=".cancel-create">
{{ localize("Cancel") }}
</i>
{{ localize("button to exit the interface.") }}
</li>
</ul>
<br />
<p>
{{ localize("Once your collection is complete, enter a ") }}
<i data-target=".collection-name">
{{ localize("name") }}
</i>
{{ localize("and click") }}
<i data-target=".create-collection">
{{ localize("Create list") }}
</i>
{{ localize(".") }}
</p>
</template>
<template v-slot:middle-content>
<div v-if="noInitialElements">
<BAlert show variant="warning" dismissible>
{{ localize("No datasets were selected") }}
{{ localize("At least one element is needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements, or upload datasets.") }}
</BAlert>
</div>
<div v-else-if="allElementsAreInvalid">
<BAlert v-if="!fromSelection" show variant="warning">
{{
localize(
"No elements in your history are valid for this list. \
You may need to switch to a different history or upload valid datasets."
)
}}
<div v-if="extensions?.length">
{{ localize("The following extensions are required for this list: ") }}
<ul>
<li v-for="extension in extensions" :key="extension">
{{ extension }}
</li>
</ul>
</div>
</BAlert>
<BAlert v-else show variant="warning" dismissible>
{{ localize("The following selections could not be included due to problems:") }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
{{ localize("At least one element is needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements, or upload valid datasets.") }}
</BAlert>
</div>
<div v-else-if="fromSelection">
<div class="collection-elements-controls">
<div>
<BButton
class="reset"
:title="localize('Reset to original state')"
size="sm"
@click="reset">
<FontAwesomeIcon :icon="faUndo" fixed-width />
{{ localize("Reset") }}
</BButton>
<BButton
class="sort-items"
:title="localize('Sort datasets by name')"
size="sm"
@click="sortByName">
<FontAwesomeIcon :icon="faSortAlphaDown" />
</BButton>
</div>
<div v-if="noMoreValidDatasets">
<BAlert show variant="warning">
{{ localize("No elements left. Would you like to") }}
<a class="reset-text" href="javascript:void(0)" role="button" @click="reset">
{{ localize("start over") }}
</a>
?
</BAlert>
<div class="center-text">
<u>{{ workingElements.length }}</u> {{ localize("elements in list") }}
</div>
<draggable
v-model="workingElements"
class="collection-elements scroll-container flex-row drop-zone"
chosen-class="bg-secondary">
<DatasetCollectionElementView
v-for="element in workingElements"
:key="element.id"
:class="{ selected: getSelectedDatasetElements.includes(element.id) }"
:element="element"
has-actions
:selected="getSelectedDatasetElements.includes(element.id)"
@element-is-selected="elementSelected"
@element-is-discarded="elementDiscarded"
@onRename="(name) => (element.name = name)" />
</draggable>
<div>
<span v-if="atLeastOneDatasetIsSelected"
>{{ localize("For selection") }} ({{ selectedDatasetElements.length }}):</span
>
<BButtonGroup class="" size="sm">
<BButton
v-if="atLeastOneDatasetIsSelected"
:title="localize('Remove selected datasets from the list')"
@click="clickRemoveSelected">
<FontAwesomeIcon :icon="faMinus" fixed-width />
{{ localize("Remove") }}
</BButton>
<BButton
v-if="
!atLeastOneDatasetIsSelected ||
selectedDatasetElements.length < workingElements.length
"
:title="localize('Select all datasets')"
size="sm"
@click="clickSelectAll">
<FontAwesomeIcon :icon="faSquare" fixed-width />
{{ localize("Select all") }}
</BButton>
<BButton
v-if="atLeastOneDatasetIsSelected"
class="clear-selected"
:title="localize('De-select all selected datasets')"
@click="clickClearAll">
<FontAwesomeIcon :icon="faTimes" fixed-width />
{{ localize("Clear") }}
</BButton>
</BButtonGroup>
</div>
</div>
<FormSelectMany
v-else
v-model="inListElements"
maintain-selection-order
:placeholder="localize('Filter datasets by name')"
:options="workingElements.map((e) => ({ label: e.name || '', value: e }))">
<template v-slot:label-area="{ value }">
<DatasetCollectionElementView
class="w-100"
:element="value"
@onRename="(name) => renameElement(value, name)" />
</template>
</FormSelectMany>
</template>
</CollectionCreator>
</div>
<div v-if="noMoreValidDatasets">
<BAlert show variant="warning">
{{ localize("No elements left. Would you like to") }}
<a class="reset-text" href="javascript:void(0)" role="button" @click="reset">
{{ localize("start over") }}
</a>
?
</BAlert>
</div>
<draggable
v-model="workingElements"
class="collection-elements scroll-container flex-row drop-zone"
chosen-class="bg-secondary">
<DatasetCollectionElementView
v-for="element in workingElements"
:key="element.id"
:class="{ selected: getSelectedDatasetElements.includes(element.id) }"
:element="element"
has-actions
:selected="getSelectedDatasetElements.includes(element.id)"
@element-is-selected="elementSelected"
@element-is-discarded="elementDiscarded"
@onRename="(name) => (element.name = name)" />
</draggable>
</div>
<FormSelectMany
v-else
v-model="inListElements"
maintain-selection-order
:placeholder="localize('Filter datasets by name')"
:options="workingElements.map((e) => ({ label: e.name || '', value: e }))">
<template v-slot:label-area="{ value }">
<DatasetCollectionElementView
class="w-100"
:element="value"
@onRename="(name) => renameElement(value, name)" />
</template>
</FormSelectMany>
</template>
</CollectionCreator>
</div>
</div>
</template>
@@ -345,149 +345,133 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
</BAlert>
</div>
<div v-else>
<div v-if="noElementsSelected">
<div v-if="fromSelection && invalidElements.length">
<BAlert show variant="warning" dismissible>
{{ localize("No datasets were selected.") }}
{{ localize("Exactly two elements needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements.") }}
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ localize("Cancel") }}
</button>
</div>
</div>
<div v-else-if="allElementsAreInvalid">
<BAlert v-if="!fromSelection" show variant="warning">
{{
localize(
"No elements in your history are valid for this pair. You may need to switch to a different history."
)
}}
<span v-if="extensions?.length">
{{ localize("The following extensions are required for this pair: ") }}
<ul>
<li v-for="extension in extensions" :key="extension">
{{ extension }}
</li>
</ul>
</span>
</BAlert>
<BAlert v-else show variant="warning" dismissible>
{{ localize("The following selections could not be included due to problems:") }}
<ul>
<li v-for="problem in invalidElements" :key="problem">
{{ problem }}
</li>
</ul>
{{ localize("Exactly two elements needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements.") }}
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ localize("Cancel") }}
</button>
</div>
</div>
<div v-else>
<div v-if="fromSelection && invalidElements.length">
<BAlert show variant="warning" dismissible>
{{ localize("The following selections could not be included due to problems:") }}
<ul>
<li v-for="problem in invalidElements" :key="problem">
{{ problem }}
</li>
</ul>
</BAlert>
</div>
<div v-if="!exactlyTwoValidElements">
<BAlert show variant="warning" dismissible>
{{ localize("Exactly two elements are needed for the pair.") }}
<span v-if="fromSelection">
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("Cancel") }}
</a>
{{ localize("and reselect new elements.") }}
</span>
</BAlert>
<div v-if="fromSelection" class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
<div v-if="!exactlyTwoValidElements">
<BAlert show variant="warning" dismissible>
{{ localize("Exactly two elements are needed for the pair.") }}
<span v-if="fromSelection">
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("Cancel") }}
</button>
</div>
</div>
</a>
{{ localize("and reselect new elements.") }}
</span>
</BAlert>
</div>
<CollectionCreator
:oncancel="() => emit('on-cancel')"
:history-id="props.historyId"
:hide-source-items="hideSourceItems"
:suggested-name="initialSuggestedName"
:extensions="props.extensions"
:extensions-toggle="removeExtensions"
@add-uploaded-files="addUploadedFiles"
@onUpdateHideSourceItems="onUpdateHideSourceItems"
@clicked-create="clickedCreate"
@remove-extensions-toggle="removeExtensionsToggle">
<template v-slot:help-content>
<!-- TODO: Update help content for case where `fromSelection` is false -->
<p>
<CollectionCreator
:oncancel="() => emit('on-cancel')"
:history-id="props.historyId"
:hide-source-items="hideSourceItems"
:suggested-name="initialSuggestedName"
:extensions="props.extensions"
:extensions-toggle="removeExtensions"
:no-items="props.initialElements.length == 0 && !props.fromSelection"
@add-uploaded-files="addUploadedFiles"
@onUpdateHideSourceItems="onUpdateHideSourceItems"
@clicked-create="clickedCreate"
@remove-extensions-toggle="removeExtensionsToggle">
<template v-slot:help-content>
<!-- TODO: Update help content for case where `fromSelection` is false -->
<p>
{{
localize(
[
"Pair collections are permanent collections containing two datasets: one forward and one reverse. ",
"Often these are forward and reverse reads. The pair collections can be passed to tools and workflows in ",
"order to have analyses done on both datasets. This interface allows you to create a pair, name it, and ",
"swap which is forward and which reverse.",
].join("")
)
}}
</p>
<ul>
<li>
{{ localize("Click the ") }}
<i data-target=".swap">
{{ localize("Swap") }}
</i>
{{
localize(
[
"Pair collections are permanent collections containing two datasets: one forward and one reverse. ",
"Often these are forward and reverse reads. The pair collections can be passed to tools and workflows in ",
"order to have analyses done on both datasets. This interface allows you to create a pair, name it, and ",
"swap which is forward and which reverse.",
].join("")
"link to make your forward dataset the reverse and the reverse dataset forward"
)
}}
</p>
</li>
<ul>
<li>
{{ localize("Click the ") }}
<i data-target=".swap">
{{ localize("Swap") }}
</i>
{{
localize(
"link to make your forward dataset the reverse and the reverse dataset forward"
)
}}
</li>
<li>
{{ localize("Click the ") }}
<i data-target=".cancel-create">
{{ localize("Cancel") }}
</i>
{{ localize("button to exit the interface.") }}
</li>
</ul>
<br />
<p>
{{ localize("Once your collection is complete, enter a ") }}
<i data-target=".collection-name"> {{ localize("name") }}</i>
{{ localize("and click ") }}
<i data-target=".create-collection">
{{ localize("Create list") }}
<li>
{{ localize("Click the ") }}
<i data-target=".cancel-create">
{{ localize("Cancel") }}
</i>
{{ localize(".") }}
</p>
</template>
{{ localize("button to exit the interface.") }}
</li>
</ul>
<template v-slot:middle-content>
<br />
<p>
{{ localize("Once your collection is complete, enter a ") }}
<i data-target=".collection-name"> {{ localize("name") }}</i>
{{ localize("and click ") }}
<i data-target=".create-collection">
{{ localize("Create list") }}
</i>
{{ localize(".") }}
</p>
</template>
<template v-slot:middle-content>
<div v-if="noElementsSelected">
<BAlert show variant="warning" dismissible>
{{ localize("No datasets were selected.") }}
{{ localize("Exactly two elements needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements, or upload datasets.") }}
</BAlert>
</div>
<div v-else-if="allElementsAreInvalid">
<BAlert v-if="!fromSelection" show variant="warning">
{{
localize(
"No elements in your history are valid for this pair. \
You may need to switch to a different history or upload valid datasets."
)
}}
<div v-if="extensions?.length">
{{ localize("The following extensions are required for this pair: ") }}
<ul>
<li v-for="extension in extensions" :key="extension">
{{ extension }}
</li>
</ul>
</div>
</BAlert>
<BAlert v-else show variant="warning" dismissible>
{{ localize("The following selections could not be included due to problems:") }}
<ul>
<li v-for="problem in invalidElements" :key="problem">
{{ problem }}
</li>
</ul>
{{ localize("Exactly two elements needed for the collection. You may need to") }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ localize("cancel") }}
</a>
{{ localize("and reselect new elements, or upload datasets.") }}
</BAlert>
</div>
<div v-else>
<div class="collection-elements-controls">
<BButton
class="swap"
@@ -531,9 +515,9 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
@onRename="(name) => (element.name = name)" />
</div>
</div>
</template>
</CollectionCreator>
</div>
</div>
</template>
</CollectionCreator>
</div>
</div>
</template>
@@ -64,7 +64,7 @@ const emit = defineEmits<{
const noElementsHeader = props.fromSelection ? localize("No elements selected") : localize("No elements available");
const allInvalidElementsPartTwo = props.fromSelection
? localize("and reselect new elements.")
: localize("and change your current history or add valid datasets for this collection.");
: localize("and change your current history or upload valid datasets for this collection.");
// Flags
const state = ref<"build" | "error" | "duplicates">("build");
@@ -817,261 +817,245 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
</BAlert>
</div>
<div v-else>
<div v-if="noElementsSelected">
<div v-if="fromSelection && returnInvalidElementsLength">
<BAlert show variant="warning" dismissible>
{{ noElementsHeader }}
{{ ALL_INVALID_ELEMENTS_PART_ONE }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</button>
</div>
</div>
<div v-else-if="allElementsAreInvalid">
<BAlert v-if="!fromSelection" show variant="warning">
{{
localize(
"No elements in your history are valid for this collection. You may need to switch to a different history."
)
}}
<span v-if="extensions?.length">
{{ localize("The following extensions are required for this collection: ") }}
<ul>
<li v-for="extension in extensions" :key="extension">
{{ extension }}
</li>
</ul>
</span>
</BAlert>
<BAlert v-else show variant="warning" dismissible>
{{ INVALID_HEADER }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
{{ ALL_INVALID_ELEMENTS_PART_ONE }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</button>
</div>
</div>
<div v-else-if="tooFewElementsSelected">
<div v-if="returnInvalidElementsLength">
<BAlert show variant="warning" dismissible>
{{ INVALID_HEADER }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
</BAlert>
</div>
<BAlert show variant="warning" dismissible>
{{ ALL_INVALID_ELEMENTS_PART_ONE }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
<div v-if="!autoPairsPossible">
<BAlert show variant="danger" dismissible @dismissed="autoPairsPossible = true">
{{
localize(
"Could not automatically create any pairs from the given dataset names. You may want to choose or enter different filters and try auto-pairing again."
)
}}
<span v-if="fromSelection">
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
</span>
</BAlert>
<div class="float-left">
<button class="cancel-create btn" tabindex="-1" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</button>
</div>
</div>
<div v-else>
<div v-if="fromSelection && returnInvalidElementsLength">
<BAlert show variant="warning" dismissible>
{{ INVALID_HEADER }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
</BAlert>
</div>
<div v-if="!autoPairsPossible">
<BAlert show variant="danger" dismissible @dismissed="autoPairsPossible = true">
<div v-if="state == 'duplicates'">
<BAlert show variant="danger">
{{
localize("Collections cannot have duplicated names. The following list names are duplicated: ")
}}
<ul>
<li v-for="name in duplicatePairNames" :key="name">{{ name }}</li>
</ul>
{{ localize("Please fix these duplicates and try again.") }}
</BAlert>
</div>
<CollectionCreator
:oncancel="() => emit('on-cancel')"
:history-id="props.historyId"
:hide-source-items="hideSourceItems"
render-extensions-toggle
:extensions-toggle="removeExtensions"
:extensions="extensions"
:no-items="props.initialElements.length == 0 && !props.fromSelection"
@add-uploaded-files="addUploadedFiles"
@onUpdateHideSourceItems="hideSourceItems = $event"
@clicked-create="clickedCreate"
@remove-extensions-toggle="removeExtensionsToggle">
<template v-slot:help-content>
<!-- TODO: Update help content for case where `fromSelection` is false -->
<p>
{{
localize(
"Could not automatically create any pairs from the given dataset names. You may want to choose or enter different filters and try auto-pairing again."
[
"Collections of paired datasets are ordered lists of dataset pairs (often forward and reverse reads). ",
"These collections can be passed to tools and workflows in order to have analyses done on each member of ",
"the entire group. This interface allows you to create a collection, choose which datasets are paired, ",
"and re-order the final collection.",
].join("")
)
}}
<span v-if="fromSelection">
</p>
<p>
{{ localize("Unpaired datasets are shown in the") }}
<i data-target=".unpaired-columns">
{{ localize("unpaired section") }}
</i>
{{ "." }}
{{ localize("Paired datasets are shown in the") }}
<i data-target=".paired-columns">
{{ localize("paired section") }}
</i>
{{ "." }}
</p>
<ul>
{{
localize("To pair datasets, you can:")
}}
<li>
{{ localize("Click a dataset in the") }}
<i data-target=".forward-column">
{{ localize("forward column") }}
</i>
{{ localize("to select it then click a dataset in the") }}
<i data-target=".reverse-column">
{{ localize("reverse column") }}
</i>
</li>
<li>
{{
localize(
"Click one of the Pair these datasets buttons in the middle column to pair the datasets in a particular row."
)
}}
</li>
<li>
{{ localize("Click") }}
<i data-target=".autopair-link">
{{ localize("Auto-pair") }}
</i>
{{ localize("to have your datasets automatically paired based on name.") }}
</li>
</ul>
<ul>
{{
localize("You can filter what is shown in the unpaired sections by:")
}}
<li>
{{ localize("Entering partial dataset names in either the ") }}
<i data-target=".forward-unpaired-filter input">
{{ localize("forward filter") }}
</i>
{{ localize("or ") }}
<i data-target=".reverse-unpaired-filter input">
{{ localize("reverse filter") }}
</i>
{{ "." }}
</li>
<li>
{{
localize(
"Choosing from a list of preset filters by clicking the arrow beside the filter input."
)
}}
</li>
<li>
{{ localize("Entering regular expressions to match dataset names. See:") }}
<a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
target="_blank">
{{ localize("MDN's JavaScript Regular Expression Tutorial") }}</a
>
{{ localize("Note: forward slashes (\\) are not needed.") }}
</li>
<li>
{{ localize("Clearing the filters by clicking the ") }}
<i data-target=".clear-filters-link">
{{ localize("Clear filters link") }}
</i>
{{ "." }}
</li>
</ul>
<p>
{{ localize("To unpair individual dataset pairs, click the ") }}
<i data-target=".unpair-btn">
{{ localize("unpair buttons (") }}
<span class="fa fa-unlink"></span>
{{ ")" }}
</i>
{{ localize("Click the") }}
<i data-target=".unpair-all-link">
{{ localize("Unpair all") }}
</i>
{{ localize("link to unpair all pairs.") }}
</p>
<p>
{{
localize(
'You can include or remove the file extensions (e.g. ".fastq") from your pair names by toggling the'
)
}}
<i data-target=".remove-extensions-prompt">
{{ localize("Remove file extensions from pair names?") }}
</i>
{{ localize("control.") }}
</p>
<p>
{{ localize("Once your collection is complete, enter a") }}
<i data-target=".collection-name">
{{ localize("name") }}
</i>
{{ localize("and click ") }}
<i data-target=".create-collection">
{{ localize("Create list") }}
</i>
{{ localize(". (Note: you do not have to pair all unpaired datasets to finish.)") }}
</p>
</template>
<template v-slot:middle-content>
<div v-if="noElementsSelected">
<BAlert show variant="warning" dismissible>
{{ noElementsHeader }}
{{ ALL_INVALID_ELEMENTS_PART_ONE }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
</span>
</BAlert>
</div>
<div v-if="state == 'duplicates'">
<BAlert show variant="danger">
{{
localize(
"Collections cannot have duplicated names. The following list names are duplicated: "
)
}}
<ul>
<li v-for="name in duplicatePairNames" :key="name">{{ name }}</li>
</ul>
{{ localize("Please fix these duplicates and try again.") }}
</BAlert>
</div>
<CollectionCreator
:oncancel="() => emit('on-cancel')"
:history-id="props.historyId"
:hide-source-items="hideSourceItems"
render-extensions-toggle
:extensions-toggle="removeExtensions"
:extensions="extensions"
@add-uploaded-files="addUploadedFiles"
@onUpdateHideSourceItems="hideSourceItems = $event"
@clicked-create="clickedCreate"
@remove-extensions-toggle="removeExtensionsToggle">
<template v-slot:help-content>
<!-- TODO: Update help content for case where `fromSelection` is false -->
<p>
</BAlert>
</div>
<div v-else-if="allElementsAreInvalid">
<BAlert v-if="!fromSelection" show variant="warning">
{{
localize(
[
"Collections of paired datasets are ordered lists of dataset pairs (often forward and reverse reads). ",
"These collections can be passed to tools and workflows in order to have analyses done on each member of ",
"the entire group. This interface allows you to create a collection, choose which datasets are paired, ",
"and re-order the final collection.",
].join("")
"No elements in your history are valid for this collection. You may need to switch to a different history."
)
}}
</p>
<p>
{{ localize("Unpaired datasets are shown in the") }}
<i data-target=".unpaired-columns">
{{ localize("unpaired section") }}
</i>
{{ "." }}
{{ localize("Paired datasets are shown in the") }}
<i data-target=".paired-columns">
{{ localize("paired section") }}
</i>
{{ "." }}
</p>
<ul>
{{
localize("To pair datasets, you can:")
}}
<li>
{{ localize("Click a dataset in the") }}
<i data-target=".forward-column">
{{ localize("forward column") }}
</i>
{{ localize("to select it then click a dataset in the") }}
<i data-target=".reverse-column">
{{ localize("reverse column") }}
</i>
</li>
<li>
{{
localize(
"Click one of the Pair these datasets buttons in the middle column to pair the datasets in a particular row."
)
}}
</li>
<li>
{{ localize("Click") }}
<i data-target=".autopair-link">
{{ localize("Auto-pair") }}
</i>
{{ localize("to have your datasets automatically paired based on name.") }}
</li>
</ul>
<ul>
{{
localize("You can filter what is shown in the unpaired sections by:")
}}
<li>
{{ localize("Entering partial dataset names in either the ") }}
<i data-target=".forward-unpaired-filter input">
{{ localize("forward filter") }}
</i>
{{ localize("or ") }}
<i data-target=".reverse-unpaired-filter input">
{{ localize("reverse filter") }}
</i>
{{ "." }}
</li>
<li>
{{
localize(
"Choosing from a list of preset filters by clicking the arrow beside the filter input."
)
}}
</li>
<li>
{{ localize("Entering regular expressions to match dataset names. See:") }}
<a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
target="_blank">
{{ localize("MDN's JavaScript Regular Expression Tutorial") }}</a
>
{{ localize("Note: forward slashes (\\) are not needed.") }}
</li>
<li>
{{ localize("Clearing the filters by clicking the ") }}
<i data-target=".clear-filters-link">
{{ localize("Clear filters link") }}
</i>
{{ "." }}
</li>
</ul>
<p>
{{ localize("To unpair individual dataset pairs, click the ") }}
<i data-target=".unpair-btn">
{{ localize("unpair buttons (") }}
<span class="fa fa-unlink"></span>
{{ ")" }}
</i>
{{ localize("Click the") }}
<i data-target=".unpair-all-link">
{{ localize("Unpair all") }}
</i>
{{ localize("link to unpair all pairs.") }}
</p>
<p>
{{
localize(
'You can include or remove the file extensions (e.g. ".fastq") from your pair names by toggling the'
)
}}
<i data-target=".remove-extensions-prompt">
{{ localize("Remove file extensions from pair names?") }}
</i>
{{ localize("control.") }}
</p>
<p>
{{ localize("Once your collection is complete, enter a") }}
<i data-target=".collection-name">
{{ localize("name") }}
</i>
{{ localize("and click ") }}
<i data-target=".create-collection">
{{ localize("Create list") }}
</i>
{{ localize(". (Note: you do not have to pair all unpaired datasets to finish.)") }}
</p>
</template>
<template v-slot:middle-content>
<span v-if="extensions?.length">
{{ localize("The following extensions are required for this collection: ") }}
<ul>
<li v-for="extension in extensions" :key="extension">
{{ extension }}
</li>
</ul>
</span>
</BAlert>
<BAlert v-else show variant="warning" dismissible>
{{ INVALID_HEADER }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
{{ ALL_INVALID_ELEMENTS_PART_ONE }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
</BAlert>
</div>
<div v-else-if="tooFewElementsSelected">
<div v-if="returnInvalidElementsLength">
<BAlert show variant="warning" dismissible>
{{ INVALID_HEADER }}
<ul>
<li v-for="problem in returnInvalidElements" :key="problem">
{{ problem }}
</li>
</ul>
</BAlert>
</div>
<BAlert show variant="warning" dismissible>
{{ ALL_INVALID_ELEMENTS_PART_ONE }}
<a class="cancel-text" href="javascript:void(0)" role="button" @click="emit('on-cancel')">
{{ CANCEL_TEXT }}
</a>
{{ allInvalidElementsPartTwo }}
</BAlert>
</div>
<div v-else>
<BCard no-body class="mb-2">
<BCardHeader
class="d-flex justify-content-between align-items-center unselectable"
@@ -1308,9 +1292,9 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
</div>
</div>
</div>
</template>
</CollectionCreator>
</div>
</div>
</template>
</CollectionCreator>
</div>
</div>
</template>
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { faChevronDown, faChevronUp, faPlus, faUpload } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BAlert, BButton, BFormCheckbox, BFormGroup, BFormInput, BTab, BTabs } from "bootstrap-vue";
import { BAlert, BButton, BFormCheckbox, BFormGroup, BFormInput, BLink, BTab, BTabs } from "bootstrap-vue";
import { storeToRefs } from "pinia";
import { computed, ref, watch } from "vue";
@@ -38,6 +38,7 @@ interface Props {
renderExtensionsToggle?: boolean;
extensions?: string[];
extensionsToggle?: boolean;
noItems?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
@@ -134,103 +135,114 @@ watch(
<template>
<BTabs v-model="currentTab" fill justified>
<BTab class="collection-creator" :title="localize('Create Collection')">
<div class="header flex-row no-flex">
<div class="main-help well clear" :class="{ expanded: isExpanded }">
<a
class="more-help"
href="javascript:void(0);"
role="button"
:title="localize('Expand or Close Help')"
@click="clickForHelp">
<div v-if="!isExpanded">
<FontAwesomeIcon :icon="faChevronDown" />
<span class="sr-only">{{ localize("Expand Help") }}</span>
</div>
<div v-else>
<FontAwesomeIcon :icon="faChevronUp" />
<span class="sr-only">{{ localize("Close Help") }}</span>
</div>
</a>
<div class="help-content">
<!-- each collection that extends this will add their own help content -->
<slot name="help-content"></slot>
<div v-if="props.noItems">
<BAlert variant="info" show>
{{ localize("No items available to create a collection.") }}
{{ localize("Exit and change your current history, or") }}
<BLink class="text-decoration-none" @click.stop.prevent="currentTab = Tabs.upload">
{{ localize("Upload some datasets.") }}
</BLink>
</BAlert>
</div>
<div v-else>
<div class="header flex-row no-flex">
<div class="main-help well clear" :class="{ expanded: isExpanded }">
<a
class="more-help"
href="javascript:void(0);"
role="button"
:title="localize('Expand or Close Help')"
@click="clickForHelp">
<span class="sr-only">{{ localize("Expand Help") }}</span>
</a>
</div>
</div>
</div>
<div class="middle flex-row flex-row-container">
<slot name="middle-content"></slot>
</div>
<div class="footer flex-row">
<div class="vertically-spaced">
<div class="d-flex align-items-center justify-content-between">
<BAlert v-if="extensions?.length" class="w-100 py-0" variant="secondary" show>
<HelpText
uri="galaxy.collections.collectionBuilder.filteredExtensions"
:text="localize('Filtered extensions: ')" />
<strong>{{ orList(extensions) }}</strong>
</BAlert>
</div>
<div class="d-flex align-items-center justify-content-between">
<BFormGroup class="inputs-form-group">
<BFormCheckbox
v-if="renderExtensionsToggle"
name="remove-extensions"
switch
:checked="extensionsToggle"
@input="emit('remove-extensions-toggle')">
{{ localize("Remove file extensions?") }}
</BFormCheckbox>
<div data-description="hide original elements">
<BFormCheckbox v-model="localHideSourceItems" name="hide-originals" switch>
<HelpText
uri="galaxy.collections.collectionBuilder.hideOriginalElements"
:text="localize('Hide original elements')" />
</BFormCheckbox>
<div v-if="!isExpanded">
<FontAwesomeIcon :icon="faChevronDown" />
<span class="sr-only">{{ localize("Expand Help") }}</span>
</div>
</BFormGroup>
<div v-else>
<FontAwesomeIcon :icon="faChevronUp" />
<span class="sr-only">{{ localize("Close Help") }}</span>
</div>
</a>
<BFormGroup
class="flex-gapx-1 d-flex align-items-center w-50 inputs-form-group"
:label="localize('Name:')"
label-for="collection-name">
<BFormInput
id="collection-name"
v-model="collectionName"
class="collection-name"
:placeholder="localize('Enter a name for your new collection')"
size="sm"
required
:state="!collectionName ? false : null" />
</BFormGroup>
<div class="help-content">
<!-- each collection that extends this will add their own help content -->
<slot name="help-content"></slot>
<a
class="more-help"
href="javascript:void(0);"
role="button"
:title="localize('Expand or Close Help')"
@click="clickForHelp">
<span class="sr-only">{{ localize("Expand Help") }}</span>
</a>
</div>
</div>
</div>
<div class="actions vertically-spaced d-flex justify-content-between">
<BButton tabindex="-1" @click="cancelCreate">
{{ localize("Cancel") }}
</BButton>
<div class="middle flex-row flex-row-container">
<slot name="middle-content"></slot>
</div>
<BButton
class="create-collection"
variant="primary"
:disabled="!validInput"
@click="emit('clicked-create', collectionName)">
{{ localize("Create collection") }}
</BButton>
<div class="footer flex-row">
<div class="vertically-spaced">
<div class="d-flex align-items-center justify-content-between">
<BAlert v-if="extensions?.length" class="w-100 py-0" variant="secondary" show>
<HelpText
uri="galaxy.collections.collectionBuilder.filteredExtensions"
:text="localize('Filtered extensions: ')" />
<strong>{{ orList(extensions) }}</strong>
</BAlert>
</div>
<div class="d-flex align-items-center justify-content-between">
<BFormGroup class="inputs-form-group">
<BFormCheckbox
v-if="renderExtensionsToggle"
name="remove-extensions"
switch
:checked="extensionsToggle"
@input="emit('remove-extensions-toggle')">
{{ localize("Remove file extensions?") }}
</BFormCheckbox>
<div data-description="hide original elements">
<BFormCheckbox v-model="localHideSourceItems" name="hide-originals" switch>
<HelpText
uri="galaxy.collections.collectionBuilder.hideOriginalElements"
:text="localize('Hide original elements')" />
</BFormCheckbox>
</div>
</BFormGroup>
<BFormGroup
class="flex-gapx-1 d-flex align-items-center w-50 inputs-form-group"
:label="localize('Name:')"
label-for="collection-name">
<BFormInput
id="collection-name"
v-model="collectionName"
class="collection-name"
:placeholder="localize('Enter a name for your new collection')"
size="sm"
required
:state="!collectionName ? false : null" />
</BFormGroup>
</div>
</div>
<div class="actions vertically-spaced d-flex justify-content-between">
<BButton tabindex="-1" @click="cancelCreate">
{{ localize("Cancel") }}
</BButton>
<BButton
class="create-collection"
variant="primary"
:disabled="!validInput"
@click="emit('clicked-create', collectionName)">
{{ localize("Create collection") }}
</BButton>
</div>
</div>
</div>
</BTab>
@@ -90,6 +90,14 @@ const dragTarget: Ref<EventTarget | null> = ref(null);
const collectionModalShow = ref(false);
const collectionModalType = ref<"list" | "list:paired" | "paired">("list");
const { currentHistoryId } = storeToRefs(useHistoryStore());
const restrictsExtensions = computed(() => {
const extensions = props.extensions;
if (!extensions || extensions.length == 0 || extensions.indexOf("data") >= 0) {
return false;
} else {
return true;
}
});
/** Store options which need to be preserved **/
const keepOptions: Record<string, SelectOption> = {};
@@ -649,7 +657,7 @@ const noOptionsWarningMessage = computed(() => {
</BButton>
</BButtonGroup>
</BButtonGroup>
<div v-if="extensions && extensions.length > 0">
<div v-if="restrictsExtensions">
<BButton :id="formatsButtonId" class="ui-link" @click="formatsVisible = !formatsVisible">
accepted formats
<FontAwesomeIcon v-if="formatsVisible" :icon="faCaretUp" />
@@ -77,7 +77,14 @@ async function submitOIDCLogin(idp: string) {
loading.value = true;
try {
const { data } = await axios.post(withPrefix(`/authnz/${idp}/login`));
const loginUrl = withPrefix(`/authnz/${idp}/login`);
const urlParams = new URLSearchParams(window.location.search);
const redirectParam = urlParams.get("redirect");
const formData = new FormData();
formData.append("next", redirectParam || "");
const { data } = await axios.post(loginUrl, formData, { withCredentials: true });
if (data.redirect_uri) {
window.location = data.redirect_uri;
+1 -1
View File
@@ -1209,7 +1209,7 @@ class NavigatesGalaxy(HasDriver):
# Make sure we're on the workflow editor and not clicking the main tool panel.
editor.canvas_body.wait_for_visible()
editor.tool_menu.wait_for_visible()
self.open_toolbox()
editor.tool_menu_section_link(section_name="inputs").wait_for_and_click()
editor.tool_menu_item_link(item_name=item_name).wait_for_and_click()
@@ -19,6 +19,7 @@ from galaxy.webapps.base.controller import JSAppLauncher
log = logging.getLogger(__name__)
PROVIDER_COOKIE_NAME = "galaxy-oidc-provider"
LOGIN_NEXT_COOKIE_NAME = "galaxy-oidc-login-next"
class OIDC(JSAppLauncher):
@@ -72,12 +73,14 @@ class OIDC(JSAppLauncher):
@web.json
@web.expose
def login(self, trans, provider, idphint=None):
def login(self, trans, provider, idphint=None, next=None):
if not trans.app.config.enable_oidc:
msg = "Login to Galaxy using third-party identities is not enabled on this Galaxy instance."
log.debug(msg)
return trans.show_error_message(msg)
success, message, redirect_uri = trans.app.authnz_manager.authenticate(provider, trans, idphint=idphint)
if next:
trans.set_cookie(value=next, name=LOGIN_NEXT_COOKIE_NAME)
success, message, redirect_uri = trans.app.authnz_manager.authenticate(provider, trans, idphint)
if success:
return {"redirect_uri": redirect_uri}
else:
@@ -86,6 +89,7 @@ class OIDC(JSAppLauncher):
@web.expose
def callback(self, trans, provider, idphint=None, **kwargs):
user = trans.user.username if trans.user is not None else "anonymous"
login_next = url_for(trans.get_cookie(name=LOGIN_NEXT_COOKIE_NAME) or "/")
if not bool(kwargs):
log.error(f"OIDC callback received no data for provider `{provider}` and user `{user}`")
return trans.show_error_message(
@@ -110,7 +114,7 @@ class OIDC(JSAppLauncher):
kwargs.get("state", " "),
kwargs["code"],
trans,
login_redirect_url=url_for("/"),
login_redirect_url=login_next,
idphint=idphint,
)
except exceptions.AuthenticationFailed: