Merge branch 'release_21.09' into dev

This commit is contained in:
mvdbeek
2022-01-22 16:35:43 +01:00
4 changed files with 87 additions and 30 deletions
@@ -73,12 +73,12 @@ describe("Invocations.vue with invocation", () => {
expect(rows.length).toBe(1);
const row = rows[0];
const columns = row.findAll("td");
expect(columns.at(0).text()).toBe("workflow name");
expect(columns.at(1).text()).toBe("history name");
expect(columns.at(2).text()).toBe(moment.utc(invocationData.create_time).fromNow());
expect(columns.at(3).text()).toBe(moment.utc(invocationData.update_time).fromNow());
expect(columns.at(4).text()).toBe("scheduled");
expect(columns.at(5).text()).toBe("");
expect(columns.at(1).text()).toBe("workflow name");
expect(columns.at(2).text()).toBe("history name");
expect(columns.at(3).text()).toBe(moment.utc(invocationData.create_time).fromNow());
expect(columns.at(4).text()).toBe(moment.utc(invocationData.update_time).fromNow());
expect(columns.at(5).text()).toBe("scheduled");
expect(columns.at(6).text()).toBe("");
});
it("toggles detail rendering", async () => {
+61 -23
View File
@@ -20,7 +20,8 @@
striped
caption-top
:busy="loading"
fixed>
fixed
class="invocations-table">
<template v-slot:row-details="row">
<b-card>
<small class="float-right" :data-invocation-id="row.item.id">
@@ -31,25 +32,39 @@
@invocation-cancelled="$emit('reload-invocations')" />
</b-card>
</template>
<template v-slot:cell(workflow_id)="data">
<template v-slot:cell(expand)="data">
<b-link
class="toggle-invocation-details"
v-b-tooltip
title="Show Invocation details"
href="#"
@click.stop="swapRowDetails(data)">
<b>{{ getWorkflowNameByInstanceId(data.item.workflow_id) }}</b>
</b-link>
v-b-tooltip.hover.top
title="Show Invocation Details"
class="btn-sm fa fa-chevron-down toggle-invocation-details"
v-if="!data.detailsShowing"
@click.stop="swapRowDetails(data)" />
<b-link
v-b-tooltip.hover.top
title="Hide Invocation Details"
class="btn-sm fa fa-chevron-up toggle-invocation-details"
v-if="data.detailsShowing"
@click.stop="swapRowDetails(data)" />
</template>
<template v-slot:cell(workflow_id)="data">
<div
v-b-tooltip.hover.top
:title="getWorkflowNameByInstanceId(data.item.workflow_id)"
class="truncate">
<b-link href="#" @click.stop="swapRowDetails(data)">
<b>{{ getWorkflowNameByInstanceId(data.item.workflow_id) }}</b>
</b-link>
</div>
</template>
<template v-slot:cell(history_id)="data">
<b-link
id="switch-to-history"
v-b-tooltip
title="Switch to History"
href="#"
@click.stop="switchHistory(data.item.history_id)">
<b>{{ getHistoryNameById(data.item.history_id) }}</b>
</b-link>
<div
v-b-tooltip.hover.top.html
:title="`<b>Switch to History:</b><br>${getHistoryNameById(data.item.history_id)}`"
class="truncate">
<b-link id="switch-to-history" href="#" @click.stop="switchHistory(data.item.history_id)">
<b>{{ getHistoryNameById(data.item.history_id) }}</b>
</b-link>
</div>
</template>
<template v-slot:cell(create_time)="data">
<UtcDate :date="data.value" mode="elapsed" />
@@ -94,12 +109,13 @@ export default {
},
data() {
const fields = [
{ key: "workflow_id", label: "Workflow" },
{ key: "history_id", label: "History" },
{ key: "create_time", label: "Invoked" },
{ key: "update_time", label: "Updated" },
{ key: "state" },
{ key: "execute", label: "" },
{ key: "expand", label: "", class: "col-button" },
{ key: "workflow_id", label: "Workflow", class: "col-name" },
{ key: "history_id", label: "History", class: "col-history" },
{ key: "create_time", label: "Invoked", class: "col-small" },
{ key: "update_time", label: "Updated", class: "col-small" },
{ key: "state", class: "col-small" },
{ key: "execute", label: "", class: "col-button" },
];
return {
invocationItemsModel: [],
@@ -145,3 +161,25 @@ export default {
},
};
</script>
<style scoped>
.invocations-table {
min-width: 40rem;
}
.table::v-deep .col-name {
width: 40%;
}
.table::v-deep .col-history {
width: 20%;
}
.table::v-deep .col-small {
width: 100px;
}
.table::v-deep .col-button {
width: 50px;
}
.table::v-deep .truncate {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
+14 -1
View File
@@ -2,6 +2,8 @@ import logging
import re
from typing import Dict, List, Optional, Tuple
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import select
from sqlalchemy.sql.expression import func
@@ -245,7 +247,18 @@ class TagHandler:
return self.sa_session.query(galaxy.model.Tag).filter_by(name=tag_name).first()
def _create_tag_instance(self, tag_name):
return galaxy.model.Tag(type=0, name=tag_name)
# For good performance caller should first check if there's already an appropriate tag
Session = sessionmaker(self.sa_session.bind)
tag = galaxy.model.Tag(type=0, name=tag_name)
with Session() as separate_session:
separate_session.add(tag)
try:
separate_session.commit()
separate_session.flush()
except IntegrityError:
# tag already exists, get from database
separate_session.rollback()
return self._get_tag(tag_name)
def _get_or_create_tag(self, tag_str):
"""Get or create a Tag object from a tag string."""
@@ -100,6 +100,12 @@ class TagHandlerTestCase(BaseTestCase):
self.tag_handler.delete_item_tags(user=self.user, item=hda)
self.assertEqual(hda.tags, [])
def test_unique_constraint_applied(self):
tag_name = 'abc'
tag = self.tag_handler._create_tag_instance(tag_name)
same_tag = self.tag_handler._create_tag_instance(tag_name)
assert tag.id == same_tag.id
def test_item_has_tag(self):
hda = self._create_vanilla_hda()
tags = ['tag1']