This repository has been archived by the owner on Jun 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #143 from cfpb/603-notes-history
Note History
- Loading branch information
Showing
13 changed files
with
715 additions
and
7 deletions.
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
File renamed without changes.
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,108 @@ | ||
import * as util from '../../../src/institution/NoteHistory/utils' | ||
|
||
const curr = { | ||
shallow: 'diff', | ||
nested: { value: 'diff' }, | ||
array: [2, 1], | ||
newKey: 'diff', | ||
} | ||
|
||
const prev = { shallow: 'old', nested: { value: 'old' }, array: [1, 2] } | ||
|
||
describe('#calcDiff', () => { | ||
it('Returns null when no differences', () => { | ||
expect(util.calcDiff(curr, curr)).to.equal(null) | ||
expect(util.calcDiff({}, {})).to.equal(null) | ||
expect(util.calcDiff(null, null)).to.equal(null) | ||
}) | ||
|
||
it('Returns all diffs when one arg is null', () => { | ||
const res_no_prev = { | ||
shallow: { oldVal: null, newVal: 'diff' }, | ||
nested: { value: { oldVal: null, newVal: 'diff' } }, | ||
array: { oldVal: null, newVal: [2, 1] }, | ||
newKey: { oldVal: null, newVal: 'diff' }, | ||
} | ||
|
||
expect(util.calcDiff(curr, null)).to.deep.equal(res_no_prev) | ||
|
||
const res_no_curr = { | ||
shallow: { oldVal: null, newVal: 'diff' }, | ||
nested: { value: { oldVal: null, newVal: 'diff' } }, | ||
array: { oldVal: null, newVal: [2, 1] }, | ||
newKey: { oldVal: null, newVal: 'diff' }, | ||
} | ||
expect(util.calcDiff(null, curr)).to.deep.equal(res_no_curr) | ||
}) | ||
|
||
it('Returns expected diff when given changed histories', () => { | ||
const expected = { | ||
shallow: { oldVal: 'old', newVal: 'diff' }, | ||
nested: { value: { oldVal: 'old', newVal: 'diff' } }, | ||
array: { oldVal: [1, 2], newVal: [2, 1] }, | ||
newKey: { oldVal: null, newVal: 'diff' }, | ||
} | ||
expect(util.calcDiff(curr, prev)).to.deep.equal(expected) | ||
|
||
}) | ||
}) | ||
|
||
describe('#allDiffs', () => { | ||
it('Returns null without fields to diff', () => { | ||
expect(util.allDiff()).to.equal(null); | ||
expect(util.allDiff({})).to.equal(null); | ||
}) | ||
|
||
it('Treats all fields as changed', () => { | ||
const expected = { | ||
shallow: { oldVal: null, newVal: 'diff' }, | ||
nested: { value: { oldVal: null, newVal: 'diff' } }, | ||
array: { oldVal: null, newVal: [2, 1] }, | ||
newKey: { oldVal: null, newVal: 'diff' }, | ||
} | ||
expect(util.allDiff(curr)).to.deep.equal(expected); | ||
}) | ||
}) | ||
|
||
describe('#formatHistoryDate', () => { | ||
it('Formats valid history ID', () => { | ||
const hID = 'FRONTENDTESTBANK9999-2019-1597866055421' | ||
const expected = 'Wed Aug 19 2020' | ||
expect(util.formatHistoryDate(hID)).to.equal(expected) | ||
}) | ||
|
||
it('Returns null for invalid history ID timestamp', () => { | ||
const hID = 'FRONTENDTESTBANK9999-2019-1597866055421-extra' | ||
expect(util.formatHistoryDate(hID)).to.equal(null) | ||
}) | ||
}) | ||
|
||
describe('#sortNotes', () => { | ||
it('Sorts notes desc by id', () => { | ||
const data = [{id: 3}, {id: 8}] | ||
expect(data[0].id < data[1].id).to.equal(true); | ||
const sorted = util.sortNotes(data) | ||
expect(data[0].id < data[1].id).to.equal(false); | ||
expect(data[1].id < data[0].id).to.equal(true); | ||
}) | ||
}) | ||
|
||
describe('#addDiff', () => { | ||
it('Injects diff into notes', () => { | ||
const notes = [ | ||
{ updatedPanel: JSON.stringify(curr) }, | ||
{ updatedPanel: JSON.stringify(prev) }, | ||
] | ||
|
||
const injected = util.addDiff(notes) | ||
|
||
const expected = { | ||
shallow: { oldVal: 'old', newVal: 'diff' }, | ||
nested: { value: { oldVal: 'old', newVal: 'diff' } }, | ||
array: { oldVal: [1, 2], newVal: [2, 1] }, | ||
newKey: { oldVal: null, newVal: 'diff' }, | ||
} | ||
|
||
expect(injected[0].diff).to.deep.equal(expected); | ||
}) | ||
}) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,90 @@ | ||
import React, { useEffect } from 'react' | ||
|
||
const NoteDetails = ({ className, diff, id, isOpen }) => { | ||
useEffect(() => { | ||
if (isOpen) { | ||
setTimeout(() => { | ||
document | ||
.getElementById(id) | ||
.scrollIntoView({ behavior: 'smooth', block: 'nearest' }) | ||
}, 300) | ||
} | ||
}, [isOpen, id]) | ||
|
||
return ( | ||
<div id={id} className={className}> | ||
<DiffTable json={diff} /> | ||
</div> | ||
) | ||
} | ||
|
||
const DiffTable = ({ json }) => { | ||
const keys = json && Object.keys(json) | ||
if (!keys || (keys.length === 1 && keys.indexOf('notes') === 0)) | ||
return <NoChanges /> | ||
|
||
return ( | ||
<> | ||
<table className='diff-table'> | ||
<DiffTableHeader /> | ||
<DiffTableBody json={json} /> | ||
</table> | ||
<pre className='json'>{JSON.stringify(json, null, 2)}</pre> | ||
</> | ||
) | ||
} | ||
|
||
const DiffTableHeader = () => ( | ||
<thead> | ||
<tr> | ||
<td>Field</td> | ||
<td>Old Value</td> | ||
<td>New Value</td> | ||
</tr> | ||
</thead> | ||
) | ||
|
||
const DiffTableBody = ({ json }) => { | ||
return ( | ||
<tbody> | ||
{Object.keys(json).map((key, idx) => { | ||
if (key === 'notes') return null | ||
const current = json[key] | ||
|
||
if (current && current.newVal !== undefined) { | ||
return ( | ||
<tr key={`${key}-${idx}`}> | ||
<td>{key}</td> | ||
<td>{checkForNone(current.oldVal)}</td> | ||
<td>{checkForNone(current.newVal)}</td> | ||
</tr> | ||
) | ||
} | ||
else if (typeof current !== 'string') { | ||
return Object.keys(current).map((nestedKey, nidx) => { | ||
const nestedCurrent = json[key][nestedKey] | ||
return ( | ||
<tr key={`${key}-${idx}-${nidx}`}> | ||
<td>{key} {nestedKey}</td> | ||
<td>{checkForNone(nestedCurrent.oldVal)}</td> | ||
<td>{checkForNone(nestedCurrent.newVal)}</td> | ||
</tr> | ||
) | ||
}) | ||
} | ||
else return null | ||
})} | ||
</tbody> | ||
) | ||
} | ||
|
||
function checkForNone(val) { | ||
if([null, undefined].indexOf(val) > -1) return '<none>' | ||
return val.toString() | ||
} | ||
|
||
const NoChanges = ({ text = 'No Changes' }) => { | ||
return <div className="no-changes">{text}</div> | ||
} | ||
|
||
export default NoteDetails |
Oops, something went wrong.