From 51c244c1f26c4cd7de4f9fb3cdc2499fd88ff3f9 Mon Sep 17 00:00:00 2001 From: Jason Madigan Date: Fri, 18 Oct 2024 14:27:21 +0100 Subject: [PATCH] Linting errors Signed-off-by: Jason Madigan --- .stylelintrc.yaml | 2 +- README.md | 15 ++ src/components/DropdownWithKebab.tsx | 14 +- .../KuadrantAuthPolicyCreatePage.tsx | 43 ++-- src/components/KuadrantCreateUpdate.tsx | 66 +++--- .../KuadrantDNSPolicyCreatePage.tsx | 216 ++++++++++++------ src/components/KuadrantOverviewPage.tsx | 160 +++++++++---- .../KuadrantRateLimitPolicyCreatePage.tsx | 36 +-- src/components/KuadrantTLSCreatePage.tsx | 195 ++++++++++------ src/components/dnspolicy/HealthCheckField.tsx | 18 +- .../dnspolicy/LoadBalancingField.tsx | 30 ++- src/components/dnspolicy/types.ts | 4 - src/components/gateway/GatewaySelect.tsx | 52 +++-- src/components/gateway/types.ts | 6 +- src/components/httproute/HTTPRouteSelect.tsx | 46 ++-- src/components/httproute/types.ts | 6 +- src/components/issuer/clusterIssuerSelect.tsx | 61 +++-- src/components/issuer/issuerSelect.tsx | 51 +++-- src/components/issuer/types.ts | 8 +- src/components/kuadrant.css | 65 ++---- .../ratelimitpolicy/AddLimitModal.tsx | 66 ++++-- .../ratelimitpolicy/LimitSelect.tsx | 25 +- src/components/ratelimitpolicy/types.ts | 15 +- src/constants/links.ts | 24 +- 24 files changed, 764 insertions(+), 460 deletions(-) diff --git a/.stylelintrc.yaml b/.stylelintrc.yaml index 7b81e88..2d20673 100644 --- a/.stylelintrc.yaml +++ b/.stylelintrc.yaml @@ -16,7 +16,7 @@ rules: # reserved by PatternFly and OpenShift console. selector-disallowed-list: - "*" - - /\.(pf|co)-/ + - "/^\\.pf-(?!theme)(?!.* )/" # Disallow naked .pf- classes but allow .pf-theme and combined .pf- classes # Plugins should avoid naked element selectors like `table` and `li` since # this can impact layout of existing pages in console. selector-max-type: diff --git a/README.md b/README.md index 9b60e1a..9cf6090 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,21 @@ best practice is to prefix your CSS classnames with your plugin name to avoid conflicts. Please don't disable these rules without understanding how they can break console styles! +### Linting Extensions + +If you'd like to auto lint, install these VSCode extensions and configure formatting on save: + +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +- [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) + +#### Format on save in VSCode: + +Update `settings.json` (File > Preferences > Settings): + +```json +"editor.formatOnSave": true +``` + ## References - [Console Plugin SDK README](https://github.com/openshift/console/tree/master/frontend/packages/console-dynamic-plugin-sdk) diff --git a/src/components/DropdownWithKebab.tsx b/src/components/DropdownWithKebab.tsx index a625d5f..b20c13a 100644 --- a/src/components/DropdownWithKebab.tsx +++ b/src/components/DropdownWithKebab.tsx @@ -38,20 +38,22 @@ const DropdownWithKebab: React.FC = ({ obj }) => { } }; - let policyType = obj.kind.toLowerCase(); + const policyType = obj.kind.toLowerCase(); const onEditClick = () => { if (obj.kind === 'AuthPolicy' || obj.kind === 'RateLimitPolicy') { history.push({ - pathname: `/k8s/ns/${obj.metadata.namespace}/${obj.apiVersion.replace("/", "~")}~${obj.kind}/${obj.metadata.name}/yaml`, - }) + pathname: `/k8s/ns/${obj.metadata.namespace}/${obj.apiVersion.replace('/', '~')}~${ + obj.kind + }/${obj.metadata.name}/yaml`, + }); } else { history.push({ pathname: `/k8s/ns/${obj.metadata.namespace}/${policyType}/name/${obj.metadata.name}/edit`, - }) + }); } - } - + }; + const onDeleteClick = () => { setIsDeleteModalOpen(true); }; diff --git a/src/components/KuadrantAuthPolicyCreatePage.tsx b/src/components/KuadrantAuthPolicyCreatePage.tsx index f587404..9992bfd 100644 --- a/src/components/KuadrantAuthPolicyCreatePage.tsx +++ b/src/components/KuadrantAuthPolicyCreatePage.tsx @@ -1,6 +1,14 @@ import * as React from 'react'; import Helmet from 'react-helmet'; -import { Button, Modal, ModalBox, ModalBoxHeader, ModalBoxBody, ModalBoxFooter, ButtonVariant } from '@patternfly/react-core'; +import { + Button, + Modal, + ModalBox, + ModalBoxHeader, + ModalBoxBody, + ModalBoxFooter, + ButtonVariant, +} from '@patternfly/react-core'; import { useTranslation } from 'react-i18next'; import { ResourceYAMLEditor, useActiveNamespace } from '@openshift-console/dynamic-plugin-sdk'; import resourceGVKMapping from '../utils/latest'; @@ -10,7 +18,8 @@ const KuadrantAuthPolicyCreatePage: React.FC = () => { const [selectedNamespace] = useActiveNamespace(); const yamlResource = { - apiVersion: resourceGVKMapping['AuthPolicy'].group + '/' + resourceGVKMapping['AuthPolicy'].version, + apiVersion: + resourceGVKMapping['AuthPolicy'].group + '/' + resourceGVKMapping['AuthPolicy'].version, kind: resourceGVKMapping['AuthPolicy'].kind, metadata: { name: 'example-authpolicy', @@ -28,10 +37,14 @@ const KuadrantAuthPolicyCreatePage: React.FC = () => { response: { unauthorized: { body: { - value: JSON.stringify({ - error: "Forbidden", - message: "Access denied by default. Create a specific auth policy for the route.", - }, null, 2), + value: JSON.stringify( + { + error: 'Forbidden', + message: 'Access denied by default. Create a specific auth policy for the route.', + }, + null, + 2, + ), }, headers: { 'content-type': { @@ -58,24 +71,20 @@ const KuadrantAuthPolicyCreatePage: React.FC = () => { {t('Create AuthPolicy')} - + - setIsErrorModalOpen(false)} - variant="medium" - > + setIsErrorModalOpen(false)} variant="medium"> {t('Error creating AuthPolicy')} {errorModalMsg} - diff --git a/src/components/KuadrantCreateUpdate.tsx b/src/components/KuadrantCreateUpdate.tsx index 8a8239e..8066636 100644 --- a/src/components/KuadrantCreateUpdate.tsx +++ b/src/components/KuadrantCreateUpdate.tsx @@ -7,59 +7,59 @@ import { k8sUpdate, } from '@openshift-console/dynamic-plugin-sdk'; import { useTranslation } from 'react-i18next'; -import { - Button, - AlertVariant, - Alert, - AlertGroup, -} from '@patternfly/react-core'; +import { Button, AlertVariant, Alert, AlertGroup } from '@patternfly/react-core'; import { History } from 'history'; - interface GenericPolicyForm { - model: K8sModel - resource: K8sResourceCommon - policyType: string, - history: History, - validation: boolean + model: K8sModel; + resource: K8sResourceCommon; + policyType: string; + history: History; + validation: boolean; } -const KuadrantCreateUpdate: React.FC = ({ model, resource, policyType, history,validation }) => { +const KuadrantCreateUpdate: React.FC = ({ + model, + resource, + policyType, + history, + validation, +}) => { const { t } = useTranslation('plugin__kuadrant-console-plugin'); - const [errorAlertMsg, setErrorAlertMsg] = React.useState('') - const update = !!resource.metadata.creationTimestamp + const [errorAlertMsg, setErrorAlertMsg] = React.useState(''); + const update = !!resource.metadata.creationTimestamp; const handleCreateUpdate = async () => { if (!validation) return; // Early return if form is not valid - setErrorAlertMsg('') - - try { + setErrorAlertMsg(''); + try { if (update == true) { const response = await k8sUpdate({ model: model, data: resource, - }) - console.log(`${policyType} updated successfully:`, response) - history.push(`/kuadrant/all-namespaces/policies/${policyType}`) + }); + console.log(`${policyType} updated successfully:`, response); + history.push(`/kuadrant/all-namespaces/policies/${policyType}`); } else { const response = await k8sCreate({ model: model, data: resource, - }) - console.log(`${policyType} created successfully:`, response) - history.push(`/kuadrant/all-namespaces/policies/${policyType}`) + }); + console.log(`${policyType} created successfully:`, response); + history.push(`/kuadrant/all-namespaces/policies/${policyType}`); } } catch (error) { if (update == true) { - console.error(t(`Cannot update ${policyType}`, error)) - setErrorAlertMsg(error.message) - } { - console.error(t(`Cannot create ${policyType}`, error)) - setErrorAlertMsg(error.message) + console.error(t(`Cannot update ${policyType}`, error)); + setErrorAlertMsg(error.message); + } + { + console.error(t(`Cannot create ${policyType}`, error)); + setErrorAlertMsg(error.message); } } - } + }; return ( <> {errorAlertMsg != '' && ( @@ -73,6 +73,6 @@ const KuadrantCreateUpdate: React.FC = ({ model, resource, po {update ? t(`Save`) : t(`Create`)} - ) -} -export default KuadrantCreateUpdate \ No newline at end of file + ); +}; +export default KuadrantCreateUpdate; diff --git a/src/components/KuadrantDNSPolicyCreatePage.tsx b/src/components/KuadrantDNSPolicyCreatePage.tsx index 2676373..8df526d 100644 --- a/src/components/KuadrantDNSPolicyCreatePage.tsx +++ b/src/components/KuadrantDNSPolicyCreatePage.tsx @@ -16,43 +16,65 @@ import { } from '@patternfly/react-core'; import { useTranslation } from 'react-i18next'; import './kuadrant.css'; -import { ResourceYAMLEditor, getGroupVersionKindForResource, useK8sModel, useK8sWatchResource, K8sResourceCommon, useActiveNamespace } from '@openshift-console/dynamic-plugin-sdk'; +import { + ResourceYAMLEditor, + getGroupVersionKindForResource, + useK8sModel, + useK8sWatchResource, + K8sResourceCommon, + useActiveNamespace, +} from '@openshift-console/dynamic-plugin-sdk'; import { useHistory, useLocation } from 'react-router-dom'; -import { LoadBalancing, HealthCheck } from './dnspolicy/types' +import { LoadBalancing, HealthCheck } from './dnspolicy/types'; import LoadBalancingField from './dnspolicy/LoadBalancingField'; import HealthCheckField from './dnspolicy/HealthCheckField'; import { Gateway } from './gateway/types'; import GatewaySelect from './gateway/GatewaySelect'; import yaml from 'js-yaml'; -import KuadrantCreateUpdate from './KuadrantCreateUpdate' +import KuadrantCreateUpdate from './KuadrantCreateUpdate'; import { handleCancel } from '../utils/cancel'; import resourceGVKMapping from '../utils/latest'; - const KuadrantDNSPolicyCreatePage: React.FC = () => { const { t } = useTranslation('plugin__kuadrant-console-plugin'); const [createView, setCreateView] = React.useState<'form' | 'yaml'>('form'); const [policyName, setPolicyName] = React.useState(''); const [selectedNamespace] = useActiveNamespace(); - const [selectedGateway, setSelectedGateway] = React.useState({ name: '', namespace: '' }); - const [loadBalancing, setLoadBalancing] = React.useState({ geo: '', weight: null, defaultGeo: true }); - const [healthCheck, setHealthCheck] = React.useState({ endpoint: '', failureThreshold: null, port: null, protocol: null, }); + const [selectedGateway, setSelectedGateway] = React.useState({ + name: '', + namespace: '', + }); + const [loadBalancing, setLoadBalancing] = React.useState({ + geo: '', + weight: null, + defaultGeo: true, + }); + const [healthCheck, setHealthCheck] = React.useState({ + endpoint: '', + failureThreshold: null, + port: null, + protocol: null, + }); const [providerRefs, setProviderRefs] = React.useState([]); const [creationTimestamp, setCreationTimestamp] = React.useState(''); const [resourceVersion, setResourceVersion] = React.useState(''); const location = useLocation(); - const pathSplit = location.pathname.split('/') - const nameEdit = pathSplit[6] - const namespaceEdit = pathSplit[3] + const pathSplit = location.pathname.split('/'); + const nameEdit = pathSplit[6]; + const namespaceEdit = pathSplit[3]; const [formDisabled, setFormDisabled] = React.useState(false); const [create, setCreate] = React.useState(true); - let isFormValid: boolean = false - + let isFormValid = false; const createDNSPolicy = () => { - const hasHealthCheck = healthCheck.endpoint || healthCheck.failureThreshold || healthCheck.port || healthCheck.protocol; + const hasHealthCheck = + healthCheck.endpoint || + healthCheck.failureThreshold || + healthCheck.port || + healthCheck.protocol; return { - apiVersion: resourceGVKMapping['DNSPolicy'].group + '/' + resourceGVKMapping['DNSPolicy'].version, + apiVersion: + resourceGVKMapping['DNSPolicy'].group + '/' + resourceGVKMapping['DNSPolicy'].version, kind: resourceGVKMapping['DNSPolicy'].kind, metadata: { name: policyName, @@ -73,25 +95,33 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => { }, providerRefs: providerRefs.length > 0 ? [providerRefs[0]] : [], - ...(hasHealthCheck ? { - healthCheck: { - ...(healthCheck?.endpoint ? { endpoint: healthCheck.endpoint } : {}), - ...(healthCheck?.failureThreshold ? { failureThreshold: healthCheck.failureThreshold } : {}), - ...(healthCheck?.port ? { port: healthCheck.port } : {}), - ...(healthCheck?.protocol ? { protocol: healthCheck.protocol } : {}), - } - } : {}), - } + ...(hasHealthCheck + ? { + healthCheck: { + ...(healthCheck?.endpoint ? { endpoint: healthCheck.endpoint } : {}), + ...(healthCheck?.failureThreshold + ? { failureThreshold: healthCheck.failureThreshold } + : {}), + ...(healthCheck?.port ? { port: healthCheck.port } : {}), + ...(healthCheck?.protocol ? { protocol: healthCheck.protocol } : {}), + }, + } + : {}), + }, }; }; - const [yamlInput, setYamlInput] = React.useState(createDNSPolicy) + const [yamlInput, setYamlInput] = React.useState(createDNSPolicy); const dnsPolicy = createDNSPolicy(); const dnsPolicyGVK = getGroupVersionKindForResource({ apiVersion: `${resourceGVKMapping['DNSPolicy'].group}/${resourceGVKMapping['DNSPolicy'].version}`, kind: resourceGVKMapping['DNSPolicy'].kind, }); - const [dnsPolicyModel] = useK8sModel({ group: dnsPolicyGVK.group, version: dnsPolicyGVK.version, kind: dnsPolicyGVK.kind }); + const [dnsPolicyModel] = useK8sModel({ + group: dnsPolicyGVK.group, + version: dnsPolicyGVK.version, + kind: dnsPolicyGVK.kind, + }); const history = useHistory(); @@ -107,7 +137,7 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => { weight?: number; geo?: string; defaultGeo?: boolean; - }, + }; providerRefs?: { name?: string; }[]; @@ -117,56 +147,61 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => { failureThreshold?: number; port?: number; protocol?: 'HTTP' | 'HTTPS'; - } - } - - + }; + }; } //Checking if the policy already exists and is to be edited or if its new and is being created - let dnsResource = null + let dnsResource = null; if (nameEdit) { dnsResource = { groupVersionKind: dnsPolicyGVK, isList: false, name: nameEdit, - namespace: namespaceEdit + namespace: namespaceEdit, }; } - const [dnsData, dnsLoaded, dnsError] = dnsResource ? useK8sWatchResource(dnsResource) : [null, false, null]; //Syntax allows for dnsResource to be null in the case of a create + const [dnsData, dnsLoaded, dnsError] = dnsResource + ? useK8sWatchResource(dnsResource) + : [null, false, null]; //Syntax allows for dnsResource to be null in the case of a create React.useEffect(() => { if (dnsLoaded && !dnsError) { if (!Array.isArray(dnsData)) { const dnsPolicyUpdate = dnsData as dnsPolicyEdit; - setCreationTimestamp(dnsPolicyUpdate.metadata.creationTimestamp) - setResourceVersion(dnsPolicyUpdate.metadata.resourceVersion) - setFormDisabled(true) - setCreate(false) + setCreationTimestamp(dnsPolicyUpdate.metadata.creationTimestamp); + setResourceVersion(dnsPolicyUpdate.metadata.resourceVersion); + setFormDisabled(true); + setCreate(false); setPolicyName(dnsPolicyUpdate.metadata?.name || ''); - setSelectedGateway({ name: dnsPolicyUpdate.spec?.targetRef?.name || '', namespace: dnsPolicyUpdate.metadata?.namespace || '' }); + setSelectedGateway({ + name: dnsPolicyUpdate.spec?.targetRef?.name || '', + namespace: dnsPolicyUpdate.metadata?.namespace || '', + }); setHealthCheck({ endpoint: dnsPolicyUpdate.spec?.healthCheck?.endpoint || '', failureThreshold: dnsPolicyUpdate.spec?.healthCheck?.failureThreshold, port: dnsPolicyUpdate.spec?.healthCheck?.port || null, protocol: dnsPolicyUpdate.spec?.healthCheck?.protocol || 'HTTP', }); - const providerRef = Array.isArray(dnsPolicyUpdate.spec?.providerRefs) && dnsPolicyUpdate.spec.providerRefs.length > 0 - ? dnsPolicyUpdate.spec.providerRefs[0] - : { name: '' }; + const providerRef = + Array.isArray(dnsPolicyUpdate.spec?.providerRefs) && + dnsPolicyUpdate.spec.providerRefs.length > 0 + ? dnsPolicyUpdate.spec.providerRefs[0] + : { name: '' }; setProviderRefs([providerRef]); setLoadBalancing({ geo: dnsPolicyUpdate.spec?.loadBalancing?.geo || '', weight: dnsPolicyUpdate.spec?.loadBalancing?.weight || 0, - defaultGeo: dnsPolicyUpdate.spec?.loadBalancing?.defaultGeo !== undefined - ? dnsPolicyUpdate.spec.loadBalancing?.defaultGeo - : false, // Default to false if not present - + defaultGeo: + dnsPolicyUpdate.spec?.loadBalancing?.defaultGeo !== undefined + ? dnsPolicyUpdate.spec.loadBalancing?.defaultGeo + : false, // Default to false if not present }); - console.log("Initializing dns with existing dns for update"); + console.log('Initializing dns with existing dns for update'); } } else if (dnsError) { console.error('Failed to fetch the resource:', dnsError); @@ -175,68 +210,90 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => { const handleYAMLChange = (yamlInput: string) => { try { - const parsedYaml = yaml.load(yamlInput) + const parsedYaml = yaml.load(yamlInput); setPolicyName(parsedYaml.metadata?.name || ''); - setSelectedGateway({ name: parsedYaml.spec?.targetRef?.name || '', namespace: parsedYaml.metadata?.namespace || '' }); + setSelectedGateway({ + name: parsedYaml.spec?.targetRef?.name || '', + namespace: parsedYaml.metadata?.namespace || '', + }); setHealthCheck({ endpoint: parsedYaml.spec?.healthCheck?.endpoint || '', failureThreshold: parsedYaml.spec?.healthCheck?.failureThreshold, port: parsedYaml.spec?.healthCheck?.port || '', protocol: parsedYaml.spec?.healthCheck?.protocol || '', }); - const providerRef = Array.isArray(parsedYaml.spec?.providerRefs) && parsedYaml.spec.providerRefs.length > 0 - ? parsedYaml.spec.providerRefs[0] - : { name: '' }; + const providerRef = + Array.isArray(parsedYaml.spec?.providerRefs) && parsedYaml.spec.providerRefs.length > 0 + ? parsedYaml.spec.providerRefs[0] + : { name: '' }; setProviderRefs([providerRef]); setLoadBalancing({ geo: parsedYaml.spec?.loadBalancing?.geo || '', weight: parsedYaml.spec?.loadBalancing?.weight || '', - defaultGeo: parsedYaml.spec?.loadBalancing?.defaultGeo !== undefined - ? parsedYaml.spec.loadBalancing?.defaultGeo - : false, // Default to false if not present - + defaultGeo: + parsedYaml.spec?.loadBalancing?.defaultGeo !== undefined + ? parsedYaml.spec.loadBalancing?.defaultGeo + : false, // Default to false if not present }); - } catch (e) { console.error(t('Error parsing YAML:'), e); } }; React.useEffect(() => { - setYamlInput(dnsPolicy) - }, [policyName, selectedNamespace, selectedGateway, providerRefs, loadBalancing, healthCheck]) - + setYamlInput(dnsPolicy); + }, [policyName, selectedNamespace, selectedGateway, providerRefs, loadBalancing, healthCheck]); const handlePolicyChange = (_event, policy: string) => { setPolicyName(policy); }; const handleProviderRefs = (_event, provider: string) => { - setProviderRefs([{ name: provider }]); // Wrap the provider in an array of objects + setProviderRefs([{ name: provider }]); // Wrap the provider in an array of objects }; const handleCancelResource = () => { handleCancel(selectedNamespace, dnsPolicy, history); }; - if (policyName && selectedNamespace && selectedGateway.name && setProviderRefs && loadBalancing.geo && loadBalancing.weight) { - isFormValid = true + if ( + policyName && + selectedNamespace && + selectedGateway.name && + setProviderRefs && + loadBalancing.geo && + loadBalancing.weight + ) { + isFormValid = true; } return ( <> - {create ? t('Create DNS Policy') : t('Edit DNS Policy')} + + {create ? t('Create DNS Policy') : t('Edit DNS Policy')} + - -
+ +
{create ? t('Create DNS Policy') : t('Edit DNS Policy')} -

-

{t('DNSPolicy configures how North-South based traffic should be balanced and reach the gateways')}
+

+

+ {t( + 'DNSPolicy configures how North-South based traffic should be balanced and reach the gateways', + )} +

- + {
{createView === 'form' ? ( - -
+ +
{ value={policyName} onChange={handlePolicyChange} isDisabled={formDisabled} - placeholder={t("Policy name")} + placeholder={t('Policy name')} /> @@ -283,7 +340,7 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => { name="provider-ref" value={providerRefs.length > 0 ? providerRefs[0].name : ''} onChange={handleProviderRefs} - placeholder={t("Provider Ref")} + placeholder={t('Provider Ref')} /> @@ -292,8 +349,16 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => {
- - + +
@@ -303,8 +368,7 @@ const KuadrantDNSPolicyCreatePage: React.FC = () => { initialResource={yamlInput} create={create} onChange={handleYAMLChange} - > - + > )} diff --git a/src/components/KuadrantOverviewPage.tsx b/src/components/KuadrantOverviewPage.tsx index 59e2c9f..5b53577 100644 --- a/src/components/KuadrantOverviewPage.tsx +++ b/src/components/KuadrantOverviewPage.tsx @@ -43,7 +43,9 @@ const KuadrantOverviewPage: React.FC = () => { const [activeNamespace, setActiveNamespace] = useActiveNamespace(); const [isExpanded, setIsExpanded] = React.useState(true); const [isOpen, setIsOpen] = React.useState(false); - const [hideCard, setHideCard] = React.useState(sessionStorage.getItem('hideGettingStarted') === 'true'); + const [hideCard, setHideCard] = React.useState( + sessionStorage.getItem('hideGettingStarted') === 'true', + ); React.useEffect(() => { if (ns && ns !== activeNamespace) { @@ -91,24 +93,29 @@ const KuadrantOverviewPage: React.FC = () => { ); - const columns = [{ - title: t('plugin__kuadrant-console-plugin~Name'), - id: 'name', - sort: 'metadata.name', - transforms: [sortable], - }, { - title: t('plugin__kuadrant-console-plugin~Namespace'), - id: 'namespace', - sort: 'metadata.namespace', - transforms: [sortable], - }, { - title: t('plugin__kuadrant-console-plugin~Status'), - id: 'Status', - }, { - title: '', - id: 'kebab', - props: { className: 'pf-v5-c-table__action' }, - }]; + const columns = [ + { + title: t('plugin__kuadrant-console-plugin~Name'), + id: 'name', + sort: 'metadata.name', + transforms: [sortable], + }, + { + title: t('plugin__kuadrant-console-plugin~Namespace'), + id: 'namespace', + sort: 'metadata.namespace', + transforms: [sortable], + }, + { + title: t('plugin__kuadrant-console-plugin~Status'), + id: 'Status', + }, + { + title: '', + id: 'kebab', + props: { className: 'pf-v5-c-table__action' }, + }, + ]; return ( <> @@ -126,7 +133,9 @@ const KuadrantOverviewPage: React.FC = () => { actions={{ actions: headerActions }} onExpand={() => setIsExpanded(!isExpanded)} toggleButtonProps={{ - 'aria-label': isExpanded ? t('Collapse Getting Started') : t('Expand Getting Started'), + 'aria-label': isExpanded + ? t('Collapse Getting Started') + : t('Expand Getting Started'), }} > {t('Getting started resources')} @@ -138,25 +147,45 @@ const KuadrantOverviewPage: React.FC = () => { <GlobeIcon /> {t('Learning Resources')} -

{t('Learn how to create, import and use Kuadrant policies on OpenShift with step-by-step instructions and tasks.')}

+

+ {t( + 'Learn how to create, import and use Kuadrant policies on OpenShift with step-by-step instructions and tasks.', + )} +

- + {t('Create Policies in')} {t('Kuadrant')} - + {t('Add a new Gateway')} - + {t('View Documentation')} - + {t('View all quick starts')} @@ -167,22 +196,41 @@ const KuadrantOverviewPage: React.FC = () => { <OptimizeIcon /> {t('Feature Highlights')} -

{t('Read about the latest information and key features in the Kuadrant highlights.')}

+

+ {t( + 'Read about the latest information and key features in the Kuadrant highlights.', + )} +

- - {t('Kuadrant')} {t('highlights')}   + + {t('Kuadrant')} {t('highlights')}   + - + {t('Kuadrant')} {t('Release Notes')} {t('6 min read')} - + {t('Visit the blog')} @@ -193,20 +241,36 @@ const KuadrantOverviewPage: React.FC = () => { <ReplicatorIcon /> {t('Enhance Your Work')} -

{t('Ease operational complexity with API management and App Connectivity by using additional Operators and tools.')}

+

+ {t( + 'Ease operational complexity with API management and App Connectivity by using additional Operators and tools.', + )} +

- + {t('API Designer')} - + Observability for {t('Kuadrant')} - + {t('cert-manager Operator')} @@ -230,10 +294,10 @@ const KuadrantOverviewPage: React.FC = () => { resourceGVKMapping['AuthPolicy'], resourceGVKMapping['DNSPolicy'], resourceGVKMapping['RateLimitPolicy'], - resourceGVKMapping['TLSPolicy'] + resourceGVKMapping['TLSPolicy'], ]} columns={columns} - namespace='#ALL_NS#' + namespace="#ALL_NS#" paginationLimit={5} /> @@ -243,29 +307,29 @@ const KuadrantOverviewPage: React.FC = () => { - - {t('Gateways')} + + + {t('Gateways')} + - - {t('APIs / HTTPRoutes')} + + + {t('APIs / HTTPRoutes')} + diff --git a/src/components/KuadrantRateLimitPolicyCreatePage.tsx b/src/components/KuadrantRateLimitPolicyCreatePage.tsx index e90bb57..ffdbc4d 100644 --- a/src/components/KuadrantRateLimitPolicyCreatePage.tsx +++ b/src/components/KuadrantRateLimitPolicyCreatePage.tsx @@ -3,7 +3,11 @@ import Helmet from 'react-helmet'; import { Button, ButtonVariant, - Modal, ModalBox, ModalBoxHeader, ModalBoxBody, ModalBoxFooter + Modal, + ModalBox, + ModalBoxHeader, + ModalBoxBody, + ModalBoxFooter, } from '@patternfly/react-core'; import { useTranslation } from 'react-i18next'; @@ -18,7 +22,10 @@ const KuadrantRateLimitPolicyCreatePage: React.FC = () => { const [errorModalMsg] = React.useState(''); const rateLimitPolicy = { - apiVersion: resourceGVKMapping['RateLimitPolicy'].group + '/' + resourceGVKMapping['RateLimitPolicy'].version, + apiVersion: + resourceGVKMapping['RateLimitPolicy'].group + + '/' + + resourceGVKMapping['RateLimitPolicy'].version, kind: resourceGVKMapping['RateLimitPolicy'].kind, metadata: { name: 'example-ratelimitpolicy', @@ -31,7 +38,7 @@ const KuadrantRateLimitPolicyCreatePage: React.FC = () => { name: 'prod-web', }, limits: { - "toystore-api-per-username": { + 'toystore-api-per-username': { rates: [ { limit: 100, @@ -42,14 +49,13 @@ const KuadrantRateLimitPolicyCreatePage: React.FC = () => { limit: 1000, duration: 1, unit: 'minute', - } + }, ], counters: ['auth.identity.username'], }, - }, }, - } + }; return ( <> @@ -57,19 +63,23 @@ const KuadrantRateLimitPolicyCreatePage: React.FC = () => { {t('Create RateLimit Policy')} - - setIsErrorModalOpen(false)} - variant="medium" - > + + setIsErrorModalOpen(false)} variant="medium"> {t('Error creating Rate Limit Policy')} {errorModalMsg} - diff --git a/src/components/KuadrantTLSCreatePage.tsx b/src/components/KuadrantTLSCreatePage.tsx index c923af3..b8e8dc1 100644 --- a/src/components/KuadrantTLSCreatePage.tsx +++ b/src/components/KuadrantTLSCreatePage.tsx @@ -34,40 +34,46 @@ import { ClusterIssuer } from './issuer/types'; import { Issuer } from './issuer/types'; import { Gateway } from './gateway/types'; import GatewaySelect from './gateway/GatewaySelect'; -import KuadrantCreateUpdate from './KuadrantCreateUpdate' +import KuadrantCreateUpdate from './KuadrantCreateUpdate'; import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk'; import resourceGVKMapping from '../utils/latest'; - const KuadrantTLSCreatePage: React.FC = () => { const history = useHistory(); const [policyName, setPolicyName] = React.useState(''); const [selectedNamespace] = useActiveNamespace(); - const [selectedGateway, setSelectedGateway] = React.useState({ name: '', namespace: '' }); - const [selectedClusterIssuers, setSelectedClusterIssuers] = React.useState({ name: '' }); + const [selectedGateway, setSelectedGateway] = React.useState({ + name: '', + namespace: '', + }); + const [selectedClusterIssuers, setSelectedClusterIssuers] = React.useState({ + name: '', + }); const [selectedIssuer, setSelectedIssuers] = React.useState({ name: '', namespace: '' }); - const [certIssuerType, setCertIssuerType] = React.useState<'clusterissuer' | 'issuer'>('clusterissuer'); + const [certIssuerType, setCertIssuerType] = React.useState<'clusterissuer' | 'issuer'>( + 'clusterissuer', + ); const { t } = useTranslation('plugin__kuadrant-console-plugin'); const location = useLocation(); - const pathSplit = location.pathname.split('/') - const nameEdit = pathSplit[6] - const namespaceEdit = pathSplit[3] + const pathSplit = location.pathname.split('/'); + const nameEdit = pathSplit[6]; + const namespaceEdit = pathSplit[3]; const [formDisabled, setFormDisabled] = React.useState(false); const [create, setCreate] = React.useState(true); const [creationTimestamp, setCreationTimestamp] = React.useState(''); const [resourceVersion, setResourceVersion] = React.useState(''); - let isFormValid: boolean = false + let isFormValid = false; // Creates TLS policy object to be used for form and yaml creation of the resource const createTlsPolicy = () => ({ - apiVersion: resourceGVKMapping['TLSPolicy'].group + '/' + resourceGVKMapping['TLSPolicy'].version, + apiVersion: + resourceGVKMapping['TLSPolicy'].group + '/' + resourceGVKMapping['TLSPolicy'].version, kind: resourceGVKMapping['TLSPolicy'].kind, metadata: { name: policyName, namespace: selectedNamespace, - ...(creationTimestamp ? { creationTimestamp } : {}), + ...(creationTimestamp ? { creationTimestamp } : {}), ...(resourceVersion ? { resourceVersion } : {}), - }, spec: { targetRef: { @@ -75,24 +81,29 @@ const KuadrantTLSCreatePage: React.FC = () => { kind: 'Gateway', name: selectedGateway.name, }, - issuerRef: certIssuerType === 'clusterissuer' - ? { - name: selectedClusterIssuers.name, - kind: 'ClusterIssuer', - } : - { - name: selectedIssuer.name, - kind: 'Issuer', - }, + issuerRef: + certIssuerType === 'clusterissuer' + ? { + name: selectedClusterIssuers.name, + kind: 'ClusterIssuer', + } + : { + name: selectedIssuer.name, + kind: 'Issuer', + }, }, - }) + }); const tlsPolicy = createTlsPolicy(); const tlsPolicyGVK = getGroupVersionKindForResource({ apiVersion: `${resourceGVKMapping['TLSPolicy'].group}/${resourceGVKMapping['TLSPolicy'].version}`, kind: resourceGVKMapping['TLSPolicy'].kind, }); - const [tlsPolicyModel] = useK8sModel({ group: tlsPolicyGVK.group, version: tlsPolicyGVK.version, kind: tlsPolicyGVK.kind }); + const [tlsPolicyModel] = useK8sModel({ + group: tlsPolicyGVK.group, + version: tlsPolicyGVK.version, + kind: tlsPolicyGVK.kind, + }); // K8sResourceCommon by default does not contain spec etc which is needed for updating resource forms interface TLSPolicyEdit extends K8sResourceCommon { @@ -110,31 +121,34 @@ const KuadrantTLSCreatePage: React.FC = () => { } //Checking if the policy already exists and is to be edited or if its new and is being created - let tlsResource = null + let tlsResource = null; if (nameEdit) { tlsResource = { groupVersionKind: tlsPolicyGVK, isList: false, name: nameEdit, - namespace: namespaceEdit + namespace: namespaceEdit, }; } - - const [tlsData, tlsLoaded, tlsError] = tlsResource ? useK8sWatchResource(tlsResource) : [null, false, null]; //Syntax allows for tlsResource to be null in the case of a create + const [tlsData, tlsLoaded, tlsError] = tlsResource + ? useK8sWatchResource(tlsResource) + : [null, false, null]; //Syntax allows for tlsResource to be null in the case of a create // When a resource is being updated setting the form from the yaml it gets from useK8sWatchResource React.useEffect(() => { - if (tlsLoaded && !tlsError) { if (!Array.isArray(tlsData)) { const tlsPolicyUpdate = tlsData as TLSPolicyEdit; - setCreationTimestamp(tlsPolicyUpdate.metadata.creationTimestamp) - setResourceVersion(tlsPolicyUpdate.metadata.resourceVersion) - setFormDisabled(true) - setCreate(false) + setCreationTimestamp(tlsPolicyUpdate.metadata.creationTimestamp); + setResourceVersion(tlsPolicyUpdate.metadata.resourceVersion); + setFormDisabled(true); + setCreate(false); setPolicyName(tlsPolicyUpdate.metadata?.name || ''); - setSelectedGateway({ name: tlsPolicyUpdate.spec?.targetRef?.name || '', namespace: tlsPolicyUpdate.metadata?.namespace || '' }); + setSelectedGateway({ + name: tlsPolicyUpdate.spec?.targetRef?.name || '', + namespace: tlsPolicyUpdate.metadata?.namespace || '', + }); if (tlsPolicyUpdate.spec?.issuerRef?.kind === 'ClusterIssuer') { setCertIssuerType('clusterissuer'); setSelectedClusterIssuers({ name: tlsPolicyUpdate.spec?.issuerRef?.name || '' }); @@ -142,11 +156,11 @@ const KuadrantTLSCreatePage: React.FC = () => { setCertIssuerType('issuer'); setSelectedIssuers({ name: tlsPolicyUpdate.spec?.issuerRef?.name || '', - namespace: tlsPolicyUpdate.metadata?.namespace || '' + namespace: tlsPolicyUpdate.metadata?.namespace || '', }); } - console.log("Initializing tls with existing TLS for update"); + console.log('Initializing tls with existing TLS for update'); } } else if (tlsError) { console.error('Failed to fetch the resource:', tlsError); @@ -160,7 +174,10 @@ const KuadrantTLSCreatePage: React.FC = () => { try { const parsedYaml = yaml.load(yamlInput); setPolicyName(parsedYaml.metadata?.name || ''); - setSelectedGateway({ name: parsedYaml.spec?.targetRef?.name || '', namespace: parsedYaml.metadata?.namespace || '' }); + setSelectedGateway({ + name: parsedYaml.spec?.targetRef?.name || '', + namespace: parsedYaml.metadata?.namespace || '', + }); if (parsedYaml.spec?.issuerRef?.kind === 'ClusterIssuer') { setCertIssuerType('clusterissuer'); setSelectedClusterIssuers({ name: parsedYaml.spec?.issuerRef?.name || '' }); @@ -171,7 +188,6 @@ const KuadrantTLSCreatePage: React.FC = () => { namespace: parsedYaml.metadata?.namespace || '', }); } - } catch (e) { console.error(t('Error parsing YAML:'), e); } @@ -179,7 +195,14 @@ const KuadrantTLSCreatePage: React.FC = () => { // When new changes are made to via form update the yaml view React.useEffect(() => { setYamlInput(tlsPolicy); - }, [policyName, selectedNamespace, selectedGateway, certIssuerType, selectedClusterIssuers, selectedIssuer]); + }, [ + policyName, + selectedNamespace, + selectedGateway, + certIssuerType, + selectedClusterIssuers, + selectedIssuer, + ]); const [view, setView] = React.useState('form'); @@ -193,8 +216,13 @@ const KuadrantTLSCreatePage: React.FC = () => { handleCancel(selectedNamespace, tlsPolicy, history); }; - if (policyName && selectedNamespace && selectedGateway.name && (selectedClusterIssuers.name || selectedIssuer.name)) { - isFormValid = true + if ( + policyName && + selectedNamespace && + selectedGateway.name && + (selectedClusterIssuers.name || selectedIssuer.name) + ) { + isFormValid = true; } return ( @@ -205,18 +233,29 @@ const KuadrantTLSCreatePage: React.FC = () => { - -
+ +
{create ? 'Create TLS Policy' : 'Edit TLS Policy'} -

-

{t('Targets Gateway API networking resources Gateways to provide TLS for gateway listeners by managing the lifecycle of TLS certificates using cert-manager')}
+

+

+ {t( + 'Targets Gateway API networking resources Gateways to provide TLS for gateway listeners by managing the lifecycle of TLS certificates using cert-manager', + )} +

- + setView('form')} id="form-view" @@ -225,7 +264,7 @@ const KuadrantTLSCreatePage: React.FC = () => { setView('yaml')} id="yaml-view" @@ -237,12 +276,8 @@ const KuadrantTLSCreatePage: React.FC = () => {
{view === 'form' ? ( -
- + + { value={policyName} onChange={handleNameChange} isDisabled={formDisabled} - placeholder={t("Policy name")} + placeholder={t('Policy name')} /> @@ -260,58 +295,67 @@ const KuadrantTLSCreatePage: React.FC = () => { - + - - + + { setCertIssuerType('clusterissuer'); - } - } + }} id="cluster-issuer" name="issuer" /> { setCertIssuerType('issuer'); - } - } + }} id="issuer" name="issuer" /> {certIssuerType === 'clusterissuer' ? ( - + ) : ( )} - - + +
) : ( {t('Loading..')}.
}> - + >
)} @@ -320,4 +364,3 @@ const KuadrantTLSCreatePage: React.FC = () => { }; export default KuadrantTLSCreatePage; - diff --git a/src/components/dnspolicy/HealthCheckField.tsx b/src/components/dnspolicy/HealthCheckField.tsx index 0cb5c63..7319481 100644 --- a/src/components/dnspolicy/HealthCheckField.tsx +++ b/src/components/dnspolicy/HealthCheckField.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { FormGroup, TextInput, FormSelect, FormSelectOption } from "@patternfly/react-core"; -import { HealthCheck } from "./types"; +import { FormGroup, TextInput, FormSelect, FormSelectOption } from '@patternfly/react-core'; +import { HealthCheck } from './types'; import { useTranslation } from 'react-i18next'; interface HealthCheckProps { @@ -28,7 +28,9 @@ const HealthCheckField: React.FC = ({ healthCheck, onChange }) id="health-check-failure-threshold" type="number" value={healthCheck.failureThreshold} - onChange={(event) => onChange({ ...healthCheck, failureThreshold: Number(event.currentTarget.value) })} + onChange={(event) => + onChange({ ...healthCheck, failureThreshold: Number(event.currentTarget.value) }) + } isRequired min={1} placeholder="0" @@ -39,7 +41,9 @@ const HealthCheckField: React.FC = ({ healthCheck, onChange }) id="health-check-port" type="number" value={healthCheck.port} - onChange={(event) => onChange({ ...healthCheck, port: Number(event.currentTarget.value) })} + onChange={(event) => + onChange({ ...healthCheck, port: Number(event.currentTarget.value) }) + } isRequired min={1} placeholder="0" @@ -49,7 +53,9 @@ const HealthCheckField: React.FC = ({ healthCheck, onChange }) onChange({ ...healthCheck, protocol: event.currentTarget.value as 'HTTP' | 'HTTPS' })} + onChange={(event) => + onChange({ ...healthCheck, protocol: event.currentTarget.value as 'HTTP' | 'HTTPS' }) + } isRequired aria-label={t('Select a Protocol')} > @@ -59,7 +65,7 @@ const HealthCheckField: React.FC = ({ healthCheck, onChange }) - ) + ); }; export default HealthCheckField; diff --git a/src/components/dnspolicy/LoadBalancingField.tsx b/src/components/dnspolicy/LoadBalancingField.tsx index 4a0a376..c9c211f 100644 --- a/src/components/dnspolicy/LoadBalancingField.tsx +++ b/src/components/dnspolicy/LoadBalancingField.tsx @@ -1,6 +1,13 @@ import * as React from 'react'; -import { FormGroup, TextInput, FormHelperText, HelperText, HelperTextItem, Radio } from '@patternfly/react-core'; +import { + FormGroup, + TextInput, + FormHelperText, + HelperText, + HelperTextItem, + Radio, +} from '@patternfly/react-core'; import { LoadBalancing } from './types'; import { useTranslation } from 'react-i18next'; @@ -32,7 +39,6 @@ const LoadBalancingField: React.FC = ({ loadBalancing, onCha isRequired type="number" placeholder="0" - /> = ({ loadBalancing, onCha placeholder={t("Geography Label (e.g. 'eu')")} /> - + + onChange={() => onChange({ ...loadBalancing, defaultGeo: true, @@ -62,9 +75,9 @@ const LoadBalancingField: React.FC = ({ loadBalancing, onCha name="default-geo" /> + onChange={() => onChange({ ...loadBalancing, defaultGeo: false, @@ -75,9 +88,8 @@ const LoadBalancingField: React.FC = ({ loadBalancing, onCha /> - ); }; -export default LoadBalancingField; \ No newline at end of file +export default LoadBalancingField; diff --git a/src/components/dnspolicy/types.ts b/src/components/dnspolicy/types.ts index 347f75e..60fd3f2 100644 --- a/src/components/dnspolicy/types.ts +++ b/src/components/dnspolicy/types.ts @@ -1,7 +1,3 @@ - - - - export interface LoadBalancing { geo: string; weight: number; diff --git a/src/components/gateway/GatewaySelect.tsx b/src/components/gateway/GatewaySelect.tsx index 1fb4dc2..0b08e71 100644 --- a/src/components/gateway/GatewaySelect.tsx +++ b/src/components/gateway/GatewaySelect.tsx @@ -1,32 +1,41 @@ import { ResourceLink, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; -import { FormGroup, FormHelperText, FormSelect, FormSelectOption, HelperText, HelperTextItem } from '@patternfly/react-core'; +import { + FormGroup, + FormHelperText, + FormSelect, + FormSelectOption, + HelperText, + HelperTextItem, +} from '@patternfly/react-core'; import * as React from 'react'; import { Gateway } from './types'; import { useTranslation } from 'react-i18next'; interface GatewaySelectProps { - selectedGateway: Gateway, + selectedGateway: Gateway; onChange: (updated: Gateway) => void; } const GatewaySelect: React.FC = ({ selectedGateway, onChange }) => { const { t } = useTranslation('plugin__kuadrant-console-plugin'); const [gateways, setGateways] = React.useState([]); - const gvk = { group: 'gateway.networking.k8s.io', version: 'v1', kind: 'Gateway' } + const gvk = { group: 'gateway.networking.k8s.io', version: 'v1', kind: 'Gateway' }; const gatewayResource = { groupVersionKind: gvk, - isList: true + isList: true, }; const [gatewayData, gatewayLoaded, gatewayError] = useK8sWatchResource(gatewayResource); React.useEffect(() => { if (gatewayLoaded && !gatewayError && Array.isArray(gatewayData)) { - setGateways(gatewayData.map((gateway) => ({ - name: gateway.metadata.name, - namespace: gateway.metadata.namespace, - }))); + setGateways( + gatewayData.map((gateway) => ({ + name: gateway.metadata.name, + namespace: gateway.metadata.namespace, + })), + ); } }, [gatewayData, gatewayLoaded, gatewayError]); @@ -44,7 +53,12 @@ const GatewaySelect: React.FC = ({ selectedGateway, onChange onChange={handleGatewayChange} aria-label={t('Select Gateway')} > - + {gateways.map((gateway, index) => ( = ({ selectedGateway, onChange - {t('Gateway: Reference to a Kubernetes resource that the policy attaches to. To create an additional gateway go to')} + + {t( + 'Gateway: Reference to a Kubernetes resource that the policy attaches to. To create an additional gateway go to', + )}{' '} + - + ); }; diff --git a/src/components/gateway/types.ts b/src/components/gateway/types.ts index 893c49a..a2d9e79 100644 --- a/src/components/gateway/types.ts +++ b/src/components/gateway/types.ts @@ -1,4 +1,4 @@ export interface Gateway { - name: string, - namespace: string -} \ No newline at end of file + name: string; + namespace: string; +} diff --git a/src/components/httproute/HTTPRouteSelect.tsx b/src/components/httproute/HTTPRouteSelect.tsx index 0983ef6..79c7680 100644 --- a/src/components/httproute/HTTPRouteSelect.tsx +++ b/src/components/httproute/HTTPRouteSelect.tsx @@ -1,11 +1,18 @@ import { ResourceLink, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; -import { FormGroup, FormHelperText, FormSelect, FormSelectOption, HelperText, HelperTextItem } from '@patternfly/react-core'; +import { + FormGroup, + FormHelperText, + FormSelect, + FormSelectOption, + HelperText, + HelperTextItem, +} from '@patternfly/react-core'; import * as React from 'react'; import { HTTPRoute } from './types'; // You will need to define this type similarly to Gateway. import { useTranslation } from 'react-i18next'; interface HTTPRouteSelectProps { - selectedHTTPRoute: HTTPRoute, + selectedHTTPRoute: HTTPRoute; onChange: (updated: HTTPRoute) => void; } @@ -16,17 +23,19 @@ const HTTPRouteSelect: React.FC = ({ selectedHTTPRoute, on const httpRouteResource = { groupVersionKind: gvk, - isList: true + isList: true, }; const [httpRouteData, httpRouteLoaded, httpRouteError] = useK8sWatchResource(httpRouteResource); React.useEffect(() => { if (httpRouteLoaded && !httpRouteError && Array.isArray(httpRouteData)) { - setHTTPRoutes(httpRouteData.map((httpRoute) => ({ - name: httpRoute.metadata.name, - namespace: httpRoute.metadata.namespace, - }))); + setHTTPRoutes( + httpRouteData.map((httpRoute) => ({ + name: httpRoute.metadata.name, + namespace: httpRoute.metadata.namespace, + })), + ); } }, [httpRouteData, httpRouteLoaded, httpRouteError]); @@ -44,7 +53,12 @@ const HTTPRouteSelect: React.FC = ({ selectedHTTPRoute, on onChange={handleHTTPRouteChange} aria-label={t('Select HTTPRoute')} > - + {httpRoutes.map((httpRoute, index) => ( = ({ selectedHTTPRoute, on - {t('You can view and create HTTPRoutes')} + + {t('You can view and create HTTPRoutes')}{' '} + diff --git a/src/components/httproute/types.ts b/src/components/httproute/types.ts index bcdb395..9c53804 100644 --- a/src/components/httproute/types.ts +++ b/src/components/httproute/types.ts @@ -1,4 +1,4 @@ export interface HTTPRoute { - name: string, - namespace: string -} \ No newline at end of file + name: string; + namespace: string; +} diff --git a/src/components/issuer/clusterIssuerSelect.tsx b/src/components/issuer/clusterIssuerSelect.tsx index ab0e275..0733ab4 100644 --- a/src/components/issuer/clusterIssuerSelect.tsx +++ b/src/components/issuer/clusterIssuerSelect.tsx @@ -1,32 +1,44 @@ import { ResourceLink, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; -import { FormGroup, FormHelperText, FormSelect, FormSelectOption, HelperText, HelperTextItem } from '@patternfly/react-core'; +import { + FormGroup, + FormHelperText, + FormSelect, + FormSelectOption, + HelperText, + HelperTextItem, +} from '@patternfly/react-core'; import * as React from 'react'; import { ClusterIssuer } from './types'; // You will need to define this type similarly to Gateway. import { useTranslation } from 'react-i18next'; interface ClusterIssuerSelectProps { - selectedClusterIssuer: ClusterIssuer, + selectedClusterIssuer: ClusterIssuer; onChange: (updated: ClusterIssuer) => void; } -const ClusterIssuerSelect: React.FC = ({ selectedClusterIssuer, onChange }) => { +const ClusterIssuerSelect: React.FC = ({ + selectedClusterIssuer, + onChange, +}) => { const { t } = useTranslation('plugin__kuadrant-console-plugin'); const [clusterIssuers, setClusterIssuers] = React.useState([]); const gvk = { group: 'cert-manager.io', version: 'v1', kind: 'ClusterIssuer' }; const clusterIssuerResource = { groupVersionKind: gvk, - isList: true + isList: true, }; - const [clusterIssuerData, clusterIssuerLoaded, clusterIssuerError] = useK8sWatchResource(clusterIssuerResource); + const [clusterIssuerData, clusterIssuerLoaded, clusterIssuerError] = + useK8sWatchResource(clusterIssuerResource); React.useEffect(() => { if (clusterIssuerLoaded && !clusterIssuerError && Array.isArray(clusterIssuerData)) { - setClusterIssuers(clusterIssuerData.map((clusterIssuer) => ({ - name: clusterIssuer.metadata.name, - - }))); + setClusterIssuers( + clusterIssuerData.map((clusterIssuer) => ({ + name: clusterIssuer.metadata.name, + })), + ); } }, [clusterIssuerData, clusterIssuerLoaded, clusterIssuerError]); @@ -37,14 +49,23 @@ const ClusterIssuerSelect: React.FC = ({ selectedClust return ( <> - + - + {clusterIssuers.map((clusterIssuer, index) => ( = ({ selectedClust - {t('Cluster Issuer: Reference to the cluster issuer for the created certificate. To create an additional ClusterIssuer go to')} + + {t( + 'Cluster Issuer: Reference to the cluster issuer for the created certificate. To create an additional ClusterIssuer go to', + )}{' '} + diff --git a/src/components/issuer/issuerSelect.tsx b/src/components/issuer/issuerSelect.tsx index 52cca35..e64e9ce 100644 --- a/src/components/issuer/issuerSelect.tsx +++ b/src/components/issuer/issuerSelect.tsx @@ -1,11 +1,18 @@ import { ResourceLink, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; -import { FormGroup, FormHelperText, FormSelect, FormSelectOption, HelperText, HelperTextItem } from '@patternfly/react-core'; +import { + FormGroup, + FormHelperText, + FormSelect, + FormSelectOption, + HelperText, + HelperTextItem, +} from '@patternfly/react-core'; import * as React from 'react'; import { Issuer } from './types'; // You will need to define this type similarly to Gateway. import { useTranslation } from 'react-i18next'; interface IssuerSelectProps { - selectedIssuer: Issuer, + selectedIssuer: Issuer; onChange: (updated: Issuer) => void; } @@ -16,17 +23,20 @@ const IssuerSelect: React.FC = ({ selectedIssuer, onChange }) const clusterIssuerResource = { groupVersionKind: gvk, - isList: true + isList: true, }; - const [clusterIssuerData, clusterIssuerLoaded, clusterIssuerError] = useK8sWatchResource(clusterIssuerResource); + const [clusterIssuerData, clusterIssuerLoaded, clusterIssuerError] = + useK8sWatchResource(clusterIssuerResource); React.useEffect(() => { if (clusterIssuerLoaded && !clusterIssuerError && Array.isArray(clusterIssuerData)) { - setIssuers(clusterIssuerData.map((clusterIssuer) => ({ - name: clusterIssuer.metadata.name, - namespace: clusterIssuer.metadata.namespace, - }))); + setIssuers( + clusterIssuerData.map((clusterIssuer) => ({ + name: clusterIssuer.metadata.name, + namespace: clusterIssuer.metadata.namespace, + })), + ); } }, [clusterIssuerData, clusterIssuerLoaded, clusterIssuerError]); @@ -44,7 +54,12 @@ const IssuerSelect: React.FC = ({ selectedIssuer, onChange }) onChange={handleIssuerChange} aria-label={t('Select Issuer')} > - + {issuers.map((clusterIssuer, index) => ( = ({ selectedIssuer, onChange }) - {t('Issuer: Reference to the issuer for the created certificate. To create an additional Issuer go to')} + + {t( + 'Issuer: Reference to the issuer for the created certificate. To create an additional Issuer go to', + )}{' '} + diff --git a/src/components/issuer/types.ts b/src/components/issuer/types.ts index 0089620..a6ecc17 100644 --- a/src/components/issuer/types.ts +++ b/src/components/issuer/types.ts @@ -1,8 +1,8 @@ export interface ClusterIssuer { - name: string, + name: string; } export interface Issuer { - name: string, - namespace: string -} \ No newline at end of file + name: string; + namespace: string; +} diff --git a/src/components/kuadrant.css b/src/components/kuadrant.css index 4d9e567..6f0bdbc 100644 --- a/src/components/kuadrant.css +++ b/src/components/kuadrant.css @@ -11,7 +11,12 @@ stroke-width: 1; stroke: var(--pf-topology__edge--Stroke); animation: dash-animation 2s linear infinite; - fill: #d4f2ffa4; + fill: var(--pf-global--palette--blue-100); +} + +.pf-theme-dark .policy-node .pf-topology__node__background { + fill-opacity: 0.3; + stroke: var(--pf-global--palette--white); } @keyframes dash-animation { @@ -21,15 +26,15 @@ } .pf-theme-light .pf-topology__node .kuadrant-topology-type-text { - fill: #000 !important; + fill: var(--pf-global--palette--black-900) !important; } .pf-theme-dark .pf-topology__node .kuadrant-topology-type-text { - fill: #fff !important; + fill: var(--pf-global--palette--white) !important; } .kuadrant-policy-topology .pf-topology__node__label__badge > text { - fill: #fff; + fill: var(--pf-global--palette--white); } .kuadrant-page-title { @@ -46,11 +51,9 @@ .kuadrant-editor-toggle { display: flex; - padding-left: 1.5rem; - padding-right: 1.5rem; + padding: var(--pf-v5-global--spacer--sm) 1.5rem var(--pf-v5-global--spacer--sm) 1.5rem; border-bottom: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--100); border-top: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--100); - padding: var(--pf-v5-global--spacer--sm) var(--pf-v5-global--spacer--lg); } .kuadrant-editor-toggle .pf-v5-c-radio { @@ -64,53 +67,41 @@ padding: 1rem; } -.kuadrant-dashboard-learning { - color: #1F0066; +.kuadrant-dashboard-learning, .kuadrant-dashboard-feature-highlights, .kuadrant-dashboard-enhance { + margin-bottom: 0.5em; } .pf-theme-light .kuadrant-dashboard-learning { - color: #1F0066; + color: var(--pf-v5-chart-color-purple-400); } .pf-theme-dark .kuadrant-dashboard-learning { - color: #9c90b9; + color: var(--pf-v5-chart-color-purple-200); } .kuadrant-dashboard-feature-highlights { - color: #0066CC; + color: var(--pf-global--palette--blue-300); } .kuadrant-dashboard-enhance { - color: #D38940; -} - -.kuadrant-dashboard-learning, .kuadrant-dashboard-feature-highlights, .kuadrant-dashboard-enhance { - margin-bottom: 0.5em; + color: var(--pf-global--palette--orange-400); } .kuadrant-dashboard-resource-link { text-decoration: none; - color: black; + color: var(--pf-global--palette--black); cursor: pointer; font-size: 0.9rem; } -.pf-theme-light .kuadrant-dashboard-resource-link { - color: black; -} - -.pf-theme-dark .kuadrant-dashboard-resource-link { - color: white; -} - .kuadrant-dashboard-resource-link:hover { text-decoration: underline; - color: #0066cc; + color: var(--pf-global--palette--blue-400); } .kuadrant-reading-time { font-size: 0.8rem; - color: grey; + color: var(--pf-global--palette--black-600); margin-left: 1rem; margin-right: 1rem } @@ -122,24 +113,6 @@ .kuadrant-limits-button, .pf-v5-c-label-group { margin: 1rem; } -.namespaceSelectWrapper { - display: flex; - align-items: center; - border: 1px solid #ccc; - padding-left: 4px; -} - -.namespaceBadge { - background-color: green; - color: white; - padding: 6px 12px; - border-radius: 70%; - display: flex; - justify-content: center; - align-items: center; - width: 24px; - height: 24px; -} .kuadrant-resource-create-container { position: relative; diff --git a/src/components/ratelimitpolicy/AddLimitModal.tsx b/src/components/ratelimitpolicy/AddLimitModal.tsx index c5a6ba0..5222f63 100644 --- a/src/components/ratelimitpolicy/AddLimitModal.tsx +++ b/src/components/ratelimitpolicy/AddLimitModal.tsx @@ -1,4 +1,12 @@ -import { FormGroup, FormSelect, FormSelectOption, Modal, TextInput, Wizard, WizardStep } from '@patternfly/react-core'; +import { + FormGroup, + FormSelect, + FormSelectOption, + Modal, + TextInput, + Wizard, + WizardStep, +} from '@patternfly/react-core'; import * as React from 'react'; import { LimitConfig } from './types'; import { useTranslation } from 'react-i18next'; @@ -23,10 +31,12 @@ const LimitConfigForm: React.FC<{ setNewLimit({ - ...newLimit, - rates: [{ ...newLimit.rates?.[0], limit: parseInt(event.currentTarget.value, 10) }] - })} + onChange={(event) => + setNewLimit({ + ...newLimit, + rates: [{ ...newLimit.rates?.[0], limit: parseInt(event.currentTarget.value, 10) }], + }) + } isRequired /> @@ -34,17 +44,31 @@ const LimitConfigForm: React.FC<{ setNewLimit({ - ...newLimit, - rates: [{ ...newLimit.rates?.[0], duration: parseInt(event.currentTarget.value, 10) }] - })} + onChange={(event) => + setNewLimit({ + ...newLimit, + rates: [ + { ...newLimit.rates?.[0], duration: parseInt(event.currentTarget.value, 10) }, + ], + }) + } isRequired /> setNewLimit({ ...newLimit, rates: [{ ...newLimit.rates?.[0], unit: event.currentTarget.value as "second" | "minute" | "hour" | "day" }] })} + onChange={(event) => + setNewLimit({ + ...newLimit, + rates: [ + { + ...newLimit.rates?.[0], + unit: event.currentTarget.value as 'second' | 'minute' | 'hour' | 'day', + }, + ], + }) + } > @@ -67,20 +91,14 @@ const AddLimitModal: React.FC<{ }> = ({ isOpen, onClose, newLimit, setNewLimit, rateName, setRateName, handleSave }) => { const { t } = useTranslation('plugin__kuadrant-console-plugin'); return ( - -
- - + +
+ + ; @@ -14,7 +14,7 @@ const LimitSelect: React.FC = ({ limits, setLimits }) => { const [isAddLimitModalOpen, setIsAddLimitModalOpen] = React.useState(false); const [isLimitNameAlertModalOpen, setIsLimitNameAlertModalOpen] = React.useState(false); const [newLimit, setNewLimit] = React.useState({ - rates: [{ duration: 60, limit: 100, unit: 'minute' }] + rates: [{ duration: 60, limit: 100, unit: 'minute' }], }); const [rateName, setRateName] = React.useState(''); @@ -51,16 +51,15 @@ const LimitSelect: React.FC = ({ limits, setLimits }) => { return ( <> - {t('Configured Limits')} + + {t('Configured Limits')} + {Object.keys(limits).length > 0 ? ( Object.entries(limits).map(([name, limitConfig], index) => ( -