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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user