diff --git a/src/components/Card/input.tsx b/src/components/Card/input.tsx index 9d339bfb..0923dc90 100644 --- a/src/components/Card/input.tsx +++ b/src/components/Card/input.tsx @@ -86,6 +86,7 @@ function input( schema, dropdowns, parentValue, + filterSchema, loading: string, getValues: (name: string) => unknown, setValue: (name: string, value: unknown) => void, @@ -155,6 +156,7 @@ function input( diff --git a/src/components/Json/Json.stories.tsx b/src/components/Json/Json.stories.tsx index c5738aec..61da49dc 100644 --- a/src/components/Json/Json.stories.tsx +++ b/src/components/Json/Json.stories.tsx @@ -4,7 +4,7 @@ import type { Meta } from '@storybook/react'; // import page from './README.mdx'; import Json from '.'; import decorators from '../test/decorator'; -import {previous, current} from '../test/diff'; +import {previous, current, schema} from '../test/diff'; const meta: Meta = { title: 'Json', @@ -21,6 +21,7 @@ export const Diff: React.FC = () => ; export const View: React.FC = () => diff --git a/src/components/Json/Json.types.ts b/src/components/Json/Json.types.ts index 0c64d5dd..086e9e1c 100644 --- a/src/components/Json/Json.types.ts +++ b/src/components/Json/Json.types.ts @@ -4,6 +4,7 @@ export interface Props extends React.HTMLAttributes { showUnchangedValues?: boolean, value: unknown, previous?: unknown, + schema?: unknown, keyValue?: boolean } diff --git a/src/components/Json/index.tsx b/src/components/Json/index.tsx index f8836cb7..de8e9a3d 100644 --- a/src/components/Json/index.tsx +++ b/src/components/Json/index.tsx @@ -36,6 +36,72 @@ const convert = keyValue => { }; }; +const flatten = (properties, root = '') => Object.entries(properties || {}).reduce( + (map, [name, property]) => { + return ('properties' in property) ? { + ...map, + [root + name]: property, + ...flatten(property.properties, root + name + '.') + } : ('items' in property) ? { + ...map, + [root + name]: property, + ...flatten(property.items.properties, root + name + '.') + } : { + ...map, + [root + name]: property + }; + }, + {} +); + +const filterBySchema = (obj, schema) => { + if (!schema) { + return obj; + } + const schemaMap = flatten(schema); + const convertType = (value, {type = 'string'}) => { + switch (Array.isArray(type) ? type.shift() : type) { + case 'number': + return parseInt(value); + case 'string': + return value?.toString(); + default: + return value; + } + }; + const filter = (obj, objPath = '') => { + return obj && Object.entries(obj).reduce( + (map, [name, property]) => { + const properties = schemaMap[objPath ? `${objPath}.${name}` : name]; + if (!properties) { + return map; + } + if (Array.isArray(property)) { + return { + ...map, + [properties.title || name]: property.map(p => + filter(p, objPath ? `${objPath}.${name}` : name) + ) + }; + } else if (typeof property === 'object' && property) { + return { + ...map, + [properties.title || name]: filter( + property, + objPath ? `${objPath}.${name}` : name + ) + }; + } + return { + ...map, + [properties.title || name]: convertType(property, properties) + }; + }, {} + ); + }; + return filter(obj); +}; + const arrow = ; const Json: ComponentProps = ({ showUnchangedValues = true, @@ -43,9 +109,12 @@ const Json: ComponentProps = ({ previous = value, keyValue, className, + schema, ...props }) => { const classes = useStyles(); + value = filterBySchema(value, schema?.properties); + previous = filterBySchema(previous, schema?.properties); const diff = keyValue ? convert(value) : compare(value, previous); const lineClass = line => diff --git a/src/components/test/diff.ts b/src/components/test/diff.ts index 613e8d8e..b0a37256 100644 --- a/src/components/test/diff.ts +++ b/src/components/test/diff.ts @@ -1,5 +1,76 @@ import merge from 'ut-function.merge'; +export const schema = { + type: 'object', + properties: { + 'General Info': { + type: 'object', + title: 'General Information', + properties: { + 'First name': { + title: 'Customer First Name', + description: 'First name', + type: 'string' + }, + 'Last name': { + type: 'string' + }, + 'National id': { + type: 'string' + }, + Gender: { + type: 'string' + }, + 'User Classification': { + type: 'number' + }, + 'Business Unit': { + type: 'string' + }, + 'Business UnitType': { + type: 'boolean' + }, + 'Lock Status': { + type: 'boolean' + } + } + }, + Credentials: { + type: 'object', + title: 'User Credentials', + properties: { + 'Set Username': { + type: 'string' + }, + 'Access Policy Status': { + type: 'number' + }, + 'Override User Access Policy': { + type: 'string' + } + } + }, + 'External Credentials': { + type: 'array', + items: { + description: 'External User', + type: 'object', + properties: { + 'External System': { + type: 'string' + }, + 'User Type': { + type: 'string' + }, + Username: { + type: 'string' + } + } + } + } + } +}; + export const previous = { 'General Info': { 'First name': 'Super',