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 { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { SaveReset } from "../advanced/SaveReset";
|
||||
import { ImportDialog } from "./ImportDialog";
|
||||
import useToggle from "../../utils/useToggle";
|
||||
|
||||
const POLICY_ENFORCEMENT_MODES = [
|
||||
"ENFORCING",
|
||||
|
@ -27,6 +29,8 @@ const DECISION_STRATEGY = ["UNANIMOUS", "AFFIRMATIVE"] as const;
|
|||
export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
||||
const { t } = useTranslation("clients");
|
||||
const [resource, setResource] = useState<ResourceServerRepresentation>();
|
||||
const [importDialog, toggleImportDialog] = useToggle();
|
||||
|
||||
const { control, reset } = useForm<ResourceServerRepresentation>({
|
||||
shouldUnregister: false,
|
||||
});
|
||||
|
@ -42,12 +46,22 @@ export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
|||
[]
|
||||
);
|
||||
|
||||
const importResource = () => {
|
||||
//different PR
|
||||
};
|
||||
|
||||
if (!resource) {
|
||||
return <KeycloakSpinner />;
|
||||
}
|
||||
|
||||
return (
|
||||
<PageSection variant="light">
|
||||
{importDialog && (
|
||||
<ImportDialog
|
||||
onConfirm={importResource}
|
||||
closeDialog={toggleImportDialog}
|
||||
/>
|
||||
)}
|
||||
<FormAccess role="manage-clients" isHorizontal>
|
||||
<FormGroup
|
||||
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>
|
||||
<Divider />
|
||||
<FormGroup
|
||||
|
|
|
@ -61,6 +61,9 @@ export default {
|
|||
UNANIMOUS: "Unanimous",
|
||||
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",
|
||||
createResourceBasedPermission: "Create resource-based permission",
|
||||
displayName: "Display name",
|
||||
|
@ -79,6 +82,7 @@ export default {
|
|||
owner: "Owner",
|
||||
uris: "URIs",
|
||||
scopes: "Scopes",
|
||||
policies: "Policies",
|
||||
createPermission: "Create permission",
|
||||
deleteResource: "Permanently delete resource?",
|
||||
deleteResourceConfirm:
|
||||
|
|
|
@ -141,15 +141,18 @@ export const FileUploadForm = ({
|
|||
isLoading={fileUpload.isLoading}
|
||||
hideDefaultPreview
|
||||
>
|
||||
{!rest.hideDefaultPreview && (
|
||||
<CodeEditor
|
||||
isLineNumbersVisible
|
||||
code={fileUpload.value}
|
||||
language={language}
|
||||
height="128px"
|
||||
onChange={(value, event) =>
|
||||
handleChange(value, fileUpload.filename, event as any)
|
||||
handleChange(value || "", fileUpload.filename, event as any)
|
||||
}
|
||||
isReadOnly={!rest.allowEditingUploadedText}
|
||||
/>
|
||||
)}
|
||||
</FileUpload>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
|
|
@ -318,6 +318,7 @@ export const PartialImportDialog = (props: PartialImportProps) => {
|
|||
<StackItem>
|
||||
<JsonFileUpload
|
||||
id="partial-import-file"
|
||||
allowEditingUploadedText
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
</StackItem>
|
||||
|
|
Loading…
Reference in a new issue