fix(slider): use and update react slider EE-4522 (#7987)

pull/7996/head
Ali 2022-11-04 14:12:53 +13:00 committed by GitHub
parent f94147b07b
commit 9f3d5185b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 154 additions and 43 deletions

View File

@ -93,17 +93,18 @@
<div class="form-group flex flex-row !mb-0">
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left"> Memory limit (MB) </label>
<div class="col-xs-6">
<slider
model="$ctrl.formValues.MemoryLimit"
floor="$ctrl.defaults.MemoryLimit"
ceil="$ctrl.state.sliderMaxMemory"
<por-slider
min="$ctrl.defaults.MemoryLimit"
max="$ctrl.state.sliderMaxMemory"
step="128"
ng-if="$ctrl.state.sliderMaxMemory"
value="$ctrl.formValues.MemoryLimit"
on-change="($ctrl.handleMemoryLimitChange)"
visible-tooltip="true"
data-cy="k8sNamespaceCreate-memoryLimitSlider"
>
</slider>
></por-slider>
</div>
<div class="col-sm-2 vertical-center">
<div class="col-sm-2 vertical-center pt-6">
<input
name="memory_limit"
type="number"
@ -138,16 +139,16 @@
<div class="form-group flex flex-row">
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU limit </label>
<div class="col-xs-8">
<slider
model="$ctrl.formValues.CpuLimit"
floor="$ctrl.defaults.CpuLimit"
ceil="$ctrl.state.sliderMaxCpu"
<por-slider
min="$ctrl.defaults.CpuLimit"
max="$ctrl.state.sliderMaxCpu"
step="0.1"
precision="2"
ng-if="$ctrl.state.sliderMaxCpu"
value="$ctrl.formValues.CpuLimit"
on-change="($ctrl.handleCpuLimitChange)"
data-cy="k8sNamespaceCreate-cpuLimitSlider"
>
</slider>
visible-tooltip="true"
></por-slider>
</div>
</div>
<!-- !cpu-limit-input -->

View File

@ -33,6 +33,8 @@ class KubernetesCreateResourcePoolController {
this.onToggleResourceQuota = this.onToggleResourceQuota.bind(this);
this.onChangeIngressControllerAvailability = this.onChangeIngressControllerAvailability.bind(this);
this.onRegistriesChange = this.onRegistriesChange.bind(this);
this.handleMemoryLimitChange = this.handleMemoryLimitChange.bind(this);
this.handleCpuLimitChange = this.handleCpuLimitChange.bind(this);
}
/* #endregion */
@ -101,6 +103,18 @@ class KubernetesCreateResourcePoolController {
}
}
handleMemoryLimitChange(memoryLimit) {
return this.$async(async () => {
this.formValues.MemoryLimit = memoryLimit;
});
}
handleCpuLimitChange(cpuLimit) {
return this.$async(async () => {
this.formValues.CpuLimit = cpuLimit;
});
}
/* #region CREATE NAMESPACE */
createResourcePool() {
return this.$async(async () => {

View File

@ -80,15 +80,18 @@
<div class="form-group flex">
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left vertical-center"> Memory limit (MB) </label>
<div class="col-sm-6">
<slider
model="ctrl.formValues.MemoryLimit"
floor="ctrl.ResourceQuotaDefaults.MemoryLimit"
ceil="ctrl.state.sliderMaxMemory"
<por-slider
min="ctrl.ResourceQuotaDefaults.MemoryLimit"
max="ctrl.state.sliderMaxMemory"
step="128"
ng-if="ctrl.state.sliderMaxMemory"
></slider>
value="ctrl.formValues.MemoryLimit"
on-change="(ctrl.handleMemoryLimitChange)"
visible-tooltip="true"
data-cy="k8sNamespaceEdit-memoryLimitSlider"
></por-slider>
</div>
<div class="col-sm-2 vertical-center">
<div class="col-sm-2 vertical-center pt-6">
<input
name="memory_limit"
type="number"
@ -97,6 +100,7 @@
class="form-control"
ng-model="ctrl.formValues.MemoryLimit"
id="memory-limit"
data-cy="k8sNamespaceEdit-memoryLimitInput"
required
/>
</div>
@ -117,14 +121,16 @@
<div class="form-group">
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px"> CPU limit </label>
<div class="col-sm-8">
<slider
model="ctrl.formValues.CpuLimit"
floor="ctrl.ResourceQuotaDefaults.CpuLimit"
ceil="ctrl.state.sliderMaxCpu"
<por-slider
min="ctrl.ResourceQuotaDefaults.CpuLimit"
max="ctrl.state.sliderMaxCpu"
step="0.1"
precision="2"
ng-if="ctrl.state.sliderMaxCpu"
></slider>
value="ctrl.formValues.CpuLimit"
on-change="(ctrl.handleCpuLimitChange)"
data-cy="k8sNamespaceEdit-cpuLimitSlider"
visible-tooltip="true"
></por-slider>
</div>
</div>
<!-- !cpu-limit-input -->

View File

@ -69,6 +69,8 @@ class KubernetesResourcePoolController {
this.onToggleStorageQuota = this.onToggleStorageQuota.bind(this);
this.onChangeIngressControllerAvailability = this.onChangeIngressControllerAvailability.bind(this);
this.onRegistriesChange = this.onRegistriesChange.bind(this);
this.handleMemoryLimitChange = this.handleMemoryLimitChange.bind(this);
this.handleCpuLimitChange = this.handleCpuLimitChange.bind(this);
}
/* #endregion */
@ -122,6 +124,18 @@ class KubernetesResourcePoolController {
}
}
handleMemoryLimitChange(memoryLimit) {
return this.$async(async () => {
this.formValues.MemoryLimit = memoryLimit;
});
}
handleCpuLimitChange(cpuLimit) {
return this.$async(async () => {
this.formValues.CpuLimit = cpuLimit;
});
}
showEditor() {
this.state.showEditorTab = true;
this.selectTab(2);

View File

@ -33,6 +33,7 @@ import { FallbackImage } from '@@/FallbackImage';
import { BadgeIcon } from '@@/BadgeIcon';
import { TeamsSelector } from '@@/TeamsSelector';
import { PortainerSelect } from '@@/form-components/PortainerSelect';
import { Slider } from '@@/form-components/Slider';
import { fileUploadField } from './file-upload-field';
import { switchField } from './switch-field';
@ -184,6 +185,18 @@ export const componentsModule = angular
'isClearable',
])
)
.component(
'porSlider',
r2a(Slider, [
'min',
'max',
'step',
'value',
'onChange',
'visibleTooltip',
'dataCy',
])
)
.component(
'porAccessManagementUsersSelector',
r2a(PorAccessManagementUsersSelector, ['onChange', 'options', 'value'])

View File

@ -7,26 +7,50 @@
}
.slider :global .rc-slider-handle {
width: 32px;
height: 32px;
margin-top: -14px;
@apply border-blue-8 border-2;
width: 24px;
height: 24px;
margin-top: -8px;
border-radius: 16px;
cursor: pointer;
background-color: #0db9f0;
background-color: #ffffff;
}
.slider :global .rc-slider-track {
@apply bg-blue-8;
}
.slider :global .rc-slider-handle:after {
position: absolute;
top: 10px;
left: 10px;
width: 8px;
height: 8px;
top: 8px;
left: 8px;
width: 9px;
height: 9px;
background: #ffffff;
border-radius: 4px;
border-radius: 5px;
content: '';
}
.slider :global .rc-slider-mark-text,
.slider :global .rc-slider-tooltip-inner {
font-family: Inter, serif;
.slider :global .rc-slider-mark-text {
font-size: 14px;
color: var(--text-body-color);
}
.slider :global .rc-slider-tooltip-arrow {
bottom: 2px;
border-top-color: var(--bg-tooltip-color);
}
.slider :global .rc-slider-tooltip-placement-top {
padding: 6px 0px;
}
.slider :global .rc-slider-tooltip-inner {
font-size: 14px;
color: var(--text-tooltip-color);
height: fit-content;
background-color: var(--bg-tooltip-color);
box-shadow: 0 2px 4px 0 rgb(34 36 38 / 12%), 0 2px 10px 0 rgb(34 36 38 / 15%);
padding: 8px 12px;
text-align: center;
}

View File

@ -8,7 +8,14 @@ export default {
title: 'Components/Form/Slider',
} as Meta;
function Template({ value, min, max, step }: JSX.IntrinsicAttributes & Props) {
function Template({
value,
min,
max,
step,
dataCy,
visibleTooltip,
}: JSX.IntrinsicAttributes & Props) {
const [sliderValue, setSliderValue] = useState(min);
useEffect(() => {
@ -22,6 +29,8 @@ function Template({ value, min, max, step }: JSX.IntrinsicAttributes & Props) {
step={step}
value={sliderValue}
onChange={setSliderValue}
dataCy={dataCy}
visibleTooltip={visibleTooltip}
/>
);
}
@ -32,4 +41,6 @@ Primary.args = {
max: 100,
step: 1,
value: 5,
visibleTooltip: true,
dataCy: 'someView-coolSlider',
};

View File

@ -8,9 +8,19 @@ function renderDefault({
step = 1,
value = min,
onChange = () => {},
dataCy = 'someView-coolSlider',
visibleTooltip = true,
}: Partial<Props> = {}) {
return render(
<Slider min={min} max={max} step={step} onChange={onChange} value={value} />
<Slider
min={min}
max={max}
step={step}
onChange={onChange}
value={value}
visibleTooltip={visibleTooltip}
dataCy={dataCy}
/>
);
}

View File

@ -9,13 +9,25 @@ export interface Props {
step: number;
value: number;
onChange: (value: number) => void;
// true if you want to always show the tooltip
dataCy: string;
visibleTooltip?: boolean;
}
export function Slider({ min, max, step, value, onChange }: Props) {
export function Slider({
min,
max,
step,
value,
onChange,
dataCy,
visibleTooltip: visible,
}: Props) {
const SliderWithTooltip = RcSlider.createSliderWithTooltip(RcSlider);
// if the tooltip is always visible, hide the marks when tooltip value gets close to the edges
const marks = {
[min]: translateMinValue(min),
[max]: max.toString(),
[min]: visible && value / max < 0.1 ? '' : translateMinValue(min),
[max]: visible && value / max > 0.9 ? '' : max.toString(),
};
return (
@ -29,6 +41,11 @@ export function Slider({ min, max, step, value, onChange }: Props) {
defaultValue={value}
onAfterChange={onChange}
className={styles.slider}
tipProps={{ visible }}
railStyle={{ height: 8 }}
trackStyle={{ height: 8 }}
dotStyle={{ visibility: 'hidden' }}
data-cy={dataCy}
/>
</div>
);

View File

@ -0,0 +1 @@
export { Slider } from './Slider';