fix(style): gpu_selector position
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
import { WrapperContext } from './use-wrapper-context';
|
import { WrapperContext } from './use-wrapper-context';
|
||||||
|
|
||||||
@@ -60,6 +60,15 @@ const ColumnWrapper: React.FC<ColumnWrapperProps> = ({
|
|||||||
return () => observer.disconnect();
|
return () => observer.disconnect();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const setContentPaddingBottom = useCallback((padding: number) => {
|
||||||
|
if (footerRef.current) {
|
||||||
|
const height = footerRef.current.getBoundingClientRect().height;
|
||||||
|
contentRef.current!.style.paddingBottom = `${height + padding - 22}px`;
|
||||||
|
} else {
|
||||||
|
contentRef.current!.style.paddingBottom = `${padding}px`;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WrapperContext.Provider
|
<WrapperContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -68,7 +77,8 @@ const ColumnWrapper: React.FC<ColumnWrapperProps> = ({
|
|||||||
scrollEventElement,
|
scrollEventElement,
|
||||||
getScrollElementScrollableHeight,
|
getScrollElementScrollableHeight,
|
||||||
scrollToBottom,
|
scrollToBottom,
|
||||||
scrollToTarget
|
scrollToTarget,
|
||||||
|
setSScrollContentPaddingBottom: setContentPaddingBottom
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -80,7 +90,9 @@ const ColumnWrapper: React.FC<ColumnWrapperProps> = ({
|
|||||||
ref={scroller}
|
ref={scroller}
|
||||||
style={{ padding: '16px 24px', ...styles.container }}
|
style={{ padding: '16px 24px', ...styles.container }}
|
||||||
>
|
>
|
||||||
<div ref={contentRef}>{children}</div>
|
<div ref={contentRef} className="child-content">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{footer && (
|
{footer && (
|
||||||
<div className="footer" ref={footerRef}>
|
<div className="footer" ref={footerRef}>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ interface WrapperContextProps {
|
|||||||
};
|
};
|
||||||
scrollToTarget?: (target: any, offset?: number) => void;
|
scrollToTarget?: (target: any, offset?: number) => void;
|
||||||
getScrollElement?: () => HTMLElement | null;
|
getScrollElement?: () => HTMLElement | null;
|
||||||
|
setSScrollContentPaddingBottom?: (padding: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WrapperContext = createContext<WrapperContextProps>(
|
export const WrapperContext = createContext<WrapperContextProps>(
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const ApiAccessInfoWrapper = styled.div`
|
|||||||
display: grid;
|
display: grid;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
grid-template-columns: max-content 1fr max-content;
|
grid-template-columns: max-content 1fr max-content;
|
||||||
gap: 12px 0px;
|
gap: 8px 0px;
|
||||||
justify-items: start;
|
justify-items: start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.label {
|
.label {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import SealCascader from '@/components/seal-form/seal-cascader';
|
|||||||
import SealSelect from '@/components/seal-form/seal-select';
|
import SealSelect from '@/components/seal-form/seal-select';
|
||||||
import TooltipList from '@/components/tooltip-list';
|
import TooltipList from '@/components/tooltip-list';
|
||||||
import useAppUtils from '@/hooks/use-app-utils';
|
import useAppUtils from '@/hooks/use-app-utils';
|
||||||
|
import { useWrapperContext } from '@/pages/_components/column-wrapper/use-wrapper-context';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form, InputNumber } from 'antd';
|
import { Form, InputNumber } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -71,6 +72,8 @@ const ScheduleTypeForm: React.FC = () => {
|
|||||||
clearCacheFormValues,
|
clearCacheFormValues,
|
||||||
initialValues
|
initialValues
|
||||||
} = useFormContext();
|
} = useFormContext();
|
||||||
|
const { setSScrollContentPaddingBottom, getScrollElementScrollableHeight } =
|
||||||
|
useWrapperContext();
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const scheduleType = Form.useWatch('scheduleType', form);
|
const scheduleType = Form.useWatch('scheduleType', form);
|
||||||
@@ -79,15 +82,41 @@ const ScheduleTypeForm: React.FC = () => {
|
|||||||
['gpu_selector', 'gpus_per_replica'],
|
['gpu_selector', 'gpus_per_replica'],
|
||||||
form
|
form
|
||||||
);
|
);
|
||||||
|
const gpuSekectorElRef = React.useRef<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
const setContentPaddingBottom = () => {
|
||||||
|
if (!gpuSekectorElRef.current) {
|
||||||
|
gpuSekectorElRef.current = document.querySelector(
|
||||||
|
'[data-field="gpu_selector.gpu_ids"]'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (gpuSekectorElRef.current) {
|
||||||
|
const { scrollHeight, scrollTop } =
|
||||||
|
getScrollElementScrollableHeight?.() || {
|
||||||
|
scrollHeight: 0,
|
||||||
|
scrollTop: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const rect = gpuSekectorElRef.current.getBoundingClientRect();
|
||||||
|
const bottomSpace =
|
||||||
|
window.innerHeight - rect.bottom + (scrollHeight - scrollTop);
|
||||||
|
if (bottomSpace < 340) {
|
||||||
|
setSScrollContentPaddingBottom?.(340 - bottomSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleScheduleTypeChange = async (value: string) => {
|
const handleScheduleTypeChange = async (value: string) => {
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 100);
|
||||||
|
});
|
||||||
if (value === ScheduleValueMap.Auto) {
|
if (value === ScheduleValueMap.Auto) {
|
||||||
await new Promise((resolve) => {
|
|
||||||
setTimeout(resolve, 100);
|
|
||||||
});
|
|
||||||
onValuesChange?.({}, form.getFieldsValue());
|
onValuesChange?.({}, form.getFieldsValue());
|
||||||
} else if (value === ScheduleValueMap.Manual) {
|
} else if (value === ScheduleValueMap.Manual) {
|
||||||
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], null);
|
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], null);
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
setContentPaddingBottom();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleGpusPerReplicasChange = (val: string | number | null) => {
|
const handleGpusPerReplicasChange = (val: string | number | null) => {
|
||||||
@@ -161,6 +190,7 @@ const ScheduleTypeForm: React.FC = () => {
|
|||||||
!form.getFieldValue('fix_gpu_type') && (
|
!form.getFieldValue('fix_gpu_type') && (
|
||||||
<>
|
<>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
data-field="gpu_selector.gpu_ids"
|
||||||
name={['gpu_selector', 'gpu_ids']}
|
name={['gpu_selector', 'gpu_ids']}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { RequestConfig, history } from '@umijs/max';
|
|||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import { DEFAULT_ENTER_PAGE } from './config/settings';
|
import { DEFAULT_ENTER_PAGE } from './config/settings';
|
||||||
|
|
||||||
// no GPUSTACK BASE API
|
// these APIs do not via the GPUSTACK_API_BASE_URL
|
||||||
const NoBaseURLAPIs = ['/auth', '/v1', '/version', '/proxy', '/update'];
|
const NoBaseURLAPIs = ['/auth', '/v1', '/version', '/proxy', '/update'];
|
||||||
|
|
||||||
export const requestConfig: RequestConfig = {
|
export const requestConfig: RequestConfig = {
|
||||||
|
|||||||
Reference in New Issue
Block a user