-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add UI directive, progress bar, and status counts #56
Merged
Merged
Changes from 18 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
449cc66
Load from static content
kennsippell 16532a0
Working solution based around modal
kennsippell 1792e5c
Change from modal to top-of-page directive
kennsippell b5e442d
Review and testing
kennsippell b61f464
Revert use of static resources
kennsippell 077ab52
Pass eslint
kennsippell 7e21778
Merge branch 'main' into 18-upload-progress-bar
kennsippell c953fbe
Quick prototype
kennsippell 631b617
Test end to end. upload-manager tests
kennsippell 2712be2
Test for no-retry
kennsippell ed50b03
Fix eslint
kennsippell b91cd88
Merge branch 'main' into 17-retries
kennsippell d8d60bd
Merge branch 'main' into 17-retries
kennsippell 974d567
Basically rewrite after testing update-conflict
kennsippell ba3103f
Eslint
kennsippell 5f66393
Merge branch 'main' into 18-upload-progress-bar
kennsippell d0115b6
Merge branch '17-retries' into 18-upload-progress-bar
kennsippell 332a8ca
Code review feedback
kennsippell 3413ce8
Merge branch 'main' into 18-upload-progress-bar
kennsippell 543ec25
1.0.15
kennsippell 59989c8
Fix lint
kennsippell File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
const express = require('express'); | ||
|
||
const app = express(); | ||
|
||
// Middleware function to set timeout for all POST requests | ||
const timeoutMiddleware = (req, res, next) => { | ||
const TIMEOUT_DURATION = 1000; | ||
|
||
req.setTimeout(TIMEOUT_DURATION, () => { | ||
// Handle timeout | ||
res.status(408).send('Request Timeout'); | ||
}); | ||
|
||
next(); | ||
}; | ||
|
||
app.post('/_session', (req, res) => { | ||
res.set('Set-Cookie', 'AuthSession=abc123'); | ||
res.status(200).send('OK'); | ||
}); | ||
|
||
app.get('/medic/_design/medic-client/_view/contacts_by_type_freetext', (req, res) => { | ||
const startkey = JSON.parse(req.query.startkey); | ||
console.log('contacts_by_type_freetext', startkey); | ||
const DATA = [ | ||
// eslint-disable-next-line max-len | ||
{ id: 'e847f6e2-6dba-46dd-8128-5b153d0cd75f', key: ['b_sub_county', 'name:malava'], value: 'false false b_sub_county malava', doc: { _id: 'e847f6e2-6dba-46dd-8128-5b153d0cd75f', _rev: '1-cd20b7095c20172237867233b0375eda', parent: { _id: '95d9abd1-7c17-41b1-af98-595509f96631' }, type: 'contact', is_name_generated: 'false', name: 'Malava', external_id: '', contact: { _id: '1e3d8375-6ab4-4409-be3f-3324db7658e9' }, contact_type: 'b_sub_county', reported_date: 1702573623984 } }, | ||
// eslint-disable-next-line max-len | ||
{ id: '2926bf4c-63eb-433d-a2b4-274fd05d2f1c', key: ['c_community_health_unit', 'name:chu'], value: 'false false c_community_health_unit chu', doc: { _id: '2926bf4c-63eb-433d-a2b4-274fd05d2f1c', _rev: '1-c15f26fe064f8357c19d1124286bf4c4', name: 'Chu', PARENT: 'Chepalungu', code: '123456', type: 'contact', contact_type: 'c_community_health_unit', parent: { _id: 'e847f6e2-6dba-46dd-8128-5b153d0cd75f', parent: { _id: '95d9abd1-7c17-41b1-af98-595509f96631' } }, contact: { _id: 'bb9ebc4c6af161ee0f53b42339001fb1' }, reported_date: 1701631255451 } }, | ||
]; | ||
res.json({ | ||
total_rows: 2, | ||
offset: 0, | ||
rows: DATA.filter(r => r.key[0] === startkey[0]) | ||
}); | ||
}); | ||
|
||
app.use(timeoutMiddleware); | ||
|
||
app.all('*', (req, res) => { | ||
setTimeout(() => { | ||
res.status(200).send('OK'); | ||
}, 2000); | ||
}); | ||
|
||
// Start the server | ||
app.listen(3556, () => { | ||
console.log(`Server is listening on port ${3556}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { AxiosError, AxiosRequestConfig } from 'axios'; | ||
import isRetryAllowed from 'is-retry-allowed'; | ||
import { UserPayload } from '../services/user-payload'; | ||
import { ChtApi } from './cht-api'; | ||
|
||
const RETRY_COUNT = 4; | ||
|
||
export const axiosRetryConfig = { | ||
retries: RETRY_COUNT, | ||
retryDelay: () => 1000, | ||
retryCondition: (err: AxiosError) => { | ||
const status = err.response?.status; | ||
return (!status || status >= 500) && isRetryAllowed(err); | ||
}, | ||
onRetry: (retryCount: number, error: AxiosError, requestConfig: AxiosRequestConfig) => { | ||
console.log(`${requestConfig.url} failure. Retrying (${retryCount})`); | ||
}, | ||
}; | ||
|
||
export async function retryOnUpdateConflict<T>(funcWithPut: () => Promise<T>): Promise<T> { | ||
for (let retryCount = 0; retryCount < RETRY_COUNT; retryCount++) { | ||
try { | ||
return await funcWithPut(); | ||
} catch (err : any) { | ||
const statusCode = err.response?.status; | ||
if (statusCode === 409) { | ||
console.log(`Retrying on update-conflict (${retryCount})`); | ||
continue; | ||
} | ||
|
||
throw err; | ||
} | ||
} | ||
|
||
throw Error('update-conflict 409 persisted'); | ||
} | ||
|
||
export async function createUserWithRetries(userPayload: UserPayload, chtApi: ChtApi): Promise<{ username: string; password: string }> { | ||
for (let retryCount = 0; retryCount < RETRY_COUNT; ++retryCount) { | ||
try { | ||
await chtApi.createUser(userPayload); | ||
return userPayload; | ||
} catch (err: any) { | ||
if (axiosRetryConfig.retryCondition(err)) { | ||
continue; | ||
} | ||
|
||
if (err.response?.status !== 400) { | ||
throw err; | ||
} | ||
|
||
const translationKey = err.response?.data?.error?.translationKey; | ||
console.error('createUser retry because', translationKey); | ||
if (translationKey === 'username.taken') { | ||
userPayload.makeUsernameMoreComplex(); | ||
continue; | ||
} | ||
|
||
const RETRY_PASSWORD_TRANSLATIONS = ['password.length.minimum', 'password.weak']; | ||
if (RETRY_PASSWORD_TRANSLATIONS.includes(translationKey)) { | ||
userPayload.regeneratePassword(); | ||
continue; | ||
} | ||
|
||
throw err; | ||
} | ||
} | ||
|
||
throw new Error('could not create user ' + userPayload.contact); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
<div class="tile is-child" hx-ext="sse" sse-connect="/events/connection"> | ||
<div id="places_parent" class="tile is-child" hx-get="/events/places_list" hx-target="#place_tables" | ||
hx-swap="innerHTML" hx-trigger="sse:places_state_change"> | ||
<div id="place_tables"> | ||
{% include "place/list.html" %} | ||
</div> | ||
<div | ||
id="places_parent" | ||
class="tile is-child" | ||
hx-get="/events/places/all" | ||
hx-target="this" | ||
hx-swap="none" | ||
hx-trigger="sse:place_state_change" | ||
> | ||
{% include "place/directive.html" %} | ||
{% include "place/list.html" %} | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<a class="{{ include.className | default: "button is-primary" }}" href="/files/credentials" download="{{ session.authInfo.domain }}.users.csv"> | ||
<span class="material-symbols-outlined">save_as</span> Save Credentials | ||
</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<a class="{{ include.className | default: "button is-primary" }}" hx-post="/app/apply-changes" hx-swap="none"> | ||
<span class="material-symbols-outlined">group_add</span> Upload | ||
</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<div class="columns is-3 is-variable" id="directive" hx-swap-oob="true"> | ||
<div class="column has-background-light is-9"> | ||
<section class="hero is-small is-light"> | ||
<div class="hero-body"> | ||
{% if progress.inProgressCount > 0 %} | ||
{% include "place/directive_3_in_progress.html" %} | ||
{% elsif progress.stagedCount > 0 %} | ||
{% include "place/directive_2_prompt_upload.html" %} | ||
{% elsif progress.successCount > 0 %} | ||
{% include "place/directive_4_prompt_save.html" %} | ||
{% else %} | ||
{% include "place/directive_1_get_started.html" %} | ||
{% endif %} | ||
</div> | ||
</section> | ||
</div> | ||
|
||
<div class="column is-3 has-background-light"> | ||
<section class="hero is-small is-light"> | ||
<div class="hero-body"> | ||
<p class="title is-5">Summary</p> | ||
<ul> | ||
<li><span class="tag">{{ progress.stagedCount }} staged</span></li> | ||
<li><span class="tag is-warning">{{ progress.validationErrorCount }} validation errors</span> </li> | ||
<li><span class="tag is-success">{{ progress.completeCount }} uploaded</span> </li> | ||
<li><span class="tag is-danger">{{ progress.failureCount }} failures</span> </li> | ||
</ul> | ||
</div> | ||
</div> | ||
</section> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<p class="title is-5"> | ||
Getting Started... | ||
</p> | ||
<p> | ||
To get started, add some users which you want to create on the <i>{{ session.authInfo.friendly }}</i> instance. | ||
</p> | ||
|
||
{% for contactType in contactTypes %} | ||
<div class="navbar-menu"> | ||
<div class="navbar-item has-dropdown is-hoverable"> | ||
<a class="navbar-link is-arrowless button" href="/add-place?type={{ contactType.name }}&op=new"> | ||
<span class="material-symbols-outlined">add</span> Add {{contactType.friendly}} | ||
</a> | ||
<div class="navbar-dropdown"> | ||
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=new">Create New</a> | ||
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=replace">Replace Existing</a> | ||
<a class="navbar-item" href="/add-place?type={{ contactType.name }}&op=bulk">Upload from CSV</a> | ||
<a class="navbar-item" href="/move/{{ contactType.name }}">Move</a> | ||
</div> | ||
</div> | ||
</div> | ||
{% endfor %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<p class="title is-5"> | ||
Upload When Ready | ||
</p> | ||
<p> | ||
You now have some <i>staged users</i> below which are ready for upload. | ||
When everything looks right, upload them to <i>{{ session.authInfo.friendly }}</i>. | ||
</p> | ||
|
||
<div class="columns is-centered"> | ||
<div class="column is-4 has-text-centered"> | ||
<a class="button is-primary" data-target="progress-modal" hx-post="/app/apply-changes" hx-swap="none"> | ||
<span class="material-symbols-outlined">group_add</span> Upload | ||
</a> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<p class="title is-5"> | ||
Upload In Progress... | ||
</p> | ||
|
||
<progress class="progress is-medium is-dark" value="{{ progress.completeCount }}" max="{{ progress.totalCount }}">{{ progress.percent }}</progress> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<p class="title is-5"> | ||
Download Resulting User Credentials | ||
</p> | ||
|
||
<p> | ||
Usernames and passwords are now available for download. Click the button below to download the credentials as a file. | ||
</p> | ||
|
||
<div class="columns is-centered"> | ||
<div class="column is-4 has-text-centered"> | ||
{% include "components/button_save_credentials.html" %} | ||
</div> | ||
</div> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have consistent header sizes and spacing with the views that already exist on the page? I also find the shadow/elevation on the boxes unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I don't know what this means. Would you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what the UI looks like without boxes. I don't particularly like this because nothing is aligned. I find there is no line to the page.
I'm currently using the default box control from Bulma. Can I ask what you would like to see? Are you thinking no boxes (above) or less elevated boxes? Happy to implement, but I'm really bad at design and need a little more input to make your dream a reality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant the headers in the directives are super huge compared to the other headers on the page. I find the elevation weird because it's makes the boxes a level higher than the navbar. Also the two boxes don't share the same background color. It's not a blocker so we can keep it and get a designer to have a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Capturing in #67 to get a designer to look at this. For now I'll reduce header size, match background color, remove elevation, and send another screenshot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks better the way it was before