forked from p96170835/amis
优化关联选择的样式
This commit is contained in:
parent
aa1040d991
commit
1bbee5bdfb
|
@ -8,6 +8,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
.is-spin {
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
.#{$ns}Spinner-overlay {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
|
|
|
@ -563,7 +563,31 @@
|
|||
border-right: 1px solid $borderColor;
|
||||
}
|
||||
|
||||
&-placeholder {
|
||||
@include checkboxes-placeholder();
|
||||
&-reload {
|
||||
text-align: center;
|
||||
color: $info;
|
||||
margin: 20px 0 0;
|
||||
|
||||
&.is-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&-box {
|
||||
line-height: $Form-input-lineHeight;
|
||||
font-size: $fontSizeSm;
|
||||
color: $text--muted-color;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
> p {
|
||||
text-align: center;
|
||||
margin: 10px 0 20px;
|
||||
color: $text--muted-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import TreeCheckboxes from './TreeCheckboxes';
|
|||
import ChainedCheckboxes from './ChainedCheckboxes';
|
||||
import Spinner from './Spinner';
|
||||
import TreeRadios from './TreeRadios';
|
||||
import {Icon} from './icons';
|
||||
|
||||
export interface AssociatedCheckboxesProps extends CheckboxesProps {
|
||||
leftOptions: Options;
|
||||
|
@ -87,6 +88,11 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||
}
|
||||
}
|
||||
|
||||
handleRetry(option: Option) {
|
||||
const {onDeferLoad} = this.props;
|
||||
onDeferLoad?.(option);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
classnames: cx,
|
||||
|
@ -132,8 +138,28 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||
<div className={cx('AssociatedCheckboxes-right')}>
|
||||
{this.state.leftValue ? (
|
||||
selectdOption ? (
|
||||
selectdOption.defer && selectdOption.loading ? (
|
||||
<Spinner size="sm" show />
|
||||
selectdOption.defer && !selectdOption.loaded ? (
|
||||
<div className={cx('AssociatedCheckboxes-box')}>
|
||||
<div
|
||||
className={cx(
|
||||
'AssociatedCheckboxes-reload',
|
||||
selectdOption.loading ? 'is-spin' : 'is-clickable'
|
||||
)}
|
||||
onClick={
|
||||
selectdOption.loading
|
||||
? undefined
|
||||
: this.handleRetry.bind(this, selectdOption)
|
||||
}
|
||||
>
|
||||
<Icon icon="reload" />
|
||||
</div>
|
||||
|
||||
{selectdOption.loading ? (
|
||||
<p>加载中</p>
|
||||
) : (
|
||||
<p>点击刷新重新加载</p>
|
||||
)}
|
||||
</div>
|
||||
) : rightMode === 'table' ? (
|
||||
<TableCheckboxes
|
||||
columns={columns!}
|
||||
|
@ -166,12 +192,12 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||
/>
|
||||
)
|
||||
) : (
|
||||
<div className={cx('AssociatedCheckboxes-placeholder')}>
|
||||
<div className={cx('AssociatedCheckboxes-box')}>
|
||||
配置错误,选项无法与左侧选项对应
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div className={cx('AssociatedCheckboxes-placeholder')}>
|
||||
<div className={cx('AssociatedCheckboxes-box')}>
|
||||
请先选择左侧数据
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -66,6 +66,9 @@ import LocationIcon from '../icons/location.svg';
|
|||
// @ts-ignore
|
||||
import ComboDraggerIcon from '../icons/combo-dragger.svg';
|
||||
|
||||
// @ts-ignore
|
||||
import ReloadIcon from '../icons/reload.svg';
|
||||
|
||||
// 兼容原来的用法,后续不直接试用。
|
||||
// @ts-ignore
|
||||
export const closeIcon = <CloseIcon />;
|
||||
|
@ -129,6 +132,7 @@ registerIcon('move', MoveIcon);
|
|||
registerIcon('info', InfoIcon);
|
||||
registerIcon('location', LocationIcon);
|
||||
registerIcon('combo-dragger', ComboDraggerIcon);
|
||||
registerIcon('reload', ReloadIcon);
|
||||
|
||||
export function Icon({
|
||||
icon,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" version="1.1">
|
||||
<g fill="currentColor" fill-rule="nonzero">
|
||||
<path d="M8.05031447,14.0555556 C5.93710692,14.0555556 4.02515723,12.9861111 2.91823899,11.2361111 L5.03144654,9.19444444 L0,9.19444444 L0,14.0555556 L1.40880503,12.6944444 C2.91823899,14.7361111 5.33333333,16 8.05031447,16 C12.0754717,16 15.4968553,13.1805556 16,9.29166667 L13.9874214,9 C13.5849057,11.9166667 11.0691824,14.0555556 8.05031447,14.0555556 Z M14.591195,3.30555556 C13.081761,1.26388889 10.6666667,0 7.94968553,0 C3.9245283,0 0.503144654,2.81944444 0,6.70833333 L2.01257862,7 C2.41509434,4.08333333 4.93081761,1.94444444 7.94968553,1.94444444 C10.0628931,1.94444444 11.9748428,3.01388889 13.081761,4.76388889 L10.9685535,6.80555556 L16,6.80555556 L16,1.94444444 L14.591195,3.30555556 Z" id="Shape">
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 902 B |
|
@ -61,7 +61,7 @@ export interface OptionsControlProps extends FormControlProps, OptionProps {
|
|||
selectedOptions: Array<Option>;
|
||||
setOptions: (value: Array<any>, skipNormalize?: boolean) => void;
|
||||
setLoading: (value: boolean) => void;
|
||||
reloadOptions: () => void;
|
||||
reloadOptions: (setError?: boolean) => void;
|
||||
deferLoad: (option: Option) => void;
|
||||
creatable?: boolean;
|
||||
onAdd?: (
|
||||
|
@ -435,6 +435,11 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||
// 当有 action 触发,如果指定了 reload 目标组件,有可能会来到这里面来
|
||||
@autobind
|
||||
reload() {
|
||||
this.reloadOptions();
|
||||
}
|
||||
|
||||
@autobind
|
||||
reloadOptions(setError?: boolean) {
|
||||
const {source, formItem, data, onChange} = this.props;
|
||||
|
||||
if (formItem && isPureVariable(source as string)) {
|
||||
|
@ -448,7 +453,14 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||
return;
|
||||
}
|
||||
|
||||
return formItem.loadOptions(source, data, undefined, false, onChange);
|
||||
return formItem.loadOptions(
|
||||
source,
|
||||
data,
|
||||
undefined,
|
||||
false,
|
||||
onChange,
|
||||
setError
|
||||
);
|
||||
}
|
||||
|
||||
@autobind
|
||||
|
|
|
@ -354,11 +354,13 @@ export const FormItemStore = types
|
|||
const fetchOptions: (
|
||||
api: Api,
|
||||
data?: object,
|
||||
config?: fetchOptions
|
||||
config?: fetchOptions,
|
||||
setErrorFlag?: boolean
|
||||
) => Promise<Payload | null> = flow(function* getInitData(
|
||||
api: string,
|
||||
data: object,
|
||||
config?: fetchOptions
|
||||
config?: fetchOptions,
|
||||
setErrorFlag?: boolean
|
||||
) {
|
||||
try {
|
||||
if (loadCancel) {
|
||||
|
@ -382,8 +384,11 @@ export const FormItemStore = types
|
|||
let result: any = null;
|
||||
|
||||
if (!json.ok) {
|
||||
setErrorFlag !== false &&
|
||||
setError(
|
||||
`加载选项失败,原因:${json.msg || (config && config.errorMessage)}`
|
||||
`加载选项失败,原因:${
|
||||
json.msg || (config && config.errorMessage)
|
||||
}`
|
||||
);
|
||||
(getRoot(self) as IRendererStore).notify(
|
||||
'error',
|
||||
|
@ -426,7 +431,8 @@ export const FormItemStore = types
|
|||
data?: object,
|
||||
config?: fetchOptions,
|
||||
clearValue?: boolean,
|
||||
onChange?: (value: any) => void
|
||||
onChange?: (value: any) => void,
|
||||
setErrorFlag?: boolean
|
||||
) => Promise<Payload | null> = flow(function* getInitData(
|
||||
api: string,
|
||||
data: object,
|
||||
|
@ -436,9 +442,10 @@ export const FormItemStore = types
|
|||
value: any,
|
||||
submitOnChange: boolean,
|
||||
changeImmediately: boolean
|
||||
) => void
|
||||
) => void,
|
||||
setErrorFlag?: boolean
|
||||
) {
|
||||
let json = yield fetchOptions(api, data, config);
|
||||
let json = yield fetchOptions(api, data, config, setErrorFlag);
|
||||
if (!json) {
|
||||
return;
|
||||
}
|
||||
|
@ -490,8 +497,15 @@ export const FormItemStore = types
|
|||
})
|
||||
);
|
||||
|
||||
let json = yield fetchOptions(api, data, config);
|
||||
let json = yield fetchOptions(api, data, config, false);
|
||||
if (!json) {
|
||||
setOptions(
|
||||
spliceTree(self.options, indexes, 1, {
|
||||
...option,
|
||||
loading: false,
|
||||
error: true
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue