Add ui:options to mask and hide

Signed-off-by: chicoribas <chico.bribas@gmail.com>
This commit is contained in:
chicoribas
2021-07-09 10:22:42 -03:00
parent 9eccc589b7
commit ac96bc7975
2 changed files with 153 additions and 3 deletions
@@ -0,0 +1,88 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getReviewData } from './MultistepJsonForm';
describe('MultistepJsonForm', () => {
const formDataMock = {
password: 'password',
masked: 'Some info to mask',
open: 'Some open info',
hidden: 'Some info to hide',
'other-open': 'Other open info',
};
const stepsMock = [
{
title: 'The test template',
schema: {
title: 'The test template',
properties: {
password: {
title: 'Password',
type: 'string',
'ui:widget': 'password',
},
masked: {
title: 'Masked',
type: 'string',
'ui:options': {
review: {
show: true,
mask: '******',
},
},
},
open: {
title: 'Open info',
type: 'string',
},
},
},
},
{
title: 'Other fields',
schema: {
title: 'Other fields',
properties: {
hidden: {
title: 'Hidden',
type: 'string',
'ui:options': {
review: {
show: false,
},
},
},
'other-open': {
title: 'Other Open Info',
type: 'string',
},
},
},
},
];
test('Fields are defined to be hidden or masked', () => {
const reviewData = getReviewData(formDataMock, stepsMock);
expect(reviewData.password).toBe('******');
expect(reviewData.masked).toBe('******');
expect(reviewData.open).toBe('Some open info');
expect(reviewData.hidden).toBeUndefined();
expect(reviewData['other-open']).toBe('Other open info');
});
});
@@ -24,7 +24,7 @@ import {
Stepper,
Typography,
} from '@material-ui/core';
import { FormProps, IChangeEvent, withTheme } from '@rjsf/core';
import { FormProps, IChangeEvent, UiSchema, withTheme } from '@rjsf/core';
import { Theme as MuiTheme } from '@rjsf/material-ui';
import React, { useState } from 'react';
import { transformSchemaToProps } from './schema';
@@ -49,6 +49,62 @@ type Props = {
fields?: FormProps<any>['fields'];
};
export function getUiSchemasFromSteps(steps: Step[]): UiSchema[] {
const uiSchemas: Array<UiSchema> = [];
steps.forEach(step => {
if (!step.schema || !step.schema.properties) return;
const schemaProps = step.schema.properties as JsonObject;
for (const key in schemaProps) {
if (Object.prototype.hasOwnProperty.call(schemaProps, key)) {
const uiSchema = schemaProps[key] as UiSchema;
uiSchema.name = key;
uiSchemas.push(uiSchema);
}
}
});
return uiSchemas;
}
export function getReviewData(formData: Record<string, any>, steps: Step[]) {
const uiSchemas = getUiSchemasFromSteps(steps);
const reviewData: Record<string, any> = {};
for (const key in formData) {
if (Object.prototype.hasOwnProperty.call(formData, key)) {
const uiSchema = uiSchemas.find(us => us.name === key);
if (!uiSchema) {
reviewData[key] = formData[key];
continue;
}
if (uiSchema['ui:widget'] === 'password') {
reviewData[key] = '******';
continue;
}
if (!uiSchema['ui:options'] || !uiSchema['ui:options'].review) {
reviewData[key] = formData[key];
continue;
}
const review = uiSchema['ui:options'].review as JsonObject;
if (!review.show) {
continue;
}
if (review.mask) {
reviewData[key] = review.mask;
continue;
}
reviewData[key] = formData[key];
}
}
return reviewData;
}
export const MultistepJsonForm = ({
steps,
formData,
@@ -59,13 +115,19 @@ export const MultistepJsonForm = ({
widgets,
}: Props) => {
const [activeStep, setActiveStep] = useState(0);
const [reviewData, setReviewData] = useState({});
const handleReset = () => {
setActiveStep(0);
onReset();
};
const handleNext = () =>
const handleNext = () => {
setActiveStep(Math.min(activeStep + 1, steps.length));
if (Math.min(activeStep + 1, steps.length) === steps.length) {
setReviewData(getReviewData(formData, steps));
}
};
const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0));
return (
@@ -113,7 +175,7 @@ export const MultistepJsonForm = ({
<Content>
<Paper square elevation={0}>
<Typography variant="h6">Review and create</Typography>
<StructuredMetadataTable dense metadata={formData} />
<StructuredMetadataTable dense metadata={reviewData} />
<Box mb={4} />
<Button onClick={handleBack}>Back</Button>
<Button onClick={handleReset}>Reset</Button>