added import dialog for authorization resources (#1604)
This commit is contained in:
parent
de1d677cc1
commit
bc8ffed934
5 changed files with 190 additions and 10 deletions
156
src/clients/authorization/ImportDialog.tsx
Normal file
156
src/clients/authorization/ImportDialog.tsx
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
import React, { Fragment, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
ButtonVariant,
|
||||||
|
Divider,
|
||||||
|
Form,
|
||||||
|
FormGroup,
|
||||||
|
Modal,
|
||||||
|
Radio,
|
||||||
|
Switch,
|
||||||
|
} from "@patternfly/react-core";
|
||||||
|
|
||||||
|
import type ResourceServerRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceServerRepresentation";
|
||||||
|
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
||||||
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||||
|
|
||||||
|
type ImportDialogProps = {
|
||||||
|
onConfirm: (value: ResourceServerRepresentation) => void;
|
||||||
|
closeDialog: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ImportDialog = ({ onConfirm, closeDialog }: ImportDialogProps) => {
|
||||||
|
const { t } = useTranslation("clients");
|
||||||
|
const [imported, setImported] = useState<ResourceServerRepresentation>({});
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={t("import")}
|
||||||
|
isOpen
|
||||||
|
variant="small"
|
||||||
|
onClose={closeDialog}
|
||||||
|
actions={[
|
||||||
|
<Button
|
||||||
|
id="modal-confirm"
|
||||||
|
key="confirm"
|
||||||
|
onClick={() => {
|
||||||
|
onConfirm(imported);
|
||||||
|
closeDialog();
|
||||||
|
}}
|
||||||
|
data-testid="confirm"
|
||||||
|
>
|
||||||
|
{t("confirm")}
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
data-testid="cancel"
|
||||||
|
id="modal-cancel"
|
||||||
|
key="cancel"
|
||||||
|
variant={ButtonVariant.link}
|
||||||
|
onClick={() => {
|
||||||
|
closeDialog();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("common:cancel")}
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Form>
|
||||||
|
<JsonFileUpload id="import-resource" onChange={setImported} />
|
||||||
|
</Form>
|
||||||
|
{Object.keys(imported).length !== 0 && (
|
||||||
|
<>
|
||||||
|
<Divider />
|
||||||
|
<p className="pf-u-my-lg">{t("importResources")}</p>
|
||||||
|
<Form isHorizontal>
|
||||||
|
<FormGroup
|
||||||
|
label={t("policyEnforcementMode")}
|
||||||
|
labelIcon={
|
||||||
|
<HelpItem
|
||||||
|
helpText="clients-help:policyEnforcementMode"
|
||||||
|
forLabel={t("policyEnforcementMode")}
|
||||||
|
forID="policyEnforcementMode"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
fieldId="policyEnforcementMode"
|
||||||
|
hasNoPaddingTop
|
||||||
|
>
|
||||||
|
<Radio
|
||||||
|
id="policyEnforcementMode"
|
||||||
|
name="policyEnforcementMode"
|
||||||
|
label={t(
|
||||||
|
`policyEnforcementModes.${imported.policyEnforcementMode}`
|
||||||
|
)}
|
||||||
|
isChecked
|
||||||
|
isDisabled
|
||||||
|
className="pf-u-mb-md"
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup
|
||||||
|
label={t("decisionStrategy")}
|
||||||
|
labelIcon={
|
||||||
|
<HelpItem
|
||||||
|
helpText="clients-help:decisionStrategy"
|
||||||
|
forLabel={t("decisionStrategy")}
|
||||||
|
forID="decisionStrategy"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
fieldId="decisionStrategy"
|
||||||
|
hasNoPaddingTop
|
||||||
|
>
|
||||||
|
<Radio
|
||||||
|
id="decisionStrategy"
|
||||||
|
name="decisionStrategy"
|
||||||
|
isChecked
|
||||||
|
isDisabled
|
||||||
|
label={t(`decisionStrategies.${imported.decisionStrategy}`)}
|
||||||
|
className="pf-u-mb-md"
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup
|
||||||
|
hasNoPaddingTop
|
||||||
|
label={t("allowRemoteResourceManagement")}
|
||||||
|
fieldId="allowRemoteResourceManagement"
|
||||||
|
labelIcon={
|
||||||
|
<HelpItem
|
||||||
|
helpText={t("allowRemoteResourceManagement")}
|
||||||
|
forLabel={t("allowRemoteResourceManagement")}
|
||||||
|
forID={"allowRemoteResourceManagement"}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
id="allowRemoteResourceManagement"
|
||||||
|
label={t("common:on")}
|
||||||
|
labelOff={t("common:off")}
|
||||||
|
isChecked={imported.allowRemoteResourceManagement}
|
||||||
|
isDisabled
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
</Form>
|
||||||
|
<div className="pf-u-mt-md">
|
||||||
|
{Object.entries(imported)
|
||||||
|
.filter(([, value]) => Array.isArray(value))
|
||||||
|
.map(([key, value]) => (
|
||||||
|
<Fragment key={key}>
|
||||||
|
<Divider />
|
||||||
|
<p className="pf-u-my-sm">
|
||||||
|
<strong>
|
||||||
|
{value.length} {t(key)}
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<Divider />
|
||||||
|
<Alert
|
||||||
|
variant="warning"
|
||||||
|
className="pf-u-mt-lg"
|
||||||
|
isInline
|
||||||
|
title={t("importWarning")}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
|
@ -16,6 +16,8 @@ import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||||
import { SaveReset } from "../advanced/SaveReset";
|
import { SaveReset } from "../advanced/SaveReset";
|
||||||
|
import { ImportDialog } from "./ImportDialog";
|
||||||
|
import useToggle from "../../utils/useToggle";
|
||||||
|
|
||||||
const POLICY_ENFORCEMENT_MODES = [
|
const POLICY_ENFORCEMENT_MODES = [
|
||||||
"ENFORCING",
|
"ENFORCING",
|
||||||
|
@ -27,6 +29,8 @@ const DECISION_STRATEGY = ["UNANIMOUS", "AFFIRMATIVE"] as const;
|
||||||
export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
const [resource, setResource] = useState<ResourceServerRepresentation>();
|
const [resource, setResource] = useState<ResourceServerRepresentation>();
|
||||||
|
const [importDialog, toggleImportDialog] = useToggle();
|
||||||
|
|
||||||
const { control, reset } = useForm<ResourceServerRepresentation>({
|
const { control, reset } = useForm<ResourceServerRepresentation>({
|
||||||
shouldUnregister: false,
|
shouldUnregister: false,
|
||||||
});
|
});
|
||||||
|
@ -42,12 +46,22 @@ export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const importResource = () => {
|
||||||
|
//different PR
|
||||||
|
};
|
||||||
|
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
return <KeycloakSpinner />;
|
return <KeycloakSpinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
|
{importDialog && (
|
||||||
|
<ImportDialog
|
||||||
|
onConfirm={importResource}
|
||||||
|
closeDialog={toggleImportDialog}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<FormAccess role="manage-clients" isHorizontal>
|
<FormAccess role="manage-clients" isHorizontal>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("import")}
|
label={t("import")}
|
||||||
|
@ -60,7 +74,9 @@ export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Button variant="secondary">{t("import")}</Button>
|
<Button variant="secondary" onClick={toggleImportDialog}>
|
||||||
|
{t("import")}
|
||||||
|
</Button>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<Divider />
|
<Divider />
|
||||||
<FormGroup
|
<FormGroup
|
||||||
|
|
|
@ -61,6 +61,9 @@ export default {
|
||||||
UNANIMOUS: "Unanimous",
|
UNANIMOUS: "Unanimous",
|
||||||
AFFIRMATIVE: "Affirmative",
|
AFFIRMATIVE: "Affirmative",
|
||||||
},
|
},
|
||||||
|
importResources: "The following settings and data will be imported:",
|
||||||
|
importWarning:
|
||||||
|
"The data and settings imported above may overwrite the data and settings that already exist.",
|
||||||
createResource: "Create resource",
|
createResource: "Create resource",
|
||||||
createResourceBasedPermission: "Create resource-based permission",
|
createResourceBasedPermission: "Create resource-based permission",
|
||||||
displayName: "Display name",
|
displayName: "Display name",
|
||||||
|
@ -79,6 +82,7 @@ export default {
|
||||||
owner: "Owner",
|
owner: "Owner",
|
||||||
uris: "URIs",
|
uris: "URIs",
|
||||||
scopes: "Scopes",
|
scopes: "Scopes",
|
||||||
|
policies: "Policies",
|
||||||
createPermission: "Create permission",
|
createPermission: "Create permission",
|
||||||
deleteResource: "Permanently delete resource?",
|
deleteResource: "Permanently delete resource?",
|
||||||
deleteResourceConfirm:
|
deleteResourceConfirm:
|
||||||
|
|
|
@ -141,15 +141,18 @@ export const FileUploadForm = ({
|
||||||
isLoading={fileUpload.isLoading}
|
isLoading={fileUpload.isLoading}
|
||||||
hideDefaultPreview
|
hideDefaultPreview
|
||||||
>
|
>
|
||||||
|
{!rest.hideDefaultPreview && (
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
isLineNumbersVisible
|
isLineNumbersVisible
|
||||||
code={fileUpload.value}
|
code={fileUpload.value}
|
||||||
language={language}
|
language={language}
|
||||||
height="128px"
|
height="128px"
|
||||||
onChange={(value, event) =>
|
onChange={(value, event) =>
|
||||||
handleChange(value, fileUpload.filename, event as any)
|
handleChange(value || "", fileUpload.filename, event as any)
|
||||||
}
|
}
|
||||||
|
isReadOnly={!rest.allowEditingUploadedText}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</FileUpload>
|
</FileUpload>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -318,6 +318,7 @@ export const PartialImportDialog = (props: PartialImportProps) => {
|
||||||
<StackItem>
|
<StackItem>
|
||||||
<JsonFileUpload
|
<JsonFileUpload
|
||||||
id="partial-import-file"
|
id="partial-import-file"
|
||||||
|
allowEditingUploadedText
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
/>
|
/>
|
||||||
</StackItem>
|
</StackItem>
|
||||||
|
|
Loading…
Reference in a new issue