Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure install, upgrade and uninstall complete successfully. #1974

Merged
merged 8 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion lib/assets/javascripts/kit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ window.GOVUKPrototypeKit = {
// Everything else
document.addEventListener('DOMContentLoaded', fn)
}
}
},
internal: {}
}

// Warn about using the kit in production
Expand Down
177 changes: 108 additions & 69 deletions lib/assets/javascripts/manage-prototype/manage-plugins.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
window.GOVUKPrototypeKit.documentReady(() => {
;(() => {
const params = new URLSearchParams(window.location.search)
const packageName = params.get('package')
const version = params.get('version')
const mode = params.get('mode') || window.location.pathname.split('/').pop()

const timeout = 30 * 1000

let requestTimeoutId
let timedOut = false
const timeout = 30 * 1000
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
let kitIsRestarting = false
let actionTimeoutId

const show = (id) => {
const element = document.getElementById(id)
Expand All @@ -23,107 +26,143 @@ window.GOVUKPrototypeKit.documentReady(() => {
}

const showCompleteStatus = () => {
clearTimeout(actionTimeoutId)
if (actionTimeoutId) {
clearTimeout(actionTimeoutId)
}
log('Successful')
hide('panel-processing')
show('panel-complete')
show('instructions-complete')
}

const showErrorStatus = () => {
if (actionTimeoutId) {
clearTimeout(actionTimeoutId)
}
log('Failed')
hide('panel-processing')
show('panel-error')
}

const postRequest = (url) => fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'CSRF-Token': token
},
body: JSON.stringify({
package: packageName,
version
const postRequest = (url) => {
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
return fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'CSRF-Token': token
},
body: JSON.stringify({
package: packageName,
version
})
})
})
.then(response => {
return response.json()
})
}

const actionTimeoutId = setTimeout(() => {
timedOut = true
}, timeout)
const makeRequest = (fn) => {
return new Promise((resolve) => {
BenSurgisonGDS marked this conversation as resolved.
Show resolved Hide resolved
if (requestTimeoutId) {
clearTimeout(requestTimeoutId)
}
if (timedOut) {
showErrorStatus()
resolve()
} else {
requestTimeoutId = setTimeout(() => fn().then(resolve), 1000)
}
})
}

const pollStatus = () => {
log('Processing')
if (requestTimeoutId) {
clearTimeout(requestTimeoutId)
}
if (timedOut) {
showErrorStatus()
} else {
// Be aware that changing this path for monitoring the status of a plugin will affect the
// kit upgrade process as the browser request and server route would be out of sync.
postRequest(`/manage-prototype/plugins/${mode}/status`)
.then(response => response.json())
.then(data => {
requestTimeoutId = setTimeout(() => {
if (data.status === 'error') {
clearTimeout(actionTimeoutId)
showErrorStatus()
} else if (data.status === 'completed') {
showCompleteStatus()
} else {
// poll status again if prototype hasn't restarted
pollStatus()
}
}, 1000)
})
.catch(() => {
requestTimeoutId = setTimeout(pollStatus, 1000)
})
}
// Be aware that changing this path for monitoring the status of a plugin will affect the
// kit upgrade process as the browser request and server route would be out of sync.
return postRequest(`/manage-prototype/plugins/${mode}/status`)
.then(data => {
if (kitIsRestarting) {
// kit has restarted as the request has returned with data
kitIsRestarting = false
if (data.status === 'processing') {
return makeRequest(performAction)
}
}
switch (data.status) {
case 'completed':
return showCompleteStatus()
case 'error': {
return showErrorStatus()
}
default: {
// poll status again if prototype hasn't restarted
return makeRequest(pollStatus)
}
}
})
.catch(() => {
// kit must be restarting as the request failed
kitIsRestarting = true
return makeRequest(pollStatus)
})
}

const performAction = (event) => {
log('Starting')

if (event) {
if (!actionTimeoutId) {
actionTimeoutId = setTimeout(() => {
timedOut = true
}, timeout)
}

if (event && event.preventDefault) {
event.preventDefault()
hide('plugin-action-confirmation')
}

show('panel-processing')

postRequest(`/manage-prototype/plugins/${mode}`)
.then(response => response.json())
return postRequest(`/manage-prototype/plugins/${mode}`)
.then(data => {
switch (data.status) {
case 'completed': {
// Command has already been run
showCompleteStatus()
break
}
case 'processing': {
pollStatus()
break
}
default: {
// Default to error
showErrorStatus()
}
case 'completed':
return showCompleteStatus()
case 'processing':
return makeRequest(pollStatus)
default:
return showErrorStatus()
}
})
.catch(() => {
showErrorStatus()
// kit must be restarting as the request failed so try again
return makeRequest(performAction)
})
}

hide('panel-manual-instructions')
const actionButton = document.getElementById('plugin-action-button')
const init = () => {
kitIsRestarting = false
timedOut = false
actionTimeoutId = null
requestTimeoutId = null

hide('panel-manual-instructions')
const actionButton = document.getElementById('plugin-action-button')

if (actionButton) {
actionButton.addEventListener('click', performAction)
} else {
return performAction()
}
}

if (actionButton) {
actionButton.addEventListener('click', performAction)
} else {
performAction()
window.GOVUKPrototypeKit.internal.managePlugins = {
showCompleteStatus,
showErrorStatus,
pollStatus,
performAction,
init
}
})
})()
Loading