Skip to content

Commit

Permalink
Merge pull request #3701 from Tangerine-Community/import-user-profile…
Browse files Browse the repository at this point in the history
…-docs

feat(import-profile): Import user profile and docs to device
  • Loading branch information
esurface authored Jun 3, 2024
2 parents 38567f7 + 6d5a302 commit 99f6289
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
}
paper-input {
margin: 15px;
}
}
#err {
color: red;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@
<paper-button [disabled]="state === STATE_SYNCING" (click)="onSubmit()">{{'submit'|translate}}</paper-button>
</p>
<p *ngIf="state === STATE_SYNCING">
{{'Syncing'|translate}}...
{{'Synced'|translate}} {{processedDocs}} {{'of'|translate}} {{totalDocs}}
</p>
<p *ngIf="state === STATE_NOT_FOUND" class="err">
{{'Record with import code'|translate}} {{shortCode}} {{'not found.'|translate}}
</p>
<p *ngIf="state === STATE_ERROR" class="err">
{{'Import not successful. Click Submit to retry.' |translate}}
</p>
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,69 @@ export class ImportUserProfileComponent implements AfterContentInit {

STATE_SYNCING = 'STATE_SYNCING'
STATE_INPUT = 'STATE_INPUT'
STATE_ERROR = 'STATE_ERROR'
STATE_NOT_FOUND ='STATE_NOT_FOUND'
appConfig: AppConfig
state = this.STATE_INPUT
docs;
totalDocs;
processedDocs = 0;
userAccount;
db;
shortCode
@ViewChild('userShortCode', {static: true}) userShortCodeInput: ElementRef;

constructor(
private router: Router,
private http: HttpClient,
private userService: UserService,
private appConfigService: AppConfigService
) { }
) { }

ngAfterContentInit() {
}

async onSubmit() {
const username = this.userService.getCurrentUser()
const db = await this.userService.getUserDatabase(this.userService.getCurrentUser())
const userAccount = await this.userService.getUserAccount(this.userService.getCurrentUser())
this.db = await this.userService.getUserDatabase(username)
this.userAccount = await this.userService.getUserAccount(username)
try {
const profileToReplace = await db.get(userAccount.userUUID)
await db.remove(profileToReplace)
const profileToReplace = await this.db.get(this.userAccount.userUUID)
await this.db.remove(profileToReplace)
} catch(e) {
// It's ok if this fails. It's probably because they are trying again and the profile has already been deleted.
}
this.state = this.STATE_SYNCING
this.appConfig = await this.appConfigService.getAppConfig()
const shortCode = this.userShortCodeInput.nativeElement.value
this.docs = await this.http.get(`${this.appConfig.serverUrl}api/${this.appConfig.groupId}/responsesByUserProfileShortCode/${shortCode}`).toPromise()
const newUserProfile = this.docs.find(doc => doc.form && doc.form.id === 'user-profile')
await this.userService.saveUserAccount({...userAccount, userUUID: newUserProfile._id, initialProfileComplete: true})
for (let doc of this.docs) {
delete doc._rev
await db.put(doc)
}
this.router.navigate([`/${this.appConfig.homeUrl}`] );
await this.startSyncing()
}

async startSyncing(){
try {
this.appConfig = await this.appConfigService.getAppConfig()
this.shortCode = this.userShortCodeInput.nativeElement.value;
let newUserProfile = await this.http.get(`${this.appConfig.serverUrl}/api/${this.appConfig.groupId}/responsesByUserProfileShortCode/${this.shortCode}/?userProfile=true`).toPromise()
if(!!newUserProfile){
this.state = this.STATE_SYNCING
await this.userService.saveUserAccount({ ...this.userAccount, userUUID: newUserProfile['_id'], initialProfileComplete: true })
this.totalDocs = (await this.http.get(`${this.appConfig.serverUrl}/api/${this.appConfig.groupId}/responsesByUserProfileShortCode/${this.shortCode}/?totalRows=true`).toPromise())['totalDocs']
const docsToQuery = 1000;
let processedDocs = +localStorage.getItem('processedDocs') || 0;
while (processedDocs < this.totalDocs) {
this.docs = await this.http.get(`${this.appConfig.serverUrl}/api/${this.appConfig.groupId}/responsesByUserProfileShortCode/${this.shortCode}/${docsToQuery}/${processedDocs}`).toPromise()
for (let doc of this.docs) {
delete doc._rev
await this.db.put(doc)
}
processedDocs += this.docs.length;
this.processedDocs = processedDocs
localStorage.setItem('processedDocs', String(processedDocs))
}
} else{
this.state = this.STATE_NOT_FOUND
}
this.router.navigate([`/${this.appConfig.homeUrl}`] );
} catch (error) {
this.state = this.STATE_ERROR
}
}

}
}
8 changes: 7 additions & 1 deletion server/src/group-views.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ module.exports.responsesByUserProfileShortCode = function(doc) {
}
}

module.exports.userProfileByUserProfileShortCode = function (doc) {
if (doc.collection === "TangyFormResponse"&&doc.form && doc.form.id === 'user-profile') {
return emit(doc._id.substr(doc._id.length - 6, doc._id.length), true);
}
}

module.exports.groupIssues = function(doc) {
if (doc.collection === "TangyFormResponse" && doc.type === "issue") {
var lastFilledOutNode;
Expand Down Expand Up @@ -214,4 +220,4 @@ module.exports.byConflictDocId = {
emit(doc.conflictDocId, doc.conflictRev);
}.toString(),
reduce: '_count'
}
}
23 changes: 19 additions & 4 deletions server/src/routes/group-responses-by-user-profile-short-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,32 @@ const log = require('tangy-log').log
module.exports = async (req, res) => {
try {
const groupDb = new DB(req.params.groupId)
let options = {key: req.params.userProfileShortCode, include_docs: true}
const userProfileShortCode = req.params.userProfileShortCode
let options = { key: userProfileShortCode, include_docs: true }
if (req.params.limit) {
options.limit = req.params.limit
}
if (req.params.skip) {
options.skip = req.params.skip
}
const results = await groupDb.query('responsesByUserProfileShortCode', options);
const docs = results.rows.map(row => row.doc)
res.send(docs)
if (req.query.totalRows) {
options.limit = 1
options.skip = 0
const results = await groupDb.query('responsesByUserProfileShortCode', options);
res.send({ totalDocs: results.total_rows })
} else if (req.query.userProfile) {
await groupDb.query("userProfileByUserProfileShortCode", { limit: 0 });
const result = await groupDb.query("userProfileByUserProfileShortCode", { key: userProfileShortCode, limit: 1, include_docs: true });
const profile = result.rows[0]
const data = profile ? {_id: profile.id, key: profile.id, formId: profile.doc.form.id, collection: profile.doc.collection}: undefined
res.send(data)
} else {
const results = await groupDb.query('responsesByUserProfileShortCode', options);
const docs = results.rows.map(row => row.doc)
res.send(docs)
}
} catch (error) {
console.log(error)
log.error(error);
res.status(500).send(error);
}
Expand Down

0 comments on commit 99f6289

Please sign in to comment.