pull in master branch
This commit is contained in:
commit
8a513e3ecf
62 changed files with 10184 additions and 8077 deletions
|
@ -1,38 +1,38 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended"
|
||||
],
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"react",
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
}
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended"
|
||||
],
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"react",
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ module.exports = function (grunt) {
|
|||
copy: {
|
||||
main: {
|
||||
cwd: "./node_modules/@patternfly/patternfly/assets/",
|
||||
src: "**/*",
|
||||
src: ["**/*", '!**/fontawesome/**'],
|
||||
dest: "public/assets/",
|
||||
expand: true,
|
||||
},
|
||||
|
|
14
package.json
14
package.json
|
@ -16,10 +16,10 @@
|
|||
"build-storybook": "build-storybook -s public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@patternfly/patternfly": "^4.31.6",
|
||||
"@patternfly/react-core": "^4.40.4",
|
||||
"@patternfly/react-icons": "^4.7.2",
|
||||
"@patternfly/react-table": "^4.15.5",
|
||||
"@patternfly/patternfly": "^4.42.2",
|
||||
"@patternfly/react-core": "4.50.2",
|
||||
"@patternfly/react-icons": "4.7.6",
|
||||
"@patternfly/react-table": "4.16.20",
|
||||
"file-saver": "^2.0.2",
|
||||
"i18next": "^19.6.2",
|
||||
"keycloak-js": "^11.0.0",
|
||||
|
@ -33,8 +33,8 @@
|
|||
"@babel/core": "^7.10.5",
|
||||
"@babel/preset-typescript": "^7.10.4",
|
||||
"@snowpack/app-scripts-react": "^1.10.0",
|
||||
"@snowpack/plugin-postcss": "^1.0.2",
|
||||
"@snowpack/plugin-webpack": "^2.0.6",
|
||||
"@snowpack/plugin-postcss": "1.0.4",
|
||||
"@snowpack/plugin-webpack": "2.0.12",
|
||||
"@storybook/addon-actions": "^6.0.21",
|
||||
"@storybook/addon-essentials": "^6.0.21",
|
||||
"@storybook/addon-info": "^5.3.21",
|
||||
|
@ -73,7 +73,7 @@
|
|||
"prettier": "^2.0.5",
|
||||
"react-is": "^16.13.1",
|
||||
"react-scripts": "^3.4.1",
|
||||
"snowpack": "^2.10.0",
|
||||
"snowpack": "2.11.1",
|
||||
"typescript": "^3.8.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
{
|
||||
"clientId": "security-admin-console-v2",
|
||||
"rootUrl": "http://localhost:8080/",
|
||||
"adminUrl": "http://localhost:8080/",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"redirectUris": [
|
||||
"http://localhost:8080/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"http://localhost:8080"
|
||||
],
|
||||
"notBefore": 0,
|
||||
"bearerOnly": false,
|
||||
"consentRequired": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"serviceAccountsEnabled": false,
|
||||
"publicClient": true,
|
||||
"frontchannelLogout": false,
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {},
|
||||
"authenticationFlowBindingOverrides": {},
|
||||
"fullScopeAllowed": true,
|
||||
"nodeReRegistrationTimeout": -1,
|
||||
"defaultClientScopes": [
|
||||
"web-origins",
|
||||
"role_list",
|
||||
"roles",
|
||||
"profile",
|
||||
"email"
|
||||
],
|
||||
"optionalClientScopes": [
|
||||
"address",
|
||||
"phone",
|
||||
"offline_access",
|
||||
"microprofile-jwt"
|
||||
],
|
||||
"access": {
|
||||
"view": true,
|
||||
"configure": true,
|
||||
"manage": true
|
||||
}
|
||||
"clientId": "security-admin-console-v2",
|
||||
"rootUrl": "http://localhost:8080/",
|
||||
"adminUrl": "http://localhost:8080/",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"redirectUris": [
|
||||
"http://localhost:8080/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"http://localhost:8080"
|
||||
],
|
||||
"notBefore": 0,
|
||||
"bearerOnly": false,
|
||||
"consentRequired": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"serviceAccountsEnabled": false,
|
||||
"publicClient": true,
|
||||
"frontchannelLogout": false,
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {},
|
||||
"authenticationFlowBindingOverrides": {},
|
||||
"fullScopeAllowed": true,
|
||||
"nodeReRegistrationTimeout": -1,
|
||||
"defaultClientScopes": [
|
||||
"web-origins",
|
||||
"role_list",
|
||||
"roles",
|
||||
"profile",
|
||||
"email"
|
||||
],
|
||||
"optionalClientScopes": [
|
||||
"address",
|
||||
"phone",
|
||||
"offline_access",
|
||||
"microprofile-jwt"
|
||||
],
|
||||
"access": {
|
||||
"view": true,
|
||||
"configure": true,
|
||||
"manage": true
|
||||
}
|
||||
}
|
15
src/App.tsx
15
src/App.tsx
|
@ -1,12 +1,14 @@
|
|||
import React from "react";
|
||||
import { Page, PageSection } from "@patternfly/react-core";
|
||||
import { Page } from "@patternfly/react-core";
|
||||
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
|
||||
|
||||
import { Header } from "./PageHeader";
|
||||
import { PageNav } from "./PageNav";
|
||||
|
||||
import { Help } from "./components/help-enabler/HelpHeader";
|
||||
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
|
||||
import { NewRealmForm } from "./realm/add/NewRealmForm";
|
||||
import { NewClientForm } from "./clients/add/NewClientForm";
|
||||
import { NewClientScopeForm } from "./client-scopes/add/NewClientScopeForm";
|
||||
|
||||
import { ImportForm } from "./clients/import/ImportForm";
|
||||
import { ClientsSection } from "./clients/ClientsSection";
|
||||
import { ClientScopesSection } from "./client-scopes/ClientScopesSection";
|
||||
|
@ -36,7 +38,7 @@ export const App = () => {
|
|||
<Route exact path="/clients" component={ClientsSection}></Route>
|
||||
<Route
|
||||
exact
|
||||
path="/client-settings"
|
||||
path="/client-settings/:id"
|
||||
component={ClientSettings}
|
||||
></Route>
|
||||
<Route exact path="/add-client" component={NewClientForm}></Route>
|
||||
|
@ -47,6 +49,11 @@ export const App = () => {
|
|||
path="/client-scopes"
|
||||
component={ClientScopesSection}
|
||||
></Route>
|
||||
<Route
|
||||
exact
|
||||
path="/add-client-scopes"
|
||||
component={NewClientScopeForm}
|
||||
></Route>
|
||||
<Route
|
||||
exact
|
||||
path="/realm-roles"
|
||||
|
|
58
src/client-scopes/ClientScopesList.tsx
Normal file
58
src/client-scopes/ClientScopesList.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableVariant,
|
||||
} from "@patternfly/react-table";
|
||||
|
||||
import { ClientScopeRepresentation } from "./models/client-scope";
|
||||
|
||||
type ClientScopeListProps = {
|
||||
clientScopes: ClientScopeRepresentation[];
|
||||
};
|
||||
|
||||
export const ClientScopeList = ({ clientScopes }: ClientScopeListProps) => {
|
||||
const { t } = useTranslation("client-scopes");
|
||||
|
||||
const columns: (keyof ClientScopeRepresentation)[] = [
|
||||
"name",
|
||||
"description",
|
||||
"protocol",
|
||||
];
|
||||
|
||||
const data = clientScopes.map((c) => {
|
||||
return { cells: columns.map((col) => c[col]) };
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table
|
||||
variant={TableVariant.compact}
|
||||
cells={[
|
||||
{ title: t("name") },
|
||||
{ title: t("description") },
|
||||
{
|
||||
title: t("protocol"),
|
||||
},
|
||||
]}
|
||||
rows={data}
|
||||
actions={[
|
||||
{
|
||||
title: t("common:export"),
|
||||
onClick: () => {},
|
||||
},
|
||||
{
|
||||
title: t("common:delete"),
|
||||
onClick: () => {},
|
||||
},
|
||||
]}
|
||||
aria-label={t("clientScopeList")}
|
||||
>
|
||||
<TableHeader />
|
||||
<TableBody />
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -1,10 +1,53 @@
|
|||
import { PageSection } from "@patternfly/react-core";
|
||||
import React from "react";
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Button, PageSection } from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
import { RealmContext } from "../components/realm-context/RealmContext";
|
||||
import { HttpClientContext } from "../http-service/HttpClientContext";
|
||||
import { ClientRepresentation } from "../realm/models/Realm";
|
||||
import { DataLoader } from "../components/data-loader/DataLoader";
|
||||
import { TableToolbar } from "../components/table-toolbar/TableToolbar";
|
||||
import { ClientScopeList } from "./ClientScopesList";
|
||||
|
||||
export const ClientScopesSection = () => {
|
||||
const { t } = useTranslation("client-scopes");
|
||||
const history = useHistory();
|
||||
|
||||
const [max, setMax] = useState(10);
|
||||
const [first, setFirst] = useState(0);
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const { realm } = useContext(RealmContext);
|
||||
|
||||
const loader = async () => {
|
||||
return await httpClient
|
||||
.doGet(`/admin/realms/${realm}/client-scopes`, { params: { first, max } })
|
||||
.then((r) => r.data as ClientRepresentation[]);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<PageSection variant="light">The Client Scopes Page</PageSection>
|
||||
</>
|
||||
<PageSection variant="light">
|
||||
<DataLoader loader={loader}>
|
||||
{(scopes) => (
|
||||
<TableToolbar
|
||||
count={scopes!.length}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
onPreviousClick={setFirst}
|
||||
onPerPageSelect={(first, max) => {
|
||||
setFirst(first);
|
||||
setMax(max);
|
||||
}}
|
||||
toolbarItem={
|
||||
<Button onClick={() => history.push("/add-client-scopes")}>
|
||||
{t("createClientScope")}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<ClientScopeList clientScopes={scopes} />
|
||||
</TableToolbar>
|
||||
)}
|
||||
</DataLoader>
|
||||
</PageSection>
|
||||
);
|
||||
};
|
||||
|
|
485
src/client-scopes/__tests__/mock-client-scopes.json
Normal file
485
src/client-scopes/__tests__/mock-client-scopes.json
Normal file
|
@ -0,0 +1,485 @@
|
|||
[
|
||||
{
|
||||
"id": "3507ed12-d8b0-455c-b91a-62a6765ecf0f",
|
||||
"name": "address",
|
||||
"description": "OpenID Connect built-in scope: address",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "true",
|
||||
"display.on.consent.screen": "true",
|
||||
"consent.screen.text": "${addressScopeConsentText}"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "b0582082-abab-4c63-b3b7-a92afe6b3436",
|
||||
"name": "address",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-address-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"user.attribute.formatted": "formatted",
|
||||
"user.attribute.country": "country",
|
||||
"user.attribute.postal_code": "postal_code",
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute.street": "street",
|
||||
"id.token.claim": "true",
|
||||
"user.attribute.region": "region",
|
||||
"access.token.claim": "true",
|
||||
"user.attribute.locality": "locality"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "eb8c7985-5459-45a9-ace5-2959ce0fd1c9",
|
||||
"name": "email",
|
||||
"description": "OpenID Connect built-in scope: email",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "true",
|
||||
"display.on.consent.screen": "true",
|
||||
"consent.screen.text": "${emailScopeConsentText}"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "348dfe5c-26e6-43e8-bc80-b7db9f842f24",
|
||||
"name": "email",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "email",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "email",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "bfe77908-4ca3-40ea-b5be-75bea87f5bb1",
|
||||
"name": "email verified",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "emailVerified",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "email_verified",
|
||||
"jsonType.label": "boolean"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "e604d76d-20ec-4d80-acee-1885af201568",
|
||||
"name": "microprofile-jwt",
|
||||
"description": "Microprofile - JWT built-in scope",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "true",
|
||||
"display.on.consent.screen": "false"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "63a71cf3-df7c-4a81-a23f-d3ba62801c72",
|
||||
"name": "upn",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "username",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "upn",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "5eb3444b-8e96-4267-9afc-20abd56613aa",
|
||||
"name": "groups",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-realm-role-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"multivalued": "true",
|
||||
"user.attribute": "foo",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "groups",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "2cdac876-a8ce-4cde-8bcb-00e28804ec91",
|
||||
"name": "offline_access",
|
||||
"description": "OpenID Connect built-in scope: offline_access",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"consent.screen.text": "${offlineAccessScopeConsentText}",
|
||||
"display.on.consent.screen": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3db88729-214e-4c71-8fac-ee744279538b",
|
||||
"name": "phone",
|
||||
"description": "OpenID Connect built-in scope: phone",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "true",
|
||||
"display.on.consent.screen": "true",
|
||||
"consent.screen.text": "${phoneScopeConsentText}"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "00ca4abc-fc26-4273-9d77-d7a793f38976",
|
||||
"name": "phone number verified",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "phoneNumberVerified",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "phone_number_verified",
|
||||
"jsonType.label": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "98885779-b84e-4565-bc1b-a0c703f03be0",
|
||||
"name": "phone number",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "phoneNumber",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "phone_number",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "82aca51c-22b4-4156-93a9-3ed33ec2adcc",
|
||||
"name": "profile",
|
||||
"description": "OpenID Connect built-in scope: profile",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "true",
|
||||
"display.on.consent.screen": "true",
|
||||
"consent.screen.text": "${profileScopeConsentText}"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "d974a079-8416-4dea-9e49-76dab694e836",
|
||||
"name": "full name",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-full-name-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"userinfo.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2b0e5ec3-cc38-44c4-8851-98c0e3e3f60d",
|
||||
"name": "birthdate",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "birthdate",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "birthdate",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "feef3c77-5a8e-4f22-94c8-fc606eb8dad0",
|
||||
"name": "website",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "website",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "website",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "e0340530-efde-4bdf-8399-c98b994e3c4f",
|
||||
"name": "nickname",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "nickname",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "nickname",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "bef63a97-20a4-4595-9e31-881273af8b47",
|
||||
"name": "locale",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "locale",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "locale",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3a4e571b-9ee4-4553-8a54-dcf0ab757b39",
|
||||
"name": "picture",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "picture",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "picture",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "d0c55da1-f814-4bfe-a311-b34ddd7ee2fb",
|
||||
"name": "updated at",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "updatedAt",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "updated_at",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "392fa527-96e9-41a5-8fa4-6deb1f3916a5",
|
||||
"name": "middle name",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "middleName",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "middle_name",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "042e6e1e-f041-432f-88bc-79421366fb99",
|
||||
"name": "gender",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "gender",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "gender",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "e269f729-2eca-4ff0-9caf-3baa4f6188c5",
|
||||
"name": "zoneinfo",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "zoneinfo",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "zoneinfo",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b3929aa6-6acf-4b13-9d23-ee459926feef",
|
||||
"name": "given name",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "firstName",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "given_name",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "877d4b97-2520-40f7-9e58-cd99560a4637",
|
||||
"name": "profile",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "profile",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "profile",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "f6aab00d-4b15-4ef3-a037-50d8a6c047ff",
|
||||
"name": "family name",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "lastName",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "family_name",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "52483504-1da0-4645-8df0-d7ec36bf835a",
|
||||
"name": "username",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "username",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "preferred_username",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dc401683-7876-4a01-a670-73deae0a10c2",
|
||||
"name": "role_list",
|
||||
"description": "SAML role list",
|
||||
"protocol": "saml",
|
||||
"attributes": {
|
||||
"consent.screen.text": "${samlRoleListScopeConsentText}",
|
||||
"display.on.consent.screen": "true"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "4903f029-ca74-4447-b9ac-cf7799f2391c",
|
||||
"name": "role list",
|
||||
"protocol": "saml",
|
||||
"protocolMapper": "saml-role-list-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"single": "false",
|
||||
"attribute.nameformat": "Basic",
|
||||
"attribute.name": "Role"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "715eec20-9d2b-45cf-b2c3-fd11aae96b63",
|
||||
"name": "roles",
|
||||
"description": "OpenID Connect scope for add user roles to the access token",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "false",
|
||||
"display.on.consent.screen": "true",
|
||||
"consent.screen.text": "${rolesScopeConsentText}"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "d1464021-822d-41d8-8195-d8962fe70f61",
|
||||
"name": "audience resolve",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-audience-resolve-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"id": "b85d197d-f195-4dcd-a873-77ee4ec9fcea",
|
||||
"name": "realm roles",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-realm-role-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"user.attribute": "foo",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "realm_access.roles",
|
||||
"jsonType.label": "String",
|
||||
"multivalued": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ef5b5c95-5236-41f1-ab9b-3e4213abbe76",
|
||||
"name": "client roles",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-client-role-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"user.attribute": "foo",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "resource_access.${client_id}.roles",
|
||||
"jsonType.label": "String",
|
||||
"multivalued": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "30b4d89f-bfd9-45d4-b71f-01dd0f64da57",
|
||||
"name": "web-origins",
|
||||
"description": "OpenID Connect scope for add allowed web origins to the access token",
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"include.in.token.scope": "false",
|
||||
"display.on.consent.screen": "false",
|
||||
"consent.screen.text": ""
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"id": "76f254c5-dc78-4048-abc9-c9de9d55f5a4",
|
||||
"name": "allowed web origins",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-allowed-origins-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
181
src/client-scopes/add/NewClientScopeForm.tsx
Normal file
181
src/client-scopes/add/NewClientScopeForm.tsx
Normal file
|
@ -0,0 +1,181 @@
|
|||
import React, { useContext, useState } from "react";
|
||||
import {
|
||||
ActionGroup,
|
||||
AlertVariant,
|
||||
Button,
|
||||
Form,
|
||||
FormGroup,
|
||||
PageSection,
|
||||
Select,
|
||||
SelectVariant,
|
||||
Switch,
|
||||
TextInput,
|
||||
} from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
import { ClientScopeRepresentation } from "../models/client-scope";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { HttpClientContext } from "../../http-service/HttpClientContext";
|
||||
import { RealmContext } from "../../components/realm-context/RealmContext";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
||||
export const NewClientScopeForm = () => {
|
||||
const { t } = useTranslation("client-scopes");
|
||||
const { register, control, handleSubmit } = useForm<
|
||||
ClientScopeRepresentation
|
||||
>();
|
||||
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const { realm } = useContext(RealmContext);
|
||||
|
||||
const [open, isOpen] = useState(false);
|
||||
const [add, Alerts] = useAlerts();
|
||||
|
||||
const save = async (clientScopes: ClientScopeRepresentation) => {
|
||||
try {
|
||||
const keyValues = Object.keys(clientScopes.attributes!).map((key) => {
|
||||
const newKey = key.replace(/_/g, ".");
|
||||
return { [newKey]: clientScopes.attributes![key] };
|
||||
});
|
||||
clientScopes.attributes = Object.assign({}, ...keyValues);
|
||||
|
||||
await httpClient.doPost(
|
||||
`/admin/realms/${realm}/client-scopes`,
|
||||
clientScopes
|
||||
);
|
||||
add(t("createClientScopeSuccess"), AlertVariant.success);
|
||||
} catch (error) {
|
||||
add(`${t("createClientScopeError")} '${error}'`, AlertVariant.danger);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PageSection variant="light">
|
||||
<Alerts />
|
||||
<Form isHorizontal onSubmit={handleSubmit(save)}>
|
||||
<FormGroup
|
||||
label={
|
||||
<>
|
||||
{t("name")} <HelpItem item="clientScope.name" />
|
||||
</>
|
||||
}
|
||||
fieldId="kc-name"
|
||||
isRequired
|
||||
>
|
||||
<TextInput
|
||||
ref={register({ required: true })}
|
||||
type="text"
|
||||
id="kc-name"
|
||||
name="name"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={
|
||||
<>
|
||||
{t("description")} <HelpItem item="clientScope.description" />
|
||||
</>
|
||||
}
|
||||
fieldId="kc-description"
|
||||
>
|
||||
<TextInput
|
||||
ref={register}
|
||||
type="text"
|
||||
id="kc-description"
|
||||
name="description"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={
|
||||
<>
|
||||
{t("protocol")} <HelpItem item="clientScope.protocol" />
|
||||
</>
|
||||
}
|
||||
fieldId="kc-protocol"
|
||||
>
|
||||
<Controller
|
||||
name="protocol"
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
id="kc-protocol"
|
||||
required
|
||||
onToggle={() => isOpen(!open)}
|
||||
onSelect={(_, value, isPlaceholder) => {
|
||||
onChange(isPlaceholder ? "" : (value as string));
|
||||
isOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
variant={SelectVariant.single}
|
||||
aria-label="Select Encryption type"
|
||||
isOpen={open}
|
||||
></Select>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={
|
||||
<>
|
||||
{t("displayOnConsentScreen")}{" "}
|
||||
<HelpItem item="clientScope.displayOnConsentScreen" />
|
||||
</>
|
||||
}
|
||||
fieldId="kc-display.on.consent.screen"
|
||||
>
|
||||
<Controller
|
||||
name="attributes.display_on_consent_screen"
|
||||
control={control}
|
||||
defaultValue={false}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id="kc-display.on.consent.screen"
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
isChecked={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={
|
||||
<>
|
||||
{t("consentScreenText")}{" "}
|
||||
<HelpItem item="clientScope.consentScreenText" />
|
||||
</>
|
||||
}
|
||||
fieldId="kc-consent-screen-text"
|
||||
>
|
||||
<TextInput
|
||||
ref={register}
|
||||
type="text"
|
||||
id="kc-consent-screen-text"
|
||||
name="attributes.consent_screen_text"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={
|
||||
<>
|
||||
{t("guiOrder")} <HelpItem item="clientScope.guiOrder" />
|
||||
</>
|
||||
}
|
||||
fieldId="kc-gui-order"
|
||||
>
|
||||
<TextInput
|
||||
ref={register}
|
||||
type="number"
|
||||
id="kc-gui-order"
|
||||
name="attributes.gui_order"
|
||||
/>
|
||||
</FormGroup>
|
||||
<ActionGroup>
|
||||
<Button variant="primary" type="submit">
|
||||
{t("common:save")}
|
||||
</Button>
|
||||
<Button variant="link">{t("common:cancel")}</Button>
|
||||
</ActionGroup>
|
||||
</Form>
|
||||
</PageSection>
|
||||
);
|
||||
};
|
14
src/client-scopes/messages.json
Normal file
14
src/client-scopes/messages.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"client-scopes": {
|
||||
"createClientScope": "Create client scope",
|
||||
"clientScopeList": "List of client scopes",
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
"protocol": "Protocol",
|
||||
"createClientScopeSuccess": "Client scope created",
|
||||
"createClientScopeError": "Could not create client scope:",
|
||||
"displayOnConsentScreen": "Display on consent screen",
|
||||
"consentScreenText": "Consent screen text",
|
||||
"guiOrder": "GUI Order"
|
||||
}
|
||||
}
|
24
src/client-scopes/models/client-scope.ts
Normal file
24
src/client-scopes/models/client-scope.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* https://www.keycloak.org/docs-api/4.1/rest-api/#_protocolmapperrepresentation
|
||||
*/
|
||||
|
||||
export interface ProtocolMapperRepresentation {
|
||||
config?: Record<string, any>;
|
||||
id?: string;
|
||||
name?: string;
|
||||
protocol?: string;
|
||||
protocolMapper?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://www.keycloak.org/docs-api/6.0/rest-api/index.html#_clientscoperepresentation
|
||||
*/
|
||||
|
||||
export interface ClientScopeRepresentation {
|
||||
attributes?: Record<string, any>;
|
||||
description?: string;
|
||||
id?: string;
|
||||
name?: string;
|
||||
protocol?: string;
|
||||
protocolMappers?: ProtocolMapperRepresentation[];
|
||||
}
|
|
@ -1,21 +1,26 @@
|
|||
import React from "react";
|
||||
import { FormGroup, TextInput } from "@patternfly/react-core";
|
||||
import { FieldElement, ValidationRules, Ref } from "react-hook-form";
|
||||
import { UseFormMethods } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
type ClientDescriptionProps = {
|
||||
register<TFieldElement extends FieldElement>(
|
||||
rules?: ValidationRules
|
||||
): (ref: (TFieldElement & Ref) | null) => void;
|
||||
form: UseFormMethods;
|
||||
};
|
||||
|
||||
export const ClientDescription = ({ register }: ClientDescriptionProps) => {
|
||||
export const ClientDescription = ({ form }: ClientDescriptionProps) => {
|
||||
const { t } = useTranslation("clients");
|
||||
const { register, errors } = form;
|
||||
return (
|
||||
<>
|
||||
<FormGroup label={t("clientID")} fieldId="kc-client-id">
|
||||
<FormGroup
|
||||
label={t("clientID")}
|
||||
fieldId="kc-client-id"
|
||||
helperTextInvalid={t("common:required")}
|
||||
validated={errors.clientId ? "error" : "default"}
|
||||
isRequired
|
||||
>
|
||||
<TextInput
|
||||
ref={register()}
|
||||
ref={register({ required: true })}
|
||||
type="text"
|
||||
id="kc-client-id"
|
||||
name="clientId"
|
||||
|
|
|
@ -36,16 +36,13 @@ export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
|||
const { realm } = useContext(RealmContext);
|
||||
const [add, Alerts] = useAlerts();
|
||||
|
||||
const convertClientId = (clientId: string) =>
|
||||
clientId.substring(0, clientId.indexOf("#"));
|
||||
const enabled = (): IFormatter => (data?: IFormatterValueType) => {
|
||||
const field = data!.toString();
|
||||
const value = convertClientId(field);
|
||||
return field.indexOf("true") !== -1 ? (
|
||||
<Link to="client-settings">{value}</Link>
|
||||
) : (
|
||||
<Link to="client-settings">
|
||||
{value} <Badge isRead>Disabled</Badge>
|
||||
const [id, clientId, disabled] = field.split("#");
|
||||
return (
|
||||
<Link to={`client-settings/${id}`}>
|
||||
{clientId}
|
||||
{disabled !== "true" && <Badge isRead>Disabled</Badge>}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
@ -75,13 +72,13 @@ export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
|||
};
|
||||
|
||||
const data = clients!
|
||||
.map((r) => {
|
||||
r.clientId = r.clientId + "#" + r.enabled;
|
||||
r.baseUrl = replaceBaseUrl(r);
|
||||
return r;
|
||||
.map((client) => {
|
||||
client.clientId = `${client.id}#${client.clientId}#${client.enabled}`;
|
||||
client.baseUrl = replaceBaseUrl(client);
|
||||
return client;
|
||||
})
|
||||
.map((c) => {
|
||||
return { cells: columns.map((col) => c[col]), client: c };
|
||||
.map((column) => {
|
||||
return { cells: columns.map((col) => column[col]), client: column };
|
||||
});
|
||||
return (
|
||||
<>
|
||||
|
@ -103,7 +100,8 @@ export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
|||
title: t("common:export"),
|
||||
onClick: (_, rowId) => {
|
||||
const clientCopy = JSON.parse(JSON.stringify(data[rowId].client));
|
||||
clientCopy.clientId = convertClientId(clientCopy.clientId);
|
||||
const [, orgClientId] = clientCopy.clientId.split("#");
|
||||
clientCopy.clientId = orgClientId;
|
||||
delete clientCopy.id;
|
||||
|
||||
if (clientCopy.protocolMappers) {
|
||||
|
|
|
@ -1,45 +1,72 @@
|
|||
import React, { useState, FormEvent } from "react";
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
FormGroup,
|
||||
TextInput,
|
||||
Form,
|
||||
Dropdown,
|
||||
DropdownToggle,
|
||||
DropdownItem,
|
||||
Switch,
|
||||
TextArea,
|
||||
PageSection,
|
||||
ActionGroup,
|
||||
Button,
|
||||
AlertVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
import { ScrollForm } from "../components/scroll-form/ScrollForm";
|
||||
import { ClientDescription } from "./ClientDescription";
|
||||
import { ClientRepresentation } from "./models/client-model";
|
||||
import { CapabilityConfig } from "./add/CapabilityConfig";
|
||||
import { RealmContext } from "../components/realm-context/RealmContext";
|
||||
import { HttpClientContext } from "../http-service/HttpClientContext";
|
||||
import { ClientRepresentation } from "../realm/models/Realm";
|
||||
import {
|
||||
convertToMultiline,
|
||||
MultiLineInput,
|
||||
toValue,
|
||||
} from "../components/multi-line-input/MultiLineInput";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
|
||||
type ClientSettingsProps = {
|
||||
client: ClientRepresentation;
|
||||
};
|
||||
|
||||
export const ClientSettings = ({ client: clientInit }: ClientSettingsProps) => {
|
||||
export const ClientSettings = () => {
|
||||
const { t } = useTranslation("clients");
|
||||
const [client, setClient] = useState({ ...clientInit });
|
||||
const form = useForm();
|
||||
const onChange = (
|
||||
value: string | boolean,
|
||||
event: FormEvent<HTMLInputElement>
|
||||
) => {
|
||||
const target = event.target;
|
||||
const name = (target as HTMLInputElement).name;
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const { realm } = useContext(RealmContext);
|
||||
const [addAlert, Alerts] = useAlerts();
|
||||
|
||||
setClient({
|
||||
...client,
|
||||
[name]: value,
|
||||
});
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const form = useForm();
|
||||
const url = `/admin/realms/${realm}/clients/${id}`;
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const fetchedClient = await httpClient.doGet<ClientRepresentation>(url);
|
||||
if (fetchedClient.data) {
|
||||
Object.entries(fetchedClient.data).map((entry) => {
|
||||
if (entry[0] !== "redirectUris") {
|
||||
form.setValue(entry[0], entry[1]);
|
||||
} else if (entry[1] && entry[1].length > 0) {
|
||||
form.setValue(entry[0], convertToMultiline(entry[1]));
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const save = async () => {
|
||||
if (await form.trigger()) {
|
||||
const redirectUris = toValue(form.getValues()["redirectUris"]);
|
||||
try {
|
||||
httpClient.doPut(url, { ...form.getValues(), redirectUris });
|
||||
addAlert(t("clientSaveSuccess"), AlertVariant.success);
|
||||
} catch (error) {
|
||||
addAlert(`${t("clientSaveError")} '${error}'`, AlertVariant.danger);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PageSection>
|
||||
<Alerts />
|
||||
<ScrollForm
|
||||
sections={[
|
||||
t("capabilityConfig"),
|
||||
|
@ -48,11 +75,9 @@ export const ClientSettings = ({ client: clientInit }: ClientSettingsProps) => {
|
|||
t("loginSettings"),
|
||||
]}
|
||||
>
|
||||
<CapabilityConfig form={form} />
|
||||
<Form isHorizontal>
|
||||
<CapabilityConfig form={form} />
|
||||
</Form>
|
||||
<Form isHorizontal>
|
||||
<ClientDescription register={form.register} />
|
||||
<ClientDescription form={form} />
|
||||
</Form>
|
||||
<Form isHorizontal>
|
||||
<FormGroup label={t("rootUrl")} fieldId="kc-root-url">
|
||||
|
@ -60,64 +85,55 @@ export const ClientSettings = ({ client: clientInit }: ClientSettingsProps) => {
|
|||
type="text"
|
||||
id="kc-root-url"
|
||||
name="rootUrl"
|
||||
value={client.rootUrl}
|
||||
onChange={onChange}
|
||||
ref={form.register}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup label={t("validRedirectUri")} fieldId="kc-redirect">
|
||||
<TextInput
|
||||
type="text"
|
||||
id="kc-redirect"
|
||||
name="redirectUris"
|
||||
onChange={onChange}
|
||||
/>
|
||||
<MultiLineInput form={form} name="redirectUris" />
|
||||
</FormGroup>
|
||||
<FormGroup label={t("homeURL")} fieldId="kc-home-url">
|
||||
<TextInput
|
||||
type="text"
|
||||
id="kc-home-url"
|
||||
name="baseUrl"
|
||||
value={client.baseUrl}
|
||||
onChange={onChange}
|
||||
ref={form.register}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
<Form isHorizontal>
|
||||
<FormGroup label={t("loginTheme")} fieldId="kc-login-theme">
|
||||
<Dropdown
|
||||
id="kc-login-theme"
|
||||
toggle={
|
||||
<DropdownToggle id="toggle-id" onToggle={() => {}}>
|
||||
{t("loginTheme")}
|
||||
</DropdownToggle>
|
||||
}
|
||||
dropdownItems={[
|
||||
<DropdownItem key="link">Link</DropdownItem>,
|
||||
<DropdownItem key="action" component="button" />,
|
||||
]}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup label={t("consentRequired")} fieldId="kc-consent">
|
||||
<Switch
|
||||
id="kc-consent"
|
||||
<Controller
|
||||
name="consentRequired"
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
isChecked={client.consentRequired}
|
||||
onChange={onChange}
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id="kc-consent"
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
isChecked={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("displayOnClient")}
|
||||
fieldId="kc-display-on-client"
|
||||
>
|
||||
<Switch
|
||||
id="kc-display-on-client"
|
||||
<Controller
|
||||
name="alwaysDisplayInConsole"
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
isChecked={client.alwaysDisplayInConsole}
|
||||
onChange={onChange}
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id="kc-display-on-client"
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
isChecked={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
|
@ -127,9 +143,15 @@ export const ClientSettings = ({ client: clientInit }: ClientSettingsProps) => {
|
|||
<TextArea
|
||||
id="kc-consent-screen-text"
|
||||
name="consentText"
|
||||
//value={client.protocolMappers![0].consentText}
|
||||
ref={form.register}
|
||||
/>
|
||||
</FormGroup>
|
||||
<ActionGroup>
|
||||
<Button variant="primary" onClick={() => save()}>
|
||||
{t("common:save")}
|
||||
</Button>
|
||||
<Button variant="link">{t("common:cancel")}</Button>
|
||||
</ActionGroup>
|
||||
</Form>
|
||||
</ScrollForm>
|
||||
</PageSection>
|
||||
|
|
|
@ -10,6 +10,7 @@ import { HttpClientContext } from "../http-service/HttpClientContext";
|
|||
import { KeycloakContext } from "../auth/KeycloakContext";
|
||||
import { ClientRepresentation } from "./models/client-model";
|
||||
import { RealmContext } from "../components/realm-context/RealmContext";
|
||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||
|
||||
export const ClientsSection = () => {
|
||||
const { t } = useTranslation("clients");
|
||||
|
@ -28,40 +29,48 @@ export const ClientsSection = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<PageSection variant="light">
|
||||
<DataLoader loader={loader}>
|
||||
{(clients) => (
|
||||
<TableToolbar
|
||||
count={clients!.length}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
onPreviousClick={setFirst}
|
||||
onPerPageSelect={(f, m) => {
|
||||
setFirst(f);
|
||||
setMax(m);
|
||||
}}
|
||||
toolbarItem={
|
||||
<>
|
||||
<Button onClick={() => history.push("/add-client")}>
|
||||
{t("createClient")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => history.push("/import-client")}
|
||||
variant="link"
|
||||
>
|
||||
{t("importClient")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<ClientList
|
||||
clients={clients}
|
||||
baseUrl={keycloak!.authServerUrl()!}
|
||||
/>
|
||||
</TableToolbar>
|
||||
)}
|
||||
</DataLoader>
|
||||
</PageSection>
|
||||
<>
|
||||
<ViewHeader
|
||||
titleKey="clients:clientList"
|
||||
subKey="clients:clientsExplain"
|
||||
/>
|
||||
<PageSection variant="light">
|
||||
<DataLoader loader={loader}>
|
||||
{(clients) => (
|
||||
<TableToolbar
|
||||
count={clients!.length}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
onPreviousClick={setFirst}
|
||||
onPerPageSelect={(first, max) => {
|
||||
setFirst(first);
|
||||
setMax(max);
|
||||
}}
|
||||
inputGroupName="clientsToolbarTextInput"
|
||||
inputGroupPlaceholder={t("Search for client")}
|
||||
toolbarItem={
|
||||
<>
|
||||
<Button onClick={() => history.push("/add-client")}>
|
||||
{t("createClient")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => history.push("/import-client")}
|
||||
variant="link"
|
||||
>
|
||||
{t("importClient")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<ClientList
|
||||
clients={clients}
|
||||
baseUrl={keycloak!.authServerUrl()!}
|
||||
/>
|
||||
</TableToolbar>
|
||||
)}
|
||||
</DataLoader>
|
||||
</PageSection>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ Object {
|
|||
<table
|
||||
aria-label="clientList"
|
||||
class="pf-c-table pf-m-grid-md pf-m-compact"
|
||||
data-ouia-component-id="0"
|
||||
data-ouia-component-id="OUIA-Generated-Table-1"
|
||||
data-ouia-component-type="PF4/Table"
|
||||
data-ouia-safe="true"
|
||||
role="grid"
|
||||
|
@ -61,7 +61,7 @@ Object {
|
|||
>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="1"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-1"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -71,7 +71,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/767756c2-21f8-431c-9f4b-edf30654d653"
|
||||
>
|
||||
account
|
||||
</a>
|
||||
|
@ -96,24 +96,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://blog.nerdin.chrealms/master/account/"
|
||||
>
|
||||
http://blog.nerdin.chrealms/master/account/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -122,7 +129,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="2"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-1"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -145,7 +152,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -154,7 +160,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="3"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-2"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -164,7 +170,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/337dc87b-e08d-409e-aaac-6ab7df4b925b"
|
||||
>
|
||||
account-console
|
||||
</a>
|
||||
|
@ -189,24 +195,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-2"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://blog.nerdin.chrealms/master/account/"
|
||||
>
|
||||
http://blog.nerdin.chrealms/master/account/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -215,7 +228,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="4"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-2"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -238,7 +251,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -247,7 +259,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="5"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-3"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -257,7 +269,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/60d59afe-7926-4c22-b829-798125793ef5"
|
||||
>
|
||||
admin-cli
|
||||
</a>
|
||||
|
@ -289,7 +301,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="6"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-3"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -312,7 +324,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -321,7 +332,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="7"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-4"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -331,7 +342,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/c2d74093-2b8c-4ecb-870f-c7358ff48237"
|
||||
>
|
||||
broker
|
||||
</a>
|
||||
|
@ -363,7 +374,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="8"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-4"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -386,7 +397,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -395,7 +405,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="9"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-5"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -405,7 +415,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/66135023-e667-4864-b1f3-f87e805fabc2"
|
||||
>
|
||||
master-realm
|
||||
</a>
|
||||
|
@ -435,7 +445,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="10"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-5"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -458,7 +468,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -467,7 +476,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="11"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-6"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -477,7 +486,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/324f4182-d302-44f8-ac8a-149eaa29dc90"
|
||||
>
|
||||
new
|
||||
</a>
|
||||
|
@ -502,24 +511,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-3"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://localhost:8080/"
|
||||
>
|
||||
http://localhost:8080/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -528,7 +544,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="12"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-6"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -551,7 +567,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -560,7 +575,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="13"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-7"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -570,7 +585,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/fb45882b-4d85-4f40-920e-6a68298d36d0"
|
||||
>
|
||||
photoz-realm
|
||||
</a>
|
||||
|
@ -600,7 +615,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="14"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-7"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -623,7 +638,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -632,7 +646,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="15"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-8"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -642,7 +656,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/9ed60e41-d794-4046-842f-3247bf32f5ce"
|
||||
>
|
||||
security-admin-console
|
||||
</a>
|
||||
|
@ -667,24 +681,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-4"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://blog.nerdin.chadmin/master/console/"
|
||||
>
|
||||
http://blog.nerdin.chadmin/master/console/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -693,7 +714,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="16"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-8"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -716,7 +737,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -736,7 +756,7 @@ Object {
|
|||
<table
|
||||
aria-label="clientList"
|
||||
class="pf-c-table pf-m-grid-md pf-m-compact"
|
||||
data-ouia-component-id="0"
|
||||
data-ouia-component-id="OUIA-Generated-Table-1"
|
||||
data-ouia-component-type="PF4/Table"
|
||||
data-ouia-safe="true"
|
||||
role="grid"
|
||||
|
@ -789,7 +809,7 @@ Object {
|
|||
>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="1"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-1"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -799,7 +819,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/767756c2-21f8-431c-9f4b-edf30654d653"
|
||||
>
|
||||
account
|
||||
</a>
|
||||
|
@ -824,24 +844,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://blog.nerdin.chrealms/master/account/"
|
||||
>
|
||||
http://blog.nerdin.chrealms/master/account/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -850,7 +877,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="2"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-1"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -873,7 +900,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -882,7 +908,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="3"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-2"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -892,7 +918,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/337dc87b-e08d-409e-aaac-6ab7df4b925b"
|
||||
>
|
||||
account-console
|
||||
</a>
|
||||
|
@ -917,24 +943,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-2"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://blog.nerdin.chrealms/master/account/"
|
||||
>
|
||||
http://blog.nerdin.chrealms/master/account/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -943,7 +976,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="4"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-2"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -966,7 +999,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -975,7 +1007,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="5"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-3"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -985,7 +1017,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/60d59afe-7926-4c22-b829-798125793ef5"
|
||||
>
|
||||
admin-cli
|
||||
</a>
|
||||
|
@ -1017,7 +1049,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="6"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-3"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1040,7 +1072,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -1049,7 +1080,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="7"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-4"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1059,7 +1090,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/c2d74093-2b8c-4ecb-870f-c7358ff48237"
|
||||
>
|
||||
broker
|
||||
</a>
|
||||
|
@ -1091,7 +1122,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="8"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-4"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1114,7 +1145,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -1123,7 +1153,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="9"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-5"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1133,7 +1163,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/66135023-e667-4864-b1f3-f87e805fabc2"
|
||||
>
|
||||
master-realm
|
||||
</a>
|
||||
|
@ -1163,7 +1193,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="10"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-5"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1186,7 +1216,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -1195,7 +1224,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="11"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-6"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1205,7 +1234,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/324f4182-d302-44f8-ac8a-149eaa29dc90"
|
||||
>
|
||||
new
|
||||
</a>
|
||||
|
@ -1230,24 +1259,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-3"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://localhost:8080/"
|
||||
>
|
||||
http://localhost:8080/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -1256,7 +1292,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="12"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-6"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1279,7 +1315,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -1288,7 +1323,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="13"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-7"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1298,7 +1333,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/fb45882b-4d85-4f40-920e-6a68298d36d0"
|
||||
>
|
||||
photoz-realm
|
||||
</a>
|
||||
|
@ -1328,7 +1363,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="14"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-7"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1351,7 +1386,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -1360,7 +1394,7 @@ Object {
|
|||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
data-ouia-component-id="15"
|
||||
data-ouia-component-id="OUIA-Generated-TableRow-8"
|
||||
data-ouia-component-type="PF4/TableRow"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1370,7 +1404,7 @@ Object {
|
|||
data-label="clientID"
|
||||
>
|
||||
<a
|
||||
href="/client-settings"
|
||||
href="/client-settings/9ed60e41-d794-4046-842f-3247bf32f5ce"
|
||||
>
|
||||
security-admin-console
|
||||
</a>
|
||||
|
@ -1395,24 +1429,31 @@ Object {
|
|||
data-label="homeURL"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-4"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://blog.nerdin.chadmin/master/console/"
|
||||
>
|
||||
http://blog.nerdin.chadmin/master/console/
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
|
@ -1421,7 +1462,7 @@ Object {
|
|||
>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="16"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-8"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -1444,7 +1485,6 @@ Object {
|
|||
>
|
||||
<path
|
||||
d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
|
|
@ -21,6 +21,7 @@ export const CapabilityConfig = ({ form }: CapabilityConfigProps) => {
|
|||
<FormGroup label={t("clientAuthentication")} fieldId="kc-authentication">
|
||||
<Controller
|
||||
name="publicClient"
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
|
@ -37,6 +38,7 @@ export const CapabilityConfig = ({ form }: CapabilityConfigProps) => {
|
|||
<FormGroup label={t("clientAuthorization")} fieldId="kc-authorization">
|
||||
<Controller
|
||||
name="authorizationServicesEnabled"
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
|
@ -52,9 +54,10 @@ export const CapabilityConfig = ({ form }: CapabilityConfigProps) => {
|
|||
</FormGroup>
|
||||
<FormGroup label={t("authenticationFlow")} fieldId="kc-flow">
|
||||
<Grid>
|
||||
<GridItem span={6}>
|
||||
<GridItem lg={4} sm={6}>
|
||||
<Controller
|
||||
name="standardFlowEnabled"
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Checkbox
|
||||
|
@ -67,9 +70,10 @@ export const CapabilityConfig = ({ form }: CapabilityConfigProps) => {
|
|||
)}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem span={6}>
|
||||
<GridItem lg={8} sm={6}>
|
||||
<Controller
|
||||
name="directAccessGrantsEnabled"
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Checkbox
|
||||
|
@ -82,9 +86,10 @@ export const CapabilityConfig = ({ form }: CapabilityConfigProps) => {
|
|||
)}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem span={6}>
|
||||
<GridItem lg={4} sm={6}>
|
||||
<Controller
|
||||
name="implicitFlowEnabled"
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Checkbox
|
||||
|
@ -97,9 +102,10 @@ export const CapabilityConfig = ({ form }: CapabilityConfigProps) => {
|
|||
)}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem span={6}>
|
||||
<GridItem lg={8} sm={6}>
|
||||
<Controller
|
||||
name="serviceAccountsEnabled"
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Checkbox
|
||||
|
|
|
@ -78,7 +78,7 @@ export const GeneralSettings = ({ form }: GeneralSettingsProps) => {
|
|||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<ClientDescription register={register} />
|
||||
<ClientDescription form={form} />
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import React, { useState, useContext } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import {
|
||||
Text,
|
||||
PageSection,
|
||||
TextContent,
|
||||
Divider,
|
||||
Wizard,
|
||||
AlertVariant,
|
||||
WizardFooter,
|
||||
|
@ -20,6 +17,7 @@ import { CapabilityConfig } from "./CapabilityConfig";
|
|||
import { ClientRepresentation } from "../models/client-model";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { RealmContext } from "../../components/realm-context/RealmContext";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
|
||||
export const NewClientForm = () => {
|
||||
const { t } = useTranslation("clients");
|
||||
|
@ -96,12 +94,10 @@ export const NewClientForm = () => {
|
|||
return (
|
||||
<>
|
||||
<Alerts />
|
||||
<PageSection variant="light">
|
||||
<TextContent>
|
||||
<Text component="h1">{title}</Text>
|
||||
</TextContent>
|
||||
</PageSection>
|
||||
<Divider />
|
||||
<ViewHeader
|
||||
titleKey="clients:createClient"
|
||||
subKey="clients:clientsExplain"
|
||||
/>
|
||||
<PageSection variant="light">
|
||||
<Wizard
|
||||
onClose={() => history.push("/clients")}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,6 @@
|
|||
import React, { useContext } from "react";
|
||||
import {
|
||||
PageSection,
|
||||
Text,
|
||||
TextContent,
|
||||
Divider,
|
||||
Form,
|
||||
FormGroup,
|
||||
TextInput,
|
||||
|
@ -19,16 +16,15 @@ import { ClientDescription } from "../ClientDescription";
|
|||
import { HttpClientContext } from "../../http-service/HttpClientContext";
|
||||
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { AlertPanel } from "../../components/alert/AlertPanel";
|
||||
import { RealmContext } from "../../components/realm-context/RealmContext";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
|
||||
export const ImportForm = () => {
|
||||
const { t } = useTranslation("clients");
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const { realm } = useContext(RealmContext);
|
||||
const { register, handleSubmit, errors, setValue } = useForm<
|
||||
ClientRepresentation
|
||||
>();
|
||||
const form = useForm<ClientRepresentation>();
|
||||
const { register, handleSubmit, setValue } = form;
|
||||
|
||||
const [add, Alerts] = useAlerts();
|
||||
|
||||
|
@ -57,17 +53,14 @@ export const ImportForm = () => {
|
|||
return (
|
||||
<>
|
||||
<Alerts />
|
||||
<PageSection variant="light">
|
||||
<TextContent>
|
||||
<Text component="h1">{t("importClient")}</Text>
|
||||
{t("clientsExplain")}
|
||||
</TextContent>
|
||||
</PageSection>
|
||||
<Divider />
|
||||
<ViewHeader
|
||||
titleKey="clients:importClient"
|
||||
subKey="clients:clientsExplain"
|
||||
/>
|
||||
<PageSection variant="light">
|
||||
<Form isHorizontal onSubmit={handleSubmit(save)}>
|
||||
<JsonFileUpload id="realm-file" onChange={handleFileChange} />
|
||||
<ClientDescription register={register} />
|
||||
<ClientDescription form={form} />
|
||||
<FormGroup label={t("type")} fieldId="kc-type">
|
||||
<TextInput
|
||||
type="text"
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
"capabilityConfig": "Capability config",
|
||||
"clientsExplain": "Clients are applications and services that can request authentication of a user",
|
||||
"clientImportError": "Could not import client",
|
||||
"clientImportSuccess": "Client imported successful",
|
||||
"clientSaveSuccess": "Client successfully updated",
|
||||
"clientSaveError": "Client could not be updated:",
|
||||
"clientImportSuccess": "Client imported successfully",
|
||||
"clientDeletedSuccess": "The client has been deleted",
|
||||
"clientDeleteError": "Could not delete client:",
|
||||
"clientAuthentication": "Client authentication",
|
||||
|
@ -31,6 +33,7 @@
|
|||
"rootUrl": "Root URL",
|
||||
"validRedirectUri": "Valid redirect URIs",
|
||||
"loginTheme": "Login theme",
|
||||
"consentRequired": "Consent required"
|
||||
"consentRequired": "Consent required",
|
||||
"searchForClient": "Search for client"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"continue": "Continue",
|
||||
"delete": "Delete",
|
||||
"next": "Next",
|
||||
"back": "Back",
|
||||
|
@ -13,6 +14,8 @@
|
|||
"clearFile": "Clear this file",
|
||||
"on": "On",
|
||||
"off":"Off",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
|
||||
"signOut": "Sign out",
|
||||
"manageAccount": "Manage account",
|
||||
|
|
|
@ -35,7 +35,7 @@ exports[`remove alert after timeout: cleared alert 1`] = `
|
|||
aria-disabled={false}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-primary"
|
||||
data-ouia-component-id={0}
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
|
@ -69,7 +69,7 @@ exports[`remove alert after timeout: with alert 1`] = `
|
|||
aria-label="Default Alert"
|
||||
aria-live="polite"
|
||||
class="pf-c-alert"
|
||||
data-ouia-component-id="1"
|
||||
data-ouia-component-id="OUIA-Generated-Alert-default-1"
|
||||
data-ouia-component-type="PF4/Alert"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -82,12 +82,11 @@ exports[`remove alert after timeout: with alert 1`] = `
|
|||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 64 896 1024"
|
||||
viewBox="0 0 896 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M320.060356,128 L575.938356,128 C575.938356,57.3 518.639356,-0.001 448.000356,-0.001 L448.000356,-0.001 C377.361356,-0.001 320.060356,57.3 320.060356,128 L320.060356,128 Z M64.2023555,192 C25.9623555,192 0.202355518,223.199 -2.84217094e-13,256 L-2.84217094e-13,256 C-0.0976444824,271.1 5.22235552,286.54 17.2223555,299.419 L17.2223555,299.419 C55.8623555,340.94 128.161356,403.399 128.161356,608 L128.161356,608 C128.161356,763.4 237.121356,887.8 384.040356,918.32 L384.040356,918.32 L384.040356,960 C384.040356,995.339 412.679356,1024 448.000356,1024 L448.000356,1024 C483.319356,1024 511.959356,995.339 511.959356,960 L511.959356,960 L511.959356,918.32 C658.878356,887.8 767.837356,763.4 767.837356,608 L767.837356,608 C767.837356,403.4 840.138356,340.94 878.778356,299.42 L878.778356,299.42 C890.777356,286.52 896.096356,271.1 895.999684,256 L895.999684,256 C895.777356,223.2 870.037356,192 831.798356,192 L831.798356,192 L64.2023555,192 Z"
|
||||
transform="rotate(180 0 512) scale(-1 1)"
|
||||
d="M448,0 C465.333333,0 480.333333,6.33333333 493,19 C505.666667,31.6666667 512,46.6666667 512,64 L512,106 L514.23,106.45 C587.89,121.39 648.48,157.24 696,214 C744,271.333333 768,338.666667 768,416 C768,500 780,568.666667 804,622 C818.666667,652.666667 841.333333,684 872,716 C873.773676,718.829136 875.780658,721.505113 878,724 C890,737.333333 896,752.333333 896,769 C896,785.666667 890,800.333333 878,813 C866,825.666667 850.666667,832 832,832 L63.3,832 C44.9533333,831.84 29.8533333,825.506667 18,813 C6,800.333333 0,785.666667 0,769 C0,752.333333 6,737.333333 18,724 L24,716 L25.06,714.9 C55.1933333,683.28 77.5066667,652.313333 92,622 C116,568.666667 128,500 128,416 C128,338.666667 152,271.333333 200,214 C248,156.666667 309.333333,120.666667 384,106 L384,63.31 C384.166667,46.27 390.5,31.5 403,19 C415.666667,6.33333333 430.666667,0 448,0 Z M576,896 L576,897.08 C575.74,932.6 563.073333,962.573333 538,987 C512.666667,1011.66667 482.666667,1024 448,1024 C413.333333,1024 383.333333,1011.66667 358,987 C332.666667,962.333333 320,932 320,896 L576,896 Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -106,7 +105,7 @@ exports[`remove alert after timeout: with alert 1`] = `
|
|||
aria-disabled="false"
|
||||
aria-label="Close alert: Hello"
|
||||
class="pf-c-button pf-m-plain"
|
||||
data-ouia-component-id="2"
|
||||
data-ouia-component-id="OUIA-Generated-Button-plain-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
title="Hello"
|
||||
|
@ -123,7 +122,6 @@ exports[`remove alert after timeout: with alert 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -152,7 +150,7 @@ exports[`remove alert after timeout: with alert 1`] = `
|
|||
aria-disabled={false}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-primary"
|
||||
data-ouia-component-id={0}
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
|
|
94
src/components/confirm-dialog/ConfirmDialog.tsx
Normal file
94
src/components/confirm-dialog/ConfirmDialog.tsx
Normal file
|
@ -0,0 +1,94 @@
|
|||
import React, { ReactElement, ReactNode, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
Modal,
|
||||
ModalVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const useConfirmDialog = (
|
||||
props: ConfirmDialogProps
|
||||
): [() => void, () => ReactElement] => {
|
||||
const [show, setShow] = useState(false);
|
||||
|
||||
function toggleDialog() {
|
||||
setShow((show) => !show);
|
||||
}
|
||||
|
||||
const Dialog = () => (
|
||||
<ConfirmDialogModal
|
||||
key="confirmDialog"
|
||||
{...props}
|
||||
open={show}
|
||||
toggleDialog={toggleDialog}
|
||||
/>
|
||||
);
|
||||
return [toggleDialog, Dialog];
|
||||
};
|
||||
|
||||
export interface ConfirmDialogModalProps extends ConfirmDialogProps {
|
||||
open: boolean;
|
||||
toggleDialog: () => void;
|
||||
}
|
||||
|
||||
export type ConfirmDialogProps = {
|
||||
titleKey: string;
|
||||
messageKey?: string;
|
||||
cancelButtonLabel?: string;
|
||||
continueButtonLabel?: string;
|
||||
continueButtonVariant?: ButtonVariant;
|
||||
onConfirm: () => void;
|
||||
onCancel?: () => void;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
export const ConfirmDialogModal = ({
|
||||
titleKey,
|
||||
messageKey,
|
||||
cancelButtonLabel,
|
||||
continueButtonLabel,
|
||||
continueButtonVariant,
|
||||
onConfirm,
|
||||
onCancel,
|
||||
children,
|
||||
open = true,
|
||||
toggleDialog,
|
||||
}: ConfirmDialogModalProps) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Modal
|
||||
title={t(titleKey)}
|
||||
isOpen={open}
|
||||
onClose={toggleDialog}
|
||||
variant={ModalVariant.small}
|
||||
actions={[
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
key="confirm"
|
||||
variant={continueButtonVariant || ButtonVariant.primary}
|
||||
onClick={() => {
|
||||
onConfirm();
|
||||
toggleDialog();
|
||||
}}
|
||||
>
|
||||
{t(continueButtonLabel || "common:continue")}
|
||||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.secondary}
|
||||
onClick={() => {
|
||||
if (onCancel) onCancel();
|
||||
toggleDialog();
|
||||
}}
|
||||
>
|
||||
{t(cancelButtonLabel || "common:cancel")}
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
{!messageKey && children}
|
||||
{messageKey && t(messageKey)}
|
||||
</Modal>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
import React from "react";
|
||||
import { mount } from "enzyme";
|
||||
import { useConfirmDialog } from "../ConfirmDialog";
|
||||
|
||||
describe("Confirmation dialog", () => {
|
||||
it("renders simple confirm dialog", () => {
|
||||
const onConfirm = jest.fn();
|
||||
const Test = () => {
|
||||
const [toggle, ConfirmDialog] = useConfirmDialog({
|
||||
titleKey: "Delete app02?",
|
||||
messageKey:
|
||||
"If you delete this client, all associated data will be removed.",
|
||||
continueButtonLabel: "Delete",
|
||||
onConfirm: onConfirm,
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<button id="show" onClick={toggle}>
|
||||
Show
|
||||
</button>
|
||||
<ConfirmDialog />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const simple = mount(<Test />);
|
||||
simple.find("#show").simulate("click");
|
||||
expect(simple).toMatchSnapshot();
|
||||
|
||||
const button = simple.find("#modal-confirm").find("button");
|
||||
expect(button).not.toBeNull();
|
||||
|
||||
button!.simulate("click");
|
||||
expect(onConfirm).toBeCalled();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,356 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Confirmation dialog renders simple confirm dialog 1`] = `
|
||||
<Test>
|
||||
<button
|
||||
id="show"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Show
|
||||
</button>
|
||||
<Dialog>
|
||||
<ConfirmDialogModal
|
||||
continueButtonLabel="Delete"
|
||||
key="confirmDialog"
|
||||
messageKey="If you delete this client, all associated data will be removed."
|
||||
onConfirm={[MockFunction]}
|
||||
open={true}
|
||||
titleKey="Delete app02?"
|
||||
toggleDialog={[Function]}
|
||||
>
|
||||
<Modal
|
||||
actions={
|
||||
Array [
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
onClick={[Function]}
|
||||
variant="primary"
|
||||
>
|
||||
Delete
|
||||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
onClick={[Function]}
|
||||
variant="secondary"
|
||||
>
|
||||
cancel
|
||||
</Button>,
|
||||
]
|
||||
}
|
||||
appendTo={[Function]}
|
||||
aria-describedby=""
|
||||
aria-label=""
|
||||
aria-labelledby=""
|
||||
className=""
|
||||
hasNoBodyWrapper={false}
|
||||
isOpen={true}
|
||||
onClose={[Function]}
|
||||
ouiaSafe={true}
|
||||
showClose={true}
|
||||
title="Delete app02?"
|
||||
variant="small"
|
||||
>
|
||||
<Portal
|
||||
containerInfo={
|
||||
<div>
|
||||
<div
|
||||
class="pf-c-backdrop"
|
||||
>
|
||||
<div
|
||||
class="pf-l-bullseye"
|
||||
>
|
||||
<div
|
||||
aria-describedby="pf-modal-part-3"
|
||||
aria-labelledby="pf-modal-part-2"
|
||||
aria-modal="true"
|
||||
class="pf-c-modal-box pf-m-sm"
|
||||
data-ouia-component-id="OUIA-Generated-Modal-small-2"
|
||||
data-ouia-component-type="PF4/ModalContent"
|
||||
data-ouia-safe="true"
|
||||
id="pf-modal-part-1"
|
||||
role="dialog"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-label="Close"
|
||||
class="pf-c-button pf-m-plain"
|
||||
data-ouia-component-id="OUIA-Generated-Button-plain-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 352 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<header
|
||||
class="pf-c-modal-box__header"
|
||||
>
|
||||
<h1
|
||||
class="pf-c-modal-box__title pf-c-modal-box__title"
|
||||
id="pf-modal-part-2"
|
||||
>
|
||||
Delete app02?
|
||||
</h1>
|
||||
</header>
|
||||
<div
|
||||
class="pf-c-modal-box__body"
|
||||
id="pf-modal-part-3"
|
||||
>
|
||||
If you delete this client, all associated data will be removed.
|
||||
</div>
|
||||
<footer
|
||||
class="pf-c-modal-box__footer"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-primary"
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
id="modal-confirm"
|
||||
type="button"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-secondary"
|
||||
data-ouia-component-id="OUIA-Generated-Button-secondary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
id="modal-cancel"
|
||||
type="button"
|
||||
>
|
||||
cancel
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<ModalContent
|
||||
actions={
|
||||
Array [
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
onClick={[Function]}
|
||||
variant="primary"
|
||||
>
|
||||
Delete
|
||||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
onClick={[Function]}
|
||||
variant="secondary"
|
||||
>
|
||||
cancel
|
||||
</Button>,
|
||||
]
|
||||
}
|
||||
aria-describedby=""
|
||||
aria-label=""
|
||||
aria-labelledby=""
|
||||
boxId="pf-modal-part-1"
|
||||
className=""
|
||||
descriptorId="pf-modal-part-3"
|
||||
hasNoBodyWrapper={false}
|
||||
isOpen={true}
|
||||
labelId="pf-modal-part-2"
|
||||
onClose={[Function]}
|
||||
ouiaId="OUIA-Generated-Modal-small-2"
|
||||
ouiaSafe={true}
|
||||
showClose={true}
|
||||
title="Delete app02?"
|
||||
variant="small"
|
||||
>
|
||||
<Backdrop>
|
||||
<div
|
||||
className="pf-c-backdrop"
|
||||
>
|
||||
<FocusTrap
|
||||
active={true}
|
||||
className="pf-l-bullseye"
|
||||
focusTrapOptions={
|
||||
Object {
|
||||
"clickOutsideDeactivates": true,
|
||||
}
|
||||
}
|
||||
paused={false}
|
||||
>
|
||||
<div
|
||||
className="pf-l-bullseye"
|
||||
>
|
||||
<ModalBox
|
||||
aria-describedby="pf-modal-part-3"
|
||||
aria-label=""
|
||||
aria-labelledby="pf-modal-part-2"
|
||||
className=""
|
||||
data-ouia-component-id="OUIA-Generated-Modal-small-2"
|
||||
data-ouia-component-type="PF4/ModalContent"
|
||||
data-ouia-safe={true}
|
||||
id="pf-modal-part-1"
|
||||
style={Object {}}
|
||||
variant="small"
|
||||
>
|
||||
<div
|
||||
aria-describedby="pf-modal-part-3"
|
||||
aria-label={null}
|
||||
aria-labelledby="pf-modal-part-2"
|
||||
aria-modal="true"
|
||||
className="pf-c-modal-box pf-m-sm"
|
||||
data-ouia-component-id="OUIA-Generated-Modal-small-2"
|
||||
data-ouia-component-type="PF4/ModalContent"
|
||||
data-ouia-safe={true}
|
||||
id="pf-modal-part-1"
|
||||
role="dialog"
|
||||
style={Object {}}
|
||||
>
|
||||
<ModalBoxCloseButton
|
||||
onClose={[Function]}
|
||||
>
|
||||
<Button
|
||||
aria-label="Close"
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
variant="plain"
|
||||
>
|
||||
<button
|
||||
aria-disabled={false}
|
||||
aria-label="Close"
|
||||
className="pf-c-button pf-m-plain"
|
||||
data-ouia-component-id="OUIA-Generated-Button-plain-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<TimesIcon
|
||||
color="currentColor"
|
||||
noVerticalAlign={false}
|
||||
size="sm"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
aria-labelledby={null}
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"verticalAlign": "-0.125em",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 352 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
|
||||
/>
|
||||
</svg>
|
||||
</TimesIcon>
|
||||
</button>
|
||||
</Button>
|
||||
</ModalBoxCloseButton>
|
||||
<ModalBoxHeader>
|
||||
<header
|
||||
className="pf-c-modal-box__header"
|
||||
>
|
||||
<ModalBoxTitle
|
||||
className="pf-c-modal-box__title"
|
||||
id="pf-modal-part-2"
|
||||
title="Delete app02?"
|
||||
>
|
||||
<h1
|
||||
className="pf-c-modal-box__title pf-c-modal-box__title"
|
||||
id="pf-modal-part-2"
|
||||
>
|
||||
Delete app02?
|
||||
</h1>
|
||||
</ModalBoxTitle>
|
||||
</header>
|
||||
</ModalBoxHeader>
|
||||
<ModalBoxBody
|
||||
id="pf-modal-part-3"
|
||||
>
|
||||
<div
|
||||
className="pf-c-modal-box__body"
|
||||
id="pf-modal-part-3"
|
||||
>
|
||||
If you delete this client, all associated data will be removed.
|
||||
</div>
|
||||
</ModalBoxBody>
|
||||
<ModalBoxFooter>
|
||||
<footer
|
||||
className="pf-c-modal-box__footer"
|
||||
>
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
key="confirm"
|
||||
onClick={[Function]}
|
||||
variant="primary"
|
||||
>
|
||||
<button
|
||||
aria-disabled={false}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-primary"
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
id="modal-confirm"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</Button>
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
key="cancel"
|
||||
onClick={[Function]}
|
||||
variant="secondary"
|
||||
>
|
||||
<button
|
||||
aria-disabled={false}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-secondary"
|
||||
data-ouia-component-id="OUIA-Generated-Button-secondary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
id="modal-cancel"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
cancel
|
||||
</button>
|
||||
</Button>
|
||||
</footer>
|
||||
</ModalBoxFooter>
|
||||
</div>
|
||||
</ModalBox>
|
||||
</div>
|
||||
</FocusTrap>
|
||||
</div>
|
||||
</Backdrop>
|
||||
</ModalContent>
|
||||
</Portal>
|
||||
</Modal>
|
||||
</ConfirmDialogModal>
|
||||
</Dialog>
|
||||
</Test>
|
||||
`;
|
|
@ -1,15 +1,18 @@
|
|||
import React from "react";
|
||||
import { ExternalLinkAltIcon } from "@patternfly/react-icons";
|
||||
import { Button, ButtonProps } from "@patternfly/react-core";
|
||||
|
||||
export const ExternalLink = ({
|
||||
title,
|
||||
href,
|
||||
...rest
|
||||
}: React.HTMLProps<HTMLAnchorElement>) => {
|
||||
export const ExternalLink = ({ title, href, ...rest }: ButtonProps) => {
|
||||
return (
|
||||
<a href={href} {...rest}>
|
||||
{title ? title : href}{" "}
|
||||
{href?.startsWith("http") && <ExternalLinkAltIcon />}
|
||||
</a>
|
||||
<Button
|
||||
variant="link"
|
||||
icon={href?.startsWith("http") && <ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
component="a"
|
||||
href={href}
|
||||
{...rest}
|
||||
>
|
||||
{title ? title : href}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -14,4 +14,18 @@ describe("<ExternalLink />", () => {
|
|||
);
|
||||
expect(comp.asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("render with internal url", () => {
|
||||
const comp = render(
|
||||
<ExternalLink href="/application/home/" title="Application page" />
|
||||
);
|
||||
expect(comp.asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("render as application", () => {
|
||||
const comp = render(
|
||||
<ExternalLink href="/application/main" title="Application link" />
|
||||
);
|
||||
expect(comp.asFragment()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,25 +1,63 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<ExternalLink /> render as application 1`] = `
|
||||
<DocumentFragment>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-4"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="/application/main"
|
||||
>
|
||||
Application link
|
||||
</a>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<ExternalLink /> render with internal url 1`] = `
|
||||
<DocumentFragment>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-3"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="/application/home/"
|
||||
>
|
||||
Application page
|
||||
</a>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<ExternalLink /> render with link 1`] = `
|
||||
<DocumentFragment>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://hello.nl/"
|
||||
>
|
||||
http://hello.nl/
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
http://hello.nl/
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
@ -27,23 +65,31 @@ exports[`<ExternalLink /> render with link 1`] = `
|
|||
exports[`<ExternalLink /> render with link and title 1`] = `
|
||||
<DocumentFragment>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-link"
|
||||
data-ouia-component-id="OUIA-Generated-Button-link-2"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
href="http://hello.nl/"
|
||||
>
|
||||
Link to Hello
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
Link to Hello
|
||||
<span
|
||||
class="pf-c-button__icon pf-m-end"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 0 512 512"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import React from "react";
|
||||
import React, { useContext } from "react";
|
||||
import { Tooltip } from "@patternfly/react-core";
|
||||
import { HelpIcon } from "@patternfly/react-icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpContext } from "./HelpHeader";
|
||||
|
||||
type HelpItemProps = {
|
||||
item: string;
|
||||
|
@ -9,11 +10,16 @@ type HelpItemProps = {
|
|||
|
||||
export const HelpItem = ({ item }: HelpItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { enabled } = useContext(HelpContext);
|
||||
return (
|
||||
<Tooltip position="right" content={t(`help:${item}`)}>
|
||||
<span id={item} data-testid={item}>
|
||||
<HelpIcon />
|
||||
</span>
|
||||
</Tooltip>
|
||||
<>
|
||||
{enabled && (
|
||||
<Tooltip position="right" content={t(`help:${item}`)}>
|
||||
<span id={item} data-testid={item}>
|
||||
<HelpIcon />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ exports[`<HelpHeader /> enable help 1`] = `
|
|||
<DocumentFragment>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right pf-m-expanded"
|
||||
data-ouia-component-id="5"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-3"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -23,12 +23,11 @@ exports[`<HelpHeader /> enable help 1`] = `
|
|||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 64 1024 1024"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512.059-73.143c-282.338 0-512.059 229.673-512.059 512.025 0 282.235 229.721 511.975 512.059 511.975 282.281 0 511.941-229.735 511.941-511.975 0.005-282.352-229.659-512.025-511.941-512.025zM512.059 826.523c-213.826 0-387.728-173.856-387.728-387.643 0-213.89 173.904-387.694 387.728-387.694 213.717 0 387.671 173.803 387.671 387.694 0.005 213.785-173.957 387.643-387.671 387.643zM585.143 164.571v109.714c0 4.951-1.808 9.237-5.429 12.857s-7.906 5.429-12.857 5.429h-109.714c-4.953 0-9.239-1.808-12.857-5.429s-5.429-7.906-5.429-12.857v-109.714c0-4.951 1.81-9.237 5.429-12.857s7.904-5.429 12.857-5.429h109.714c4.951 0 9.237 1.808 12.857 5.429s5.429 7.906 5.429 12.857zM521.616 365.714c118.343 0 214.286 88.965 214.286 187.429s-95.943 178.286-214.286 178.286c-173.045 0-208.091-93.714-213.963-171.113 0-7.936 6.729-9.838 15.872-9.838s108.073 0 113.143 0c6.096 0 14.475 0.633 17.554 10.571 0 48.857 135.968 54.953 135.968-7.904 0-31.506-29.717-63.817-68.571-66.194s-82.286-7.607-82.286-54.199c0-13.022 0-25.673 0-44.693 0-19.015 9.717-22.343 27.431-22.343s54.853-0.002 54.853-0.002z"
|
||||
transform="rotate(180 0 512) scale(-1 1)"
|
||||
d="M521.3,576 C627.5,576 713.7,502 713.7,413.7 C713.7,325.4 627.6,253.6 521.3,253.6 C366,253.6 334.5,337.7 329.2,407.2 C329.2,414.3 335.2,416 343.5,416 L445,416 C450.5,416 458,415.5 460.8,406.5 C460.8,362.6 582.9,357.1 582.9,413.6 C582.9,441.9 556.2,470.9 521.3,473 C486.4,475.1 447.3,479.8 447.3,521.7 L447.3,553.8 C447.3,570.8 456.1,576 472,576 C487.9,576 521.3,576 521.3,576 M575.3,751.3 L575.3,655.3 C575.313862,651.055109 573.620137,646.982962 570.6,644 C567.638831,640.947672 563.552355,639.247987 559.3,639.29884 L463.3,639.29884 C459.055109,639.286138 454.982962,640.979863 452,644 C448.947672,646.961169 447.247987,651.047645 447.29884,655.3 L447.29884,751.3 C447.286138,755.544891 448.979863,759.617038 452,762.6 C454.961169,765.652328 459.047645,767.352013 463.3,767.30116 L559.3,767.30116 C563.544891,767.313862 567.617038,765.620137 570.6,762.6 C573.659349,759.643612 575.360354,755.553963 575.3,751.3 M512,896 C300.2,896 128,723.9 128,512 C128,300.3 300.2,128 512,128 C723.8,128 896,300.2 896,512 C896,723.8 723.7,896 512,896 M512.1,0 C229.7,0 0,229.8 0,512 C0,794.2 229.8,1024 512.1,1024 C794.4,1024 1024,794.3 1024,512 C1024,229.7 794.4,0 512.1,0"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
@ -69,7 +68,6 @@ exports[`<HelpHeader /> enable help 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -101,7 +99,7 @@ exports[`<HelpHeader /> enable help 1`] = `
|
|||
>
|
||||
<label
|
||||
class="pf-c-switch"
|
||||
data-ouia-component-id="6"
|
||||
data-ouia-component-id="OUIA-Generated-Switch-2"
|
||||
data-ouia-component-type="PF4/Switch"
|
||||
data-ouia-safe="true"
|
||||
for="enableHelp"
|
||||
|
@ -130,7 +128,6 @@ exports[`<HelpHeader /> enable help 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -160,7 +157,7 @@ exports[`<HelpHeader /> open dropdown 1`] = `
|
|||
<DocumentFragment>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right pf-m-expanded"
|
||||
data-ouia-component-id="2"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-2"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -179,12 +176,11 @@ exports[`<HelpHeader /> open dropdown 1`] = `
|
|||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 64 1024 1024"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512.059-73.143c-282.338 0-512.059 229.673-512.059 512.025 0 282.235 229.721 511.975 512.059 511.975 282.281 0 511.941-229.735 511.941-511.975 0.005-282.352-229.659-512.025-511.941-512.025zM512.059 826.523c-213.826 0-387.728-173.856-387.728-387.643 0-213.89 173.904-387.694 387.728-387.694 213.717 0 387.671 173.803 387.671 387.694 0.005 213.785-173.957 387.643-387.671 387.643zM585.143 164.571v109.714c0 4.951-1.808 9.237-5.429 12.857s-7.906 5.429-12.857 5.429h-109.714c-4.953 0-9.239-1.808-12.857-5.429s-5.429-7.906-5.429-12.857v-109.714c0-4.951 1.81-9.237 5.429-12.857s7.904-5.429 12.857-5.429h109.714c4.951 0 9.237 1.808 12.857 5.429s5.429 7.906 5.429 12.857zM521.616 365.714c118.343 0 214.286 88.965 214.286 187.429s-95.943 178.286-214.286 178.286c-173.045 0-208.091-93.714-213.963-171.113 0-7.936 6.729-9.838 15.872-9.838s108.073 0 113.143 0c6.096 0 14.475 0.633 17.554 10.571 0 48.857 135.968 54.953 135.968-7.904 0-31.506-29.717-63.817-68.571-66.194s-82.286-7.607-82.286-54.199c0-13.022 0-25.673 0-44.693 0-19.015 9.717-22.343 27.431-22.343s54.853-0.002 54.853-0.002z"
|
||||
transform="rotate(180 0 512) scale(-1 1)"
|
||||
d="M521.3,576 C627.5,576 713.7,502 713.7,413.7 C713.7,325.4 627.6,253.6 521.3,253.6 C366,253.6 334.5,337.7 329.2,407.2 C329.2,414.3 335.2,416 343.5,416 L445,416 C450.5,416 458,415.5 460.8,406.5 C460.8,362.6 582.9,357.1 582.9,413.6 C582.9,441.9 556.2,470.9 521.3,473 C486.4,475.1 447.3,479.8 447.3,521.7 L447.3,553.8 C447.3,570.8 456.1,576 472,576 C487.9,576 521.3,576 521.3,576 M575.3,751.3 L575.3,655.3 C575.313862,651.055109 573.620137,646.982962 570.6,644 C567.638831,640.947672 563.552355,639.247987 559.3,639.29884 L463.3,639.29884 C459.055109,639.286138 454.982962,640.979863 452,644 C448.947672,646.961169 447.247987,651.047645 447.29884,655.3 L447.29884,751.3 C447.286138,755.544891 448.979863,759.617038 452,762.6 C454.961169,765.652328 459.047645,767.352013 463.3,767.30116 L559.3,767.30116 C563.544891,767.313862 567.617038,765.620137 570.6,762.6 C573.659349,759.643612 575.360354,755.553963 575.3,751.3 M512,896 C300.2,896 128,723.9 128,512 C128,300.3 300.2,128 512,128 C723.8,128 896,300.2 896,512 C896,723.8 723.7,896 512,896 M512.1,0 C229.7,0 0,229.8 0,512 C0,794.2 229.8,1024 512.1,1024 C794.4,1024 1024,794.3 1024,512 C1024,229.7 794.4,0 512.1,0"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
@ -225,7 +221,6 @@ exports[`<HelpHeader /> open dropdown 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -257,7 +252,7 @@ exports[`<HelpHeader /> open dropdown 1`] = `
|
|||
>
|
||||
<label
|
||||
class="pf-c-switch"
|
||||
data-ouia-component-id="3"
|
||||
data-ouia-component-id="OUIA-Generated-Switch-1"
|
||||
data-ouia-component-type="PF4/Switch"
|
||||
data-ouia-safe="true"
|
||||
for="enableHelp"
|
||||
|
@ -286,7 +281,6 @@ exports[`<HelpHeader /> open dropdown 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -311,7 +305,7 @@ exports[`<HelpHeader /> render 1`] = `
|
|||
<DocumentFragment>
|
||||
<div
|
||||
class="pf-c-dropdown pf-m-align-right"
|
||||
data-ouia-component-id="0"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-1"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -330,12 +324,11 @@ exports[`<HelpHeader /> render 1`] = `
|
|||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 64 1024 1024"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512.059-73.143c-282.338 0-512.059 229.673-512.059 512.025 0 282.235 229.721 511.975 512.059 511.975 282.281 0 511.941-229.735 511.941-511.975 0.005-282.352-229.659-512.025-511.941-512.025zM512.059 826.523c-213.826 0-387.728-173.856-387.728-387.643 0-213.89 173.904-387.694 387.728-387.694 213.717 0 387.671 173.803 387.671 387.694 0.005 213.785-173.957 387.643-387.671 387.643zM585.143 164.571v109.714c0 4.951-1.808 9.237-5.429 12.857s-7.906 5.429-12.857 5.429h-109.714c-4.953 0-9.239-1.808-12.857-5.429s-5.429-7.906-5.429-12.857v-109.714c0-4.951 1.81-9.237 5.429-12.857s7.904-5.429 12.857-5.429h109.714c4.951 0 9.237 1.808 12.857 5.429s5.429 7.906 5.429 12.857zM521.616 365.714c118.343 0 214.286 88.965 214.286 187.429s-95.943 178.286-214.286 178.286c-173.045 0-208.091-93.714-213.963-171.113 0-7.936 6.729-9.838 15.872-9.838s108.073 0 113.143 0c6.096 0 14.475 0.633 17.554 10.571 0 48.857 135.968 54.953 135.968-7.904 0-31.506-29.717-63.817-68.571-66.194s-82.286-7.607-82.286-54.199c0-13.022 0-25.673 0-44.693 0-19.015 9.717-22.343 27.431-22.343s54.853-0.002 54.853-0.002z"
|
||||
transform="rotate(180 0 512) scale(-1 1)"
|
||||
d="M521.3,576 C627.5,576 713.7,502 713.7,413.7 C713.7,325.4 627.6,253.6 521.3,253.6 C366,253.6 334.5,337.7 329.2,407.2 C329.2,414.3 335.2,416 343.5,416 L445,416 C450.5,416 458,415.5 460.8,406.5 C460.8,362.6 582.9,357.1 582.9,413.6 C582.9,441.9 556.2,470.9 521.3,473 C486.4,475.1 447.3,479.8 447.3,521.7 L447.3,553.8 C447.3,570.8 456.1,576 472,576 C487.9,576 521.3,576 521.3,576 M575.3,751.3 L575.3,655.3 C575.313862,651.055109 573.620137,646.982962 570.6,644 C567.638831,640.947672 563.552355,639.247987 559.3,639.29884 L463.3,639.29884 C459.055109,639.286138 454.982962,640.979863 452,644 C448.947672,646.961169 447.247987,651.047645 447.29884,655.3 L447.29884,751.3 C447.286138,755.544891 448.979863,759.617038 452,762.6 C454.961169,765.652328 459.047645,767.352013 463.3,767.30116 L559.3,767.30116 C563.544891,767.313862 567.617038,765.620137 570.6,762.6 C573.659349,759.643612 575.360354,755.553963 575.3,751.3 M512,896 C300.2,896 128,723.9 128,512 C128,300.3 300.2,128 512,128 C723.8,128 896,300.2 896,512 C896,723.8 723.7,896 512,896 M512.1,0 C229.7,0 0,229.8 0,512 C0,794.2 229.8,1024 512.1,1024 C794.4,1024 1024,794.3 1024,512 C1024,229.7 794.4,0 512.1,0"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
|
|
@ -13,12 +13,11 @@ exports[`<HelpItem /> render 1`] = `
|
|||
height="1em"
|
||||
role="img"
|
||||
style="vertical-align: -0.125em;"
|
||||
viewBox="0 64 1024 1024"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512.059-73.143c-282.338 0-512.059 229.673-512.059 512.025 0 282.235 229.721 511.975 512.059 511.975 282.281 0 511.941-229.735 511.941-511.975 0.005-282.352-229.659-512.025-511.941-512.025zM512.059 826.523c-213.826 0-387.728-173.856-387.728-387.643 0-213.89 173.904-387.694 387.728-387.694 213.717 0 387.671 173.803 387.671 387.694 0.005 213.785-173.957 387.643-387.671 387.643zM585.143 164.571v109.714c0 4.951-1.808 9.237-5.429 12.857s-7.906 5.429-12.857 5.429h-109.714c-4.953 0-9.239-1.808-12.857-5.429s-5.429-7.906-5.429-12.857v-109.714c0-4.951 1.81-9.237 5.429-12.857s7.904-5.429 12.857-5.429h109.714c4.951 0 9.237 1.808 12.857 5.429s5.429 7.906 5.429 12.857zM521.616 365.714c118.343 0 214.286 88.965 214.286 187.429s-95.943 178.286-214.286 178.286c-173.045 0-208.091-93.714-213.963-171.113 0-7.936 6.729-9.838 15.872-9.838s108.073 0 113.143 0c6.096 0 14.475 0.633 17.554 10.571 0 48.857 135.968 54.953 135.968-7.904 0-31.506-29.717-63.817-68.571-66.194s-82.286-7.607-82.286-54.199c0-13.022 0-25.673 0-44.693 0-19.015 9.717-22.343 27.431-22.343s54.853-0.002 54.853-0.002z"
|
||||
transform="rotate(180 0 512) scale(-1 1)"
|
||||
d="M521.3,576 C627.5,576 713.7,502 713.7,413.7 C713.7,325.4 627.6,253.6 521.3,253.6 C366,253.6 334.5,337.7 329.2,407.2 C329.2,414.3 335.2,416 343.5,416 L445,416 C450.5,416 458,415.5 460.8,406.5 C460.8,362.6 582.9,357.1 582.9,413.6 C582.9,441.9 556.2,470.9 521.3,473 C486.4,475.1 447.3,479.8 447.3,521.7 L447.3,553.8 C447.3,570.8 456.1,576 472,576 C487.9,576 521.3,576 521.3,576 M575.3,751.3 L575.3,655.3 C575.313862,651.055109 573.620137,646.982962 570.6,644 C567.638831,640.947672 563.552355,639.247987 559.3,639.29884 L463.3,639.29884 C459.055109,639.286138 454.982962,640.979863 452,644 C448.947672,646.961169 447.247987,651.047645 447.29884,655.3 L447.29884,751.3 C447.286138,755.544891 448.979863,759.617038 452,762.6 C454.961169,765.652328 459.047645,767.352013 463.3,767.30116 L559.3,767.30116 C563.544891,767.313862 567.617038,765.620137 570.6,762.6 C573.659349,759.643612 575.360354,755.553963 575.3,751.3 M512,896 C300.2,896 128,723.9 128,512 C128,300.3 300.2,128 512,128 C723.8,128 896,300.2 896,512 C896,723.8 723.7,896 512,896 M512.1,0 C229.7,0 0,229.8 0,512 C0,794.2 229.8,1024 512.1,1024 C794.4,1024 1024,794.3 1024,512 C1024,229.7 794.4,0 512.1,0"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
|
|
@ -118,6 +118,7 @@ exports[`<JsonFileUpload /> render 1`] = `
|
|||
id="test-filename"
|
||||
innerRef={null}
|
||||
isDisabled={false}
|
||||
isLeftTruncated={false}
|
||||
isReadOnly={true}
|
||||
isRequired={false}
|
||||
name="test-filename"
|
||||
|
@ -135,7 +136,9 @@ exports[`<JsonFileUpload /> render 1`] = `
|
|||
disabled={false}
|
||||
id="test-filename"
|
||||
name="test-filename"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder="Drag a file here or browse to upload"
|
||||
readOnly={true}
|
||||
required={false}
|
||||
|
@ -155,7 +158,7 @@ exports[`<JsonFileUpload /> render 1`] = `
|
|||
aria-disabled={false}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-control"
|
||||
data-ouia-component-id={0}
|
||||
data-ouia-component-id="OUIA-Generated-Button-control-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
|
@ -176,7 +179,7 @@ exports[`<JsonFileUpload /> render 1`] = `
|
|||
aria-disabled={true}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-control pf-m-disabled"
|
||||
data-ouia-component-id={1}
|
||||
data-ouia-component-id="OUIA-Generated-Button-control-2"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={true}
|
||||
|
@ -370,6 +373,7 @@ exports[`<JsonFileUpload /> upload file 1`] = `
|
|||
id="upload-filename"
|
||||
innerRef={null}
|
||||
isDisabled={false}
|
||||
isLeftTruncated={false}
|
||||
isReadOnly={true}
|
||||
isRequired={false}
|
||||
name="upload-filename"
|
||||
|
@ -387,7 +391,9 @@ exports[`<JsonFileUpload /> upload file 1`] = `
|
|||
disabled={false}
|
||||
id="upload-filename"
|
||||
name="upload-filename"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder="Drag a file here or browse to upload"
|
||||
readOnly={true}
|
||||
required={false}
|
||||
|
@ -407,7 +413,7 @@ exports[`<JsonFileUpload /> upload file 1`] = `
|
|||
aria-disabled={false}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-control"
|
||||
data-ouia-component-id={4}
|
||||
data-ouia-component-id="OUIA-Generated-Button-control-3"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={false}
|
||||
|
@ -428,7 +434,7 @@ exports[`<JsonFileUpload /> upload file 1`] = `
|
|||
aria-disabled={true}
|
||||
aria-label={null}
|
||||
className="pf-c-button pf-m-control pf-m-disabled"
|
||||
data-ouia-component-id={5}
|
||||
data-ouia-component-id="OUIA-Generated-Button-control-4"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe={true}
|
||||
disabled={true}
|
||||
|
|
|
@ -20,7 +20,6 @@ exports[`<ListEmptyState /> render 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
<h4
|
||||
|
@ -36,7 +35,7 @@ exports[`<ListEmptyState /> render 1`] = `
|
|||
<button
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-primary"
|
||||
data-ouia-component-id="0"
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
type="button"
|
||||
|
|
78
src/components/multi-line-input/MultiLineInput.tsx
Normal file
78
src/components/multi-line-input/MultiLineInput.tsx
Normal file
|
@ -0,0 +1,78 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { useFieldArray, UseFormMethods } from "react-hook-form";
|
||||
import {
|
||||
TextInput,
|
||||
Split,
|
||||
SplitItem,
|
||||
Button,
|
||||
ButtonVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { MinusIcon, PlusIcon } from "@patternfly/react-icons";
|
||||
|
||||
type MultiLine = {
|
||||
value: string;
|
||||
};
|
||||
|
||||
export function convertToMultiline(fields: string[]): MultiLine[] {
|
||||
return fields.map((field) => {
|
||||
return { value: field };
|
||||
});
|
||||
}
|
||||
|
||||
export function toValue(formValue: MultiLine[]): string[] {
|
||||
return formValue.map((field) => field.value);
|
||||
}
|
||||
|
||||
export type MultiLineInputProps = {
|
||||
form: UseFormMethods;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const MultiLineInput = ({ name, form }: MultiLineInputProps) => {
|
||||
const { register, control } = form;
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
name,
|
||||
control,
|
||||
});
|
||||
useEffect(() => {
|
||||
form.reset({
|
||||
[name]: [{ value: "" }],
|
||||
});
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
{fields.map(({ id, value }, index) => (
|
||||
<Split key={id}>
|
||||
<SplitItem>
|
||||
<TextInput
|
||||
id={id}
|
||||
ref={register()}
|
||||
name={`${name}[${index}].value`}
|
||||
defaultValue={value}
|
||||
/>
|
||||
</SplitItem>
|
||||
<SplitItem>
|
||||
{index === fields.length - 1 && (
|
||||
<Button
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => append({})}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
)}
|
||||
{index !== fields.length - 1 && (
|
||||
<Button
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => remove(index)}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<MinusIcon />
|
||||
</Button>
|
||||
)}
|
||||
</SplitItem>
|
||||
</Split>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useContext } from "react";
|
||||
import React, { useState, useContext, useEffect } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
import {
|
||||
|
@ -34,14 +34,19 @@ export const RealmSelector = ({ realmList }: RealmSelectorProps) => {
|
|||
realmName.charAt(0).toUpperCase() + realmName.slice(1);
|
||||
|
||||
const RealmText = ({ value }: { value: string }) => (
|
||||
<Split>
|
||||
<Split className="keycloak__realm_selector__list-item-split">
|
||||
<SplitItem isFilled>{toUpperCase(value)}</SplitItem>
|
||||
<SplitItem>{value === realm && <CheckIcon />}</SplitItem>
|
||||
</Split>
|
||||
);
|
||||
|
||||
const AddRealm = () => (
|
||||
<Button component="div" isBlock onClick={() => history.push("/add-realm")}>
|
||||
const AddRealm = ({ className }: { className?: string }) => (
|
||||
<Button
|
||||
component="div"
|
||||
isBlock
|
||||
onClick={() => history.push("/add-realm")}
|
||||
className={className}
|
||||
>
|
||||
Create Realm
|
||||
</Button>
|
||||
);
|
||||
|
@ -56,6 +61,10 @@ export const RealmSelector = ({ realmList }: RealmSelectorProps) => {
|
|||
setFilteredItems(filtered || []);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
onFilter();
|
||||
}, [search]);
|
||||
|
||||
const dropdownItems = realmList.map((r) => (
|
||||
<DropdownItem
|
||||
key={r.id}
|
||||
|
|
|
@ -79,7 +79,7 @@ exports[`renders realm selector 1`] = `
|
|||
>
|
||||
<div
|
||||
className="pf-c-dropdown keycloak__realm_selector__dropdown"
|
||||
data-ouia-component-id={0}
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-1"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe={true}
|
||||
id="realm-select"
|
||||
|
@ -98,7 +98,7 @@ exports[`renders realm selector 1`] = `
|
|||
Object {
|
||||
"current": <div
|
||||
class="pf-c-dropdown pf-m-expanded keycloak__realm_selector__dropdown"
|
||||
data-ouia-component-id="1"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-1"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
id="realm-select"
|
||||
|
@ -129,7 +129,6 @@ exports[`renders realm selector 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
@ -148,7 +147,7 @@ exports[`renders realm selector 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="pf-l-split"
|
||||
class="pf-l-split keycloak__realm_selector__list-item-split"
|
||||
>
|
||||
<div
|
||||
class="pf-l-split__item pf-m-fill"
|
||||
|
@ -176,7 +175,7 @@ exports[`renders realm selector 1`] = `
|
|||
<div
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
data-ouia-component-id="2"
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -207,7 +206,7 @@ exports[`renders realm selector 1`] = `
|
|||
Object {
|
||||
"current": <div
|
||||
class="pf-c-dropdown pf-m-expanded keycloak__realm_selector__dropdown"
|
||||
data-ouia-component-id="1"
|
||||
data-ouia-component-id="OUIA-Generated-Dropdown-1"
|
||||
data-ouia-component-type="PF4/Dropdown"
|
||||
data-ouia-safe="true"
|
||||
id="realm-select"
|
||||
|
@ -238,7 +237,6 @@ exports[`renders realm selector 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
@ -257,7 +255,7 @@ exports[`renders realm selector 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="pf-l-split"
|
||||
class="pf-l-split keycloak__realm_selector__list-item-split"
|
||||
>
|
||||
<div
|
||||
class="pf-l-split__item pf-m-fill"
|
||||
|
@ -285,7 +283,7 @@ exports[`renders realm selector 1`] = `
|
|||
<div
|
||||
aria-disabled="false"
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
data-ouia-component-id="2"
|
||||
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
||||
data-ouia-component-type="PF4/Button"
|
||||
data-ouia-safe="true"
|
||||
>
|
||||
|
@ -337,7 +335,6 @@ exports[`renders realm selector 1`] = `
|
|||
>
|
||||
<path
|
||||
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
|
||||
transform=""
|
||||
/>
|
||||
</svg>
|
||||
</CaretDownIcon>
|
||||
|
|
|
@ -26,6 +26,18 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.keycloak__realm_selector__list-item-split {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* the last child is the realm selector button, and this is the only way to style the li around it */
|
||||
.keycloak__realm_selector__context_selector li:last-child {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background-color: var(--pf-c-context-selector__menu--BackgroundColor);
|
||||
}
|
||||
|
||||
.keycloak__page_nav__nav_item__realm-selector {
|
||||
margin-top: var(--pf-c-nav__link--PaddingTop);
|
||||
padding-right: var(--pf-c-nav__link--PaddingRight);
|
||||
|
|
|
@ -7,9 +7,11 @@ import {
|
|||
InputGroup,
|
||||
TextInput,
|
||||
Button,
|
||||
ButtonVariant,
|
||||
Pagination,
|
||||
} from "@patternfly/react-core";
|
||||
import { SearchIcon } from "@patternfly/react-icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
type TableToolbarProps = {
|
||||
count: number;
|
||||
|
@ -20,6 +22,12 @@ type TableToolbarProps = {
|
|||
onPerPageSelect: (max: number, first: number) => void;
|
||||
toolbarItem?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
inputGroupName?: string;
|
||||
inputGroupPlaceholder?: string;
|
||||
inputGroupOnChange?: (
|
||||
newInput: string,
|
||||
event: React.FormEvent<HTMLInputElement>
|
||||
) => void;
|
||||
};
|
||||
|
||||
export const TableToolbar = ({
|
||||
|
@ -31,7 +39,11 @@ export const TableToolbar = ({
|
|||
onPerPageSelect,
|
||||
toolbarItem,
|
||||
children,
|
||||
inputGroupName,
|
||||
inputGroupPlaceholder,
|
||||
inputGroupOnChange,
|
||||
}: TableToolbarProps) => {
|
||||
const { t } = useTranslation("groups");
|
||||
const page = first / max;
|
||||
const pagination = (variant: "top" | "bottom" = "top") => (
|
||||
<Pagination
|
||||
|
@ -55,15 +67,29 @@ export const TableToolbar = ({
|
|||
<>
|
||||
<Toolbar>
|
||||
<ToolbarContent>
|
||||
<ToolbarItem>
|
||||
<InputGroup>
|
||||
<TextInput type="text" aria-label="search for client criteria" />
|
||||
<Button variant="control" aria-label="search for client">
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</ToolbarItem>
|
||||
{toolbarItem && <ToolbarItem>{toolbarItem}</ToolbarItem>}
|
||||
<React.Fragment>
|
||||
{inputGroupName && (
|
||||
<ToolbarItem>
|
||||
<InputGroup>
|
||||
<TextInput
|
||||
name={inputGroupName}
|
||||
id={inputGroupName}
|
||||
type="search"
|
||||
aria-label={t("Search")}
|
||||
placeholder={inputGroupPlaceholder}
|
||||
onChange={inputGroupOnChange}
|
||||
/>
|
||||
<Button
|
||||
variant={ButtonVariant.control}
|
||||
aria-label={t("Search")}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</ToolbarItem>
|
||||
)}
|
||||
</React.Fragment>
|
||||
{toolbarItem}
|
||||
<ToolbarItem variant="pagination">{pagination()}</ToolbarItem>
|
||||
</ToolbarContent>
|
||||
</Toolbar>
|
||||
|
|
108
src/components/view-header/ViewHeader.tsx
Normal file
108
src/components/view-header/ViewHeader.tsx
Normal file
|
@ -0,0 +1,108 @@
|
|||
import React, { ReactElement, useContext, useState } from "react";
|
||||
import {
|
||||
Text,
|
||||
PageSection,
|
||||
TextContent,
|
||||
Divider,
|
||||
Level,
|
||||
LevelItem,
|
||||
Switch,
|
||||
Toolbar,
|
||||
ToolbarContent,
|
||||
ToolbarItem,
|
||||
Badge,
|
||||
Select,
|
||||
} from "@patternfly/react-core";
|
||||
import { HelpContext } from "../help-enabler/HelpHeader";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export type ViewHeaderProps = {
|
||||
titleKey: string;
|
||||
badge?: string;
|
||||
subKey: string;
|
||||
selectItems?: ReactElement[];
|
||||
isEnabled?: boolean;
|
||||
onSelect?: (value: string) => void;
|
||||
onToggle?: (value: boolean) => void;
|
||||
};
|
||||
|
||||
export const ViewHeader = ({
|
||||
titleKey,
|
||||
badge,
|
||||
subKey,
|
||||
selectItems,
|
||||
isEnabled,
|
||||
onSelect,
|
||||
onToggle,
|
||||
}: ViewHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { enabled } = useContext(HelpContext);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [checked, setChecked] = useState(isEnabled);
|
||||
return (
|
||||
<>
|
||||
<PageSection variant="light">
|
||||
<Level hasGutter>
|
||||
<LevelItem>
|
||||
<Level>
|
||||
<LevelItem>
|
||||
<TextContent className="pf-u-mr-sm">
|
||||
<Text component="h1">{t(titleKey)}</Text>
|
||||
</TextContent>
|
||||
</LevelItem>
|
||||
{badge && (
|
||||
<LevelItem>
|
||||
<Badge>{badge}</Badge>
|
||||
</LevelItem>
|
||||
)}
|
||||
</Level>
|
||||
</LevelItem>
|
||||
<LevelItem></LevelItem>
|
||||
{selectItems && (
|
||||
<LevelItem>
|
||||
<Toolbar>
|
||||
<ToolbarContent>
|
||||
<ToolbarItem>
|
||||
<Switch
|
||||
id={`${titleKey}-switch`}
|
||||
label={t("common:enabled")}
|
||||
labelOff={t("common:disabled")}
|
||||
className="pf-u-mr-lg"
|
||||
isChecked={checked}
|
||||
onChange={(value) => {
|
||||
if (onToggle) {
|
||||
onToggle(value);
|
||||
}
|
||||
setChecked(value);
|
||||
}}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Select
|
||||
isOpen={open}
|
||||
onToggle={() => setOpen(!open)}
|
||||
onSelect={(_, value) => {
|
||||
if (onSelect) {
|
||||
onSelect(value as string);
|
||||
}
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
{selectItems}
|
||||
</Select>
|
||||
</ToolbarItem>
|
||||
</ToolbarContent>
|
||||
</Toolbar>
|
||||
</LevelItem>
|
||||
)}
|
||||
</Level>
|
||||
{enabled && (
|
||||
<TextContent>
|
||||
<Text>{t(subKey)}</Text>
|
||||
</TextContent>
|
||||
)}
|
||||
</PageSection>
|
||||
<Divider />
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -11,10 +11,11 @@ import {
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { HttpClientContext } from "../http-service/HttpClientContext";
|
||||
import { RealmContext } from "../components/realm-context/RealmContext";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
|
||||
export const GroupsCreateModal = ({isCreateModalOpen, handleModalToggle}) => {
|
||||
|
||||
const { t } = useTranslation("group");
|
||||
const { t } = useTranslation("groups");
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const { realm } = useContext(RealmContext);
|
||||
const [ nameValue, setNameValue ] = useState("");
|
||||
|
@ -46,7 +47,7 @@ export const GroupsCreateModal = ({isCreateModalOpen, handleModalToggle}) => {
|
|||
]}
|
||||
>
|
||||
<Form isHorizontal>
|
||||
<FormGroup label={t("rootUrl")} fieldId="kc-root-url">
|
||||
<FormGroup label={t("name")} fieldId="kc-root-url">
|
||||
<TextInput
|
||||
type="text"
|
||||
id="create-group-name"
|
||||
|
|
|
@ -1,35 +1,106 @@
|
|||
import React from "react";
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableBody,
|
||||
TableVariant,
|
||||
} from "@patternfly/react-table";
|
||||
import { GroupRepresentation } from "./models/groups";
|
||||
import { Button } from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GroupRepresentation } from "./models/groups";
|
||||
import { UsersIcon } from "@patternfly/react-icons";
|
||||
import { HttpClientContext } from "../http-service/HttpClientContext";
|
||||
|
||||
type GroupsListProps = {
|
||||
list: GroupRepresentation[];
|
||||
list?: GroupRepresentation[];
|
||||
};
|
||||
|
||||
export const GroupsList = ({ list }: GroupsListProps) => {
|
||||
const { t } = useTranslation("group");
|
||||
const columns: (keyof GroupRepresentation)[] = ["name"];
|
||||
const { t } = useTranslation("groups");
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const columnGroupName: keyof GroupRepresentation = "name";
|
||||
const columnGroupNumber: keyof GroupRepresentation = "membersLength";
|
||||
const [formattedData, setFormattedData] = useState([
|
||||
{ cells: [<Button key="0">Test</Button>], selected: false },
|
||||
]);
|
||||
|
||||
const data = list.map((c) => {
|
||||
return { cells: columns.map((col) => c[col]) };
|
||||
});
|
||||
const formatData = (data: GroupRepresentation[]) =>
|
||||
data.map((group: { [key: string]: any }, index) => {
|
||||
const groupName = group[columnGroupName];
|
||||
const groupNumber = group[columnGroupNumber];
|
||||
return {
|
||||
cells: [
|
||||
<Button variant="link" key={index}>
|
||||
{groupName}
|
||||
</Button>,
|
||||
<div className="keycloak-admin--groups__member-count" key={index}>
|
||||
<UsersIcon />
|
||||
{groupNumber}
|
||||
</div>,
|
||||
],
|
||||
selected: false,
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setFormattedData(formatData(list!));
|
||||
}, [list]);
|
||||
|
||||
function onSelect(
|
||||
event: React.FormEvent<HTMLInputElement>,
|
||||
isSelected: boolean,
|
||||
rowId: number
|
||||
) {
|
||||
let localRow;
|
||||
if (rowId === undefined) {
|
||||
localRow = formattedData.map((row: { [key: string]: any }) => {
|
||||
row.selected = isSelected;
|
||||
return row;
|
||||
});
|
||||
} else {
|
||||
localRow = [...formattedData];
|
||||
localRow[rowId].selected = isSelected;
|
||||
setFormattedData(localRow);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete individual rows using the action in the table
|
||||
function onDelete(rowIndex: number) {
|
||||
const localFilteredData = [...list!];
|
||||
httpClient.doDelete(
|
||||
`/admin/realms/master/groups/${localFilteredData[rowIndex].id}`
|
||||
);
|
||||
// TO DO update the state
|
||||
}
|
||||
|
||||
const tableHeader = [{ title: t("groupName") }, { title: t("members") }];
|
||||
const actions = [
|
||||
{
|
||||
title: t("moveTo"),
|
||||
onClick: () => console.log("TO DO: Add move to functionality"),
|
||||
},
|
||||
{
|
||||
title: t("common:Delete"),
|
||||
onClick: () => onDelete,
|
||||
},
|
||||
];
|
||||
|
||||
console.log(list);
|
||||
return (
|
||||
<Table
|
||||
aria-label="Simple Table"
|
||||
variant={TableVariant.compact}
|
||||
cells={[{ title: t("Name") }]}
|
||||
rows={data}
|
||||
>
|
||||
<TableHeader />
|
||||
<TableBody />
|
||||
</Table>
|
||||
<React.Fragment>
|
||||
{formattedData && (
|
||||
<Table
|
||||
actions={actions}
|
||||
variant={TableVariant.compact}
|
||||
onSelect={onSelect}
|
||||
canSelectAll={false}
|
||||
aria-label={t("tableOfGroups")}
|
||||
cells={tableHeader}
|
||||
rows={formattedData}
|
||||
>
|
||||
<TableHeader />
|
||||
<TableBody />
|
||||
</Table>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
|
10
src/groups/GroupsSection.css
Normal file
10
src/groups/GroupsSection.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
.keycloak-admin--groups__member-count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.keycloak-admin--groups__member-count svg {
|
||||
color: var(--pf-global--Color--200);
|
||||
font-size: var(--pf-global--FontSize--md);
|
||||
margin-right: var(--pf-global--spacer--sm);
|
||||
}
|
|
@ -1,21 +1,40 @@
|
|||
import React, { useContext, useState } from "react";
|
||||
import React, { useContext, useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Button, PageSection } from "@patternfly/react-core";
|
||||
|
||||
import { HttpClientContext } from "../http-service/HttpClientContext";
|
||||
import { GroupsList } from "./GroupsList";
|
||||
import { GroupsCreateModal } from "./GroupsCreateModal";
|
||||
import { DataLoader } from "../components/data-loader/DataLoader";
|
||||
import { GroupRepresentation } from "./models/groups";
|
||||
import {
|
||||
ServerGroupsArrayRepresentation,
|
||||
ServerGroupMembersRepresentation,
|
||||
} from "./models/server-info";
|
||||
import { TableToolbar } from "../components/table-toolbar/TableToolbar";
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
KebabToggle,
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
Title,
|
||||
TitleSizes,
|
||||
ToolbarItem,
|
||||
} from "@patternfly/react-core";
|
||||
import "./GroupsSection.css";
|
||||
|
||||
export const GroupsSection = () => {
|
||||
const { t } = useTranslation("groups");
|
||||
const history = useHistory();
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const [rawData, setRawData] = useState([{}]);
|
||||
const [filteredData, setFilteredData] = useState([{}]);
|
||||
const [max, setMax] = useState(10);
|
||||
const [first, setFirst] = useState(0);
|
||||
const [isKebabOpen, setIsKebabOpen] = useState(false);
|
||||
const columnID: keyof GroupRepresentation = "id";
|
||||
const membersLength: keyof GroupRepresentation = "membersLength";
|
||||
const columnGroupName: keyof GroupRepresentation = "name";
|
||||
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
|
||||
|
@ -24,41 +43,113 @@ export const GroupsSection = () => {
|
|||
};
|
||||
|
||||
const loader = async () => {
|
||||
return await httpClient
|
||||
.doGet("/admin/realms/master/groups", { params: { first, max } })
|
||||
.then((r) => r.data as GroupRepresentation[]);
|
||||
const groups = await httpClient.doGet<ServerGroupsArrayRepresentation[]>(
|
||||
"/admin/realms/master/groups",
|
||||
{ params: { first, max } }
|
||||
);
|
||||
const groupsData = groups.data!;
|
||||
|
||||
const getMembers = async (id: number) => {
|
||||
const response = await httpClient.doGet<
|
||||
ServerGroupMembersRepresentation[]
|
||||
>(`/admin/realms/master/groups/${id}/members`);
|
||||
const responseData = response.data!;
|
||||
return responseData.length;
|
||||
};
|
||||
|
||||
const memberPromises = groupsData.map((group: { [key: string]: any }) =>
|
||||
getMembers(group[columnID])
|
||||
);
|
||||
const memberData = await Promise.all(memberPromises);
|
||||
const updatedObject = groupsData.map(
|
||||
(group: { [key: string]: any }, i: number) => {
|
||||
const object = Object.assign({}, group);
|
||||
object[membersLength] = memberData[i];
|
||||
return object;
|
||||
}
|
||||
);
|
||||
return updatedObject;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loader().then((data: GroupRepresentation[]) => {
|
||||
data && setRawData(data);
|
||||
setFilteredData(data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Filter groups
|
||||
const filterGroups = (newInput: string) => {
|
||||
const localRowData: object[] = [];
|
||||
rawData.forEach(function (obj: { [key: string]: string }) {
|
||||
const groupName = obj[columnGroupName];
|
||||
if (groupName.toLowerCase().includes(newInput.toLowerCase())) {
|
||||
localRowData.push(obj);
|
||||
}
|
||||
});
|
||||
setFilteredData(localRowData);
|
||||
};
|
||||
|
||||
// Kebab delete action
|
||||
const onKebabToggle = (isOpen: boolean) => {
|
||||
setIsKebabOpen(isOpen);
|
||||
};
|
||||
|
||||
const onKebabSelect = () => {
|
||||
setIsKebabOpen(!isKebabOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageSection variant="light">
|
||||
<DataLoader loader={loader}>
|
||||
{(groups) => (
|
||||
<TableToolbar
|
||||
count={groups!.length}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
onPreviousClick={setFirst}
|
||||
onPerPageSelect={(f, m) => {
|
||||
setFirst(f);
|
||||
setMax(m);
|
||||
}}
|
||||
toolbarItem={
|
||||
<>
|
||||
<Button onClick={() => handleModalToggle()}>
|
||||
{t("Create group")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<GroupsList list={groups} />
|
||||
</TableToolbar>
|
||||
|
||||
<React.Fragment>
|
||||
<PageSection variant={PageSectionVariants.light}>
|
||||
<Title headingLevel="h3" size={TitleSizes["2xl"]}>
|
||||
{t("groups")}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<Divider />
|
||||
<PageSection variant={PageSectionVariants.light}>
|
||||
<TableToolbar
|
||||
count={10}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
onPreviousClick={setFirst}
|
||||
onPerPageSelect={(f, m) => {
|
||||
setFirst(f);
|
||||
setMax(m);
|
||||
}}
|
||||
inputGroupName="groupsToolbarTextInput"
|
||||
inputGroupPlaceholder="Search groups"
|
||||
inputGroupOnChange={filterGroups}
|
||||
toolbarItem={
|
||||
<>
|
||||
<ToolbarItem>
|
||||
<Button variant="primary" onClick={() => handleModalToggle()}>
|
||||
{t("createGroup")}
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
onSelect={onKebabSelect}
|
||||
toggle={<KebabToggle onToggle={onKebabToggle} />}
|
||||
isOpen={isKebabOpen}
|
||||
isPlain
|
||||
dropdownItems={[
|
||||
<DropdownItem key="action" component="button">
|
||||
{t("delete")}
|
||||
</DropdownItem>,
|
||||
]}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{rawData && filteredData && (
|
||||
<GroupsList list={filteredData ? filteredData : rawData} />
|
||||
)}
|
||||
</DataLoader>
|
||||
</TableToolbar>
|
||||
<GroupsCreateModal isCreateModalOpen={isCreateModalOpen} handleModalToggle={handleModalToggle}/>
|
||||
</PageSection>
|
||||
</>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
|
26
src/groups/__tests__/mock-groups.json
Normal file
26
src/groups/__tests__/mock-groups.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
{
|
||||
"name": "IT-1",
|
||||
"groupNumber": 732
|
||||
},
|
||||
{
|
||||
"name": "IT-2",
|
||||
"groupNumber": 532
|
||||
},
|
||||
{
|
||||
"name": "IT-3",
|
||||
"groupNumber": 43
|
||||
},
|
||||
{
|
||||
"name": "3scale-group",
|
||||
"groupNumber": 732
|
||||
},
|
||||
{
|
||||
"name": "Fuse-group",
|
||||
"groupNumber": 532
|
||||
},
|
||||
{
|
||||
"name": "Apicurio-group",
|
||||
"groupNumber": 43
|
||||
}
|
||||
]
|
15
src/groups/messages.json
Normal file
15
src/groups/messages.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"groups": {
|
||||
"groups": "Groups",
|
||||
"createGroup": "Create group",
|
||||
"groupName": "Group name",
|
||||
"searchForGroups": "Search for groups",
|
||||
"searchGroups": "Search groups",
|
||||
"search": "Search",
|
||||
"members": "Members",
|
||||
"moveTo": "Move to",
|
||||
"delete": "Delete",
|
||||
"tableOfGroups": "Table of groups",
|
||||
"name": "Name"
|
||||
}
|
||||
}
|
|
@ -7,4 +7,7 @@ export interface GroupRepresentation {
|
|||
clientRoles?: { [index: string]: string[] };
|
||||
subGroups?: GroupRepresentation[];
|
||||
access?: { [index: string]: boolean };
|
||||
groupNumber?: number;
|
||||
membersLength?: number;
|
||||
list?: [];
|
||||
}
|
15
src/groups/models/server-info.ts
Normal file
15
src/groups/models/server-info.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export interface ServerGroupsRepresentation {
|
||||
id?: number;
|
||||
name?: string;
|
||||
path?: string;
|
||||
subGroups?: [];
|
||||
}
|
||||
|
||||
// TO DO: Update this to represent the data that is returned
|
||||
export interface ServerGroupMembersRepresentation {
|
||||
data?: [];
|
||||
}
|
||||
|
||||
export interface ServerGroupsArrayRepresentation {
|
||||
groups: { [index: string]: ServerGroupsRepresentation[] };
|
||||
}
|
|
@ -1,5 +1,13 @@
|
|||
{
|
||||
"help": {
|
||||
"storybook": "Sometimes you need some help and it's nice when the app does that"
|
||||
"storybook": "Sometimes you need some help and it's nice when the app does that",
|
||||
"clientScope": {
|
||||
"name": "Name of the client scope. Must be unique in the realm. Name should not contain space characters as it is used as value of scope parameter",
|
||||
"description": "Description of the client scope",
|
||||
"protocol": "Which SSO protocol configuration is being supplied by this client scope",
|
||||
"displayOnConsentScreen": "If on, and this client scope is added to some client with consent required, the text specified by 'Consent Screen Text' will be displayed on consent screen. If off, this client scope will not be displayed on the consent screen",
|
||||
"consentScreenText": "Text that will be shown on the consent screen when this client scope is added to some client with consent required. Defaults to name of client scope if it is not filled",
|
||||
"guiOrder": "Specify order of the provider in GUI (such as in Consent page) as integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
src/i18n.ts
13
src/i18n.ts
|
@ -4,15 +4,24 @@ import { initReactI18next } from "react-i18next";
|
|||
|
||||
import common from "./common-messages.json";
|
||||
import clients from "./clients/messages.json";
|
||||
import clientScopes from "./client-scopes/messages.json";
|
||||
import groups from "./groups/messages.json";
|
||||
import realm from "./realm/messages.json";
|
||||
import roles from "./realm-roles/messages.json";
|
||||
import help from "./help.json";
|
||||
|
||||
const initOptions = {
|
||||
ns: ["common", "help", "clients", "realm", "roles"],
|
||||
defaultNS: "common",
|
||||
resources: {
|
||||
en: { ...common, ...help, ...clients, ...realm, ...roles },
|
||||
en: {
|
||||
...common,
|
||||
...help,
|
||||
...clients,
|
||||
...clientScopes,
|
||||
...groups,
|
||||
...realm,
|
||||
...roles,
|
||||
},
|
||||
},
|
||||
lng: "en",
|
||||
fallbackLng: "en",
|
||||
|
|
|
@ -1,77 +1,77 @@
|
|||
[
|
||||
{
|
||||
"name":"Admin",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Author",
|
||||
"composite":false,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Billing",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit"
|
||||
},
|
||||
{
|
||||
"name":"Contributor",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit, consecte"
|
||||
},
|
||||
{
|
||||
"name":"Editor",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Engineer",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Member",
|
||||
"composite":false,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Moderator",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Owner",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Reader",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Subscriber",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit "
|
||||
},
|
||||
{
|
||||
"name":"Teenager",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet, consecte occaecat"
|
||||
},
|
||||
{
|
||||
"name":"User",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet, consecte"
|
||||
},
|
||||
{
|
||||
"name":"Writer",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor"
|
||||
},
|
||||
{
|
||||
"name":"Zara",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
}
|
||||
]
|
||||
{
|
||||
"name":"Admin",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Author",
|
||||
"composite":false,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Billing",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit"
|
||||
},
|
||||
{
|
||||
"name":"Contributor",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit, consecte"
|
||||
},
|
||||
{
|
||||
"name":"Editor",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Engineer",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Member",
|
||||
"composite":false,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Moderator",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Owner",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Reader",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
},
|
||||
{
|
||||
"name":"Subscriber",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit "
|
||||
},
|
||||
{
|
||||
"name":"Teenager",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet, consecte occaecat"
|
||||
},
|
||||
{
|
||||
"name":"User",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet, consecte"
|
||||
},
|
||||
{
|
||||
"name":"Writer",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor"
|
||||
},
|
||||
{
|
||||
"name":"Zara",
|
||||
"composite":true,
|
||||
"description": "Lorem ipsum dolor sit amet"
|
||||
}
|
||||
]
|
|
@ -1,22 +1,21 @@
|
|||
{
|
||||
"roles": {
|
||||
"createRole": "Create role",
|
||||
"importRole": "Import role",
|
||||
"roleID": "Role ID",
|
||||
"type": "Type",
|
||||
"homeURL": "Home URL",
|
||||
"roleExplain": "Realm-level roles are a global namespace to define your roles.",
|
||||
"roleName": "Role name",
|
||||
"composite": "Composite",
|
||||
"description": "Description",
|
||||
"roleList": "Role list",
|
||||
"generalSettings": "General Settings",
|
||||
"capabilityConfig": "Capability config",
|
||||
"roleImportError": "Could not import role",
|
||||
"roleImportSuccess": "Role imported succeful",
|
||||
"roleDeletedSucess": "The role has been deleted",
|
||||
"roleDeleteError": "Could not delete role:",
|
||||
"roleAuthentication": "Role authentication"
|
||||
}
|
||||
"roles": {
|
||||
"createRole": "Create role",
|
||||
"importRole": "Import role",
|
||||
"roleID": "Role ID",
|
||||
"type": "Type",
|
||||
"homeURL": "Home URL",
|
||||
"roleExplain": "Realm-level roles are a global namespace to define your roles.",
|
||||
"roleName": "Role name",
|
||||
"composite": "Composite",
|
||||
"description": "Description",
|
||||
"roleList": "Role list",
|
||||
"generalSettings": "General Settings",
|
||||
"capabilityConfig": "Capability config",
|
||||
"roleImportError": "Could not import role",
|
||||
"roleImportSuccess": "Role imported succeful",
|
||||
"roleDeletedSucess": "The role has been deleted",
|
||||
"roleDeleteError": "Could not delete role:",
|
||||
"roleAuthentication": "Role authentication"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import React, { useState, FormEvent, useContext } from "react";
|
||||
import React, { useContext } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Text,
|
||||
PageSection,
|
||||
TextContent,
|
||||
FormGroup,
|
||||
Form,
|
||||
TextInput,
|
||||
Switch,
|
||||
ActionGroup,
|
||||
Button,
|
||||
Divider,
|
||||
AlertVariant,
|
||||
} from "@patternfly/react-core";
|
||||
|
||||
|
@ -19,6 +16,7 @@ import { RealmRepresentation } from "../models/Realm";
|
|||
import { HttpClientContext } from "../../http-service/HttpClientContext";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
|
||||
export const NewRealmForm = () => {
|
||||
const { t } = useTranslation("realm");
|
||||
|
@ -50,12 +48,7 @@ export const NewRealmForm = () => {
|
|||
return (
|
||||
<>
|
||||
<Alerts />
|
||||
<PageSection variant="light">
|
||||
<TextContent>
|
||||
<Text component="h1">Create Realm</Text>
|
||||
</TextContent>
|
||||
</PageSection>
|
||||
<Divider />
|
||||
<ViewHeader titleKey="realm:createRealm" subKey="realm:realmExplain" />
|
||||
<PageSection variant="light">
|
||||
<Form isHorizontal onSubmit={handleSubmit(save)}>
|
||||
<JsonFileUpload id="kc-realm-filename" onChange={handleFileChange} />
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
"enabled":"Enabled",
|
||||
"create":"Create",
|
||||
"createRealm": "Create realm",
|
||||
"realmExplain": "A realm manages a set of users, credentials, roles, and groups. A user belongs to and logs into a realm. Realms are isolated from one another and can only manage and authenticate the users that they control.",
|
||||
"noRealmRoles": "No realm roles",
|
||||
"emptyStateText": "There aren't any realm roles in this realm. Create a realm role to get started."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { ClientScopeRepresentation } from "../../client-scopes/models/client-scope";
|
||||
|
||||
export interface RealmRepresentation {
|
||||
id: string;
|
||||
realm: string;
|
||||
|
@ -231,15 +233,6 @@ export interface ClientRepresentation {
|
|||
origin: string;
|
||||
}
|
||||
|
||||
export interface ClientScopeRepresentation {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
protocol: string;
|
||||
attributes: { [index: string]: string };
|
||||
protocolMappers: ProtocolMapperRepresentation[];
|
||||
}
|
||||
|
||||
export interface UserFederationProviderRepresentation {
|
||||
id: string;
|
||||
displayName: string;
|
||||
|
|
67
src/stories/ConfirmDialog.stories.tsx
Normal file
67
src/stories/ConfirmDialog.stories.tsx
Normal file
|
@ -0,0 +1,67 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TextContent,
|
||||
Text,
|
||||
TextVariants,
|
||||
ButtonVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { Meta, Story } from "@storybook/react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
|
||||
import {
|
||||
ConfirmDialogModal,
|
||||
ConfirmDialogModalProps,
|
||||
useConfirmDialog,
|
||||
} from "../components/confirm-dialog/ConfirmDialog";
|
||||
|
||||
export default {
|
||||
title: "Confirmation Dialog",
|
||||
component: ConfirmDialogModal,
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ConfirmDialogModalProps> = (args) => (
|
||||
<ConfirmDialogModal {...args} />
|
||||
);
|
||||
|
||||
export const Simple = Template.bind({});
|
||||
Simple.args = {
|
||||
titleKey: "Delete app02?",
|
||||
messageKey: "If you delete this client, all associated data will be removed.",
|
||||
continueButtonLabel: "Delete",
|
||||
continueButtonVariant: ButtonVariant.danger,
|
||||
};
|
||||
|
||||
export const Children = Template.bind({});
|
||||
Children.args = {
|
||||
titleKey: "Children as content!",
|
||||
continueButtonVariant: ButtonVariant.primary,
|
||||
children: (
|
||||
<>
|
||||
<TextContent>
|
||||
<Text component={TextVariants.h3}>Hello World</Text>
|
||||
</TextContent>
|
||||
<p>Example of some other patternfly components.</p>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
const Test = () => {
|
||||
const [toggle, Dialog] = useConfirmDialog({
|
||||
titleKey: "Delete app02?",
|
||||
messageKey:
|
||||
"If you delete this client, all associated data will be removed.",
|
||||
continueButtonLabel: "Delete",
|
||||
onConfirm: action("confirm"),
|
||||
onCancel: action("cancel"),
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<button id="show" onClick={toggle}>
|
||||
Show
|
||||
</button>
|
||||
<Dialog />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Api = () => <Test />;
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react";
|
||||
import { Meta, Story } from "@storybook/react";
|
||||
import {
|
||||
ConfirmationDialog,
|
||||
ConfirmationDialogProps,
|
||||
} from "../components/confirmation-dialog/ConfirmationDialog";
|
||||
|
||||
export default {
|
||||
title: "Confirmation dailog",
|
||||
component: ConfirmationDialog,
|
||||
parameters: { actions: { argTypesRegex: "^on.*" } },
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ConfirmationDialogProps> = (args) => (
|
||||
<ConfirmationDialog {...args} />
|
||||
);
|
||||
|
||||
export const Dialog = Template.bind({});
|
||||
Dialog.args = {
|
||||
onConfirm: () => "Confirm",
|
||||
};
|
|
@ -1,15 +1,14 @@
|
|||
import React from "react";
|
||||
import { Meta, Story } from "@storybook/react";
|
||||
import { ExternalLink } from "../components/external-link/ExternalLink";
|
||||
import { ButtonProps } from "@patternfly/react-core";
|
||||
|
||||
export default {
|
||||
title: "External link",
|
||||
component: ExternalLink,
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<React.HTMLProps<HTMLAnchorElement>> = (args) => (
|
||||
<ExternalLink {...args} />
|
||||
);
|
||||
const Template: Story<ButtonProps> = (args) => <ExternalLink {...args} />;
|
||||
|
||||
export const WithTitle = Template.bind({});
|
||||
WithTitle.args = {
|
||||
|
@ -21,3 +20,16 @@ export const WithoutTitle = Template.bind({});
|
|||
WithoutTitle.args = {
|
||||
href: "http://some-other-link.nl/super",
|
||||
};
|
||||
|
||||
export const ApplicationLink = Template.bind({});
|
||||
ApplicationLink.args = {
|
||||
title: "Application link",
|
||||
href: "/application/main",
|
||||
};
|
||||
|
||||
export const DisabledLink = Template.bind({});
|
||||
DisabledLink.args = {
|
||||
title: "Disabled link",
|
||||
href: "http://some-other-link.nl/super",
|
||||
isAriaDisabled: true,
|
||||
};
|
||||
|
|
37
src/stories/MultiLineInput.stories.tsx
Normal file
37
src/stories/MultiLineInput.stories.tsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
import React from "react";
|
||||
import { Meta, Story } from "@storybook/react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { Button } from "@patternfly/react-core";
|
||||
|
||||
import {
|
||||
MultiLineInput,
|
||||
MultiLineInputProps,
|
||||
toValue,
|
||||
} from "../components/multi-line-input/MultiLineInput";
|
||||
|
||||
export default {
|
||||
title: "MultiLineInput component",
|
||||
component: MultiLineInput,
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<MultiLineInputProps> = (args) => {
|
||||
const form = useForm();
|
||||
return (
|
||||
<form
|
||||
onSubmit={form.handleSubmit((data) => {
|
||||
action("submit")(toValue(data.items));
|
||||
})}
|
||||
>
|
||||
<MultiLineInput {...args} form={form} />
|
||||
<br />
|
||||
<br />
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export const View = Template.bind({});
|
||||
View.args = {
|
||||
name: "items",
|
||||
};
|
39
src/stories/ViewHeader.stories.tsx
Normal file
39
src/stories/ViewHeader.stories.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
import React from "react";
|
||||
import { Meta, Story } from "@storybook/react";
|
||||
import { Page, SelectOption } from "@patternfly/react-core";
|
||||
import {
|
||||
ViewHeader,
|
||||
ViewHeaderProps,
|
||||
} from "../components/view-header/ViewHeader";
|
||||
|
||||
export default {
|
||||
title: "View Header",
|
||||
component: ViewHeader,
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ViewHeaderProps> = (args) => (
|
||||
<Page>
|
||||
<ViewHeader {...args} />
|
||||
</Page>
|
||||
);
|
||||
|
||||
export const Extended = Template.bind({});
|
||||
Extended.args = {
|
||||
titleKey: "This is the title",
|
||||
badge: "badge",
|
||||
subKey: "This is the description.",
|
||||
selectItems: [
|
||||
<SelectOption key="first" value="first-item">
|
||||
First item
|
||||
</SelectOption>,
|
||||
<SelectOption key="second" value="second-item">
|
||||
Second item
|
||||
</SelectOption>,
|
||||
],
|
||||
};
|
||||
|
||||
export const Simple = Template.bind({});
|
||||
Simple.args = {
|
||||
titleKey: "Title simple",
|
||||
subKey: "Some lengthy description about what this is about.",
|
||||
};
|
233
yarn.lock
233
yarn.lock
|
@ -2839,56 +2839,51 @@
|
|||
dependencies:
|
||||
mkdirp "^1.0.4"
|
||||
|
||||
"@open-wc/webpack-import-meta-loader@^0.4.7":
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/@open-wc/webpack-import-meta-loader/-/webpack-import-meta-loader-0.4.7.tgz#d8212640a386a66bf06a2a4c101936467839b5a1"
|
||||
integrity sha512-F3d1EHRckk2+ZpgEEAgVITp8BU9DYLBhKOhNMREeQ1BwILRIhrt+V1bebpnd0Mz595jzd7Yh1wSibLsXibkCpg==
|
||||
"@patternfly/patternfly@4.42.2", "@patternfly/patternfly@^4.42.2":
|
||||
version "4.42.2"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.42.2.tgz#236d87bd85f00cb7a16d0c2956638ecedc3fa6ef"
|
||||
integrity sha512-VLDhNko4D09sKcnzWEzMr8T8z9btqAYpuK0ntWMsAwi+/C9XsKyaxPioxuEsm7PeuW6OU0neEzSDYMSUnwrMBQ==
|
||||
|
||||
"@patternfly/patternfly@4.31.6", "@patternfly/patternfly@^4.31.6":
|
||||
version "4.31.6"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.31.6.tgz#ef9919df610171760cd19920a904ca9b09a74593"
|
||||
integrity sha512-gp8tpbE4Z6C1PIQwNiWMjO5XSr/UGjXs4InL/zmxgZbToyizUxsudwJyCObtdvDNoN57ZJp0gYWYy0tIuwEyMA==
|
||||
|
||||
"@patternfly/react-core@^4.40.4":
|
||||
version "4.40.4"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.40.4.tgz#e4409f89327e2fcdcd07a08833c0149e6f2f6966"
|
||||
integrity sha512-NQuUgIVEty7BBNJMJAVRXejOGRGpRQwgQ8Rw/J/JlgkhtOrCSFX5cEbpAXMXLYWkJrz0++XfRK/FQMoQbvS2hQ==
|
||||
"@patternfly/react-core@4.50.2", "@patternfly/react-core@^4.50.2":
|
||||
version "4.50.2"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.50.2.tgz#b66d9bd8804994af70c2d80ce43a0dee6b90de5c"
|
||||
integrity sha512-EAzrgsNivoYJb+Zk0YGKgr24J4qqY8dnPt96NJKhEcSRmVeqJEvL6Uhd1xJF1hRKQ5Bzrn/Lp66C+u5fgmnUBw==
|
||||
dependencies:
|
||||
"@patternfly/react-icons" "^4.7.2"
|
||||
"@patternfly/react-styles" "^4.7.2"
|
||||
"@patternfly/react-tokens" "^4.9.4"
|
||||
"@patternfly/react-icons" "^4.7.6"
|
||||
"@patternfly/react-styles" "^4.7.5"
|
||||
"@patternfly/react-tokens" "^4.9.8"
|
||||
focus-trap "4.0.2"
|
||||
react-dropzone "9.0.0"
|
||||
tippy.js "5.1.2"
|
||||
tslib "^1.11.1"
|
||||
|
||||
"@patternfly/react-icons@^4.7.2":
|
||||
version "4.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.7.2.tgz#f4ad252cb5682bd95da474ce9ce6ddf7fb3a1ac1"
|
||||
integrity sha512-r1yCVHxUtRSblo8VwfaUM0d49z4eToZXAI0VzOnfKPRgSmGZrn6l8soQgDDtyQsSDr534Qvm55y/qLrlR9JCnw==
|
||||
"@patternfly/react-icons@4.7.6", "@patternfly/react-icons@^4.7.6":
|
||||
version "4.7.6"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.7.6.tgz#d5f19192912284fc334abb034bc08967b4245f22"
|
||||
integrity sha512-B1+gVqe4zS+xQGrQh09z846rWxS6JNAs7PpQJYPEJ1SLzLOwy5wEaOK67im9dD6niEJifJqCcbacCNtVZjlWag==
|
||||
|
||||
"@patternfly/react-styles@^4.7.2":
|
||||
version "4.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.7.2.tgz#6671a243401ef55adddcb0e0922f5f5f4eea840e"
|
||||
integrity sha512-r3zyrt1mXcqdXaEq+otl1cGsN0Ou1k8uIJSY+4EGe2A5jLGbX3vBTwUrpPKLB6tUdNL+mZriFf+3oKhWbVZDkw==
|
||||
"@patternfly/react-styles@^4.7.5":
|
||||
version "4.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.7.5.tgz#b5d7161c0c75b54974b7a4db5a69ab30f6dbcb45"
|
||||
integrity sha512-xom9hI2QzztT5pxByTFj2h3E0s4zD/+wVVLqvugl98cy8bCNpfo97OftfDCxBSV0MuhFDMs8/zr9QJUcq/O8Lw==
|
||||
|
||||
"@patternfly/react-table@^4.15.5":
|
||||
version "4.15.5"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.15.5.tgz#7fc3fcd37a6fd4dca00cc32d24c76199ee41a7f1"
|
||||
integrity sha512-GlyKrEDMY+yLvczj5rWpNKcUp90Ib7alKV9JK8rVLOpTsukQ0QplXxYFsnIrombcaw2V54XVdflZGjsB0GoHEw==
|
||||
"@patternfly/react-table@4.16.20":
|
||||
version "4.16.20"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.16.20.tgz#43e1f855e6cde5fb39b7ce1a6e63c989abadf242"
|
||||
integrity sha512-EBxTnlmEMUcIoL8r1i4sBGB2y1IY1ym9zc47TniC+huC+jWDgxLy2866N/GA+GHtuBT3aPR/0WtziWCD/To8QQ==
|
||||
dependencies:
|
||||
"@patternfly/patternfly" "4.31.6"
|
||||
"@patternfly/react-core" "^4.40.4"
|
||||
"@patternfly/react-icons" "^4.7.2"
|
||||
"@patternfly/react-styles" "^4.7.2"
|
||||
"@patternfly/react-tokens" "^4.9.4"
|
||||
"@patternfly/patternfly" "4.42.2"
|
||||
"@patternfly/react-core" "^4.50.2"
|
||||
"@patternfly/react-icons" "^4.7.6"
|
||||
"@patternfly/react-styles" "^4.7.5"
|
||||
"@patternfly/react-tokens" "^4.9.8"
|
||||
lodash "^4.17.19"
|
||||
tslib "^1.11.1"
|
||||
|
||||
"@patternfly/react-tokens@^4.9.4":
|
||||
version "4.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.9.4.tgz#71ea3c33045fb29bcc8d98f2c0f07bfcdc89a12c"
|
||||
integrity sha512-AJpcAvzWXvfThT2mx24rV7OJSHvZnIsOP1bVrXiubpFAJhi/Suq+LGe/lTPUnuSXaflwyDBRZDXWWmJb4yaWqg==
|
||||
"@patternfly/react-tokens@^4.9.8":
|
||||
version "4.9.8"
|
||||
resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.9.8.tgz#260079b01359bcaf23875890e412f3c6e87e0202"
|
||||
integrity sha512-HBbtQHlWl3/B9KrS1fI3/k6sXDowfTsmw0zKuHXWjG552l0ApOrDmzh120Q7m6cvvkFv/Cw6XRwtJIDZBCEiyg==
|
||||
|
||||
"@reach/router@^1.2.1", "@reach/router@^1.3.3":
|
||||
version "1.3.4"
|
||||
|
@ -2948,6 +2943,14 @@
|
|||
is-module "^1.0.0"
|
||||
resolve "^1.17.0"
|
||||
|
||||
"@rollup/plugin-replace@^2.3.3":
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.3.3.tgz#cd6bae39444de119f5d905322b91ebd4078562e7"
|
||||
integrity sha512-XPmVXZ7IlaoWaJLkSCDaa0Y6uVo5XQYHhiMFzOd5qSv5rE+t/UJToPIOE56flKIxBFQI27ONsxb7dqHnwSsjKQ==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.8"
|
||||
magic-string "^0.25.5"
|
||||
|
||||
"@rollup/pluginutils@^3.0.4", "@rollup/pluginutils@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
||||
|
@ -3002,10 +3005,10 @@
|
|||
"@babel/core" "^7.10.5"
|
||||
workerpool "^6.0.0"
|
||||
|
||||
"@snowpack/plugin-build-script@^2.0.6":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-build-script/-/plugin-build-script-2.0.6.tgz#95c85cc6c4c53763a91a2d170633918ecd0d3cc8"
|
||||
integrity sha512-qtvXQq54MaBYJrCTa+DaK/KzUXYBkRukaGzIdhpqW/xzOknCjpufiQIy0VUzxwRQk0OlLC6/h3sV1hSMsoTVJw==
|
||||
"@snowpack/plugin-build-script@^2.0.7":
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-build-script/-/plugin-build-script-2.0.7.tgz#1d133030ceac51efce471b66622d1b7320d5ab9f"
|
||||
integrity sha512-f1fZN0Blsfk25oMBf62wvhHm6v7DUG0W85+JFKzYI6SHOIHrYL37o9xaJX7RJpn2kEKCRymWsQo4PclQdnL77w==
|
||||
dependencies:
|
||||
execa "^4.0.3"
|
||||
npm-run-path "^4.0.1"
|
||||
|
@ -3018,10 +3021,10 @@
|
|||
dotenv "^8.2.0"
|
||||
dotenv-expand "^5.1.0"
|
||||
|
||||
"@snowpack/plugin-postcss@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-postcss/-/plugin-postcss-1.0.2.tgz#902eacf40ecd465be52137b01dbbfc773902be6c"
|
||||
integrity sha512-DRRBe2uySvuQ9AEeOnJEtZEcjS8h9g3f8idGHohVcU0G1Anff+MQgEEZ2sFgrFuERVFaqoFTz3av3ArBkT5G8A==
|
||||
"@snowpack/plugin-postcss@1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-postcss/-/plugin-postcss-1.0.4.tgz#59a7e40bfb225525b4894d06d20d1205f476af0c"
|
||||
integrity sha512-7znEgujAa1IECR63tx50PPjZkH3DlxIECLZVMngi1/RgRZlKAqWxkORH0y8RtrxLmszHb/TnCwRY0dK5/zJGGQ==
|
||||
|
||||
"@snowpack/plugin-react-refresh@^2.1.0":
|
||||
version "2.1.0"
|
||||
|
@ -3030,30 +3033,31 @@
|
|||
dependencies:
|
||||
react-refresh "^0.8.3"
|
||||
|
||||
"@snowpack/plugin-run-script@^2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-run-script/-/plugin-run-script-2.1.1.tgz#f0f71cab5e0a482dfceb3306ae3e7d9cab859746"
|
||||
integrity sha512-ZLOcu6n+eLDNxTxKlKK/+smn9PWr/epUKGPw8tBHr3qdKQ64WNpCVr0jnafanzWpzQWD8k92J8POfskKMuEI5Q==
|
||||
"@snowpack/plugin-run-script@^2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-run-script/-/plugin-run-script-2.1.2.tgz#51a620f99cc8ba4a23d3fc5c748f3c16aada7ad4"
|
||||
integrity sha512-120uF0GKpEY/jHRuOZnxH8siLPXDSKB44Fy9d+zMWybsVvkIvV7pqcT9T9ojnth6QRB+f39tPaiqt+Ej/ByBjg==
|
||||
dependencies:
|
||||
execa "^4.0.3"
|
||||
npm-run-path "^4.0.1"
|
||||
|
||||
"@snowpack/plugin-webpack@^2.0.6":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-webpack/-/plugin-webpack-2.0.6.tgz#8d9e206c5fd1ec829413368584470395eb52bd29"
|
||||
integrity sha512-XbiE9+QLEz7sJchuQP1nu6JCwC/jXstBOE4Kwnx1w2ulTRnN4bFWLHIy4ZCh9zQp3/XH9xinC6+hmJHScbnrfg==
|
||||
"@snowpack/plugin-webpack@2.0.12":
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@snowpack/plugin-webpack/-/plugin-webpack-2.0.12.tgz#44907f36542a35d326032108dcf9379e74bb0324"
|
||||
integrity sha512-kX7Jfgz5V/vwgtsrnGQNOguKqrGsEHmLAnHnTQ2WRKS7i90F1zb4UUoWqLgrH1cYdD1cdAhlfsXnl9ex3iI+7w==
|
||||
dependencies:
|
||||
"@open-wc/webpack-import-meta-loader" "^0.4.7"
|
||||
babel-loader "^8.1.0"
|
||||
core-js "^3.5.0"
|
||||
css-loader "^3.5.3"
|
||||
file-loader "^6.0.0"
|
||||
glob "^7.1.6"
|
||||
html-minifier "^4.0.0"
|
||||
jsdom "^16.2.2"
|
||||
mini-css-extract-plugin "^0.9.0"
|
||||
optimize-css-assets-webpack-plugin "^5.0.3"
|
||||
terser-webpack-plugin "^3.0.1"
|
||||
webpack "^4.43.0"
|
||||
webpack-manifest-plugin "^2.2.0"
|
||||
|
||||
"@storybook/addon-actions@6.0.21", "@storybook/addon-actions@^6.0.21":
|
||||
version "6.0.21"
|
||||
|
@ -6527,6 +6531,14 @@ callsites@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
camel-case@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
|
||||
integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
|
||||
dependencies:
|
||||
no-case "^2.2.0"
|
||||
upper-case "^1.1.1"
|
||||
|
||||
camel-case@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547"
|
||||
|
@ -6774,7 +6786,7 @@ classnames@^2.2.5:
|
|||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||
|
||||
clean-css@^4.2.3:
|
||||
clean-css@^4.2.1, clean-css@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
|
||||
integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==
|
||||
|
@ -8397,10 +8409,10 @@ es-get-iterator@^1.0.2:
|
|||
is-string "^1.0.5"
|
||||
isarray "^2.0.5"
|
||||
|
||||
es-module-lexer@^0.3.17:
|
||||
version "0.3.19"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.3.19.tgz#91065ea884f436a2e140e5006b1aaf154ab23f71"
|
||||
integrity sha512-EMav8JgMd66ltDkVTVjknEyjxwjnFg4dfoTJD2T8yH9qunGK3kMKsIqDDSEWied2bOdNm2zTOUcZaKTScjWFiQ==
|
||||
es-module-lexer@^0.3.24:
|
||||
version "0.3.25"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.3.25.tgz#24a1abcb9c5dc96923a8e42be033b801f788de06"
|
||||
integrity sha512-H9VoFD5H9zEfiOX2LeTWDwMvAbLqcAyA2PIb40TOAvGpScOjit02oTGWgIh+M0rx2eJOKyJVM9wtpKFVgnyC3A==
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
|
@ -8447,10 +8459,10 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3:
|
|||
d "^1.0.1"
|
||||
ext "^1.1.2"
|
||||
|
||||
esbuild@^0.6.11:
|
||||
version "0.6.28"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.6.28.tgz#b14fc7a2a04d13c416f75024ac5c449f4248edc4"
|
||||
integrity sha512-VU1QBpzUiuPdrmt6oN1Xd/w/xurSqvsrIUFKPIV9K25Fedqx0Zb9NaBtPlFXawM5vt0dxsbpKJxgylmPz1GlyQ==
|
||||
esbuild@^0.6.28:
|
||||
version "0.6.34"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.6.34.tgz#76565a60e006f45d5f273b6e59e61ed0816551f5"
|
||||
integrity sha512-InRdL/Q96pUucPqovJzvuLhquZr6jOn81FDVwFjCKz1rYKIm9OdOC+7Fs4vr6x48vKBl5LzKgtjU39BUpO636A==
|
||||
|
||||
escalade@^3.0.1:
|
||||
version "3.0.1"
|
||||
|
@ -8812,6 +8824,11 @@ eventemitter3@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
|
||||
integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
|
||||
|
||||
eventemitter3@^4.0.4:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
events@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
|
||||
|
@ -10308,6 +10325,19 @@ html-minifier-terser@^5.0.1:
|
|||
relateurl "^0.2.7"
|
||||
terser "^4.6.3"
|
||||
|
||||
html-minifier@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-4.0.0.tgz#cca9aad8bce1175e02e17a8c33e46d8988889f56"
|
||||
integrity sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==
|
||||
dependencies:
|
||||
camel-case "^3.0.0"
|
||||
clean-css "^4.2.1"
|
||||
commander "^2.19.0"
|
||||
he "^1.2.0"
|
||||
param-case "^2.1.1"
|
||||
relateurl "^0.2.7"
|
||||
uglify-js "^3.5.1"
|
||||
|
||||
html-parse-stringify2@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
|
||||
|
@ -11214,6 +11244,11 @@ isarray@^2.0.5:
|
|||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
||||
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
|
||||
|
||||
isbinaryfile@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.6.tgz#edcb62b224e2b4710830b67498c8e4e5a4d2610b"
|
||||
integrity sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
|
@ -12500,7 +12535,7 @@ kleur@^3.0.3:
|
|||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||
|
||||
kleur@^4.1.0:
|
||||
kleur@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.1.tgz#80b49dd7d1afeba41b8dcdf4ecfff9252205fc52"
|
||||
integrity sha512-BsNhM6T/yTWFG580CRnYhT3LfUuPK7Hwrm+W2H0G8lK/nogalP5Nsrh/cHjxVVkzl0sFm7z8b8rNcZCfKxeoxA==
|
||||
|
@ -12785,6 +12820,11 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
|
|||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
lower-case@^1.1.1:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
|
||||
integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
|
||||
|
||||
lower-case@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7"
|
||||
|
@ -13393,6 +13433,13 @@ nice-try@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
no-case@^2.2.0:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
|
||||
integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
|
||||
dependencies:
|
||||
lower-case "^1.1.1"
|
||||
|
||||
no-case@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8"
|
||||
|
@ -13985,12 +14032,12 @@ p-map@^4.0.0:
|
|||
dependencies:
|
||||
aggregate-error "^3.0.0"
|
||||
|
||||
p-queue@^6.2.1:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.4.0.tgz#5050b379393ea1814d6f9613a654f687d92c0466"
|
||||
integrity sha512-X7ddxxiQ+bLR/CUt3/BVKrGcJDNxBr0pEEFKHHB6vTPWNUhgDv36GpIH18RmGM3YGPpBT+JWGjDDqsVGuF0ERw==
|
||||
p-queue@^6.6.1:
|
||||
version "6.6.1"
|
||||
resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.1.tgz#578891ada028a61371ec2692b26614d1b7d2b10a"
|
||||
integrity sha512-miQiSxLYPYBxGkrldecZC18OTLjdUqnlRebGzPRiVxB8mco7usCmm7hFuxiTvp93K18JnLtE4KMMycjAu/cQQg==
|
||||
dependencies:
|
||||
eventemitter3 "^4.0.0"
|
||||
eventemitter3 "^4.0.4"
|
||||
p-timeout "^3.1.0"
|
||||
|
||||
p-reduce@^1.0.0:
|
||||
|
@ -14036,6 +14083,13 @@ parallel-transform@^1.1.0:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^2.1.5"
|
||||
|
||||
param-case@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
|
||||
integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
|
||||
dependencies:
|
||||
no-case "^2.2.0"
|
||||
|
||||
param-case@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238"
|
||||
|
@ -15183,7 +15237,12 @@ prepend-http@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
|
||||
|
||||
prettier@^2.0.5, prettier@~2.0.5:
|
||||
prettier@^2.0.5:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5"
|
||||
integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==
|
||||
|
||||
prettier@~2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
|
||||
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
|
||||
|
@ -17035,10 +17094,10 @@ snapdragon@^0.8.1:
|
|||
source-map-resolve "^0.5.0"
|
||||
use "^3.1.0"
|
||||
|
||||
snowpack@^2.10.0:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/snowpack/-/snowpack-2.10.0.tgz#143b78e4a25f5bf604042d59628acb213acb6807"
|
||||
integrity sha512-kZCGWV8cH+CaRcHe+vZEcbbfVqTlKqshHDKUIj7yM5al61WnoDXrFfK6RSDOW3BzxYTiuIyuyULCkWicdIzTaw==
|
||||
snowpack@2.11.1:
|
||||
version "2.11.1"
|
||||
resolved "https://registry.yarnpkg.com/snowpack/-/snowpack-2.11.1.tgz#8565bed98806162bc1b001d3796c8863b18a2084"
|
||||
integrity sha512-trEBfCRUaPLaoMZdyDyLdzQfQGy2tOrr0gGeSV8AVjos3m412s2mWsfhYEGCT1AE/t0mrGMhj7ccVz5fh5yOnQ==
|
||||
dependencies:
|
||||
"@babel/plugin-syntax-import-meta" "^7.10.4"
|
||||
"@rollup/plugin-alias" "^3.0.1"
|
||||
|
@ -17046,8 +17105,9 @@ snowpack@^2.10.0:
|
|||
"@rollup/plugin-inject" "^4.0.2"
|
||||
"@rollup/plugin-json" "^4.0.0"
|
||||
"@rollup/plugin-node-resolve" "^9.0.0"
|
||||
"@snowpack/plugin-build-script" "^2.0.6"
|
||||
"@snowpack/plugin-run-script" "^2.1.1"
|
||||
"@rollup/plugin-replace" "^2.3.3"
|
||||
"@snowpack/plugin-build-script" "^2.0.7"
|
||||
"@snowpack/plugin-run-script" "^2.1.2"
|
||||
cacache "^15.0.0"
|
||||
cachedir "^2.3.0"
|
||||
chokidar "^3.4.0"
|
||||
|
@ -17056,8 +17116,8 @@ snowpack@^2.10.0:
|
|||
css-modules-loader-core "^1.1.0"
|
||||
deepmerge "^4.2.2"
|
||||
detect-port "^1.3.0"
|
||||
es-module-lexer "^0.3.17"
|
||||
esbuild "^0.6.11"
|
||||
es-module-lexer "^0.3.24"
|
||||
esbuild "^0.6.28"
|
||||
etag "^1.8.1"
|
||||
execa "^4.0.3"
|
||||
find-cache-dir "^3.3.1"
|
||||
|
@ -17066,13 +17126,14 @@ snowpack@^2.10.0:
|
|||
got "^11.1.4"
|
||||
http-proxy "^1.18.1"
|
||||
is-builtin-module "^3.0.0"
|
||||
isbinaryfile "^4.0.6"
|
||||
jsonschema "^1.2.5"
|
||||
kleur "^4.1.0"
|
||||
kleur "^4.1.1"
|
||||
mime-types "^2.1.26"
|
||||
mkdirp "^1.0.3"
|
||||
npm-run-path "^4.0.1"
|
||||
open "^7.0.4"
|
||||
p-queue "^6.2.1"
|
||||
p-queue "^6.6.1"
|
||||
resolve-from "^5.0.0"
|
||||
rimraf "^3.0.0"
|
||||
rollup "^2.23.0"
|
||||
|
@ -18149,6 +18210,11 @@ ua-parser-js@^0.7.18:
|
|||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777"
|
||||
integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==
|
||||
|
||||
uglify-js@^3.5.1:
|
||||
version "3.10.4"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.10.4.tgz#dd680f5687bc0d7a93b14a3482d16db6eba2bfbb"
|
||||
integrity sha512-kBFT3U4Dcj4/pJ52vfjCSfyLyvG9VYYuGYPmrPvAxRw/i7xHiT4VvCev+uiEMcEEiu6UNB6KgWmGtSUYIWScbw==
|
||||
|
||||
unbzip2-stream@^1.0.9:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
|
||||
|
@ -18343,6 +18409,11 @@ upath@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
|
||||
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
|
||||
|
||||
upper-case@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
|
||||
integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
|
@ -18745,7 +18816,7 @@ webpack-log@^2.0.0:
|
|||
ansi-colors "^3.0.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
webpack-manifest-plugin@2.2.0:
|
||||
webpack-manifest-plugin@2.2.0, webpack-manifest-plugin@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz#19ca69b435b0baec7e29fbe90fb4015de2de4f16"
|
||||
integrity sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==
|
||||
|
|
Loading…
Reference in a new issue