Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export default class Project {
return response
} catch (error) {
console.error("Error updating roles:", error)
alert("Failed to update roles. Please try again.")
eventDispatcher.dispatch('tpen-alert', { message: "Failed to update roles. Please try again." })
}
}

Expand Down
71 changes: 46 additions & 25 deletions components/annotorious-annotator/line-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ class AnnotoriousAnnotator extends HTMLElement {
}, 500)
this.#pendingTimeouts.add(timeoutId)
})
this.renderCleanup.onElement(deleteAllBtn, "click", async (e) => await this.deleteAllAnnotations(e))
this.renderCleanup.onElement(deleteAllBtn, "click", (e) => this.deleteAllAnnotations(e))
this.renderCleanup.onWindow('beforeunload', (ev) => {
if (this.#resolvedAnnotationPage?.$isDirty) {
ev.preventDefault()
Expand Down Expand Up @@ -715,8 +715,16 @@ class AnnotoriousAnnotator extends HTMLElement {
srcDown: "../interfaces/annotator/images/transcribe.png",
onClick: (e) => {
if (this.#resolvedAnnotationPage?.$isDirty) {
if (confirm("Stop identifying lines and go transcribe? Unsaved changes will be lost."))
location.href = `/transcribe?projectID=${TPEN.activeProject._id}&pageID=${this.#annotationPageID}`
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
location.href = `/transcribe?projectID=${TPEN.activeProject._id}&pageID=${this.#annotationPageID}`
}
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: "Stop identifying lines and go transcribe? Unsaved changes will be lost." })
}
else {
location.href = `/transcribe?projectID=${TPEN.activeProject._id}&pageID=${this.#annotationPageID}`
Expand Down Expand Up @@ -808,13 +816,18 @@ class AnnotoriousAnnotator extends HTMLElement {
_this.#pendingTimeouts.delete(timeoutId)
// Timeout required in order to allow the click-and-focus native functionality to complete.
// Also stops the goofy UX for naturally slow clickers.
let c = confirm("Are you sure you want to remove this?")
if (c) {
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
_this.#annotoriousInstance.removeAnnotation(originalAnnotation)
_this.#resolvedAnnotationPage.$isDirty = true
} else {
}
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
_this.#annotoriousInstance.cancelSelected()
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: "Are you sure you want to remove this?" })
}, 500)
_this.#pendingTimeouts.add(timeoutId)
}
Expand Down Expand Up @@ -1143,26 +1156,34 @@ class AnnotoriousAnnotator extends HTMLElement {
* Use Annotorious to delete all known Annotations
* https://annotorious.dev/api-reference/openseadragon-annotator/#clearannotations
*/
async deleteAllAnnotations() {
if (!confirm('This will remove all Annotations and will take effect immediately. This action cannot be undone.')) return
const deleteAllBtn = this.shadowRoot.getElementById("deleteAllBtn")
deleteAllBtn.setAttribute("disabled", "true")
deleteAllBtn.textContent = "deleting. please wait..."
this.#annotoriousInstance.clearAnnotations()
this.#resolvedAnnotationPage.$isDirty = true
try {
await this.saveAnnotations()
await this.clearColumnsServerSide()
} catch (err) {
console.error("Could not delete all annotations.", err)
TPEN.eventDispatcher.dispatch("tpen-toast", {
message: "Could not delete all annotations.",
status: "error"
})
} finally {
deleteAllBtn.removeAttribute("disabled")
deleteAllBtn.textContent = "Delete All Annotations"
deleteAllAnnotations() {
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
const deleteAllBtn = this.shadowRoot.getElementById("deleteAllBtn")
deleteAllBtn.setAttribute("disabled", "true")
deleteAllBtn.textContent = "deleting. please wait..."
this.#annotoriousInstance.clearAnnotations()
this.#resolvedAnnotationPage.$isDirty = true
this.saveAnnotations()
.then(() => this.clearColumnsServerSide())
.catch(err => {
console.error("Could not delete all annotations.", err)
TPEN.eventDispatcher.dispatch("tpen-toast", {
message: "Could not delete all annotations.",
status: "error"
})
})
.finally(() => {
deleteAllBtn.removeAttribute("disabled")
deleteAllBtn.textContent = "Delete All Annotations"
})
}
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: 'This will remove all Annotations and will take effect immediately. This action cannot be undone.' })
}

/**
Expand Down
12 changes: 8 additions & 4 deletions components/annotorious-annotator/plain.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class AnnotoriousAnnotator extends HTMLElement {
}
this.#annotationPageURI = TPEN.screen.pageInQuery
if(!this.#annotationPageURI) {
alert("You must provide a ?pageID=theid in the URL. The value should be the URI of an existing AnnotationPage.")
TPEN.eventDispatcher.dispatch('tpen-alert', { message: "You must provide a ?pageID=theid in the URL. The value should be the URI of an existing AnnotationPage." })
return
}
this.setAttribute("annotationpage", this.#annotationPageURI)
Expand Down Expand Up @@ -257,13 +257,17 @@ class AnnotoriousAnnotator extends HTMLElement {
_this.#eraseConfirmTimeout = null
// Timeout required in order to allow the click-and-focus native functionality to complete.
// Also stops the goofy UX for naturally slow clickers.
let c = confirm("Are you sure you want to remove this?")
if(c) {
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
_this.#annotoriousInstance.removeAnnotation(annotation)
}
else{
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
_this.#annotoriousInstance.cancelSelected()
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: "Are you sure you want to remove this?" })
}, 500)
}
})
Expand Down
82 changes: 45 additions & 37 deletions components/decline-project/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,45 +87,53 @@ class DeclineInvite extends HTMLElement {
}

declineInvitation(collaboratorID, projectID) {
if (!confirm("You are declining a chance to be a part of this TPEN3 project.")) return
let redir = true
const declineBtn = this.shadowRoot.getElementById("declineBtn")
declineBtn.setAttribute("disabled", "disabled")
declineBtn.setAttribute("value", "declining...")
fetch(`${TPEN.servicesURL}/project/${this.#project}/collaborator/${this.#user}/decline`)
.then(resp => {
if (resp.ok) return resp.text()
redir = false
return resp.json()
})
.then(message => {
let userMessage = (typeof message === "string") ? message : message?.message
if (redir) {
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
let redir = true
const declineBtn = this.shadowRoot.getElementById("declineBtn")
declineBtn.setAttribute("disabled", "disabled")
declineBtn.setAttribute("value", "declining...")
fetch(`${TPEN.servicesURL}/project/${this.#project}/collaborator/${this.#user}/decline`)
.then(resp => {
if (resp.ok) return resp.text()
redir = false
return resp.json()
})
.then(message => {
let userMessage = (typeof message === "string") ? message : message?.message
if (redir) {
this.shadowRoot.innerHTML = `
<h3> ${userMessage} </h3>
`
setTimeout(() => {
document.location.href = TPEN.TPEN3URL
}, 3000)
return
}
this.shadowRoot.innerHTML = `
<h3> ${userMessage} </h3>
<h3>There was an error declining the invitation.</h3>
<p>
The message below has more details.
Refresh the page to try again or contact the TPEN3 Administrators.
</p>
<code> ${userMessage} <code>
`
setTimeout(() => {
document.location.href = TPEN.TPEN3URL
}, 3000)
return
}
this.shadowRoot.innerHTML = `
<h3>There was an error declining the invitation.</h3>
<p>
The message below has more details.
Refresh the page to try again or contact the TPEN3 Administrators.
</p>
<code> ${userMessage} <code>
`
})
.catch(err => {
this.shadowRoot.innerHTML = `
<h3>
There was an error declining the invitation. Refresh the page to try again
or contact the TPEN3 Administrators.
</h3>
`
})
})
.catch(err => {
this.shadowRoot.innerHTML = `
<h3>
There was an error declining the invitation. Refresh the page to try again
or contact the TPEN3 Administrators.
</h3>
`
})
}
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: "You are declining a chance to be a part of this TPEN3 project." })
}
}

Expand Down
92 changes: 50 additions & 42 deletions components/leave-project/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,51 +140,59 @@ class LeaveProject extends HTMLElement {
}

leaveProject() {
if (!confirm("You are leaving this TPEN3 project.")) return
let redir = true
const leaveBtn = this.shadowRoot.getElementById("leaveBtn")
leaveBtn.setAttribute("disabled", "disabled")
leaveBtn.setAttribute("value", "leaving...")
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
let redir = true
const leaveBtn = this.shadowRoot.getElementById("leaveBtn")
leaveBtn.setAttribute("disabled", "disabled")
leaveBtn.setAttribute("value", "leaving...")

fetch(`${TPEN.servicesURL}/project/${TPEN.activeProject._id}/leave`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${TPEN.getAuthorization()}`
}
})
.then(resp => {
if (resp.ok) return resp.text()
redir = false
return resp.json()
})
.then(message => {
let userMessage = (typeof message === "string") ? message : message?.message
if (redir) {
fetch(`${TPEN.servicesURL}/project/${TPEN.activeProject._id}/leave`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${TPEN.getAuthorization()}`
}
})
.then(resp => {
if (resp.ok) return resp.text()
redir = false
return resp.json()
})
.then(message => {
let userMessage = (typeof message === "string") ? message : message?.message
if (redir) {
this.shadowRoot.innerHTML = `
<h3>Now you are not a project member. Goodbye 👋</h3>
`
setTimeout(() => {
document.location.href = TPEN.BASEURL
}, 3000)
return
}
this.shadowRoot.innerHTML = `
<h3>Now you are not a project member. Goodbye 👋</h3>
<h3>There was an error leaving the project.</h3>
<p>
The message below has more details.
Refresh the page to try again or contact the TPEN3 Administrators.
</p>
<code>${userMessage}<code>
`
setTimeout(() => {
document.location.href = TPEN.BASEURL
}, 3000)
return
}
this.shadowRoot.innerHTML = `
<h3>There was an error leaving the project.</h3>
<p>
The message below has more details.
Refresh the page to try again or contact the TPEN3 Administrators.
</p>
<code>${userMessage}<code>
`
})
.catch(err => {
this.shadowRoot.innerHTML = `
<h3>
There was an error leaving the project. Refresh the page to try again
or contact the TPEN3 Administrators.
</h3>
`
})
})
.catch(err => {
this.shadowRoot.innerHTML = `
<h3>
There was an error leaving the project. Refresh the page to try again
or contact the TPEN3 Administrators.
</h3>
`
})
}
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: "You are leaving this TPEN3 project." })
}
}

Expand Down
39 changes: 23 additions & 16 deletions components/manage-layers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,24 +244,31 @@ class ProjectLayers extends HTMLElement {
})
return
}
if (!confirm("This Layer will be deleted and the Pages will no longer be a part of this project. This action cannot be undone.")) return
const url = event.target.getAttribute("data-layer-id")
const layerId = url.substring(url.lastIndexOf("/") + 1)

fetch(`${TPEN.servicesURL}/project/${TPEN.activeProject._id}/layer/${layerId}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${TPEN.getAuthorization()}`
}
})
.then(response => {
return TPEN.eventDispatcher.dispatch("tpen-toast",
response.ok ?
{ status: "info", message: 'Successfully Deleted Layer' } :
{ status: "error", message: 'Error Deleting Layer' }
)
})
const onPositive = () => {
TPEN.eventDispatcher.off('tpen-confirm-negative', onNegative)
fetch(`${TPEN.servicesURL}/project/${TPEN.activeProject._id}/layer/${layerId}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${TPEN.getAuthorization()}`
}
})
.then(response => {
return TPEN.eventDispatcher.dispatch("tpen-toast",
response.ok ?
{ status: "info", message: 'Successfully Deleted Layer' } :
{ status: "error", message: 'Error Deleting Layer' }
)
})
}
const onNegative = () => {
TPEN.eventDispatcher.off('tpen-confirm-positive', onPositive)
}
TPEN.eventDispatcher.one('tpen-confirm-positive', onPositive)
TPEN.eventDispatcher.one('tpen-confirm-negative', onNegative)
TPEN.eventDispatcher.dispatch('tpen-confirm', { message: "This Layer will be deleted and the Pages will no longer be a part of this project. This action cannot be undone." })
})
})

Expand Down
Loading