Merge pull request #6423 from chicoribas/Mask-or-hide-values-on-Scaffolder-Review-Step

Mask or hide values on scaffolder review step
This commit is contained in:
Ben Lambert
2021-07-14 18:25:03 +02:00
committed by GitHub
4 changed files with 180 additions and 3 deletions
@@ -0,0 +1,88 @@
/*
* Copyright 2021 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:backstage': {
review: {
show: true,
mask: '******',
},
},
},
open: {
title: 'Open info',
type: 'string',
},
},
},
},
{
title: 'Other fields',
schema: {
title: 'Other fields',
properties: {
hidden: {
title: 'Hidden',
type: 'string',
'ui:backstage': {
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,59 @@ type Props = {
fields?: FormProps<any>['fields'];
};
export function getUiSchemasFromSteps(steps: Step[]): UiSchema[] {
const uiSchemas: Array<UiSchema> = [];
steps.forEach(step => {
const schemaProps = step.schema.properties as JsonObject;
for (const key in schemaProps) {
if (schemaProps.hasOwnProperty(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 (formData.hasOwnProperty(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:backstage'] || !uiSchema['ui:backstage'].review) {
reviewData[key] = formData[key];
continue;
}
const review = uiSchema['ui:backstage'].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,
@@ -64,8 +117,9 @@ export const MultistepJsonForm = ({
setActiveStep(0);
onReset();
};
const handleNext = () =>
const handleNext = () => {
setActiveStep(Math.min(activeStep + 1, steps.length));
};
const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0));
return (
@@ -113,7 +167,10 @@ export const MultistepJsonForm = ({
<Content>
<Paper square elevation={0}>
<Typography variant="h6">Review and create</Typography>
<StructuredMetadataTable dense metadata={formData} />
<StructuredMetadataTable
dense
metadata={getReviewData(formData, steps)}
/>
<Box mb={4} />
<Button onClick={handleBack}>Back</Button>
<Button onClick={handleReset}>Reset</Button>