Skip to content

Commit

Permalink
Host Checks selection (#1669)
Browse files Browse the repository at this point in the history
* Add navigation to host check selection (#1658)

* Align cluster/host naming related to checks selection and actions

* Add Checks related Call to actions in host detail

* Host detail - Move exporters mapping to components in a separate variable

* Cluster settings page refactor (#1659)

* Remove old ChecksSelection UI

* Rewrite ClusterSettingsPage

* Wire up ClusterSettingsPage to the router

* Make checks selection great again (#1682)

* Add a new selector for cluster checks

* Update ChecksSelection component to new UX

* Update ClusterSettingsPage to new UX

* Update Host Settings to new UX

* Add a disabled prop to Button component

* Align the behavior of the save checks button

* fixup! Align the behavior of the save checks button

* Improved tooltip (#1674)

* Install react-tooltip

* Add new Tooltipo component

* Update Tooltip stories

* Add a global css object for tests

* Replace legacy tooltip with new one

* Use spans as tooltip anchor wrapper

* Replace react-tooltip with rc-tooltip

Co-authored-by: Alessio Biancalana <alessio.biancalana@suse.com>

* Switch Tooltip implementation to rc-tooltip

Co-authored-by: Alessio Biancalana <alessio.biancalana@suse.com>

---------

Co-authored-by: Alessio Biancalana <alessio.biancalana@suse.com>

---------

Co-authored-by: Alessio Biancalana <alessio.biancalana@suse.com>
  • Loading branch information
nelsonkopliku and dottorblaster committed Aug 4, 2023
1 parent c34a9c9 commit db75dd2
Show file tree
Hide file tree
Showing 40 changed files with 959 additions and 1,094 deletions.
1 change: 1 addition & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* This file is for your main application CSS */
@import './markdown.scss';
@import './tooltip.scss';

@tailwind base;

Expand Down
193 changes: 193 additions & 0 deletions assets/css/tooltip.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/**
Style retrieved here https://stackblitz.com/edit/vitejs-vite-drjjx5?file=src%2Fassets%2Fstyles%2Frc-tooltip.scss
as mentioned in issue https://github.com/react-component/tooltip/issues/445
*/
.rc-tooltip-fade-enter,
.rc-tooltip-fade-leave {
display: block;
}
.rc-tooltip.rc-tooltip-fade-enter,
.rc-tooltip.rc-tooltip-fade-appear {
opacity: 0;
animation-duration: 0.2s;
animation-play-state: paused;
animation-timing-function: linear;
animation-fill-mode: both;
}
.rc-tooltip.rc-tooltip-fade-leave {
animation-duration: 0.2s;
animation-play-state: paused;
animation-timing-function: linear;
animation-fill-mode: both;
}
.rc-tooltip.rc-tooltip-fade-enter.rc-tooltip-fade-enter-active,
.rc-tooltip.rc-tooltip-fade-appear.rc-tooltip-fade-appear-active {
animation-name: rcToolTipFadeIn;
animation-play-state: running;
}
.rc-tooltip.rc-tooltip-fade-leave.rc-tooltip-fade-leave-active {
animation-name: rcToolTipFadeOut;
animation-play-state: running;
}
@keyframes rcToolTipFadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes rcToolTipFadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.rc-tooltip {
/**
max-width: 200px;
font-size: 12px;
line-height: 1.5;
*/
@apply block absolute visible opacity-100;

&.rc-tooltip.rc-tooltip-fade-enter,
&.rc-tooltip.rc-tooltip-fade-appear {
animation-duration: 0.2s;
animation-play-state: paused;
animation-timing-function: linear;
animation-fill-mode: both;
@apply opacity-0;
}
&.rc-tooltip.rc-tooltip-fade-leave {
animation-duration: 0.2s;
animation-play-state: paused;
animation-timing-function: linear;
animation-fill-mode: both;
}
&.rc-tooltip.rc-tooltip-fade-enter.rc-tooltip-fade-enter-active,
&.rc-tooltip.rc-tooltip-fade-appear.rc-tooltip-fade-appear-active {
animation-name: rcToolTipFadeIn;
animation-play-state: running;
}
&.rc-tooltip.rc-tooltip-fade-leave.rc-tooltip-fade-leave-active {
animation-name: rcToolTipFadeOut;
animation-play-state: running;
}
}
.rc-tooltip-hidden {
@apply hidden;
}
.rc-tooltip-placement-top,
.rc-tooltip-placement-topLeft,
.rc-tooltip-placement-topRight {
padding: 5px 0 5px 0;
}
.rc-tooltip-placement-right,
.rc-tooltip-placement-rightTop,
.rc-tooltip-placement-rightBottom {
padding: 0 5px 0 5px;
}
.rc-tooltip-placement-bottom,
.rc-tooltip-placement-bottomLeft,
.rc-tooltip-placement-bottomRight {
padding: 5px 0 5px 0;
}
.rc-tooltip-placement-left,
.rc-tooltip-placement-leftTop,
.rc-tooltip-placement-leftBottom {
padding: 0 5px 0 5px;
}

/**
.rc-tooltip-inner is not styled to allow customization from the
.rc-tooltip-inner {
min-height: 34px;
padding: 8px 10px;
border-radius: 6px;
background-color: #373737;
color: #fff;
text-decoration: none;
text-align: center;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);
}
*/
.rc-tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border-style: solid;
border-color: transparent;
}
.rc-tooltip-placement-top .rc-tooltip-arrow,
.rc-tooltip-placement-topLeft .rc-tooltip-arrow,
.rc-tooltip-placement-topRight .rc-tooltip-arrow {
bottom: 0;
margin-left: -5px;
border-width: 5px 5px 0;
border-top-color: #373737;
}
.rc-tooltip-placement-top .rc-tooltip-arrow {
left: 50%;
}
.rc-tooltip-placement-topLeft .rc-tooltip-arrow {
left: 15%;
}
.rc-tooltip-placement-topRight .rc-tooltip-arrow {
right: 15%;
}
.rc-tooltip-placement-right .rc-tooltip-arrow,
.rc-tooltip-placement-rightTop .rc-tooltip-arrow,
.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {
left: 4px;
margin-top: -5px;
border-width: 5px 5px 5px 0;
border-right-color: #373737;
}
.rc-tooltip-placement-right .rc-tooltip-arrow {
top: 50%;
}
.rc-tooltip-placement-rightTop .rc-tooltip-arrow {
top: 15%;
margin-top: 0;
}
.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {
bottom: 15%;
}
.rc-tooltip-placement-left .rc-tooltip-arrow,
.rc-tooltip-placement-leftTop .rc-tooltip-arrow,
.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {
right: 4px;
margin-top: -5px;
border-width: 5px 0 5px 5px;
border-left-color: #373737;
}
.rc-tooltip-placement-left .rc-tooltip-arrow {
top: 50%;
}
.rc-tooltip-placement-leftTop .rc-tooltip-arrow {
top: 15%;
margin-top: 0;
}
.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {
bottom: 15%;
}
.rc-tooltip-placement-bottom .rc-tooltip-arrow,
.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,
.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
top: 4px;
margin-left: -5px;
border-width: 0 5px 5px;
border-bottom-color: #373737;
}
.rc-tooltip-placement-bottom .rc-tooltip-arrow {
left: 50%;
}
.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {
left: 15%;
}
.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
right: 15%;
}
11 changes: 9 additions & 2 deletions assets/js/components/Button/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ const getButtonClasses = (type) => {
}
};

function Button({ children, className, type, size, ...props }) {
function Button({ children, className, type, size, disabled, ...props }) {
const buttonClasses = classNames(
getButtonClasses(type),
getSizeClasses(size),
{ 'opacity-50': disabled },
className
);

return (
<button type="button" className={buttonClasses} {...props}>
<button
type="button"
className={buttonClasses}
disabled={disabled}
{...props}
>
{children}
</button>
);
Expand Down
4 changes: 4 additions & 0 deletions assets/js/components/Button/Button.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ export function SmallSecondary() {
</Button>
);
}

export function Disabled() {
return <Button disabled>Hello world!</Button>;
}
14 changes: 10 additions & 4 deletions assets/js/components/Button/Button.test.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import React from 'react';
import { faker } from '@faker-js/faker';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';

import Button from '.';

describe('Button', () => {
it('should display a button with its text', () => {
render(<Button>Hello there General Kenobi</Button>);
expect(screen.getByRole('button')).toHaveTextContent(
'Hello there General Kenobi'
);
const content = faker.vehicle.vehicle();
render(<Button>{content}</Button>);
expect(screen.getByRole('button')).toHaveTextContent(content);
});

it('should display a disabled button with its text', () => {
const content = faker.vehicle.vehicle();
render(<Button disabled>{content}</Button>);
expect(screen.getByRole('button')).toHaveTextContent(content);
});
});
60 changes: 6 additions & 54 deletions assets/js/components/ChecksSelection/ChecksSelection.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import React, { useState, useEffect } from 'react';
import React, { useEffect } from 'react';
import classNames from 'classnames';

import { remove, uniq, toggle, groupBy } from '@lib/lists';

import { EOS_LOADING_ANIMATED } from 'eos-icons-react';

import CatalogContainer from '@components/ChecksCatalog/CatalogContainer';
import ChecksSelectionGroup, {
NONE_CHECKED,
Expand All @@ -13,8 +11,6 @@ import ChecksSelectionGroup, {
allSelected,
} from './ChecksSelectionGroup';
import ChecksSelectionItem from './ChecksSelectionItem';
import FailAlert from './FailAlert';
import ExecutionSuggestion from './ExecutionSuggestion';

const isSelected = (selectedChecks, checkID) =>
selectedChecks ? selectedChecks.includes(checkID) : false;
Expand All @@ -33,23 +29,13 @@ const defaultSelectedChecks = [];

function ChecksSelection({
className,
targetID,
targetName,
catalog,
selected = defaultSelectedChecks,
selectedChecks = defaultSelectedChecks,
loading = false,
saving = false,
error,
success = false,
catalogError,
hosts,
onUpdateCatalog,
onStartExecution,
onSave,
onClear,
onChange,
}) {
const [selectedChecks, setSelectedChecks] = useState(selected);

const groupedChecks = Object.entries(groupBy(catalog, 'group')).map(
([group, checks]) => {
const groupChecks = checks.map((check) => ({
Expand All @@ -67,17 +53,15 @@ function ChecksSelection({

useEffect(() => {
onUpdateCatalog();
onClear();
}, []);

const onCheckSelectionGroupChange = (checks, groupSelected) => {
const groupChecks = checks.map((check) => check.id);
if (allSelected(groupSelected)) {
setSelectedChecks(remove(groupChecks, selectedChecks));
onChange(remove(groupChecks, selectedChecks));
} else {
setSelectedChecks(uniq([...selectedChecks, ...groupChecks]));
onChange(uniq([...selectedChecks, ...groupChecks]));
}
onClear();
};

return (
Expand Down Expand Up @@ -108,45 +92,13 @@ function ChecksSelection({
premium={check.premium}
selected={check.selected}
onChange={() => {
setSelectedChecks(toggle(check.id, selectedChecks));
onClear();
onChange(toggle(check.id, selectedChecks));
}}
/>
))}
</ChecksSelectionGroup>
))}
</div>
<div className="place-items-end flex">
<button
className="flex justify-center items-center bg-jungle-green-500 hover:opacity-75 text-white font-bold py-2 px-4 rounded"
disabled={saving}
onClick={() => onSave(selectedChecks, targetID, targetName)}
type="button"
data-testid="save-selection-button"
>
{saving ? (
<span className="px-20">
<EOS_LOADING_ANIMATED color="green" size={25} />
</span>
) : (
'Save Check Selection'
)}
</button>
{error && (
<FailAlert onClose={onClear}>
<p>{error}</p>
</FailAlert>
)}
{success && selectedChecks.length > 0 && (
<ExecutionSuggestion
targetID={targetID}
selectedChecks={selectedChecks}
hosts={hosts}
onClose={onClear}
onStartExecution={onStartExecution}
/>
)}
</div>
</div>
</CatalogContainer>
</div>
Expand Down

0 comments on commit db75dd2

Please sign in to comment.