Skip to content

Commit

Permalink
Merge branch 'rc/1.0.3' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
jrtcppv committed May 23, 2023
2 parents 2d547b9 + 70e3d5d commit fc10a25
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 245 deletions.
4 changes: 4 additions & 0 deletions api/main/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1794,6 +1794,7 @@ class Meta:
# e.g. Not relaying solely on `db_index=True` in django.
BUILT_IN_INDICES = {
MediaType: [
{'name': '$id', 'dtype': 'native'},
{'name': '$name', 'dtype': 'native_string'},
{'name': '$created_datetime', 'dtype': 'native'},
{'name': '$modified_datetime', 'dtype': 'native'},
Expand All @@ -1803,14 +1804,17 @@ class Meta:
{'name': '$archive_state', 'dtype': 'native_string'}
],
LocalizationType: [
{'name': '$id', 'dtype': 'native'},
{'name': '$created_datetime', 'dtype': 'native'},
{'name': '$modified_datetime', 'dtype': 'native'}
],
StateType: [
{'name': '$id', 'dtype': 'native'},
{'name': '$created_datetime', 'dtype': 'native'},
{'name': '$modified_datetime', 'dtype': 'native'},
],
LeafType: [
{'name': '$id', 'dtype': 'native'},
{'name': '$name', 'dtype': 'string'},
{'name': '$path', 'dtype': 'string'},
{'name': '$name', 'dtype': 'upper_string'},
Expand Down
4 changes: 4 additions & 0 deletions api/main/rest/_media_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def _get_media_psql_queryset(project, filter_ops, params):
gid = params.get('gid')
uid = params.get('uid')
after = params.get('after')
after_name = params.get('after_name')
start = params.get('start')
stop = params.get('stop')
section_id = params.get('section')
Expand Down Expand Up @@ -106,6 +107,9 @@ def _get_media_psql_queryset(project, filter_ops, params):
if after is not None:
qs = qs.filter(pk__gt=after)

if after_name is not None:
qs = qs.filter(name__gt=after_name)

if archive_states is not None:
qs = qs.filter(archive_state__in=archive_states)

Expand Down
9 changes: 9 additions & 0 deletions api/main/schema/_media_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@
'parameters are relative to this modified range.',
'schema': {'type': 'integer'},
},
{
'name': 'after_name',
'in': 'query',
'required': False,
'description': 'If given, all results returned will be after the '
'media with this name. The `start` and `stop` '
'parameters are relative to this modified range.',
'schema': {'type': 'string'},
},
{
"name": "archive_lifecycle",
"in": "query",
Expand Down
5 changes: 4 additions & 1 deletion api/main/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ def _get_unique_index_name(entity_type, attribute):
entity_name_sanitized=re.sub(r"[^a-zA-Z0-9]","_",entity_type.name).lower()
attribute_name_sanitized=re.sub(r"[^a-zA-Z0-9]","_",attribute['name']).lower()
if attribute['name'].startswith('$'):
index_name=f"tator_proj_{entity_type.project.id}_{type_name_sanitized}_internal_{attribute_name_sanitized}"
if attribute['dtype'] == 'native':
index_name=f"tator_proj_{entity_type.project.id}_internal_{attribute_name_sanitized}"
else:
index_name=f"tator_proj_{entity_type.project.id}_{type_name_sanitized}_internal_{attribute_name_sanitized}"
else:
index_name=f"tator_proj_{entity_type.project.id}_{type_name_sanitized}_{entity_name_sanitized}_{attribute_name_sanitized}"
return index_name
Expand Down
2 changes: 1 addition & 1 deletion ui/src/js/annotation/annotation-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ export class AnnotationPage extends TatorPage {

});
const countUrl = `/rest/MediaCount/${data.project}?${searchParams.toString()}`;
searchParams.set("after", data.id);
searchParams.set("after_name", data.name);
const afterUrl = `/rest/MediaCount/${data.project}?${searchParams.toString()}`;
const countPromise = fetchRetry(countUrl, {
method: "GET",
Expand Down
62 changes: 0 additions & 62 deletions ui/src/js/components/filter-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ export class FilterInterface extends TatorElement {
const filterButton = document.createElement("filter-data-button");
this._filterNavDiv.appendChild(filterButton);

this._algoButton = document.createElement("algorithm-button");
this._filterNavDiv.appendChild(this._algoButton);

/**
* Filter condition interface
*/
Expand Down Expand Up @@ -61,8 +58,6 @@ export class FilterInterface extends TatorElement {
cancel.textContent = "Cancel";
footerDiv.appendChild(cancel);



/**
* Filter condition pill boxes
*/
Expand All @@ -81,9 +76,6 @@ export class FilterInterface extends TatorElement {
this._moreNavDiv.setAttribute("class", "analysis__more_nav px-1");
this._topNav.appendChild(this._moreNavDiv);

this._confirmRunAlgorithm = document.createElement("confirm-run-algorithm");
this._shadow.appendChild(this._confirmRunAlgorithm);

this._modalNotify = document.createElement("modal-notify");
this._shadow.appendChild(this._modalNotify);

Expand Down Expand Up @@ -111,10 +103,6 @@ export class FilterInterface extends TatorElement {
this._filterStringDiv.style.display = "flex";
this._moreNavDiv.style.display = "block";
});

// Respond to user requesting to run an algorithm
this._algoButton.addEventListener("runAlgorithm", this._openConfirmRunAlgoModal.bind(this));
this._confirmRunAlgorithm.addEventListener("close", this._closeConfirmRunAlgoModal.bind(this));
}

_notify(title, message, error_or_ok) {
Expand All @@ -123,51 +111,6 @@ export class FilterInterface extends TatorElement {
this.setAttribute("has-open-modal", "");
}

/**
* Callback when user clicks on an algorithm button.
* This launches the confirm run algorithm modal window.
*/
_openConfirmRunAlgoModal(evt) {

var extraParameters = [
{
name: "encoded_filters",
value: encodeURIComponent(encodeURIComponent(JSON.stringify(this._filterConditionGroup.getConditions()))),
}
]
console.log(extraParameters);
this._confirmRunAlgorithm.init(evt.detail.algorithmName, evt.detail.projectId, [], null, extraParameters);
this._confirmRunAlgorithm.setAttribute("is-open","");
this.setAttribute("has-open-modal", "");
document.body.classList.add("shortcuts-disabled");
}

/**
* Callback from confirm run algorithm modal choice
*/
_closeConfirmRunAlgoModal(evt) {

this._confirmRunAlgorithm.removeAttribute("is-open");
this.removeAttribute("has-open-modal");
document.body.classList.remove("shortcuts-disabled");

var that = this;
if (evt.detail.confirm) {
this._dataView.launchAlgorithm(evt.detail.algorithmName, evt.detail.extraParameters).then(launched => {
if (launched) {
that._notify("Algorithm launched!",
`Successfully launched ${evt.detail.algorithmName}!`,
"ok");
}
else {
that._notify("Error launching algorithm!",
`Failed to launch ${evt.detail.algorithmName}`,
"error");
}
});
}
}

/**
* Applies the filter conditions based on the dialog, updates the GUI appropriately and
* dispatches the filterParameters event
Expand Down Expand Up @@ -202,11 +145,6 @@ export class FilterInterface extends TatorElement {
this._filterConditionGroup.data = this._dataView.getAllTypes();
this._filterConditionGroup._div.style.marginTop = "10px";
this._conditionsDiv.appendChild(this._filterConditionGroup);

// Get the algorithm information. If there are no registered algorithms, disable the button
this._algoButton.setAttribute("project-id", this._dataView.getProjectId());
this._algoButton.algorithms = this._dataView.getAlgorithms();
this._algoButton.hideNewAlgorithm();
}

/**
Expand Down
4 changes: 0 additions & 4 deletions ui/src/js/project-detail/algorithm-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ export class AlgorithmButton extends TatorElement {
set algorithms(val) {
this._algorithmMenu.algorithms = val;
}

hideNewAlgorithm() {
this._algorithmMenu.hideNewAlgorithm();
}
}

if (!customElements.get("algorithm-button")) {
Expand Down
15 changes: 3 additions & 12 deletions ui/src/js/project-detail/algorithm-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ export class AlgorithmMenu extends TatorElement {
this._algorithmButtons = document.createElement("div");
this._algorithmButtons.setAttribute("class", "d-flex flex-column px-4 py-3 lh-condensed");
this._shadow.appendChild(this._algorithmButtons);

this._newAlgorithm = document.createElement("new-algorithm-button");
this._algorithmButtons.appendChild(this._newAlgorithm);

this._newAlgorithm.addEventListener("click", evt => {
this.dispatchEvent(new Event("newAlgorithm", {composed: true}));
});
}

set algorithms(val) {

for (let algorithm of val) {
const button = document.createElement("button");
button.setAttribute("class", "btn-clear py-2 px-0 text-gray hover-text-white d-flex flex-items-center");
this._algorithmButtons.insertBefore(button, this._newAlgorithm);
button.style.textAlign = "left";
this._algorithmButtons.appendChild(button);

const span = document.createElement("span");
span.setAttribute("class", "px-2");
Expand All @@ -35,10 +30,6 @@ export class AlgorithmMenu extends TatorElement {
});
}
}

hideNewAlgorithm() {
this._newAlgorithm.hidden = true;
}
}

if (!customElements.get("algorithm-menu")) {
Expand Down
115 changes: 101 additions & 14 deletions ui/src/js/project-detail/confirm-run-algorithm.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
import { ModalDialog } from "../components/modal-dialog.js";
import { fetchRetry } from "../util/fetch-retry.js";
import { svgNamespace } from "../components/tator-element.js";

export class ConfirmRunAlgorithm extends ModalDialog {
constructor() {
super();

const icon = document.createElement("modal-warning");
this._header.insertBefore(icon, this._titleDiv);
const iconWrapper = document.createElement("div");
this._header.insertBefore(iconWrapper, this._titleDiv);

const svg = document.createElementNS(svgNamespace, "svg");
svg.setAttribute("width", "24");
svg.setAttribute("height", "24");
svg.setAttribute("viewBox", "0 0 24 24");
svg.setAttribute("fill", "none");
svg.style.fill = "none";
svg.setAttribute("stroke", "currentColor");
svg.setAttribute("stroke-width", "2");
svg.setAttribute("stroke-linecap", "round");
svg.setAttribute("stroke-linejoin", "round");
iconWrapper.appendChild(svg);

const poly = document.createElementNS(svgNamespace, "polyline");
poly.setAttribute("points", "22 12 18 12 15 21 9 3 6 12 2 12");
svg.appendChild(poly);

this._message = document.createElement("p");
this._message.setAttribute("class", "text-semibold py-3 text-center");
this._message.setAttribute("class", "py-3 text-center");
this._main.appendChild(this._message);

this._icon = document.createElement("div");
this._icon.setAttribute("class", "text-center py-3")
this._icon.style.margin = "auto";
this._icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="4em" height="4em" viewBox="0 0 32 32" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="no-fill"><line x1="12" y1="2" x2="12" y2="6"></line><line x1="12" y1="18" x2="12" y2="22"></line><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line><line x1="2" y1="12" x2="6" y2="12"></line><line x1="18" y1="12" x2="22" y2="12"></line><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line></svg>';
this._icon.style.display = "none";
//this._main.appendChild(this._icon);

this._accept = document.createElement("button");
this._accept.setAttribute("class", "btn btn-clear btn-purple");
this._accept.textContent = "Yes";
this._footer.appendChild(this._accept);

this._cancel = document.createElement("button");
this._cancel.setAttribute("class", "btn btn-clear btn-charcoal");
this._cancel.textContent = "No";
Expand All @@ -37,7 +62,7 @@ export class ConfirmRunAlgorithm extends ModalDialog {
confirm: true,
projectId: this._projectId,
mediaIds: this._mediaIds,
mediaQuery: this._mediaQuery,
section: this._section,
algorithmName: this._algorithmName,
extraParameters: this._extraParameters}}));
});
Expand All @@ -46,21 +71,83 @@ export class ConfirmRunAlgorithm extends ModalDialog {
/**
* Initialize the dialog window with the algorithm information prior
* to displaying it
*
*
* @param {integer} projectId Project ID associate with algorithm
* @param {string} algorithmName Name of algorithm to run
* @param {array} mediaIds List of media IDs to process
* @param {string} mediaQuery Media query string when launching algorithm
* @param {array} extraParameters #TODO add useful info
* @param {string} algorithmName Name of workflow to run
* @param {array} mediaIds List of media IDs to process. Can be null, if so section is checked.
* @param {Tator.Section} section Section to process. If this and mediaIds is null, assume that all the media in the project will be processed.
* @param {array} extraParameters key/value pairs of parameters to pass along when launching the workflow
*/
init(algorithmName, projectId, mediaIds, mediaQuery, extraParameters)
async init(algorithmName, projectId, mediaIds, section, extraParameters)
{
this._title.nodeValue = "Run Algorithm";
this._message.textContent = "Do you want to run " + algorithmName + "?";
this._title.nodeValue = `Launch Workflow`;
this._accept.style.display = "none";
this._cancel.style.display = "none";
this._message.textContent = `Retrieving data...`;
this._message.classList.add("text-gray");

if (mediaIds == null) {

if (section == null) {
var response = await fetchRetry(`/rest/MediaCount/${projectId}`, {
method: "GET",
credentials: "same-origin",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
"Accept": "application/json",
"Content-Type": "application/json"
}
});
var count = await response.json();
var msgText = `Do you want to run <span class="text-purple text-semibold">` + algorithmName + `</span> on <br /><span class="text-purple text-semibold">ALL media (media count: ${count})</span>?`;
}
else {
var response = await fetchRetry(`/rest/MediaCount/${projectId}?section=${section.id}`, {
method: "GET",
credentials: "same-origin",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
"Accept": "application/json",
"Content-Type": "application/json"
}
});
var count = await response.json();
var msgText = `Do you want to run <span class="text-purple text-semibold">` + algorithmName + `</span> on <br />media in <span class="text-purple text-semibold">${section.name} (media count: ${count})</span>?`;
}

// Small delay so that the user can acknowledge something was happening.
// This isn't something we want users to rush through anyway.
await new Promise(resolve => setTimeout(resolve, 2000));
}
else {
var count = mediaIds.length;
if (count == 1) {

var response = await fetchRetry(`/rest/Media/${mediaIds[0]}`, {
method: "GET",
credentials: "same-origin",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
"Accept": "application/json",
"Content-Type": "application/json"
}
});
var media = await response.json();
var msgText = `Do you want to run <span class="text-purple text-semibold">` + algorithmName + `</span> on <br /><span class="text-purple text-semibold">${media.name} (ID: ${media.id})</span>?`;
}
else {
var msgText = `Do you want to run <span class="text-purple text-semibold">` + algorithmName + `</span> on <br /><span class="text-purple text-semibold">${count} media</span>?`;
}
}

this._message.classList.remove("text-gray");
this._accept.style.display = "flex";
this._cancel.style.display = "flex";
this._message.innerHTML = msgText;
this._algorithmName = algorithmName;
this._projectId = projectId;
this._mediaIds = mediaIds;
this._mediaQuery = mediaQuery;
this._section = section;
this._extraParameters = extraParameters;
}

Expand Down
Loading

0 comments on commit fc10a25

Please sign in to comment.