don't add empty key values (#25472)

* don't add empty key values

fixes: #24678

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* fixed test

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

---------

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2023-12-15 13:30:16 +01:00 committed by GitHub
parent c6ce859493
commit 8263c538d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 13 deletions

View file

@ -115,6 +115,7 @@ export default class AddMapperPage {
.contains("Advanced Attribute to Role") .contains("Advanced Attribute to Role")
.click(); .click();
cy.findByTestId("attributes-add-row").click();
cy.get(this.#attributesKeyInput).clear(); cy.get(this.#attributesKeyInput).clear();
cy.get(this.#attributesKeyInput).type("key"); cy.get(this.#attributesKeyInput).type("key");
@ -394,6 +395,7 @@ export default class AddMapperPage {
cy.findByTestId(this.#idpMapperSelect).contains("Claim to Role").click(); cy.findByTestId(this.#idpMapperSelect).contains("Claim to Role").click();
cy.findByTestId("claims-add-row").click();
const keyValue = new LegacyKeyValueInput("config.claims"); const keyValue = new LegacyKeyValueInput("config.claims");
keyValue.fillKeyValue({ key: "key", value: "value" }); keyValue.fillKeyValue({ key: "key", value: "value" });

View file

@ -945,7 +945,7 @@ homeURL=Home URL
eventTypes.REVOKE_GRANT_ERROR.name=Revoke grant error eventTypes.REVOKE_GRANT_ERROR.name=Revoke grant error
contentSecurityPolicyReportOnly=Content-Security-Policy-Report-Only contentSecurityPolicyReportOnly=Content-Security-Policy-Report-Only
firstBrokerLoginFlowAlias=First login flow firstBrokerLoginFlowAlias=First login flow
missingAttributes=No attributes have been defined yet. Click the below button to add attributes, key and value are required for a key pair. missingAttributes=No {{name}} have been defined yet. Click the below button to add {{name}}, key and value are required for a key pair.
testConnectionError=Error\! {{error}} testConnectionError=Error\! {{error}}
authenticatedAccessPoliciesHelp=Those Policies are used when Client Registration Service is invoked by authenticated request. This means that the request contains Initial Access Token or Bearer Token. authenticatedAccessPoliciesHelp=Those Policies are used when Client Registration Service is invoked by authenticated request. This means that the request contains Initial Access Token or Bearer Token.
deleteClientPolicyProfileSuccess=Profile successfully removed from the policy. deleteClientPolicyProfileSuccess=Profile successfully removed from the policy.

View file

@ -2,6 +2,8 @@ import {
ActionList, ActionList,
ActionListItem, ActionListItem,
Button, Button,
EmptyState,
EmptyStateBody,
Flex, Flex,
FlexItem, FlexItem,
FormGroup, FormGroup,
@ -27,6 +29,7 @@ export const MapComponent = ({
label, label,
helpText, helpText,
required, required,
isDisabled,
}: ComponentProps) => { }: ComponentProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -37,15 +40,20 @@ export const MapComponent = ({
useEffect(() => { useEffect(() => {
register(fieldName); register(fieldName);
const values: KeyValueType[] = JSON.parse(getValues(fieldName) || "[]"); const values: KeyValueType[] = JSON.parse(getValues(fieldName) || "[]");
if (!values.length) {
values.push({ key: "", value: "" });
}
setMap(values.map((value) => ({ ...value, id: generateId() }))); setMap(values.map((value) => ({ ...value, id: generateId() })));
}, [register, getValues]); }, []);
const appendNew = () =>
setMap([...map, { key: "", value: "", id: generateId() }]);
const update = (val = map) => { const update = (val = map) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars setValue(
setValue(fieldName, JSON.stringify(val.map(({ id, ...entry }) => entry))); fieldName,
JSON.stringify(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
val.filter((e) => e.key !== "").map(({ id, ...entry }) => entry),
),
);
}; };
const updateKey = (index: number, key: string) => { const updateKey = (index: number, key: string) => {
@ -65,7 +73,7 @@ export const MapComponent = ({
update(value); update(value);
}; };
return ( return map.length !== 0 ? (
<FormGroup <FormGroup
label={t(label!)} label={t(label!)}
labelIcon={<HelpItem helpText={t(helpText!)} fieldLabelId={`${label}`} />} labelIcon={<HelpItem helpText={t(helpText!)} fieldLabelId={`${label}`} />}
@ -115,7 +123,7 @@ export const MapComponent = ({
<Button <Button
variant="link" variant="link"
title={t("removeAttribute")} title={t("removeAttribute")}
isDisabled={map.length === 1} isDisabled={isDisabled}
onClick={() => remove(index)} onClick={() => remove(index)}
data-testid={`${fieldName}.${index}.remove`} data-testid={`${fieldName}.${index}.remove`}
> >
@ -132,14 +140,30 @@ export const MapComponent = ({
className="pf-u-px-0 pf-u-mt-sm" className="pf-u-px-0 pf-u-mt-sm"
variant="link" variant="link"
icon={<PlusCircleIcon />} icon={<PlusCircleIcon />}
onClick={() => onClick={() => appendNew()}
setMap([...map, { key: "", value: "", id: generateId() }])
}
> >
{t("addAttribute")} {t("addAttribute")}
</Button> </Button>
</ActionListItem> </ActionListItem>
</ActionList> </ActionList>
</FormGroup> </FormGroup>
) : (
<EmptyState
data-testid={`${name}-empty-state`}
className="pf-u-p-0"
variant="xs"
>
<EmptyStateBody>{t("missingAttributes", { name })}</EmptyStateBody>
<Button
data-testid={`${name}-add-row`}
variant="link"
icon={<PlusCircleIcon />}
isSmall
onClick={appendNew}
isDisabled={isDisabled}
>
{t("addAttribute")}
</Button>
</EmptyState>
); );
}; };

View file

@ -165,7 +165,9 @@ export const KeyValueInput = ({
className="pf-u-p-0" className="pf-u-p-0"
variant="xs" variant="xs"
> >
<EmptyStateBody>{t("missingAttributes")}</EmptyStateBody> <EmptyStateBody>
{t("missingAttributes", { name: "attributes" })}
</EmptyStateBody>
<Button <Button
data-testid={`${name}-add-row`} data-testid={`${name}-add-row`}
variant="link" variant="link"