2022-03-26 22:52:54 +08:00
|
|
|
import type { App, VNodeTypes, Plugin, ExtractPropTypes, PropType } from 'vue';
|
2021-06-26 09:35:40 +08:00
|
|
|
import { defineComponent, computed } from 'vue';
|
2020-03-07 19:45:13 +08:00
|
|
|
import PropTypes from '../_util/vue-types';
|
2020-04-04 22:03:18 +08:00
|
|
|
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
|
|
|
|
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
|
|
|
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
|
|
|
|
import WarningFilled from '@ant-design/icons-vue/WarningFilled';
|
2020-03-07 19:45:13 +08:00
|
|
|
import noFound from './noFound';
|
|
|
|
import serverError from './serverError';
|
|
|
|
import unauthorized from './unauthorized';
|
2023-01-27 16:00:17 +08:00
|
|
|
import useConfigInject from '../config-provider/hooks/useConfigInject';
|
2021-06-07 17:35:03 +08:00
|
|
|
import classNames from '../_util/classNames';
|
2023-05-18 21:22:58 +08:00
|
|
|
import type { CustomSlotsType } from '../_util/type';
|
2020-03-07 19:45:13 +08:00
|
|
|
|
2023-02-12 14:44:50 +08:00
|
|
|
import useStyle from './style';
|
|
|
|
|
2020-03-07 19:45:13 +08:00
|
|
|
export const IconMap = {
|
2020-04-04 22:03:18 +08:00
|
|
|
success: CheckCircleFilled,
|
|
|
|
error: CloseCircleFilled,
|
|
|
|
info: ExclamationCircleFilled,
|
|
|
|
warning: WarningFilled,
|
2020-03-07 19:45:13 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
export const ExceptionMap = {
|
|
|
|
'404': noFound,
|
|
|
|
'500': serverError,
|
|
|
|
'403': unauthorized,
|
|
|
|
};
|
|
|
|
|
2022-03-26 22:52:54 +08:00
|
|
|
export type ExceptionStatusType = 403 | 404 | 500 | '403' | '404' | '500';
|
|
|
|
export type ResultStatusType = ExceptionStatusType | keyof typeof IconMap;
|
|
|
|
|
2020-03-07 19:45:13 +08:00
|
|
|
// ExceptionImageMap keys
|
|
|
|
const ExceptionStatus = Object.keys(ExceptionMap);
|
|
|
|
|
2022-03-26 22:52:54 +08:00
|
|
|
export const resultProps = () => ({
|
|
|
|
prefixCls: String,
|
2020-03-07 19:45:13 +08:00
|
|
|
icon: PropTypes.any,
|
2022-03-26 22:52:54 +08:00
|
|
|
status: { type: [Number, String] as PropType<ResultStatusType>, default: 'info' },
|
2020-03-07 19:45:13 +08:00
|
|
|
title: PropTypes.any,
|
|
|
|
subTitle: PropTypes.any,
|
|
|
|
extra: PropTypes.any,
|
2022-03-26 22:52:54 +08:00
|
|
|
});
|
2020-03-07 19:45:13 +08:00
|
|
|
|
2022-03-26 22:52:54 +08:00
|
|
|
export type ResultProps = Partial<ExtractPropTypes<ReturnType<typeof resultProps>>>;
|
2021-06-07 17:35:03 +08:00
|
|
|
|
2020-10-18 00:36:04 +08:00
|
|
|
const renderIcon = (prefixCls: string, { status, icon }) => {
|
2020-03-15 14:02:16 +08:00
|
|
|
if (ExceptionStatus.includes(`${status}`)) {
|
2020-03-07 19:45:13 +08:00
|
|
|
const SVGComponent = ExceptionMap[status];
|
|
|
|
return (
|
|
|
|
<div class={`${prefixCls}-icon ${prefixCls}-image`}>
|
|
|
|
<SVGComponent />
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2020-04-04 22:03:18 +08:00
|
|
|
const IconComponent = IconMap[status];
|
|
|
|
const iconNode = icon || <IconComponent />;
|
2020-03-07 19:45:13 +08:00
|
|
|
return <div class={`${prefixCls}-icon`}>{iconNode}</div>;
|
|
|
|
};
|
|
|
|
|
2020-10-18 00:36:04 +08:00
|
|
|
const renderExtra = (prefixCls: string, extra: VNodeTypes) =>
|
|
|
|
extra && <div class={`${prefixCls}-extra`}>{extra}</div>;
|
2020-03-07 19:45:13 +08:00
|
|
|
|
2020-10-18 00:36:04 +08:00
|
|
|
const Result = defineComponent({
|
2022-09-26 21:33:41 +08:00
|
|
|
compatConfig: { MODE: 3 },
|
2020-03-07 19:45:13 +08:00
|
|
|
name: 'AResult',
|
2023-02-12 14:44:50 +08:00
|
|
|
inheritAttrs: false,
|
2022-03-26 22:52:54 +08:00
|
|
|
props: resultProps(),
|
2023-05-18 21:22:58 +08:00
|
|
|
slots: Object as CustomSlotsType<{
|
|
|
|
title?: any;
|
|
|
|
subTitle?: any;
|
|
|
|
icon?: any;
|
|
|
|
extra?: any;
|
2023-05-18 22:53:21 +08:00
|
|
|
default?: any;
|
2023-05-18 21:22:58 +08:00
|
|
|
}>,
|
2023-02-12 14:44:50 +08:00
|
|
|
setup(props, { slots, attrs }) {
|
2021-06-07 17:35:03 +08:00
|
|
|
const { prefixCls, direction } = useConfigInject('result', props);
|
2023-02-12 14:44:50 +08:00
|
|
|
|
|
|
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
|
|
|
|
2021-06-07 17:35:03 +08:00
|
|
|
const className = computed(() =>
|
2023-02-12 14:44:50 +08:00
|
|
|
classNames(prefixCls.value, hashId.value, `${prefixCls.value}-${props.status}`, {
|
2021-06-07 17:35:03 +08:00
|
|
|
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
|
|
|
|
}),
|
2020-03-07 19:45:13 +08:00
|
|
|
);
|
2021-06-07 17:35:03 +08:00
|
|
|
return () => {
|
|
|
|
const title = props.title ?? slots.title?.();
|
|
|
|
const subTitle = props.subTitle ?? slots.subTitle?.();
|
|
|
|
const icon = props.icon ?? slots.icon?.();
|
|
|
|
const extra = props.extra ?? slots.extra?.();
|
|
|
|
const pre = prefixCls.value;
|
2023-02-12 14:44:50 +08:00
|
|
|
return wrapSSR(
|
|
|
|
<div {...attrs} class={[className.value, attrs.class]}>
|
2021-06-07 17:35:03 +08:00
|
|
|
{renderIcon(pre, { status: props.status, icon })}
|
|
|
|
<div class={`${pre}-title`}>{title}</div>
|
|
|
|
{subTitle && <div class={`${pre}-subtitle`}>{subTitle}</div>}
|
|
|
|
{renderExtra(pre, extra)}
|
|
|
|
{slots.default && <div class={`${pre}-content`}>{slots.default()}</div>}
|
2023-02-12 14:44:50 +08:00
|
|
|
</div>,
|
2021-06-07 17:35:03 +08:00
|
|
|
);
|
|
|
|
};
|
2020-03-07 19:45:13 +08:00
|
|
|
},
|
2020-10-18 00:36:04 +08:00
|
|
|
});
|
2020-03-07 19:45:13 +08:00
|
|
|
|
|
|
|
/* add resource */
|
|
|
|
Result.PRESENTED_IMAGE_403 = ExceptionMap[403];
|
|
|
|
Result.PRESENTED_IMAGE_404 = ExceptionMap[404];
|
|
|
|
Result.PRESENTED_IMAGE_500 = ExceptionMap[500];
|
|
|
|
|
|
|
|
/* istanbul ignore next */
|
2021-06-23 23:08:16 +08:00
|
|
|
Result.install = function (app: App) {
|
2020-06-08 14:53:35 +08:00
|
|
|
app.component(Result.name, Result);
|
2020-10-13 19:14:56 +08:00
|
|
|
return app;
|
2020-03-07 19:45:13 +08:00
|
|
|
};
|
2020-10-18 00:36:04 +08:00
|
|
|
|
2020-11-01 15:03:33 +08:00
|
|
|
export default Result as typeof Result &
|
|
|
|
Plugin & {
|
|
|
|
readonly PRESENTED_IMAGE_403: typeof unauthorized;
|
|
|
|
readonly PRESENTED_IMAGE_404: typeof noFound;
|
|
|
|
readonly PRESENTED_IMAGE_500: typeof serverError;
|
|
|
|
};
|