+
+
+
+ {/*
+
+
+
+
+
+ */}
+
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === ENUM) {
+ elements.push(
+
+
+
+
+
+
+
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === SUBDOCUMENT_TYPE) {
+ let subDocCss = interest === BEFORE ? {color: "text-danger", borderStyle: "border-danger"} : {color: "text-success", borderStyle: "border-success"}
+ elements.push(
+ removedSubDocumentElement(subDocCss, label)
+ )
+ }
+ return elements
+}
+
+/**
+ *
+ * @param {*} value value to display
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} css css to control look and feel
+ * @returns a react element with values controlled by css to display diffs
+ */
+ function displayElements(value, schema, label, required, css, interest) {
+ let elements=[]
+
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === DATA_TYPE) {
+ elements.push(
+
+
+
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === DOCUMENT) {
+ let inputSelectCss="text_diff_select"
+ if(interest) {
+ if(interest === BEFORE) {
+ css="text-danger"
+ inputSelectCss="text-danger text_diff_select text_diff_underline"
+ }
+ else {
+ css="text-success"
+ inputSelectCss="text-success text_diff_select text_diff_underline"
+ }
+ }
+ elements.push(
+
+
+
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === ENUM) {
+ let inputSelectCss="text_diff_select"
+ if(interest) {
+ if(interest === BEFORE) {
+ css="text-danger"
+ inputSelectCss="text-danger text_diff_select"
+ }
+ else {
+ css="text-success"
+ inputSelectCss="text-success text_diff_select"
+ }
+ }
+ elements.push(
+
+
+
+
+ )
+ }
+ return elements
+}
+
+/**
+ *
+* @param {*} diffPatch diff object
+ * @param {*} item current property
+ * @param {*} formData formData - can be old or new value
+ * @param {*} startFormDataIndex start index to loop through formdata to understand changes
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} interest BEFORE or AFTER
+ * @param {*} css css to control look and feel
+ * @param {*} fullFrame full frame
+ * @param {*} frame frame of interest
+ * @param {*} type document type
+ * @returns
+ */
+function displaySubDocumentElements(diffPatch, item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualList) {
+ let renderElements=[], elementSchema=schema, currentChoice=false, choiceCss="tdb__input"
+ for(var fds=0; fds
+
+
+
+
+
+
+ {fields}
+
+
+ )
+ }
+ else {
+ let accordianCss="border-0"
+ if(hasChanged) {
+ if(interest === BEFORE) accordianCss="original_subDoc_diff_border"
+ else accordianCss="changed_subDoc_diff_border"
+ }
+ renderElements.push(
+
+
+
+
+
+
+
+
+
+ {fields}
+
+
+
+ )
+ }
+ }
+ return renderElements
+}
+
+/**
+ *
+ * @param {*} diffPatch diff object
+ * @param {*} item current property
+ * @param {*} formData formData - can be old or new value
+ * @param {*} startFormDataIndex start index to loop through formdata to understand changes
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} interest BEFORE or AFTER
+ * @param {*} css css to control look and feel
+ * @returns
+ */
+function doOperation(diffPatch, item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualList) {
+ let renderElements=[], currentFormDataIndex=startFormDataIndex
+
+ if(Array.isArray(diffPatch)) { // simple swapValue Operation
+ let isSubDocumentType=true
+ diffPatch.map(diffs => {
+ if(diffs.hasOwnProperty(interest)) {
+ isSubDocumentType=false
+ let elements=displayElements(diffs[interest], schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ })
+ if(isSubDocumentType) { // subdocument
+ let subDocumentElement=displaySubDocumentElements(diffPatch, item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualList)
+ renderElements.push(subDocumentElement)
+ }
+ }
+ else if(Object.keys(diffPatch).length>0 &&
+ diffPatch.hasOwnProperty(OPERATION)){
+ // copy list operation
+ if(diffPatch[OPERATION] === COPY_LIST) {
+ if(diffPatch.hasOwnProperty(REST)) {
+ if(Array.isArray(diffPatch[REST])) {
+ let copyTill=diffPatch[REST][0][interest]
+ // break when first match found
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ if(copyTill === formData[item][index]){
+ currentFormDataIndex=index+diffPatch[REST].length
+ break
+ }
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ if(Object.keys(diffPatch[REST]).length>0 &&
+ diffPatch[REST].hasOwnProperty(interest)) {
+ let copyTill= diffPatch[REST][BEFORE].length>0 ? diffPatch[REST][BEFORE][0] : diffPatch[REST][AFTER][0]
+ let skipToNext=diffPatch[REST][BEFORE].length>0 ? diffPatch[REST][BEFORE].length : diffPatch[REST][AFTER].length>0
+ // break when first match found
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ if(copyTill === formData[item][index]){
+ currentFormDataIndex=index+skipToNext
+ break
+ }
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ let rest=doOperation(diffPatch[REST], item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualList)
+ renderElements.push(rest)
+ }
+ }
+ // patch list operation
+ if(diffPatch[OPERATION] === PATCH_LIST) {
+ if(diffPatch[PATCH][0].hasOwnProperty(interest)) {
+ let copyTill=diffPatch[PATCH][0][interest]
+ // break when first match found
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ if(copyTill === formData[item][index]){
+ currentFormDataIndex=index+diffPatch[PATCH].length
+ break
+ }
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ renderElements.push(getLabel(label, type))
+ // stitch in patch object
+ diffPatch[PATCH].map(patch => {
+ let elements=displayElements(patch[interest], schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ })
+ }
+ else {
+ let subDocumentElement=displaySubDocumentElements(diffPatch[PATCH], item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualList)
+ renderElements.push(subDocumentElement)
+ }
+ // loop throught the rest list to see what has been changed
+ if(diffPatch.hasOwnProperty(REST)) {
+ let rest=doOperation(diffPatch[REST], item, formData, currentFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualList)
+ renderElements.push(rest)
+ }
+ }
+ // swap list operation
+ if(diffPatch[OPERATION] === SWAP_LIST) {
+ diffPatch[interest].map(diff => {
+ let elements=displayElements(diff, schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ })
+ if(diffPatch[interest].length === 0) {
+ let oppInterest=interest === BEFORE ? AFTER : BEFORE
+ for(var count=0; count < diffPatch[oppInterest].length; count ++) {
+ let elements=getRemovedElements(schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ }
+ // keep list opeartion
+ if(diffPatch[OPERATION] === KEEP_LIST) {
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ // swap value operation
+ if(diffPatch[OPERATION] === SWAP_VALUE) {
+ let elements=displayElements(diffPatch[interest], schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ return renderElements
+}
+
+function checkIfChoicesAreSame(item, oldValue, newValue, interest) {
+ let choiceEqualList=[]
+
+ if(oldValue.hasOwnProperty(item)) {
+ for(var index =0; index < oldValue[item].length; index ++ ) {
+ if(oldValue[item][index]["@type"] === newValue[item][index]["@type"]) {
+ // choice equal
+ choiceEqualList.push("tdb__input")
+ }
+ else {
+ if(interest === BEFORE) choiceEqualList.push("text-danger tdb__diff__original")
+ else choiceEqualList.push("text-success tdb__diff__changed")
+ }
+ }
+ }
+ return choiceEqualList
+}
+
+/**
+ *
+ * @param {*} fullFrame fullFrame of data product
+ * @param {*} frame frame of document type of interest
+ * @param {*} diffPatch diff object
+ * @param {*} item current property
+ * @param {*} type current document type of interest
+ * @param {*} oldValue old form data
+ * @param {*} newValue new form data
+ * @returns
+ */
+export function getListFieldDiffs (fullFrame, frame, diffPatch, item, type, oldValue, newValue) {
+ let diffUIFrames={
+ originalUIFrame: {
+ [item]:{}
+ },
+ changedUIFrame: {
+ [item]:{}
+ }
+ }
+
+ // no change in list - hence not available in diff patch object
+ if(!diffPatch.hasOwnProperty(item)) {
+ return diffUIFrames
+ }
+
+ function getOriginalUIFrame(props) {
+ let renderElements=[]
+ if(props.schema.hasOwnProperty(INFO) &&
+ props.schema[INFO] === CHOICESUBCLASSES) {
+ let choicesEqualList=checkIfChoicesAreSame(item, oldValue, newValue, BEFORE)
+ renderElements=doOperation(diffPatch[item], item, oldValue, 0, props.schema, props.name, props.required, BEFORE, "text-danger tdb__diff__original mb-3", fullFrame, frame, type, choicesEqualList)
+ }
+ else renderElements=doOperation(diffPatch[item], item, oldValue, 0, props.schema.items[0], props.name, props.required, BEFORE, "text-danger tdb__diff__original mb-3", fullFrame, frame, type, null)
+ return <>
+ {renderElements}
+ >
+ }
+
+ function getChangedUIFrame(props) {
+ let renderElements=[]
+ if(props.schema.hasOwnProperty(INFO) &&
+ props.schema[INFO] === CHOICESUBCLASSES) {
+ let choicesEqualList=checkIfChoicesAreSame(item, oldValue, newValue, AFTER)
+ renderElements=doOperation(diffPatch[item], item, newValue, 0, props.schema, props.name, props.required, AFTER, "text-success tdb__diff__changed mb-3", fullFrame, frame, type, choicesEqualList)
+ }
+ else renderElements=doOperation(diffPatch[item], item, newValue, 0, props.schema.items[0], props.name, props.required, AFTER, "text-success tdb__diff__changed mb-3", fullFrame, frame, type, null)
+ return <>
+ {renderElements}
+ >
+ }
+
+
+ diffUIFrames[ORIGINAL_UI_FRAME][item] = {
+ "ui:diff": getOriginalUIFrame
+ }
+ diffUIFrames[CHANGED_UI_FRAME][item] = {
+ "ui:diff": getChangedUIFrame
+ }
+
+ return diffUIFrames
+}
\ No newline at end of file
diff --git a/packages/tdb-documents-ui/src/diffs/oneOfFieldDiffs.js b/packages/tdb-documents-ui/src/diffs/oneOfFieldDiffs.js
new file mode 100644
index 00000000..999efe4b
--- /dev/null
+++ b/packages/tdb-documents-ui/src/diffs/oneOfFieldDiffs.js
@@ -0,0 +1,72 @@
+
+import React from "react"
+import {generateDiffUIFrames} from "./diffViewer.utils"
+import {ORIGINAL_UI_FRAME, CHANGED_UI_FRAME} from "../constants"
+import {isDataType, isSysDataType} from "../utils"
+
+function getValueFromFormData(data, oneOf) {
+ let extracted
+ for(var item in data) {
+ if(typeof data[item] === "object") {
+ extracted=getValueFromFormData(data[item], oneOf)
+ }
+ if(item === oneOf) {
+ return {[oneOf]: data[item]}
+ }
+ }
+ return extracted
+}
+
+export const getOneOfFieldDiffs = (fullFrame, frame, diffPatch, item, type, oldValue, newValue) => {
+ let diffUIFrames={
+ originalUIFrame: {
+ [type]:{
+ "ui:diff": {}
+ }
+ },
+ changedUIFrame: {
+ [type]:{
+ "ui:diff": {}
+ }
+ }
+ }
+
+ if(!Array.isArray(frame[item])) return
+
+ let constructedFrame, alteredOldValue, alteredNewValue, alteredDiffPatch
+ for(let oneOf in frame[item][0]) {
+ if(diffPatch.hasOwnProperty(oneOf)) {
+ let documentClass=frame[item][0][oneOf]
+ let documentClassIRI = `${documentClass}` // xsd:string
+ if(typeof documentClass === "object" && documentClass.hasOwnProperty("@class")) documentClassIRI=documentClass["@class"] // document class
+
+ if(isDataType(documentClassIRI)) {
+ constructedFrame={[oneOf]: documentClassIRI}
+ alteredOldValue=getValueFromFormData(oldValue, oneOf)
+ alteredNewValue=getValueFromFormData(newValue, oneOf)
+ alteredDiffPatch={[oneOf]: diffPatch[oneOf]}
+ }
+ else if(isSysDataType(documentClassIRI)) {
+ constructedFrame={[oneOf]: "sys:Unit"}
+ alteredOldValue=getValueFromFormData(oldValue, oneOf)
+ alteredNewValue=getValueFromFormData(newValue, oneOf)
+ alteredDiffPatch={[oneOf]: diffPatch[oneOf]}
+ }
+ else {
+ constructedFrame = fullFrame[documentClassIRI]
+ alteredOldValue=getValueFromFormData(oldValue, oneOf)
+ alteredNewValue=getValueFromFormData(newValue, oneOf)
+ alteredDiffPatch=diffPatch.hasOwnProperty(oneOf) ? diffPatch[oneOf] : diffPatch
+ }
+ }
+ }
+
+
+ // swap value
+ let oneOfDocumentDiff = generateDiffUIFrames(fullFrame, constructedFrame, type, alteredOldValue, alteredNewValue, alteredDiffPatch)
+
+ diffUIFrames[ORIGINAL_UI_FRAME][type]["ui:diff"]=oneOfDocumentDiff[ORIGINAL_UI_FRAME]
+ diffUIFrames[CHANGED_UI_FRAME][type]["ui:diff"]=oneOfDocumentDiff[CHANGED_UI_FRAME]
+
+ return diffUIFrames
+}
\ No newline at end of file
diff --git a/packages/tdb-documents-ui/src/diffs/setFieldDiffs.js b/packages/tdb-documents-ui/src/diffs/setFieldDiffs.js
new file mode 100644
index 00000000..c2bcc9a8
--- /dev/null
+++ b/packages/tdb-documents-ui/src/diffs/setFieldDiffs.js
@@ -0,0 +1,570 @@
+
+import React, {useState} from "react"
+import {AiFillMinusCircle} from "react-icons/ai"
+import Stack from 'react-bootstrap/Stack'
+import Card from 'react-bootstrap/Card'
+import Accordion from 'react-bootstrap/Accordion'
+import {FrameViewer} from "../FrameViewer"
+import {
+ ORIGINAL_UI_FRAME,
+ CHANGED_UI_FRAME,
+ DATA_TYPE,
+ DOCUMENT,
+ INFO,
+ CHOICESUBCLASSES,
+ SUBDOCUMENT_TYPE,
+ ENUM,
+ SYS_JSON_TYPE,
+ ONEOFVALUES
+} from "../constants"
+import {
+ AFTER,
+ BEFORE,
+ REST,
+ PATCH,
+ OPERATION,
+ PATCH_LIST,
+ COPY_LIST,
+ KEEP_LIST,
+ SWAP_LIST,
+ SWAP_VALUE
+} from "./diff.constants"
+import {removedSubDocumentElement} from "./subDocumentFieldDiffs"
+import {displaySysJSONElements} from "./sysFieldDiffs"
+import {generateDiffUIFrames} from "./diffViewer.utils"
+
+/** returns a label field */
+export function getLabel(label, required, interest) {
+ let css = interest === BEFORE ? "text-danger" : "text-success"
+ return
+}
+
+/**
+ *
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} css css to control look and feel
+ * @returns a react element with deleted display
+ */
+ function getRemovedElements(schema, label, required, css, interest) {
+ let elements=[]
+ if(schema.hasOwnProperty(INFO)
+ && schema[INFO] === DATA_TYPE) {
+ elements.push(
+
+
+ { /**/}
+
+
+
+
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === DOCUMENT) {
+ elements.push(
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === ENUM) {
+ elements.push(
+
+
+ )
+ }
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === SUBDOCUMENT_TYPE) {
+ let subDocCss = interest === BEFORE ? {color: "text-danger", borderStyle: "border-danger"} : {color: "text-success", borderStyle: "border-success"}
+ elements.push(
+ removedSubDocumentElement(subDocCss, label)
+ )
+ }
+ return elements
+}
+
+/**
+ *
+ * @param {*} value value to display
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} css css to control look and feel
+ * @returns a react element with values controlled by css to display diffs
+ */
+ function displayElements(value, schema, label, required, css, interest) {
+ let elements=[]
+ if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === DATA_TYPE) {
+ elements.push(
+
+
+
+ )
+ }
+ else if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === DOCUMENT) {
+ let inputSelectCss="text_diff_select"
+ if(interest) {
+ if(interest === BEFORE) {
+ css="text-danger"
+ inputSelectCss="text-danger text_diff_select text_diff_underline"
+ }
+ else {
+ css="text-success"
+ inputSelectCss="text-success text_diff_select text_diff_underline"
+ }
+ }
+ if(Array.isArray(value)) {
+ value.map(val => {
+ elements.push(
+
+
+
+ )
+ })
+ }
+ else {
+ elements.push(
+
+
+
+ )
+ }
+ }
+ else if(schema.hasOwnProperty(INFO) &&
+ schema[INFO] === ENUM) {
+ let inputSelectCss="text_diff_select"
+ if(interest) {
+ if(interest === BEFORE) {
+ css="text-danger"
+ inputSelectCss="text-danger text_diff_select"
+ }
+ else {
+ css="text-success"
+ inputSelectCss="text-success text_diff_select"
+ }
+ }
+ elements.push(
+
+
+
+ )
+ }
+ return elements
+}
+
+/**
+ *
+* @param {*} diffPatch diff object
+ * @param {*} item current property
+ * @param {*} formData formData - can be old or new value
+ * @param {*} startFormDataIndex start index to loop through formdata to understand changes
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} interest BEFORE or AFTER
+ * @param {*} css css to control look and feel
+ * @param {*} fullFrame full frame
+ * @param {*} frame frame of interest
+ * @param {*} type document type
+ * @returns
+ */
+function displaySubDocumentElements(diffPatch, item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet) {
+ let renderElements=[], elementSchema=schema, currentChoice=false, choiceCss="tdb__input"
+ if(!formData.hasOwnProperty(item)) return renderElements
+ for(var fds=0; fds
+
+
+
+
+
+
+ {fields}
+
+
+ )
+ }
+ else {
+
+ let accordianCss="border-0"
+ if(hasChanged) {
+ if(interest === BEFORE) accordianCss="original_subDoc_diff_border"
+ else accordianCss="changed_subDoc_diff_border"
+ }
+ renderElements.push(
+
+
+
+
+
+
+
+
+
+ {fields}
+
+
+
+ )
+ }
+ }
+ return renderElements
+}
+
+/**
+ *
+ * @param {*} diffPatch diff object
+ * @param {*} item current property
+ * @param {*} formData formData - can be old or new value
+ * @param {*} startFormDataIndex start index to loop through formdata to understand changes
+ * @param {*} schema schema to control data types
+ * @param {*} label name of property
+ * @param {*} required is required property
+ * @param {*} interest BEFORE or AFTER
+ * @param {*} css css to control look and feel
+ * @returns
+ */
+function doOperation(diffPatch, item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet) {
+ let renderElements=[], currentFormDataIndex=startFormDataIndex
+
+ if(Array.isArray(diffPatch)) { // simple swapValue Operation
+ let isSubDocumentType=true
+ if(schema && schema.hasOwnProperty(INFO) && schema[INFO] === DOCUMENT) {
+ // display label for DOCUMENT types
+ renderElements.push(getLabel(label, required, interest))
+ }
+ diffPatch.map(diffs => {
+ if(diffs.hasOwnProperty(interest)) {
+ isSubDocumentType=false
+ let elements=displayElements(diffs[interest], schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ })
+ if(isSubDocumentType) { // subdocument
+ renderElements.push(getLabel(label, required, interest))
+ let subDocumentElement=displaySubDocumentElements(diffPatch, item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet)
+ renderElements.push(subDocumentElement)
+ }
+ }
+ else if(Object.keys(diffPatch).length>0 &&
+ diffPatch.hasOwnProperty(OPERATION)){
+ // copy set operation
+ if(diffPatch[OPERATION] === COPY_LIST) {
+ if(diffPatch.hasOwnProperty(REST)) {
+ if(Array.isArray(diffPatch[REST])) {
+ let copyTill=diffPatch[REST][0][interest]
+ // break when first match found
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ if(copyTill === formData[item][index]){
+ currentFormDataIndex=index+diffPatch[REST].length
+ break
+ }
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ if(Object.keys(diffPatch[REST]).length>0 &&
+ diffPatch[REST].hasOwnProperty(interest)) {
+ let copyTill= diffPatch[REST][BEFORE].length>0 ? diffPatch[REST][BEFORE][0] : diffPatch[REST][AFTER][0]
+ let skipToNext=diffPatch[REST][BEFORE].length>0 ? diffPatch[REST][BEFORE].length : diffPatch[REST][AFTER].length>0
+ // break when first match found
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ if(copyTill === formData[item][index]){
+ currentFormDataIndex=index+skipToNext
+ break
+ }
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ let rest=doOperation(diffPatch[REST], item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet)
+ renderElements.push(rest)
+ }
+ }
+ // patch list operation
+ if(diffPatch[OPERATION] === PATCH_LIST) {
+ if(diffPatch[PATCH][0].hasOwnProperty(interest)) {
+ let copyTill=diffPatch[PATCH][0][interest]
+ // break when first match found
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ if(copyTill === formData[item][index]){
+ currentFormDataIndex=index+diffPatch[PATCH].length
+ break
+ }
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ renderElements.push(getLabel(label, type, interest))
+ // stitch in patch object
+ diffPatch[PATCH].map(patch => {
+ let elements=displayElements(patch[interest], schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ })
+ }
+ else {
+ renderElements.push(getLabel(label, required, interest))
+ let subDocumentElement=displaySubDocumentElements(diffPatch[PATCH], item, formData, startFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet)
+ renderElements.push(subDocumentElement)
+ }
+ // loop throught the rest list to see what has been changed
+ if(diffPatch.hasOwnProperty(REST)) {
+ let rest=doOperation(diffPatch[REST], item, formData, currentFormDataIndex, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet)
+ renderElements.push(rest)
+ }
+ }
+ // swap list operation
+ if(diffPatch[OPERATION] === SWAP_LIST) {
+ diffPatch[interest].map(diff => {
+ let elements=displayElements(diff, schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ })
+ if(diffPatch[interest].length === 0) {
+ let oppInterest=interest === BEFORE ? AFTER : BEFORE
+ for(var count=0; count < diffPatch[oppInterest].length; count ++) {
+ let elements=getRemovedElements(schema, label, required, css, interest)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ }
+ // keep list opeartion
+ if(diffPatch[OPERATION] === KEEP_LIST) {
+ for(var index=startFormDataIndex; index < formData[item].length ; index++) {
+ let elements=displayElements(formData[item][index], schema, label, required, "tdb__input mb-3", null)
+ renderElements.push( <>
+ {elements}
+ >)
+ }
+ }
+ // swap value operation
+ if(diffPatch[OPERATION] === SWAP_VALUE) {
+ renderElements.push(getLabel(label, type, interest))
+ if(diffPatch[interest] === null) {
+ // removed items
+ let oppInterest=interest === BEFORE ? AFTER : BEFORE
+ for(var count=0; count < diffPatch[oppInterest].length; count ++) {
+ let elements=getRemovedElements(schema, label, required, css, interest)
+ renderElements.push( <> {elements} >)
+ }
+ }
+ else {
+ let elements=displayElements(diffPatch[interest], schema, label, required, css, interest)
+ renderElements.push( <> {elements} >)
+ }
+ }
+ }
+
+ return renderElements
+}
+
+
+function checkIfChoicesAreSame(item, oldValue, newValue, interest) {
+ let choiceEqualSet=[]
+
+ if(oldValue.hasOwnProperty(item)) {
+ for(var index =0; index < oldValue[item].length; index ++ ) {
+ if(oldValue[item][index]["@type"] === newValue[item][index]["@type"]) {
+ // choice equal
+ choiceEqualSet.push("tdb__input")
+ }
+ else {
+ if(interest === BEFORE) choiceEqualSet.push("text-danger tdb__diff__original")
+ else choiceEqualSet.push("text-success tdb__diff__changed")
+ }
+ }
+ }
+ return choiceEqualSet
+}
+
+function displayOneOfElements(diffPatch, item, oldValue, newValue, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet) {
+ if(!Array.isArray(diffPatch[item])) return false
+ let elements=[]
+ diffPatch[item].map(diff => {
+ if(Object.keys(diff).length > 0){
+ let constructedFrame={}
+
+ let classDocument=frame[item]["@class"]
+ if(fullFrame.hasOwnProperty(classDocument)) {
+ for(let its in fullFrame[classDocument][ONEOFVALUES][0]){
+ if(its === Object.keys(diff)[0]) {
+ constructedFrame={[its]: fullFrame[classDocument][ONEOFVALUES][0][its]}
+ }
+ }
+ }
+
+
+ let test = generateDiffUIFrames(fullFrame, constructedFrame, type, oldValue, newValue, diff)
+ console.log("test", test)
+ //elements.push(<>{Object.keys(diff)[0]}>)
+ //elements.push(<>{test}>)
+ elements.push()
+ }
+ })
+ return elements
+}
+
+/**
+ *
+ * @param {*} fullFrame fullFrame of data product
+ * @param {*} frame frame of document type of interest
+ * @param {*} diffPatch diff object
+ * @param {*} item current property
+ * @param {*} type current document type of interest
+ * @param {*} oldValue old form data
+ * @param {*} newValue new form data
+ * @returns
+ */
+export function getSetFieldDiffs (fullFrame, frame, diffPatch, item, type, oldValue, newValue) {
+ let diffUIFrames={
+ originalUIFrame: {
+ [item]:{}
+ },
+ changedUIFrame: {
+ [item]:{}
+ }
+ }
+
+ // no change in set - hence not available in diff patch object
+ if(!diffPatch.hasOwnProperty(item)) {
+ return diffUIFrames
+ }
+
+ function getOriginalUIFrame(props) {
+ let renderElements=[]
+ if(props.schema.hasOwnProperty(INFO) &&
+ props.schema[INFO] === CHOICESUBCLASSES) {
+ let choiceEqualSet=checkIfChoicesAreSame(item, oldValue, newValue, BEFORE)
+ renderElements=doOperation(diffPatch[item], item, oldValue, 0, props.schema, props.name, props.required, BEFORE, "text-danger tdb__diff__original mb-3", fullFrame, frame, type, choiceEqualSet)
+ }
+ else if(props.schema.hasOwnProperty(INFO) &&
+ props.schema[INFO] === ONEOFVALUES) {
+ let oneOfElement=displayOneOfElements(diffPatch, item, oldValue, newValue, props.schema, props.name, props.required, BEFORE, "css", fullFrame, frame, type)
+ renderElements.push(oneOfElement)
+ }
+ else if (props.schema.hasOwnProperty(INFO) &&
+ props.schema.info === SYS_JSON_TYPE) {
+ let sysJSONElement=displaySysJSONElements(diffPatch, item, oldValue, newValue, props.schema, props.name, props.required, BEFORE, "css", fullFrame, frame, type)
+ renderElements.push(sysJSONElement)
+ }
+ else {
+ // we pass schema as additionalItems (there maybe cases when Item's emmpty)
+ let schema = props.schema.hasOwnProperty("additionalItems") ? props.schema.additionalItems : props.schema.items[0]
+ renderElements=doOperation(diffPatch[item], item, oldValue, 0, schema, props.name, props.required, BEFORE, "text-danger tdb__diff__original mb-3", fullFrame, frame, type, null)
+ }
+ return <>
+ {renderElements}
+ >
+ }
+
+ function getChangedUIFrame(props) {
+ let renderElements=[]
+ if(props.schema.hasOwnProperty(INFO) &&
+ props.schema[INFO] === CHOICESUBCLASSES) {
+ let choiceEqualSet=checkIfChoicesAreSame(item, oldValue, newValue, AFTER)
+ renderElements=doOperation(diffPatch[item], item, newValue, 0, props.schema, props.name, props.required, AFTER, "text-success tdb__diff__changed mb-3", fullFrame, frame, type, choiceEqualSet)
+ }
+ else if (props.schema.hasOwnProperty(INFO) &&
+ props.schema.info === SYS_JSON_TYPE) {
+ let sysJSONElement=displaySysJSONElements(diffPatch, item, oldValue, newValue, props.schema, props.name, props.required, AFTER, "css", fullFrame, frame, type)
+ renderElements.push(sysJSONElement)
+ }
+ else {
+ let schema = props.schema.hasOwnProperty("additionalItems") ? props.schema.additionalItems : props.schema.items[0]
+ renderElements=doOperation(diffPatch[item], item, newValue, 0, schema, props.name, props.required, AFTER, "text-success tdb__diff__changed mb-3", fullFrame, frame, type, null)
+ }
+ return <>
+ {renderElements}
+ >
+ }
+
+
+ diffUIFrames[ORIGINAL_UI_FRAME][item] = {
+ "ui:diff": getOriginalUIFrame
+ }
+ diffUIFrames[CHANGED_UI_FRAME][item] = {
+ "ui:diff": getChangedUIFrame
+ }
+
+ return diffUIFrames
+}
\ No newline at end of file
diff --git a/packages/tdb-documents-ui/src/diffs/subDocumentFieldDiffs.js b/packages/tdb-documents-ui/src/diffs/subDocumentFieldDiffs.js
new file mode 100644
index 00000000..21fdf8e9
--- /dev/null
+++ b/packages/tdb-documents-ui/src/diffs/subDocumentFieldDiffs.js
@@ -0,0 +1,92 @@
+
+import React from "react"
+import {AiFillMinusCircle, AiFillPlusCircle} from "react-icons/ai"
+import Stack from 'react-bootstrap/Stack'
+import {ORIGINAL_UI_FRAME, CHANGED_UI_FRAME} from "../constants"
+import {generateDiffUIFrames} from "./diffViewer.utils"
+import {AFTER, BEFORE, SUBDOCUMENT_DOSENT_EXIST} from "./diff.constants"
+
+export function removedSubDocumentElement (css, label) {
+ return
+
+
+
+
+
+ {label}
+
+
+ {SUBDOCUMENT_DOSENT_EXIST}
+
+
+
+
+
+
+
+
+
+
+
+}
+
+// function to show removed element for changed
+export function showRemovedSubDocumentChanged(props) {
+ return removedSubDocumentElement({color: "text-success", borderStyle: "border-success"}, props.name)
+}
+
+// function to show removed element for original
+export function showRemovedSubDocumentOriginal(props) {
+ return removedSubDocumentElement({color: "text-danger", borderStyle: "border-danger"}, props.name)
+}
+
+
+export function getSubDocumentFieldDiffs (fullFrame, frame, diffPatch, item, type, oldValue, newValue) {
+ let diffUIFrames={
+ originalUIFrame: {
+ [item]:{}
+ },
+ changedUIFrame: {
+ [item]:{}
+ }
+ }
+
+ let classDocument=frame[item]["@class"]
+ let constructedFrame=fullFrame.hasOwnProperty(classDocument) ? fullFrame[classDocument] : {}
+
+ // if values are same then dont do anything
+ if(JSON.stringify(oldValue) === JSON.stringify(newValue)) return diffUIFrames
+
+ let extractedOldValue=oldValue.hasOwnProperty(item) ? oldValue[item] : {}
+ let extractedNewValue=newValue.hasOwnProperty(item) ? newValue[item] : {}
+ let subDocumentDiff = generateDiffUIFrames(fullFrame, constructedFrame, type, extractedOldValue, extractedNewValue, diffPatch[item])
+
+ diffUIFrames[ORIGINAL_UI_FRAME][item]=subDocumentDiff[ORIGINAL_UI_FRAME]
+ diffUIFrames[CHANGED_UI_FRAME][item]=subDocumentDiff[CHANGED_UI_FRAME]
+
+ diffUIFrames[CHANGED_UI_FRAME][item]["styleObject"]={
+ headingClassNames: "text-success",
+ borderClassNames: "border-success",
+ bgClassNames: "tdb__diff__changed__textrea"
+ }
+ diffUIFrames[ORIGINAL_UI_FRAME][item]["styleObject"]={
+ headingClassNames: "text-danger",
+ borderClassNames: "border-danger",
+ bgClassNames: "tdb__diff__original__textrea"
+ }
+
+ if(diffPatch[item].hasOwnProperty(BEFORE) && diffPatch[item][BEFORE] === null){
+ diffUIFrames[ORIGINAL_UI_FRAME][item]["ui:field"]=showRemovedSubDocumentOriginal
+ }
+
+ if(diffPatch[item].hasOwnProperty(AFTER) && diffPatch[item][AFTER] === null){
+ diffUIFrames[CHANGED_UI_FRAME][item]["ui:field"]=showRemovedSubDocumentChanged
+ }
+
+ return diffUIFrames
+}
\ No newline at end of file
diff --git a/packages/tdb-documents-ui/src/diffs/sysFieldDiffs.js b/packages/tdb-documents-ui/src/diffs/sysFieldDiffs.js
new file mode 100644
index 00000000..de507467
--- /dev/null
+++ b/packages/tdb-documents-ui/src/diffs/sysFieldDiffs.js
@@ -0,0 +1,264 @@
+
+import React from "react"
+import ReactDiffViewer from 'react-diff-viewer'
+import {BEFORE, AFTER, JSON_DIFF_STYLES} from "./diff.constants"
+import {ORIGINAL_UI_FRAME, CHANGED_UI_FRAME, SYS_UNIT_DATA_TYPE} from "../constants"
+import {AiFillMinusCircle} from "react-icons/ai"
+import Stack from 'react-bootstrap/Stack'
+
+export function displaySysJSONElements (diffPatch, item, oldValue, newValue, schema, label, required, interest, css, fullFrame, frame, type, choicesEqualSet) {
+ let renderElements=[]
+
+ if(interest === BEFORE) {
+ for(var index=0; index < oldValue[item].length; index ++) {
+ let data=newValue.hasOwnProperty(item) ? newValue[item][index] : {}
+ renderElements.push(
+
+
+
+
+
+
+ )
+ }
+ }
+
+ if(interest === AFTER) {
+ for(var index=0; index < newValue[item].length; index ++) {
+ let data=oldValue.hasOwnProperty(item) ? oldValue[item][index] : {}
+ renderElements.push(
+
+
+
+
+
+
+ )
+ }
+ }
+
+ // some elements might be removed here
+ if(interest===AFTER && oldValue[item].length > newValue[item].length) {
+ let difference = oldValue[item].length - newValue[item].length -1
+
+ for(var times=difference; times{"{"} )
+ for(var thing in oldValue[item][times]) {
+ elements.push(
+