优化关联选择的样式

This commit is contained in:
2betop 2020-05-29 18:02:03 +08:00
parent aa1040d991
commit 1bbee5bdfb
7 changed files with 117 additions and 17 deletions

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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>
)}

View File

@ -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,

6
src/icons/reload.svg Normal file
View File

@ -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

View File

@ -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

View File

@ -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;
}