mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
replaced code editor with code mirror (#35342)
* replaced code editor with code mirror fixes: #32901 Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fixed tests 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:
parent
2e85dc5177
commit
944512b32f
@ -119,13 +119,12 @@ describe("Partial import test", () => {
|
||||
|
||||
//clear button should be disabled if there is nothing in the dialog
|
||||
modal.clearButton().should("be.disabled");
|
||||
modal.textArea().get(".view-lines").should("have.text", "");
|
||||
modal.textArea().get(".view-lines").click();
|
||||
modal.textArea().should("have.text", "");
|
||||
modal.textArea().type("{}", { force: true });
|
||||
modal.textArea().get(".view-lines").should("have.text", "{}");
|
||||
modal.textArea().should("have.text", "{}");
|
||||
modal.clearButton().should("not.be.disabled");
|
||||
modal.clearButton().click();
|
||||
modal.clickClearConfirmButton();
|
||||
modal.textArea().get(".view-lines").should("have.text", "");
|
||||
modal.textArea().should("have.text", "");
|
||||
});
|
||||
});
|
||||
|
||||
@ -6,7 +6,7 @@ export default class CreateRealmPage {
|
||||
#enabledSwitch = ".pf-v5-c-toolbar .pf-v5-c-switch__toggle";
|
||||
#createBtn = '.pf-v5-c-form__group:last-child button[type="submit"]';
|
||||
#cancelBtn = '.pf-v5-c-form__group:last-child button[type="button"]';
|
||||
#codeEditor = ".pf-v5-c-code-editor__code";
|
||||
#codeEditor = ".w-tc-editor-text";
|
||||
|
||||
#getClearBtn() {
|
||||
return cy.findByText("Clear");
|
||||
@ -19,8 +19,6 @@ export default class CreateRealmPage {
|
||||
}
|
||||
|
||||
fillCodeEditor() {
|
||||
cy.get(".view-lines");
|
||||
cy.get(this.#codeEditor).click();
|
||||
cy.get(this.#codeEditor).type("clear this field");
|
||||
|
||||
return this;
|
||||
|
||||
@ -14,7 +14,7 @@ export default class GroupModal {
|
||||
};
|
||||
|
||||
textArea() {
|
||||
return cy.get(".pf-v5-c-code-editor__code textarea");
|
||||
return cy.get(".w-tc-editor-text");
|
||||
}
|
||||
|
||||
importButton() {
|
||||
|
||||
@ -190,7 +190,7 @@ export default class RealmSettingsPage extends CommonPage {
|
||||
#jsonEditorSaveBtn = "jsonEditor-saveBtn";
|
||||
#jsonEditorSavePoliciesBtn = "jsonEditor-policies-saveBtn";
|
||||
#jsonEditorReloadBtn = "jsonEditor-reloadBtn";
|
||||
#jsonEditor = ".monaco-scrollable-element.editor-scrollable.vs";
|
||||
#jsonEditor = ".w-tc-editor-text";
|
||||
#clientPolicyDrpDwn = '[data-testid="action-dropdown"]';
|
||||
#deleteclientPolicyDrpDwn = "deleteClientPolicyDropdown";
|
||||
#clientProfileOne =
|
||||
|
||||
@ -200,7 +200,7 @@ export default class UserProfile {
|
||||
}
|
||||
|
||||
#textArea() {
|
||||
return cy.get(".pf-v5-c-code-editor__code textarea");
|
||||
return cy.get(".w-tc-editor-text");
|
||||
}
|
||||
|
||||
#getText() {
|
||||
|
||||
@ -91,11 +91,11 @@
|
||||
"@keycloak/keycloak-admin-client": "workspace:*",
|
||||
"@keycloak/keycloak-ui-shared": "workspace:*",
|
||||
"@patternfly/patternfly": "^5.4.2",
|
||||
"@patternfly/react-code-editor": "^5.4.13",
|
||||
"@patternfly/react-core": "^5.4.10",
|
||||
"@patternfly/react-icons": "^5.4.2",
|
||||
"@patternfly/react-styles": "^5.4.1",
|
||||
"@patternfly/react-table": "^5.4.11",
|
||||
"@uiw/react-textarea-code-editor": "^3.1.0",
|
||||
"admin-ui": "file:",
|
||||
"dagre": "^0.8.5",
|
||||
"file-saver": "^2.0.5",
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const JavaScript = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -26,11 +25,10 @@ export const JavaScript = () => {
|
||||
<CodeEditor
|
||||
id="code"
|
||||
data-testid="code"
|
||||
onChange={field.onChange}
|
||||
code={field.value}
|
||||
height="600px"
|
||||
language={Language.javascript}
|
||||
isReadOnly={true}
|
||||
readOnly
|
||||
value={field.value}
|
||||
style={{ height: "600px", overflow: "scroll" }}
|
||||
language="js"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { fetchWithError } from "@keycloak/keycloak-admin-client";
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
import { Language } from "@patternfly/react-code-editor";
|
||||
import {
|
||||
ActionGroup,
|
||||
AlertVariant,
|
||||
@ -110,7 +109,7 @@ export default function ImportForm() {
|
||||
<FormProvider {...form}>
|
||||
<FileUploadForm
|
||||
id="realm-file"
|
||||
language={Language.json}
|
||||
language="json"
|
||||
extension=".json,.xml"
|
||||
helpText={t("helpFileUploadClient")}
|
||||
onChange={handleFileChange}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
@ -38,12 +37,11 @@ export const ScriptComponent = ({
|
||||
<CodeEditor
|
||||
id={name!}
|
||||
data-testid={name}
|
||||
isReadOnly={isDisabled}
|
||||
type="text"
|
||||
readOnly={isDisabled}
|
||||
onChange={field.onChange}
|
||||
code={Array.isArray(field.value) ? field.value[0] : field.value}
|
||||
height="600px"
|
||||
language={Language.javascript}
|
||||
value={Array.isArray(field.value) ? field.value[0] : field.value}
|
||||
style={{ height: "600px", overflow: "scroll" }}
|
||||
language="js"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import {
|
||||
Button,
|
||||
DropEvent,
|
||||
@ -11,6 +10,7 @@ import {
|
||||
Modal,
|
||||
ModalVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import {
|
||||
ChangeEvent,
|
||||
DragEvent as ReactDragEvent,
|
||||
@ -37,7 +37,7 @@ export type FileUploadFormProps = Omit<FileUploadProps, "onChange"> & {
|
||||
onChange: (value: string) => void;
|
||||
helpText?: string;
|
||||
unWrap?: boolean;
|
||||
language?: Language;
|
||||
language?: string;
|
||||
};
|
||||
|
||||
export const FileUploadForm = ({
|
||||
@ -129,7 +129,7 @@ export const FileUploadForm = ({
|
||||
/>
|
||||
)}
|
||||
{!unWrap && (
|
||||
<FormGroup label={t("resourceFile")} fieldId={id}>
|
||||
<FormGroup label={t("resourceFile")} fieldId={id + "-filename"}>
|
||||
<FileUpload
|
||||
data-testid={id}
|
||||
id={id}
|
||||
@ -152,12 +152,12 @@ export const FileUploadForm = ({
|
||||
>
|
||||
{!rest.hideDefaultPreview && (
|
||||
<CodeEditor
|
||||
isLineNumbersVisible
|
||||
code={fileUpload.value}
|
||||
aria-label="File content"
|
||||
value={fileUpload.value}
|
||||
language={language}
|
||||
height="128px"
|
||||
onChange={handleTextOrDataChange}
|
||||
isReadOnly={!rest.allowEditingUploadedText}
|
||||
style={{ height: "128px", overflow: "scroll" }}
|
||||
onChange={(value) => handleTextOrDataChange(value.target.value)}
|
||||
readOnly={!rest.allowEditingUploadedText}
|
||||
/>
|
||||
)}
|
||||
</FileUpload>
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import { Language } from "@patternfly/react-code-editor";
|
||||
|
||||
import { FileUploadForm, FileUploadFormProps } from "./FileUploadForm";
|
||||
|
||||
export type JsonFileUploadProps = Omit<
|
||||
@ -22,7 +20,7 @@ export const JsonFileUpload = ({ onChange, ...props }: JsonFileUploadProps) => {
|
||||
return (
|
||||
<FileUploadForm
|
||||
{...props}
|
||||
language={Language.json}
|
||||
language="json"
|
||||
extension=".json"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import type AdminEventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/adminEventRepresentation";
|
||||
import {
|
||||
Action,
|
||||
KeycloakDataTable,
|
||||
KeycloakSelect,
|
||||
ListEmptyState,
|
||||
SelectVariant,
|
||||
TextControl,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import {
|
||||
ActionGroup,
|
||||
Button,
|
||||
@ -33,14 +35,13 @@ import {
|
||||
Tr,
|
||||
cellWidth,
|
||||
} from "@patternfly/react-table";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import { pickBy } from "lodash-es";
|
||||
import { PropsWithChildren, useMemo, useState } from "react";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import DropdownPanel from "../components/dropdown-panel/DropdownPanel";
|
||||
import { ListEmptyState } from "@keycloak/keycloak-ui-shared";
|
||||
import { Action, KeycloakDataTable } from "@keycloak/keycloak-ui-shared";
|
||||
import { useRealm } from "../context/realm-context/RealmContext";
|
||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||
import { prettyPrintJSON } from "../util";
|
||||
@ -263,11 +264,10 @@ export const AdminEvents = () => {
|
||||
onClose={() => setRepresentationEvent(undefined)}
|
||||
>
|
||||
<CodeEditor
|
||||
isLineNumbersVisible
|
||||
isReadOnly
|
||||
code={code}
|
||||
language={Language.json}
|
||||
height="8rem"
|
||||
readOnly
|
||||
value={code}
|
||||
language="json"
|
||||
style={{ height: "8rem", overflow: "scroll" }}
|
||||
/>
|
||||
</DisplayDialog>
|
||||
)}
|
||||
|
||||
@ -33,4 +33,8 @@ input[type="checkbox"] {
|
||||
|
||||
#app {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.w-tc-editor {
|
||||
font-family: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace';
|
||||
}
|
||||
@ -5,7 +5,7 @@ import {
|
||||
useAlerts,
|
||||
useFetch,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import {
|
||||
AlertVariant,
|
||||
Button,
|
||||
@ -289,13 +289,10 @@ export const PoliciesTab = () => {
|
||||
<>
|
||||
<div className="pf-v5-u-mt-md pf-v5-u-ml-lg">
|
||||
<CodeEditor
|
||||
isLineNumbersVisible
|
||||
isLanguageLabelVisible
|
||||
isReadOnly={false}
|
||||
code={code}
|
||||
language={Language.json}
|
||||
height="30rem"
|
||||
onChange={setCode}
|
||||
value={code}
|
||||
language="json"
|
||||
style={{ height: "30rem", overflow: "scroll" }}
|
||||
onChange={(event) => setCode(event.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="pf-v5-u-mt-md">
|
||||
|
||||
@ -5,7 +5,7 @@ import {
|
||||
useAlerts,
|
||||
useFetch,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import {
|
||||
ActionGroup,
|
||||
AlertVariant,
|
||||
@ -252,15 +252,10 @@ export default function ProfilesTab() {
|
||||
<FormGroup fieldId={"jsonEditor"}>
|
||||
<div className="pf-v5-u-mt-md pf-v5-u-ml-lg">
|
||||
<CodeEditor
|
||||
isLineNumbersVisible
|
||||
isLanguageLabelVisible
|
||||
isReadOnly={false}
|
||||
code={code}
|
||||
language={Language.json}
|
||||
height="30rem"
|
||||
onChange={(value) => {
|
||||
setCode(value ?? "");
|
||||
}}
|
||||
value={code}
|
||||
language="json"
|
||||
style={{ height: "30rem", overflow: "scroll" }}
|
||||
onChange={(event) => setCode(event.target.value ?? "")}
|
||||
/>
|
||||
</div>
|
||||
<ActionGroup>
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import { ActionGroup, Button, Form, PageSection } from "@patternfly/react-core";
|
||||
import type { editor } from "monaco-editor";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { ActionGroup, Button, Form, PageSection } from "@patternfly/react-core";
|
||||
import CodeEditor from "@uiw/react-textarea-code-editor";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { prettyPrintJSON } from "../../util";
|
||||
import { useUserProfile } from "./UserProfileContext";
|
||||
|
||||
@ -11,16 +10,14 @@ export const JsonEditorTab = () => {
|
||||
const { config, save, isSaving } = useUserProfile();
|
||||
const { t } = useTranslation();
|
||||
const { addError } = useAlerts();
|
||||
const [editor, setEditor] = useState<editor.IStandaloneCodeEditor>();
|
||||
|
||||
useEffect(() => resetCode(), [config, editor]);
|
||||
const [code, setCode] = useState(prettyPrintJSON(config));
|
||||
|
||||
function resetCode() {
|
||||
editor?.setValue(config ? prettyPrintJSON(config) : "");
|
||||
setCode(config ? prettyPrintJSON(config) : "");
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
const value = editor?.getValue();
|
||||
const value = code;
|
||||
|
||||
if (!value) {
|
||||
return;
|
||||
@ -37,10 +34,10 @@ export const JsonEditorTab = () => {
|
||||
return (
|
||||
<PageSection variant="light">
|
||||
<CodeEditor
|
||||
language={Language.json}
|
||||
height="30rem"
|
||||
onEditorDidMount={(editor) => setEditor(editor)}
|
||||
isLanguageLabelVisible
|
||||
language="json"
|
||||
value={code}
|
||||
style={{ height: "30rem", overflow: "scroll" }}
|
||||
onChange={(event) => setCode(event.target.value ?? "")}
|
||||
/>
|
||||
<Form>
|
||||
<ActionGroup>
|
||||
|
||||
552
js/pnpm-lock.yaml
generated
552
js/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user