+
{`${t('common.headers.conditions')}:`}
diff --git a/src/shared/components/ResourcesList/ResourcesList.js b/src/shared/components/ResourcesList/ResourcesList.js
index e1314a5b60..77486ad7c7 100644
--- a/src/shared/components/ResourcesList/ResourcesList.js
+++ b/src/shared/components/ResourcesList/ResourcesList.js
@@ -67,54 +67,62 @@ ResourcesList.propTypes = {
omitColumnsIds: PropTypes.arrayOf(PropTypes.string.isRequired),
resourceUrlPrefix: PropTypes.string,
disableCreate: PropTypes.bool,
- disableEdit: PropTypes.bool,
disableDelete: PropTypes.bool,
disableMargin: PropTypes.bool,
enableColumnLayout: PropTypes.bool,
layoutNumber: PropTypes.string,
handleRedirect: PropTypes.func,
+ filterFn: PropTypes.func,
};
-ResourcesList.defaultProps = {
- customHeaderActions: null,
- customColumns: [],
- createResourceForm: null,
- showTitle: false,
- listHeaderActions: null,
- readOnly: false,
- disableCreate: false,
- disableEdit: false,
- disableDelete: false,
- disableMargin: false,
- enableColumnLayout: false,
- layoutNumber: 'StartColumn',
- filterFn: () => true,
-};
-
-export function ResourcesList(props) {
- const headerInjections = useGetInjections(props.resourceType, 'list-header');
- if (!props.resourceUrl) {
+export function ResourcesList({
+ customHeaderActions = null,
+ resourceUrl,
+ resourceType,
+ resourceTitle,
+ isCompact,
+ description,
+ layoutNumber = 'StartColumn',
+ resources,
+ filterFn = () => true,
+ ...props
+}) {
+ const headerInjections = useGetInjections(resourceType, 'list-header');
+ if (!resourceUrl) {
return <>>; // wait for the context update
}
+ const allProps = {
+ customHeaderActions,
+ resourceUrl,
+ resourceType,
+ resourceTitle,
+ isCompact,
+ description,
+ layoutNumber,
+ resources,
+ filterFn,
+ ...props,
+ };
+
const content = (
<>
}
/>
- {props.resources ? (
+ {resources ? (
) : (
-
+
)}
>
);
@@ -122,24 +130,24 @@ export function ResourcesList(props) {
const headerActions = headerInjections.length ? (
<>
- {props.customHeaderActions}
+ {customHeaderActions}
>
) : (
- props.customHeaderActions
+ customHeaderActions
);
return (
<>
- {!props.isCompact ? (
+ {!isCompact ? (
) : (
@@ -174,9 +182,9 @@ function Resources(props) {
);
}
@@ -188,13 +196,13 @@ export function ResourceListRenderer({
namespace,
customColumns = [],
columns,
- createResourceForm: CreateResourceForm,
+ createResourceForm: CreateResourceForm = null,
createActionLabel,
hasDetailsView,
title,
- showTitle,
- listHeaderActions,
- readOnly,
+ showTitle = false,
+ listHeaderActions = null,
+ readOnly = false,
customUrl,
testid,
omitColumnsIds = ['namespace'],
@@ -205,10 +213,10 @@ export function ResourceListRenderer({
resources,
resourceUrlPrefix,
nameSelector = entry => entry?.metadata.name, // overriden for CRDGroupList
- disableCreate,
- disableDelete,
- disableMargin,
- enableColumnLayout,
+ disableCreate = false,
+ disableDelete = false,
+ disableMargin = false,
+ enableColumnLayout = false,
columnLayout,
customColumnLayout,
layoutCloseCreateUrl,
diff --git a/src/shared/components/RunningPodsStatus.js b/src/shared/components/RunningPodsStatus.js
index e22073c680..3f7ad30598 100644
--- a/src/shared/components/RunningPodsStatus.js
+++ b/src/shared/components/RunningPodsStatus.js
@@ -7,7 +7,7 @@ export function RunningPodsStatus({ running, expected }) {
running === 1
? t('common.tooltips.running-pods-singular')
: t('common.tooltips.running-pods-plural', { running });
- const statusType = running === expected ? 'Success' : 'Error';
+ const statusType = running === expected ? 'Positive' : 'Negative';
return (
{name && (
-
- {name}
-
+ {name}
)}
{types &&
types
@@ -36,17 +33,18 @@ export function JSONSchema({
}
})
.map(type => (
- {type.toUpperCase()}
- ))}{' '}
+
+ {type.toUpperCase()}
+
+ ))}
{isRequired && (
-
+
{t('schema.required')}
)}
)}
{description && {description}
}
-
diff --git a/src/shared/components/SchemaViewer/ObjectProperties.js b/src/shared/components/SchemaViewer/ObjectProperties.js
index 25fbecc0c8..9a14bcdd45 100644
--- a/src/shared/components/SchemaViewer/ObjectProperties.js
+++ b/src/shared/components/SchemaViewer/ObjectProperties.js
@@ -4,7 +4,6 @@ import classNames from 'classnames';
import { Text, Icon } from '@ui5/webcomponents-react';
import { Generic, PROPERTIES } from './handlers';
-import { spacing } from '@ui5/webcomponents-react-base';
function ObjectProperty({ label, val, handler, required, expanded = false }) {
const [collapsed, setCollapsed] = useState(!expanded);
@@ -20,7 +19,7 @@ function ObjectProperty({ label, val, handler, required, expanded = false }) {
>
{handler.expandable && (
setSchemaMode('viewer')}
>
{t('schema.modes.viewer')}
setSchemaMode('json')}
>
{t('schema.modes.json')}
setSchemaMode('yaml')}
>
{t('schema.modes.yaml')}
diff --git a/src/shared/components/Secret/test/SecretData.cy.js b/src/shared/components/Secret/test/SecretData.cy.js
new file mode 100644
index 0000000000..a2ebfc82cd
--- /dev/null
+++ b/src/shared/components/Secret/test/SecretData.cy.js
@@ -0,0 +1,78 @@
+/* global cy */
+import SecretData from '../SecretData';
+import '@ui5/webcomponents-icons/dist/AllIcons.js';
+
+describe('SecretData Component', () => {
+ const secret = {
+ data: {
+ client_id: btoa('client-id'),
+ client_secret: btoa('client-secret'),
+ },
+ };
+
+ const empty_secret = {};
+
+ const mountComponent = secretProp => {
+ cy.mount();
+ };
+
+ const expectInitialState = () => {
+ cy.get('pre.secret')
+ .filter(':contains("*****")')
+ .should('have.length', 2);
+
+ cy.contains(secret.data.client_id).should('not.exist');
+ cy.contains(secret.data.client_secret).should('not.exist');
+ cy.contains(btoa(secret.data.client_id)).should('not.exist');
+ cy.contains(btoa(secret.data.client_secret)).should('not.exist');
+ };
+
+ const expectDecodedState = () => {
+ cy.contains(atob(secret.data.client_id)).should('be.visible');
+ cy.contains(atob(secret.data.client_secret)).should('be.visible');
+
+ cy.contains(secret.data.client_id).should('not.exist');
+ cy.contains(secret.data.client_secret).should('not.exist');
+ };
+
+ const expectEncodedState = () => {
+ cy.contains(secret.data.client_id).should('be.visible');
+ cy.contains(secret.data.client_secret).should('be.visible');
+
+ cy.contains(btoa(secret.data.client_id)).should('not.exist');
+ cy.contains(btoa(secret.data.client_secret)).should('not.exist');
+ };
+
+ it('Renders header', () => {
+ mountComponent(secret);
+ cy.contains('secrets.data').should('be.visible');
+ });
+
+ it('Decodes and encodes secret values', () => {
+ mountComponent(secret);
+
+ expectInitialState();
+
+ cy.contains('secrets.buttons.decode')
+ .first()
+ .click();
+
+ expectDecodedState();
+
+ cy.contains('secrets.buttons.encode')
+ .first()
+ .click();
+
+ expectEncodedState();
+ });
+
+ it('Renders secret not found', () => {
+ mountComponent(null);
+ cy.contains('secrets.secret-not-found').should('be.visible');
+ });
+
+ it('Renders empty secret', () => {
+ mountComponent(empty_secret);
+ cy.contains('secrets.secret-empty').should('be.visible');
+ });
+});
diff --git a/src/shared/components/Secret/test/SecretData.test.js b/src/shared/components/Secret/test/SecretData.test.js
deleted file mode 100644
index 7aa88404e4..0000000000
--- a/src/shared/components/Secret/test/SecretData.test.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import { render, fireEvent, cleanup } from '@testing-library/react';
-import { ThemeProvider } from '@ui5/webcomponents-react';
-import '@ui5/webcomponents-icons/dist/AllIcons.js';
-
-import SecretData from '../SecretData';
-
-export const secret = {
- data: {
- client_id: btoa('client-id'),
- client_secret: btoa('client-secret'),
- },
-};
-
-export const empty_secret = {};
-
-describe('SecretData', () => {
- const expectInitialState = async ({ getAllByText, queryByText }) => {
- expect(await getAllByText('*****')).toHaveLength(2);
-
- expect(queryByText(secret.data.client_id)).not.toBeInTheDocument();
- expect(queryByText(secret.data.client_secret)).not.toBeInTheDocument();
- expect(queryByText(btoa(secret.data.client_id))).not.toBeInTheDocument();
- expect(
- queryByText(btoa(secret.data.client_secret)),
- ).not.toBeInTheDocument();
- };
-
- const expectDecodedState = async ({ findByText, queryByText }) => {
- expect(await findByText(atob(secret.data.client_id))).toBeInTheDocument();
- expect(
- await findByText(atob(secret.data.client_secret)),
- ).toBeInTheDocument();
-
- expect(queryByText(secret.data.client_id)).not.toBeInTheDocument();
- expect(queryByText(secret.data.client_secret)).not.toBeInTheDocument();
- };
-
- const expectEncodedState = async ({ findByText, queryByText }) => {
- expect(await findByText(secret.data.client_id)).toBeInTheDocument();
- expect(await findByText(secret.data.client_secret)).toBeInTheDocument();
-
- expect(queryByText(btoa(secret.data.client_id))).not.toBeInTheDocument();
- expect(
- queryByText(btoa(secret.data.client_secret)),
- ).not.toBeInTheDocument();
- };
-
- it('Renders header', async () => {
- const { queryByText } = render(
-
-
- ,
- );
-
- expect(queryByText('secrets.data')).toBeInTheDocument();
- cleanup();
- });
-
- it('Decodes and encodes secret values', async () => {
- const { findByText, getAllByText, queryByText } = render(
-
-
- ,
- );
-
- await expectInitialState({ getAllByText, queryByText });
-
- fireEvent.click(getAllByText('secrets.buttons.decode')[0]);
- await expectDecodedState({ findByText, queryByText });
-
- fireEvent.click(getAllByText('secrets.buttons.encode')[0]);
- await expectEncodedState({ findByText, queryByText });
- cleanup();
- });
-
- it('Renders secret not found', async () => {
- const { findByText } = render(
-
-
- ,
- );
- expect(await findByText('secrets.secret-not-found')).toBeInTheDocument();
- cleanup();
- });
-
- it('Renders empty secret', async () => {
- const { findByText } = render(
-
-
- ,
- );
- expect(await findByText('secrets.secret-empty')).toBeInTheDocument();
- cleanup();
- });
-});
diff --git a/src/shared/components/Selector/Selector.js b/src/shared/components/Selector/Selector.js
index fe849f6a69..63a67e9a38 100644
--- a/src/shared/components/Selector/Selector.js
+++ b/src/shared/components/Selector/Selector.js
@@ -6,7 +6,6 @@ import { MatchExpressionsList } from '../MatchExpressionsList';
import { isEmpty, isEqual } from 'lodash';
import { Text, Title } from '@ui5/webcomponents-react';
import { UI5Panel } from '../UI5Panel/UI5Panel';
-import { spacing } from '@ui5/webcomponents-react-base';
const SelectorDetails = ({
expressions,
@@ -25,7 +24,7 @@ const SelectorDetails = ({
};
const relatedResources = RelatedResources ? (
-
+
) : (
{isSelectorDefinedOrEmpty ? (
-
+
{message || t('selector.message.empty-selector')}
) : (
diff --git a/src/shared/components/Selector/tests/Selector.cy.js b/src/shared/components/Selector/tests/Selector.cy.js
new file mode 100644
index 0000000000..ed5830e765
--- /dev/null
+++ b/src/shared/components/Selector/tests/Selector.cy.js
@@ -0,0 +1,147 @@
+/* global cy */
+import { useTranslation } from 'react-i18next';
+import { Selector } from '../Selector';
+
+const MockedRelatedPods = ({ namespace }) => (
+ Related Pods for {namespace}
+);
+
+describe('Selector tests', () => {
+ describe('Selector tests for Kubernetes resources', () => {
+ it('Does not render Selector when selector is null', () => {
+ cy.mount();
+ cy.contains('selector.title').should('not.exist');
+ });
+
+ it('Renders default message when selector labels are null', () => {
+ const mockedSelector = {};
+
+ cy.mount();
+ cy.contains('selector.message.empty-selector').should('be.visible');
+ });
+
+ it('Renders Selector with labels and pods list', () => {
+ const mockedSelector = {
+ matchLabels: {
+ test: 'test',
+ },
+ };
+
+ cy.mount(
+ ,
+ );
+ cy.contains('Related Pods for test-namespace').should('be.visible');
+ cy.contains('test=test').should('be.visible');
+ });
+
+ it('Renders Selector with matchExpressions and without pods list', () => {
+ const mockedSelector = {
+ matchLabels: {
+ test: 'test',
+ },
+ matchExpressions: [
+ { key: 'test-key', operator: 'In', values: ['test-value'] },
+ ],
+ };
+
+ cy.mount(
+ ,
+ );
+ cy.contains('match-expressions.title').should('be.visible');
+ cy.contains('test=test').should('be.visible');
+ cy.contains('test-key').should('be.visible');
+ cy.contains('In').should('be.visible');
+ });
+
+ it('Renders custom message when selector labels are null', () => {
+ const mockedSelector = {};
+ const CustomSelector = () => {
+ const { t } = useTranslation();
+ return (
+
+ );
+ };
+
+ cy.mount();
+ cy.contains('persistent-volume-claims.message.empty-selector').should(
+ 'be.visible',
+ );
+ });
+
+ it('Renders Selector with custom RelatedResources', () => {
+ const mockedSelector = {
+ matchLabels: {
+ test: 'test',
+ },
+ };
+ const CustomRelatedResources = () => Persistent Volumes
;
+
+ cy.mount(
+ ,
+ );
+ cy.contains('Persistent Volumes').should('be.visible');
+ });
+ });
+
+ describe('Selector tests for Istio resources', () => {
+ it('Renders message when selector is null', () => {
+ cy.mount();
+ cy.contains('selector.message.empty-selector').should('be.visible');
+ });
+
+ it('Renders Selector with custom title', () => {
+ const CustomTitleSelector = () => {
+ const { t } = useTranslation();
+ return (
+
+ );
+ };
+
+ cy.mount();
+ cy.contains('workload-selector-title').should('be.visible');
+ });
+
+ it('Renders Selector with non-empty labels', () => {
+ const mockedSelector = {
+ matchLabels: {
+ test: 'test',
+ },
+ };
+ const CustomRelatedResources = () => Custom Resources
;
+
+ cy.mount(
+ ,
+ );
+ cy.contains('Custom Resources').should('be.visible');
+ cy.contains('test=test').should('be.visible');
+ });
+ });
+});
diff --git a/src/shared/components/Selector/tests/Selector.test.js b/src/shared/components/Selector/tests/Selector.test.js
deleted file mode 100644
index 1f2e52cf29..0000000000
--- a/src/shared/components/Selector/tests/Selector.test.js
+++ /dev/null
@@ -1,205 +0,0 @@
-import { act, render, waitFor } from 'testing/reactTestingUtils';
-import { useTranslation } from 'react-i18next';
-import { Selector } from '../Selector';
-import { ThemeProvider } from '@ui5/webcomponents-react';
-
-vi.mock('../../RelatedPods.js', () => ({
- RelatedPods: ({ namespace }) => Related Pods for {namespace}
,
-}));
-
-describe('Selector tests', () => {
- describe('Selector tests for Kubernetes resources', () => {
- it('Does not render Selector when selector is null', async () => {
- const { queryByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(queryByText('selector.title')).not.toBeInTheDocument();
- });
- });
- });
-
- it('Renders default message when selector labels are null', async () => {
- const mockedSelector = {};
-
- const { getByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(
- getByText('selector.message.empty-selector'),
- ).toBeInTheDocument();
- });
- });
- });
-
- it('Renders Selector with labels and pods list', async () => {
- const mockedSelector = {
- matchLabels: {
- test: 'test',
- },
- };
-
- const { getByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(
- getByText('Related Pods for test-namespace'),
- ).toBeInTheDocument();
- expect(getByText('test=test')).toBeInTheDocument(); // selector labels
- });
- });
- });
-
- it('Renders Selector with matchExpressions and without pods list', async () => {
- const mockedSelector = {
- matchLabels: {
- test: 'test',
- },
- matchExpressions: [
- { key: 'test-key', operator: 'In', values: ['test-value'] },
- ],
- };
-
- const { getByText, getAllByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(
- getAllByText('match-expressions.title')[0],
- ).toBeInTheDocument(); //title of the matchExpressions table
- expect(getAllByText('test=test')[0]).toBeInTheDocument();
- expect(getByText('test-key')).toBeInTheDocument(); // matchExpressions elements
- expect(getByText('In')).toBeInTheDocument();
- });
- });
- });
-
- it('Renders custom message when selector labels are null ', async () => {
- const mockedSelector = {};
- const { t } = useTranslation();
- const { getByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(
- getByText('persistent-volume-claims.message.empty-selector'),
- ).toBeInTheDocument();
- });
- });
- });
-
- it('Renders Selector with custom RelatedResources', async () => {
- const mockedSelector = {
- matchLabels: {
- test: 'test',
- },
- };
- const { getByText } = render(
-
- Persistent Volumes
}
- />
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(getByText('Persistent Volumes')).toBeInTheDocument();
- });
- });
- });
- });
-
- describe('Selector tests for Istio resources', () => {
- it('Renders message when selector is null', async () => {
- const { getByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(
- getByText('selector.message.empty-selector'),
- ).toBeInTheDocument();
- });
- });
- });
-
- it('Renders Selector with custom title', async () => {
- const { t } = useTranslation();
-
- const { getByText } = render(
-
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(getByText('workload-selector-title')).toBeInTheDocument();
- });
- });
- });
-
- it('Renders Selector with non-empty labels', async () => {
- const mockedSelector = {
- matchLabels: {
- test: 'test',
- },
- };
-
- const { getByText } = render(
-
- Custom Resources
}
- />
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(getByText('Custom Resources')).toBeInTheDocument();
- expect(getByText('test=test')).toBeInTheDocument();
- });
- });
- });
- });
-});
diff --git a/src/shared/components/ServiceAccountTokenStatus.tsx b/src/shared/components/ServiceAccountTokenStatus.tsx
index 558156c714..3cc4a25613 100644
--- a/src/shared/components/ServiceAccountTokenStatus.tsx
+++ b/src/shared/components/ServiceAccountTokenStatus.tsx
@@ -61,11 +61,11 @@ export const ServiceAccountTokenStatus = ({
{
+ onClose={e => {
e.stopPropagation();
setOpenPopover(false);
}}
- placementType="Right"
+ placement="End"
>
{accountTokenValues.tooltipContent}
,
diff --git a/src/shared/components/SideDrawer/test/SideDrawer.cy.js b/src/shared/components/SideDrawer/test/SideDrawer.cy.js
new file mode 100644
index 0000000000..05445b1886
--- /dev/null
+++ b/src/shared/components/SideDrawer/test/SideDrawer.cy.js
@@ -0,0 +1,25 @@
+/* global cy */
+import { SideDrawer } from '../SideDrawer';
+import '@ui5/webcomponents-icons/dist/AllIcons.js';
+
+describe('SideDrawer', () => {
+ const testText1 = 'hi there';
+ const testContent1 = {testText1}
;
+
+ const testText2 = 'oh, hello';
+ const testContent2 = {testText2}
;
+
+ it('Renders content', () => {
+ cy.mount({testContent1});
+
+ cy.contains(testText1).should('exist');
+ });
+
+ it('Renders bottom content', () => {
+ cy.mount(
+ {testContent1},
+ );
+
+ cy.contains(testText2).should('exist');
+ });
+});
diff --git a/src/shared/components/SideDrawer/test/SideDrawer.test.js b/src/shared/components/SideDrawer/test/SideDrawer.test.js
deleted file mode 100644
index 3dfea6dc58..0000000000
--- a/src/shared/components/SideDrawer/test/SideDrawer.test.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// import React from 'react';
-// import { render } from '@testing-library/react';
-// import { SideDrawer } from 'shared/components/SideDrawer/SideDrawer.js';
-
-//TODO (task created) Jest works in node, it cannot parse ECMAScript Modules by default, so it doesn't compile Monaco. Find a way to run it.
-
-describe.skip('SideDrawer', () => {
- // const testText1 = 'hi there';
- // const testContent1 = {testText1}
;
-
- // const testText2 = 'oh, hello';
- // const testContent2 = {testText2}
;
-
- it('Renders content', () => {
- // const { queryByText } = render(
- // {testContent1},
- // );
- //
- // expect(queryByText(testText1)).toBeInTheDocument();
- });
-
- it('Renders bottom content', () => {
- // const { queryByText } = render(
- // {testContent1},
- // );
- // expect(queryByText(testText2)).toBeInTheDocument();
- });
-});
diff --git a/src/shared/components/Spinner/Spinner.tsx b/src/shared/components/Spinner/Spinner.tsx
index cce2570412..15fa951457 100644
--- a/src/shared/components/Spinner/Spinner.tsx
+++ b/src/shared/components/Spinner/Spinner.tsx
@@ -1,15 +1,14 @@
import { BusyIndicator } from '@ui5/webcomponents-react';
-import { spacing } from '@ui5/webcomponents-react-base';
type SpinnerProps = {
ariaLabel?: string;
- size?: 'Large' | 'Medium' | 'Small';
+ size?: 'L' | 'M' | 'S';
center?: boolean;
};
export const Spinner = ({
ariaLabel = 'Loading',
- size = 'Medium',
+ size = 'M',
center = true,
}: SpinnerProps) => {
const style = center
@@ -17,13 +16,8 @@ export const Spinner = ({
width: '100%',
display: 'flex',
justifyContent: 'center',
- marginTop: spacing.sapUiSmallMarginTop.marginTop,
- marginBottom: spacing.sapUiSmallMarginBottom.marginBottom,
}
- : {
- marginTop: spacing.sapUiSmallMarginTop.marginTop,
- marginBottom: spacing.sapUiSmallMarginBottom.marginBottom,
- };
+ : {};
return (
);
};
diff --git a/src/shared/components/StatusBadge/StatusBadge.js b/src/shared/components/StatusBadge/StatusBadge.js
index 61079d019a..014f70f675 100644
--- a/src/shared/components/StatusBadge/StatusBadge.js
+++ b/src/shared/components/StatusBadge/StatusBadge.js
@@ -27,17 +27,17 @@ const resolveType = status => {
case 'Success':
case 'Succeeded':
case 'Ok':
- return 'Success';
+ return 'Positive';
case 'Unknown':
case 'Warning':
- return 'Warning';
+ return 'Critical';
case 'Failed':
case 'Error':
case 'Failure':
case 'Invalid':
- return 'Error';
+ return 'Negative';
default:
return 'None';
@@ -58,9 +58,9 @@ const prepareTranslationPath = (resourceKind, value, type) => {
};
const TYPE_FALLBACK = new Map([
- ['success', 'Success'],
- ['warning', 'Warning'],
- ['error', 'Error'],
+ ['positive', 'Positive'],
+ ['critical', 'Critical'],
+ ['negative', 'Negative'],
['info', 'Information'],
]);
@@ -168,7 +168,13 @@ export const StatusBadge = ({
StatusBadge.propTypes = {
additionalContent: PropTypes.node,
tooltipContent: PropTypes.node,
- type: PropTypes.oneOf(['Information', 'Success', 'Error', 'Warning', 'None']),
+ type: PropTypes.oneOf([
+ 'Information',
+ 'Positive',
+ 'Negative',
+ 'Critical',
+ 'None',
+ ]),
autoResolveType: PropTypes.bool,
noTooltip: PropTypes.bool,
resourceKind: PropTypes.string,
diff --git a/src/shared/components/StatusBadge/test/StatusBadge.cy.js b/src/shared/components/StatusBadge/test/StatusBadge.cy.js
new file mode 100644
index 0000000000..b32638f414
--- /dev/null
+++ b/src/shared/components/StatusBadge/test/StatusBadge.cy.js
@@ -0,0 +1,39 @@
+/* global cy */
+import { StatusBadge } from '../StatusBadge';
+
+describe('StatusBadge', () => {
+ it('renders status text with proper role', () => {
+ cy.mount(Initial);
+
+ cy.get('[role="status"]')
+ .should('be.visible')
+ .and('contain.text', 'Initial');
+ });
+
+ it('displays warning when autoResolveType is set and "children" is a node', () => {
+ cy.spy(console, 'warn').as('consoleWarn');
+
+ cy.mount(
+
+ Status
+ ,
+ );
+
+ cy.get('@consoleWarn').should('have.been.calledOnce');
+ cy.get('@consoleWarn')
+ .its('firstCall.args')
+ .should('exist');
+ });
+
+ it('renders status text without tooltip', () => {
+ cy.mount(Initial);
+
+ cy.get('[data-testid="no-tooltip"]').should('be.visible');
+ });
+
+ it('renders status text with tooltip', () => {
+ cy.mount(Initial);
+
+ cy.get('[data-testid="has-tooltip"]').should('be.visible');
+ });
+});
diff --git a/src/shared/components/StatusBadge/test/StatusBadge.test.js b/src/shared/components/StatusBadge/test/StatusBadge.test.js
index d81784b15f..17eb642b45 100644
--- a/src/shared/components/StatusBadge/test/StatusBadge.test.js
+++ b/src/shared/components/StatusBadge/test/StatusBadge.test.js
@@ -1,14 +1,17 @@
+import { forwardRef } from 'react';
import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge';
import { act, render, waitFor } from '@testing-library/react';
-import { ThemeProvider } from '@ui5/webcomponents-react';
+
+vi.mock('@ui5/webcomponents-react', () => {
+ return {
+ ObjectStatus: props => {props.children}
,
+ Popover: forwardRef((props, ref) => {props.children}
),
+ };
+});
describe('StatusBadge', () => {
it('renders status text with proper role', async () => {
- const { queryByRole } = render(
-
- Initial
- ,
- );
+ const { queryByRole } = render(Initial);
await waitFor(async () => {
await act(async () => {
@@ -19,31 +22,9 @@ describe('StatusBadge', () => {
});
});
- it('displays warning when autoResolveType is set and "children" is a node', async () => {
- console.warn = vi.fn();
-
- render(
-
-
- Status
-
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- expect(console.warn.mock.calls[0]).toMatchSnapshot();
- });
- });
- });
-
it('renders status text with DEFAULT_STATUSES_PATH', async () => {
const DEFAULT_STATUSES_PATH = 'common.statuses.initial';
- // 'common.statuses.initial,common.statuses.initial,fallback';
- const { queryByRole } = render(
-
- Initial
- ,
- );
+ const { queryByRole } = render(Initial);
await waitFor(async () => {
await act(async () => {
const status = queryByRole('status');
@@ -57,9 +38,7 @@ describe('StatusBadge', () => {
const RESOURCE_KIND = 'resource';
const RESOURCE_STATUSES_PATH = 'resource.statuses.initial';
const { queryByRole } = render(
-
- Initial
- ,
+ Initial,
);
await waitFor(async () => {
await act(async () => {
@@ -69,32 +48,4 @@ describe('StatusBadge', () => {
});
});
});
-
- it('renders status text without tooltip', async () => {
- const { getByTestId } = render(
-
- Initial
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- const status = getByTestId('no-tooltip');
- expect(status).toBeInTheDocument();
- });
- });
- });
-
- it('renders status text with tooltip', async () => {
- const { getByTestId } = render(
-
- Initial
- ,
- );
- await waitFor(async () => {
- await act(async () => {
- const status = getByTestId('has-tooltip');
- expect(status).toBeInTheDocument();
- });
- });
- });
});
diff --git a/src/shared/components/StatusBadge/test/__snapshots__/StatusBadge.test.js.snap b/src/shared/components/StatusBadge/test/__snapshots__/StatusBadge.test.js.snap
deleted file mode 100644
index c6a0c4728d..0000000000
--- a/src/shared/components/StatusBadge/test/__snapshots__/StatusBadge.test.js.snap
+++ /dev/null
@@ -1,7 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`StatusBadge > displays warning when autoResolveType is set and "children" is a node 1`] = `
-[
- "'autoResolveType' prop requires 'children' prop to be a string.",
-]
-`;
diff --git a/src/shared/components/SubscriptionConditionStatus.js b/src/shared/components/SubscriptionConditionStatus.js
index 47c160a9e5..d3b1a1cb88 100644
--- a/src/shared/components/SubscriptionConditionStatus.js
+++ b/src/shared/components/SubscriptionConditionStatus.js
@@ -7,11 +7,11 @@ export const SubscriptionConditionStatus = ({ condition }) => {
const statusBadgeProperties =
condition?.status === 'True'
? {
- type: 'Success',
+ type: 'Positive',
text: t('common.statuses.ready'),
}
: {
- type: 'Error',
+ type: 'Negative',
text: t('common.statuses.error'),
};
return (
diff --git a/src/shared/components/TileButton/TileButton.tsx b/src/shared/components/TileButton/TileButton.tsx
index 86da100b9a..32595d0ee4 100644
--- a/src/shared/components/TileButton/TileButton.tsx
+++ b/src/shared/components/TileButton/TileButton.tsx
@@ -1,5 +1,6 @@
import React, { ReactNode } from 'react';
import classNames from 'classnames';
+import { Text } from '@ui5/webcomponents-react';
import './TileButton.scss';
@@ -24,8 +25,8 @@ export function TileButton({
diff --git a/src/shared/components/Tokens.js b/src/shared/components/Tokens.js
index 2cffb49c77..c2dac5eb2f 100644
--- a/src/shared/components/Tokens.js
+++ b/src/shared/components/Tokens.js
@@ -1,20 +1,19 @@
-import React from 'react';
-
-import { Token } from '@ui5/webcomponents-react';
+import { Tag } from '@ui5/webcomponents-react';
import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants';
-import { spacing } from '@ui5/webcomponents-react-base';
-
const Tokens = ({ tokens }) => (
<>
{tokens?.length
? tokens.map(scope => (
-
+ className="sap-margin-end-tiny"
+ design="Set2"
+ colorScheme="9"
+ hideStateIcon
+ >
+ {scope}
+
))
: EMPTY_TEXT_PLACEHOLDER}
>
diff --git a/src/shared/components/Tooltip/Tooltip.js b/src/shared/components/Tooltip/Tooltip.js
index 929b66545f..aface391c1 100644
--- a/src/shared/components/Tooltip/Tooltip.js
+++ b/src/shared/components/Tooltip/Tooltip.js
@@ -1,4 +1,3 @@
-import React from 'react';
import PropTypes from 'prop-types';
import { Tooltip as TippyTooltip } from 'react-tippy';
@@ -10,7 +9,7 @@ export const Tooltip = ({
children,
content,
position,
- trigger,
+ trigger = 'mouseenter',
tippyProps,
delay = [200, 0],
}) => {
@@ -34,7 +33,3 @@ Tooltip.propTypes = {
trigger: PropTypes.oneOf(['mouseenter', 'focus', 'click', 'manual']),
children: PropTypes.node,
};
-
-Tooltip.defaultProps = {
- trigger: 'mouseenter',
-};
diff --git a/src/shared/components/TooltipBadge/TooltipBadge.js b/src/shared/components/TooltipBadge/TooltipBadge.js
index f1337f04b8..bad968809d 100644
--- a/src/shared/components/TooltipBadge/TooltipBadge.js
+++ b/src/shared/components/TooltipBadge/TooltipBadge.js
@@ -39,7 +39,13 @@ export const TooltipBadge = ({
TooltipBadge.propTypes = {
tooltipContent: PropTypes.node,
- type: PropTypes.oneOf(['Information', 'Success', 'Error', 'Warning', 'None']),
+ type: PropTypes.oneOf([
+ 'Information',
+ 'Positive',
+ 'Negative',
+ 'Critical',
+ 'None',
+ ]),
tooltipProps: PropTypes.object,
className: PropTypes.string,
};
diff --git a/src/shared/components/UI5Panel/UI5Panel.tsx b/src/shared/components/UI5Panel/UI5Panel.tsx
index 0d285e8f55..f2c7dd47f6 100644
--- a/src/shared/components/UI5Panel/UI5Panel.tsx
+++ b/src/shared/components/UI5Panel/UI5Panel.tsx
@@ -1,15 +1,9 @@
-import {
- Panel,
- Text,
- Title,
- Toolbar,
- ToolbarSeparator,
- ToolbarSpacer,
-} from '@ui5/webcomponents-react';
-
-import { spacing } from '@ui5/webcomponents-react-base';
+import { ReactNode, useEffect } from 'react';
+import { Panel, Text, Title } from '@ui5/webcomponents-react';
+import { Toolbar } from '@ui5/webcomponents-react-compat/dist/components/Toolbar/index.js';
+import { ToolbarSpacer } from '@ui5/webcomponents-react-compat/dist/components/ToolbarSpacer/index.js';
+import { ToolbarSeparator } from '@ui5/webcomponents-react-compat/dist/components/ToolbarSeparator/index.js';
import './UI5Panel.scss';
-import { CSSProperties, ReactNode, useEffect } from 'react';
type UI5PanelProps = {
fixed?: boolean;
@@ -22,7 +16,6 @@ type UI5PanelProps = {
className?: string;
children: ReactNode;
description?: string;
- style?: CSSProperties;
stickyHeader?: boolean;
headerTop?: string;
};
@@ -38,7 +31,6 @@ export const UI5Panel = ({
className = '',
children,
description = '',
- style = undefined,
stickyHeader = false,
headerTop = '0',
}: UI5PanelProps) => {
@@ -46,7 +38,7 @@ export const UI5Panel = ({
if (headerTop !== '0')
setTimeout(() => {
const stickyHeader = document
- .querySelector('ui5-panel')
+ .querySelector('.resource-form--panel')
?.shadowRoot?.querySelector('.ui5-panel-root')
?.querySelector(
'.ui5-panel-heading-wrapper.ui5-panel-heading-wrapper-sticky',
@@ -61,10 +53,9 @@ export const UI5Panel = ({
{
+ it('Renders valid UI5RadialChart', () => {
+ cy.mount(
+ ,
+ );
+
+ cy.get('.radial-chart').should('exist');
+ cy.contains('33%').should('exist');
+ cy.contains('33.33m / 100m').should('exist');
+ });
+});
diff --git a/src/shared/components/UI5RadialChart/test/UI5RadialChart.test.js b/src/shared/components/UI5RadialChart/test/UI5RadialChart.test.js
deleted file mode 100644
index ee752af005..0000000000
--- a/src/shared/components/UI5RadialChart/test/UI5RadialChart.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { render } from '@testing-library/react';
-import { ThemeProvider } from '@ui5/webcomponents-react';
-import { UI5RadialChart } from '../UI5RadialChart';
-
-beforeAll(() => {
- vi.spyOn(console, 'warn').mockImplementationOnce(() => {});
-});
-
-describe('UI5RadialChart', () => {
- it('Renders valid UI5RadialChart', () => {
- const { container, queryByText } = render(
-
-
- ,
- );
-
- const radialChart = container.querySelector('.radial-chart');
- expect(radialChart).toBeInTheDocument();
- expect(queryByText('33.33m / 100m')).toBeInTheDocument();
- });
-});
diff --git a/src/shared/components/UnsavedMessageBox/UnsavedMessageBox.tsx b/src/shared/components/UnsavedMessageBox/UnsavedMessageBox.tsx
index c40d2985fc..de8a241d5f 100644
--- a/src/shared/components/UnsavedMessageBox/UnsavedMessageBox.tsx
+++ b/src/shared/components/UnsavedMessageBox/UnsavedMessageBox.tsx
@@ -1,12 +1,5 @@
-import {
- Button,
- ButtonDomRef,
- ButtonPropTypes,
- MessageBox,
- WithWebComponentPropTypes,
-} from '@ui5/webcomponents-react';
+import { Button, MessageBox } from '@ui5/webcomponents-react';
import { useTranslation } from 'react-i18next';
-import { ForwardRefExoticComponent, RefAttributes } from 'react';
import { useRecoilState } from 'recoil';
import { isResourceEditedState } from 'state/resourceEditedAtom';
import { isFormOpenState } from 'state/formOpenAtom';
@@ -22,23 +15,13 @@ export function UnsavedMessageBox({ isOpen }: UnsavedMessageBoxProps) {
);
const [isFormOpen, setIsFormOpen] = useRecoilState(isFormOpenState);
- const handleClose = (event: {
- detail: {
- action:
- | string
- | ForwardRefExoticComponent<
- ButtonPropTypes &
- WithWebComponentPropTypes &
- RefAttributes
- >;
- };
- }) => {
- if (event.detail.action === '0: custom action') {
+ const handleClose = (action, escapedPressed) => {
+ if (action === '0: custom action' || escapedPressed) {
if (isResourceEdited.discardAction) {
isResourceEdited.discardAction();
}
setIsFormOpen({ formOpen: false, leavingForm: false });
- } else if (event.detail.action === '1: custom action') {
+ } else if (action === '1: custom action') {
setIsResourceEdited({ isEdited: true });
setIsFormOpen({ formOpen: true, leavingForm: false });
return;
diff --git a/src/shared/components/VerticalTabs/VerticalTabs.scss b/src/shared/components/VerticalTabs/VerticalTabs.scss
index f215087e1c..ce245d58dd 100644
--- a/src/shared/components/VerticalTabs/VerticalTabs.scss
+++ b/src/shared/components/VerticalTabs/VerticalTabs.scss
@@ -7,6 +7,7 @@
ul {
padding: 0;
+ margin: 0;
}
& > :first-child {
diff --git a/src/shared/components/WizardButtons/WizardButtons.js b/src/shared/components/WizardButtons/WizardButtons.js
index 3523c9797c..e5c203cfaa 100644
--- a/src/shared/components/WizardButtons/WizardButtons.js
+++ b/src/shared/components/WizardButtons/WizardButtons.js
@@ -1,8 +1,6 @@
import { Button } from '@ui5/webcomponents-react';
import { useTranslation } from 'react-i18next';
-import { spacing } from '@ui5/webcomponents-react-base';
-
export function WizardButtons({
selected,
setSelected,
@@ -25,12 +23,12 @@ export function WizardButtons({
};
return (
-
+
{!firstStep && (