push
This commit is contained in:
719
lib/component/table/table.vue
Normal file
719
lib/component/table/table.vue
Normal file
@@ -0,0 +1,719 @@
|
||||
<!-- @format -->
|
||||
|
||||
<template>
|
||||
<div class="ns-table" :class="{ 'ns-table-no-search': !(formConfig?.schemas.length > 0) }">
|
||||
<!-- tabletitle -->
|
||||
<div
|
||||
class="ns-table-title"
|
||||
@click="
|
||||
() => {
|
||||
showBack ? navigateBack() : '';
|
||||
}
|
||||
"
|
||||
v-if="tableTitle">
|
||||
<ns-icon v-if="showBack" class="backIcon" name="left" />{{ tableTitle }}
|
||||
</div>
|
||||
<!-- {{ formConfig }} -->
|
||||
<a-spin :spinning="tableState.loading">
|
||||
<div class="ns-table-search" v-if="!isEmpty(formConfig)">
|
||||
<ns-form
|
||||
ref="formElRef"
|
||||
class="ns-table-form"
|
||||
:showAction="true"
|
||||
v-bind="formConfig"
|
||||
:expand="expand"
|
||||
:showExpand="showExpand"
|
||||
:model="formModel"
|
||||
@finish="formFinish" />
|
||||
</div>
|
||||
<a-row type="flex" class="ns-table-main">
|
||||
<a-col :flex="getTreeWidth" v-if="!isEmpty(treeConfig)">
|
||||
<ns-tree v-if="getTreeData.length" v-bind="getTreeBindValue" @select="treeSelect" />
|
||||
</a-col>
|
||||
<a-col flex="auto">
|
||||
<ns-table-header
|
||||
v-if="!isEmpty(headerActions) || tableTitle"
|
||||
:headerActions="headerActions"
|
||||
:searchData="formModel"
|
||||
:tableTitle="tableTitle"
|
||||
:data="tableState.selectedRows">
|
||||
<template #header="data">
|
||||
<slot name="header" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</ns-table-header>
|
||||
<ns-basic-table ref="tableElRef" v-bind="getTableBindValues" :dataSource="tableData">
|
||||
<template #emptyText>
|
||||
<template v-if="tableState.loadError">
|
||||
<div class="ns-table-content">
|
||||
<div class="fetch-error">
|
||||
<p>{{ tableState.loadErrorMessage }}</p>
|
||||
<ns-button type="primary" ghost @click="reload">重新加载</ns-button></div
|
||||
></div
|
||||
>
|
||||
</template>
|
||||
<template v-else-if="tableState.loading"
|
||||
><div class="ns-table-content"></div
|
||||
></template>
|
||||
<template v-else>
|
||||
<div class="ns-table-content"> <a-empty /> </div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
<template v-if="item === 'bodyCell'">
|
||||
<template v-if="data?.column?.textEllipsis">
|
||||
<span
|
||||
class="tool-tips"
|
||||
:style="{ width: `${data.column.textWidth || data.column.width}px` }">
|
||||
<ns-tooltip
|
||||
placement="top"
|
||||
v-if="
|
||||
data.column.customRender
|
||||
? data.column.customRender(data)
|
||||
: data.record[data.column.dataIndex]
|
||||
">
|
||||
<template #title>
|
||||
<span>{{
|
||||
data.column.customRender
|
||||
? data.column.customRender(data)
|
||||
: data.record[data.column.dataIndex] || '-'
|
||||
}}</span>
|
||||
</template>
|
||||
<span class="text-ellipsis">{{
|
||||
data.column.customRender
|
||||
? data.column.customRender(data)
|
||||
: data.record[data.column.dataIndex] || '-'
|
||||
}}</span>
|
||||
</ns-tooltip>
|
||||
<span class="text-ellipsis" v-else> - </span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="data.column.dataIndex === 'tableAction'">
|
||||
<ns-table-action
|
||||
:data="data.record"
|
||||
:searchData="formModel"
|
||||
:columnActions="getColumnActions" />
|
||||
</template>
|
||||
<template v-if="data.column.edit">
|
||||
<ns-table-cell
|
||||
:value="data.text"
|
||||
:record="data.record"
|
||||
:column="data.column"
|
||||
:index="data.index" />
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="item === 'footer'">
|
||||
<ns-table-footer :footerActions="footerActions" :data="ediRowData" />
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="data" v-if="!Object.keys($slots).includes('bodyCell')">
|
||||
<template v-if="data.column.textEllipsis">
|
||||
<span
|
||||
class="tool-tips"
|
||||
:style="{ width: `${data.column.textWidth || data.column.width}px` }">
|
||||
<ns-tooltip
|
||||
placement="top"
|
||||
v-if="
|
||||
data.column.customRender
|
||||
? data.column.customRender(data)
|
||||
: data.record[data.column.dataIndex]
|
||||
">
|
||||
<template #title>
|
||||
<span>{{
|
||||
data.column.customRender
|
||||
? data.column.customRender(data)
|
||||
: data.record[data.column.dataIndex] || '-'
|
||||
}}</span>
|
||||
</template>
|
||||
<span class="text-ellipsis">{{
|
||||
data.column.customRender
|
||||
? data.column.customRender(data)
|
||||
: data.record[data.column.dataIndex] || '-'
|
||||
}}</span>
|
||||
</ns-tooltip>
|
||||
<span class="text-ellipsis" v-else> - </span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="data.column.dataIndex === 'tableAction'">
|
||||
<ns-table-action
|
||||
:data="data.record"
|
||||
:searchData="formModel"
|
||||
:columnActions="getColumnActions" />
|
||||
</template>
|
||||
<template v-if="data.column.edit">
|
||||
<ns-table-cell
|
||||
:value="data.text"
|
||||
:record="data.record"
|
||||
:column="data.column"
|
||||
:index="data.index" />
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template
|
||||
#footer
|
||||
v-if="!Object.keys($slots).includes('footer') && !isEmpty(footerActions)">
|
||||
<ns-table-footer :footerActions="footerActions" :data="ediRowData" />
|
||||
</template>
|
||||
</ns-basic-table>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, provide, reactive, ref, unref, watch } from 'vue';
|
||||
import { RequestParams } from '/nerv-lib/component/table/table';
|
||||
import {
|
||||
cloneDeep,
|
||||
debounce,
|
||||
throttle,
|
||||
get,
|
||||
isArray,
|
||||
isEmpty,
|
||||
isEqual,
|
||||
isFunction,
|
||||
isObject,
|
||||
isString,
|
||||
isUndefined,
|
||||
} from 'lodash-es';
|
||||
import NsTableAction from './table-action.vue';
|
||||
import NsTableHeader from './table-header.vue';
|
||||
import NsTableFooter from './table-footer.vue';
|
||||
import NsTableCell from './edit/table-cell.vue';
|
||||
import { useParams } from '/nerv-lib/use/use-params';
|
||||
import { transformColumns } from '/nerv-lib/component/table/table-columns';
|
||||
import NsBasicTable from '/nerv-lib/component/table/basic-table.vue';
|
||||
import { tableProps } from '/nerv-lib/component/table/props';
|
||||
import { AxiosRequestConfig } from 'axios';
|
||||
import { useApi } from '/nerv-lib/use/use-api';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useTableEdit } from '/nerv-lib/component/table/use-table-edit';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { stringUtil } from '/nerv-lib/util/string-util';
|
||||
import { useTableRefresh } from '/nerv-lib/component/table/use-table-refresh';
|
||||
import { tableConfig } from '/nerv-base/config/table.config';
|
||||
import { useTableSession } from '/nerv-lib/component/table/use-table-session';
|
||||
import { useTableColumn } from '/nerv-lib/component/table/use-table-column';
|
||||
import { useNavigate } from '/nerv-lib/use/use-navigate';
|
||||
export default defineComponent({
|
||||
name: 'NsTable',
|
||||
components: {
|
||||
NsBasicTable,
|
||||
NsTableAction,
|
||||
NsTableHeader,
|
||||
NsTableFooter,
|
||||
NsTableCell,
|
||||
},
|
||||
props: tableProps,
|
||||
|
||||
emits: ['cellChange', 'update:value', 'dataSourceChange', 'update:dataSource'],
|
||||
setup(props, { attrs, emit }) {
|
||||
const tableElRef = ref(null);
|
||||
const formElRef = ref(null);
|
||||
const dataRef = ref([]);
|
||||
const treeParamsRef = ref({});
|
||||
const formParamsRef = ref({});
|
||||
const orderRef = ref({});
|
||||
const formModel = reactive<Recordable>({});
|
||||
const tableData = ref<Recordable[]>([]);
|
||||
const tableState = reactive({
|
||||
selectedRowKeys: [],
|
||||
selectedRows: [],
|
||||
loading: false,
|
||||
loadError: false,
|
||||
loadErrorMessage: '',
|
||||
loadinterval: 0,
|
||||
});
|
||||
const route = useRoute();
|
||||
const { getColumnActionWidth } = useTableColumn({
|
||||
columnActions: Object.assign({}, tableConfig.columnActions, props.columnActions),
|
||||
});
|
||||
const { navigateBack } = useNavigate();
|
||||
const defaultPageRef = ref(1 - props.pageFieldOffset);
|
||||
|
||||
const { setTableSession } = useTableSession(
|
||||
formModel,
|
||||
formParamsRef,
|
||||
defaultPageRef,
|
||||
treeParamsRef,
|
||||
);
|
||||
|
||||
const { delayFetch } = useTableRefresh({ props, reload });
|
||||
|
||||
watch(
|
||||
[() => props.value, () => props.dataSource],
|
||||
() => {
|
||||
tableData.value = props.value || props.dataSource || [];
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
const formItemContext = Form.useInjectFormItemContext();
|
||||
|
||||
const getColumnActions = computed(() => {
|
||||
const { actions } = props.columnActions as any;
|
||||
const _tableConfig = cloneDeep(tableConfig);
|
||||
if (actions) {
|
||||
_tableConfig.columnActions.width = getColumnActionWidth(actions);
|
||||
}
|
||||
return Object.assign(_tableConfig.columnActions, props.columnActions);
|
||||
});
|
||||
|
||||
const getColumns = computed(() => {
|
||||
const columns = transformColumns(cloneDeep(props.columns || []));
|
||||
const { title, width, dataIndex, fixed } = getColumnActions.value;
|
||||
if (props.columnActions) {
|
||||
columns.push({
|
||||
title,
|
||||
width,
|
||||
dataIndex,
|
||||
fixed,
|
||||
});
|
||||
}
|
||||
return columns;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => tableData.value,
|
||||
(val) => {
|
||||
// console.log(val, tableData.value);
|
||||
|
||||
if (isEqual(val, tableData.value)) return;
|
||||
|
||||
const data = cloneDeep(tableData.value);
|
||||
if (props.editable) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
delete data[key][props.rowKey];
|
||||
});
|
||||
}
|
||||
// emit('update:value', data);
|
||||
emit('dataSourceChange', data);
|
||||
formItemContext.onFieldChange();
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
const tableEdit = useTableEdit({
|
||||
dataSource: tableData,
|
||||
columns: getColumns,
|
||||
rowKey: props.rowKey,
|
||||
editable: ref(props.editable),
|
||||
});
|
||||
provide('tableEdit', tableEdit);
|
||||
|
||||
const { getParams } = useParams();
|
||||
|
||||
const rowSelection = computed(() => {
|
||||
const { rowSelection } = props;
|
||||
if (rowSelection === false || rowSelection === null) {
|
||||
return null;
|
||||
}
|
||||
return Object.assign(
|
||||
{
|
||||
fixed: true,
|
||||
columnWidth: 48,
|
||||
preserveSelectedRowKeys: true, // 跨页选中默认不清除选中key
|
||||
selectedRowKeys: tableState.selectedRowKeys,
|
||||
onChange: (selectedRowKeys: never[], selectedRows: never[]) => {
|
||||
tableState.selectedRowKeys = selectedRowKeys;
|
||||
tableState.selectedRows = selectedRows;
|
||||
},
|
||||
},
|
||||
rowSelection,
|
||||
);
|
||||
});
|
||||
|
||||
const customizeRenderEmpty = computed(() => {
|
||||
return () => '暂无数据';
|
||||
});
|
||||
|
||||
const formFinish = debounce((data: object) => {
|
||||
formParamsRef.value = data;
|
||||
fetch({
|
||||
page: 1,
|
||||
});
|
||||
}, 300);
|
||||
|
||||
function setLoading(loading: boolean) {
|
||||
tableState.loading = loading;
|
||||
}
|
||||
|
||||
const tableChangeEvent = (pagination: Props, filters: [], sorter: any) => {
|
||||
// console.log('params', pagination, filters, sorter);
|
||||
if (sorter?.field) {
|
||||
if (sorter.order) {
|
||||
orderRef.value = {
|
||||
[props.paramsOrderField]: stringUtil.toLine(
|
||||
`${sorter.field} ${sorter.order.replace('end', '')}`,
|
||||
),
|
||||
};
|
||||
} else {
|
||||
orderRef.value = { [props.paramsOrderField]: '' }; //覆盖默认params
|
||||
}
|
||||
fetch({
|
||||
page: pagination?.current || getPagination.value?.current || 1,
|
||||
pageSize: pagination?.pageSize,
|
||||
});
|
||||
} else if (pagination?.current) {
|
||||
fetch({
|
||||
page: pagination?.current,
|
||||
pageSize: pagination.pageSize,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// pagination
|
||||
const getPagination: Recordable | Boolean = computed(() => {
|
||||
const { pagination } = props;
|
||||
const { getPageParams } = attrs;
|
||||
|
||||
if (pagination) {
|
||||
const current = get(dataRef.value, props.pageField);
|
||||
// console.log(current);
|
||||
function getTotal() {
|
||||
let total = 0;
|
||||
if (isFunction(getPageParams)) {
|
||||
total = getPageParams(dataRef)['total'];
|
||||
} else {
|
||||
total = get(dataRef.value, props.totalField);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
return {
|
||||
showQuickJumper: true,
|
||||
showLessItems: true,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total: number, range: Array<number>) => {
|
||||
return `显示第${range[0]}到${range[1]}条记录 ,共 ${
|
||||
get(dataRef.value, props.totalField) || total
|
||||
} 条记录`;
|
||||
},
|
||||
...(pagination as Props),
|
||||
total: getTotal(),
|
||||
current: (current >= 0 ? current : 0) + props.pageFieldOffset, // 后端0 开始
|
||||
pageSize: get(dataRef.value, props.sizeField),
|
||||
};
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const getTableBindValues = computed(() => {
|
||||
const { params, dynamicParams } = props;
|
||||
return {
|
||||
...attrs,
|
||||
...props,
|
||||
rowSelection: rowSelection.value,
|
||||
params: dynamicParams
|
||||
? getParams({ ...route.params, ...route.query }, dynamicParams, params)
|
||||
: params || {},
|
||||
columns: getColumns.value,
|
||||
pagination: getPagination.value,
|
||||
onChange: tableChangeEvent,
|
||||
};
|
||||
});
|
||||
|
||||
watch(
|
||||
() => getTableBindValues.value.api,
|
||||
() => {
|
||||
// console.log(getTableBindValues.value.api);
|
||||
|
||||
fetch(); //路由切换导致api切换 导致发送请求
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// watch(
|
||||
// () => getTableBindValues.value.params,
|
||||
// () => {
|
||||
// fetch();
|
||||
// },
|
||||
// {
|
||||
// immediate: true,
|
||||
// },
|
||||
// );
|
||||
|
||||
/**
|
||||
* 请求函数
|
||||
* @param requestParams 主要是传入页面,部分变量闭包处理
|
||||
* @param clearDelay 是否需要清除刷新时间(页面操作之后,自动刷新重新计算)
|
||||
*/
|
||||
|
||||
function fetch(requestParams: RequestParams = {}, clearDelay = true) {
|
||||
clearDelay && delayFetch();
|
||||
if (tableState.loadinterval) {
|
||||
clearTimeout(tableState.loadinterval);
|
||||
}
|
||||
if (tableState.loading) {
|
||||
tableState.loadinterval = setTimeout(() => {
|
||||
fetch(requestParams, clearDelay);
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
const { api, pagination } = props;
|
||||
const { page, pageSize } = requestParams;
|
||||
if (api) {
|
||||
let pageParams: Recordable = {};
|
||||
|
||||
if (pagination !== false) {
|
||||
pageParams = {
|
||||
[props.paramsPageField]: page ? page - props.pageFieldOffset : defaultPageRef.value, // 后端0 开始
|
||||
[props.paramsPageSizeField]:
|
||||
pageSize || getPagination.value?.pageSize || props.defaultPageSize,
|
||||
};
|
||||
} else {
|
||||
pageParams = {
|
||||
[props.paramsPageField]: defaultPageRef.value, // 后端0 开始
|
||||
[props.paramsPageSizeField]:
|
||||
pageSize || getPagination.value?.pageSize || props.defaultPageSize,
|
||||
};
|
||||
}
|
||||
const httpParams = {
|
||||
...getTableBindValues.value.params,
|
||||
...pageParams,
|
||||
...formParamsRef.value,
|
||||
...treeParamsRef.value,
|
||||
...orderRef.value,
|
||||
};
|
||||
if (!checkrequiredParams(httpParams)) {
|
||||
console.log('check fail');
|
||||
return;
|
||||
}
|
||||
|
||||
setTableSession(pageParams[props.paramsPageField]);
|
||||
|
||||
clearDelay && setLoading(true);
|
||||
|
||||
const requestConfig: AxiosRequestConfig = { method: 'get' };
|
||||
const { httpRequest } = useApi();
|
||||
httpRequest({
|
||||
api,
|
||||
params: httpParams,
|
||||
pathParams: { ...route.params, ...route.query },
|
||||
requestConfig,
|
||||
})
|
||||
.then((res: any) => {
|
||||
tableState.loadError = false;
|
||||
tableState.loadErrorMessage = '';
|
||||
dataRef.value = res;
|
||||
console.log(props.listField);
|
||||
tableData.value = get(unref(dataRef), props.listField);
|
||||
//saas项目配置
|
||||
if (attrs['getPageParams']) {
|
||||
const getPageParams = attrs['getPageParams'];
|
||||
let realPage = getPageParams(dataRef, pageParams.page)['page'];
|
||||
if (realPage !== pageParams.page) {
|
||||
fetch({ page: realPage });
|
||||
}
|
||||
}
|
||||
emit('update:dataSource', tableData.value);
|
||||
clearDelay && setLoading(false);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
const { response, code, message } = error || {};
|
||||
let errMessage = response?.data?.msg;
|
||||
const err: string = error?.toString?.() ?? '';
|
||||
if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
|
||||
errMessage = '接口请求超时,请刷新页面重试!';
|
||||
}
|
||||
if (err?.includes('Network Error')) {
|
||||
errMessage = '网络异常,请检查您的网络连接是否正常!';
|
||||
}
|
||||
|
||||
// console.log(getPagination.value);
|
||||
tableState.loadError = true;
|
||||
tableState.loadErrorMessage = errMessage;
|
||||
clearDelay && setLoading(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测requiredParams是否全部获得数据
|
||||
* @param params
|
||||
*/
|
||||
function checkrequiredParams(params: Recordable) {
|
||||
const { params: dynamicParams } = getTableBindValues.value as any;
|
||||
let { requiredParams } = props;
|
||||
if (requiredParams) {
|
||||
if (requiredParams === true) requiredParams = dynamicParams as any;
|
||||
if (isFunction(requiredParams)) {
|
||||
console.error(
|
||||
'Property dynamicParams of props cannot set to Function when using requiredParams',
|
||||
);
|
||||
return false;
|
||||
} else {
|
||||
if (isString(requiredParams)) {
|
||||
if (isUndefined(params[requiredParams])) return false;
|
||||
} else if (isArray(requiredParams)) {
|
||||
for (let i = 0, l = requiredParams.length; i < l; i++) {
|
||||
if (isUndefined(params[requiredParams[i]])) return false;
|
||||
}
|
||||
} else if (isObject(requiredParams)) {
|
||||
const keys = Object.keys(requiredParams);
|
||||
for (let i = 0, l = keys.length; i < l; i++) {
|
||||
if (isUndefined(params[keys[i]])) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function treeSelect(
|
||||
selectedKeys: never[],
|
||||
e: {
|
||||
selected: boolean;
|
||||
selectedNodes: { props: { dataRef: any } }[];
|
||||
node: any;
|
||||
event: any;
|
||||
},
|
||||
) {
|
||||
// console.log(selectedKeys, e);
|
||||
const { dataRef } = e.selectedNodes[0].props;
|
||||
treeParamsRef.value = getParams(dataRef, props.params);
|
||||
fetch({
|
||||
page: 1,
|
||||
});
|
||||
}
|
||||
|
||||
const getTreeData = computed(() => {
|
||||
return props?.treeConfig?.treeData || [];
|
||||
});
|
||||
|
||||
const getTreeWidth = computed(() => {
|
||||
return props?.treeConfig?.width || '300px';
|
||||
});
|
||||
|
||||
const getTreeBindValue = computed(() => ({
|
||||
...props?.treeConfig,
|
||||
}));
|
||||
//todo 异步加载|| 树形接口
|
||||
|
||||
function reload(clearDelay = true) {
|
||||
const pagination = unref(getPagination);
|
||||
fetch(
|
||||
{
|
||||
page: pagination === false ? 1 : pagination.current,
|
||||
},
|
||||
clearDelay,
|
||||
);
|
||||
}
|
||||
|
||||
provide('reload', reload); //提供刷新功能
|
||||
|
||||
return {
|
||||
navigateBack,
|
||||
reload,
|
||||
formElRef,
|
||||
tableElRef,
|
||||
getColumnActions,
|
||||
getTableBindValues,
|
||||
formModel,
|
||||
tableState,
|
||||
isEmpty,
|
||||
formFinish,
|
||||
tableChangeEvent,
|
||||
treeSelect,
|
||||
getTreeBindValue,
|
||||
getTreeWidth,
|
||||
getTreeData,
|
||||
customizeRenderEmpty,
|
||||
tableData,
|
||||
treeParamsRef,
|
||||
formParamsRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.backIcon {
|
||||
cursor: pointer;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.ns-table-title {
|
||||
text-align: left;
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
//font-size: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
user-select: text;
|
||||
padding-left: 16px;
|
||||
background: #fff;
|
||||
width: calc(100% + 32px);
|
||||
margin-left: -16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ns-table-content {
|
||||
// background: #e5ebf0;
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
:deep(.ant-spin-nested-loading > div > .ant-spin) {
|
||||
max-height: none;
|
||||
}
|
||||
.ns-table-search {
|
||||
padding-top: 16px;
|
||||
}
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ns-table {
|
||||
position: relative;
|
||||
// min-height: 400px;
|
||||
// background: #e5ebf0;
|
||||
.ant-spin-nested-loading {
|
||||
height: 100%;
|
||||
// min-height: 400px;
|
||||
}
|
||||
|
||||
.ns-table-content {
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fetch-error {
|
||||
p {
|
||||
line-height: 40px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
width: 88px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-ellipsis {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
.tool-tips {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user