| | |
| | | <template> |
| | | <div :class="prefixCls"> |
| | | <div |
| | | v-show="!isEdit" |
| | | :class="{ [`${prefixCls}__normal`]: true, 'ellipsis-cell': column.ellipsis }" |
| | | @click="handleEdit" |
| | | > |
| | | <div class="cell-content" :title="column.ellipsis ? getValues ?? '' : ''"> |
| | | {{ getValues || getValues === 0 ? getValues : ' ' }} |
| | | </div> |
| | | <FormOutlined :class="`${prefixCls}__normal-icon`" v-if="!column.editRow" /> |
| | | </div> |
| | | |
| | | <a-spin v-if="isEdit" :spinning="spinning"> |
| | | <div :class="`${prefixCls}__wrapper`" v-click-outside="onClickOutside"> |
| | | <CellComponent |
| | | v-bind="getComponentProps" |
| | | :component="getComponent" |
| | | :style="getWrapperStyle" |
| | | :popoverVisible="getRuleVisible" |
| | | :rule="getRule" |
| | | :ruleMessage="ruleMessage" |
| | | :class="getWrapperClass" |
| | | ref="elRef" |
| | | @change="handleChange" |
| | | @options-change="handleOptionsChange" |
| | | @pressEnter="handleEnter" |
| | | /> |
| | | <div :class="`${prefixCls}__action`" v-if="!getRowEditable"> |
| | | <CheckOutlined :class="[`${prefixCls}__icon`, 'mx-2']" @click="handleSubmitClick" /> |
| | | <CloseOutlined :class="`${prefixCls}__icon `" @click="handleCancel" /> |
| | | </div> |
| | | </div> |
| | | </a-spin> |
| | | </div> |
| | | </template> |
| | | <script lang="ts"> |
| | | <script lang="tsx"> |
| | | import type { CSSProperties, PropType } from 'vue'; |
| | | import { computed, defineComponent, nextTick, ref, toRaw, unref, watchEffect } from 'vue'; |
| | | import type { BasicColumn } from '../../types/table'; |
| | |
| | | |
| | | export default defineComponent({ |
| | | name: 'EditableCell', |
| | | components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent, ASpin: Spin }, |
| | | components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent, Spin }, |
| | | directives: { |
| | | clickOutside, |
| | | }, |
| | |
| | | }); |
| | | |
| | | const getComponentProps = computed(() => { |
| | | const compProps = props.column?.editComponentProps ?? {}; |
| | | const component = unref(getComponent); |
| | | const apiSelectProps: Recordable = {}; |
| | | if (component === 'ApiSelect') { |
| | | apiSelectProps.cache = true; |
| | | } |
| | | |
| | | const isCheckValue = unref(getIsCheckComp); |
| | | |
| | | const valueField = isCheckValue ? 'checked' : 'value'; |
| | |
| | | |
| | | const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val; |
| | | |
| | | let compProps = props.column?.editComponentProps ?? {}; |
| | | const { record, column, index } = props; |
| | | |
| | | if (isFunction(compProps)) { |
| | | compProps = compProps({ text: val, record, column, index }) ?? {}; |
| | | } |
| | | const component = unref(getComponent); |
| | | const apiSelectProps: Recordable = {}; |
| | | if (component === 'ApiSelect') { |
| | | apiSelectProps.cache = true; |
| | | } |
| | | |
| | | return { |
| | | size: 'small', |
| | | getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body, |
| | | getCalendarContainer: () => unref(table?.wrapRef.value) ?? document.body, |
| | | placeholder: createPlaceholderMessage(unref(getComponent)), |
| | | ...apiSelectProps, |
| | | ...omit(compProps, 'onChange'), |
| | | [valueField]: value, |
| | | }; |
| | | } as any; |
| | | }); |
| | | |
| | | const getValues = computed(() => { |
| | | const { editComponentProps, editValueMap } = props.column; |
| | | const { editValueMap } = props.column; |
| | | |
| | | const value = unref(currentValueRef); |
| | | |
| | |
| | | return value; |
| | | } |
| | | |
| | | const options: LabelValueOptions = editComponentProps?.options ?? (unref(optionsRef) || []); |
| | | const options: LabelValueOptions = |
| | | unref(getComponentProps)?.options ?? (unref(optionsRef) || []); |
| | | const option = options.find((item) => `${item.value}` === `${value}`); |
| | | |
| | | return option?.label ?? value; |
| | |
| | | } else if (isString(e) || isBoolean(e) || isNumber(e)) { |
| | | currentValueRef.value = e; |
| | | } |
| | | const onChange = props.column?.editComponentProps?.onChange; |
| | | const onChange = unref(getComponentProps)?.onChange; |
| | | if (onChange && isFunction(onChange)) onChange(...arguments); |
| | | |
| | | table.emit?.('edit-change', { |
| | |
| | | |
| | | // only ApiSelect or TreeSelect |
| | | function handleOptionsChange(options: LabelValueOptions) { |
| | | const { replaceFields } = props.column?.editComponentProps ?? {}; |
| | | const { replaceFields } = unref(getComponentProps); |
| | | const component = unref(getComponent); |
| | | if (component === 'ApiTreeSelect') { |
| | | const { title = 'title', value = 'value', children = 'children' } = replaceFields || {}; |
| | |
| | | |
| | | if (props.column.dataIndex) { |
| | | if (!props.record.editValueRefs) props.record.editValueRefs = {}; |
| | | props.record.editValueRefs[props.column.dataIndex] = currentValueRef; |
| | | props.record.editValueRefs[props.column.dataIndex as any] = currentValueRef; |
| | | } |
| | | /* eslint-disable */ |
| | | props.record.onCancelEdit = () => { |
| | |
| | | spinning, |
| | | }; |
| | | }, |
| | | render() { |
| | | return ( |
| | | <div class={this.prefixCls}> |
| | | <div |
| | | v-show={!this.isEdit} |
| | | class={{ [`${this.prefixCls}__normal`]: true, 'ellipsis-cell': this.column.ellipsis }} |
| | | onClick={this.handleEdit} |
| | | > |
| | | <div class="cell-content" title={this.column.ellipsis ? this.getValues ?? '' : ''}> |
| | | {this.column.editRender |
| | | ? this.column.editRender({ |
| | | text: this.value, |
| | | record: this.record as Recordable, |
| | | column: this.column, |
| | | index: this.index, |
| | | }) |
| | | : this.getValues |
| | | ? this.getValues |
| | | : '\u00A0'} |
| | | </div> |
| | | {!this.column.editRow && <FormOutlined class={`${this.prefixCls}__normal-icon`} />} |
| | | </div> |
| | | {this.isEdit && ( |
| | | <Spin spinning={this.spinning}> |
| | | <div class={`${this.prefixCls}__wrapper`} v-click-outside={this.onClickOutside}> |
| | | <CellComponent |
| | | {...this.getComponentProps} |
| | | component={this.getComponent} |
| | | style={this.getWrapperStyle} |
| | | popoverVisible={this.getRuleVisible} |
| | | rule={this.getRule} |
| | | ruleMessage={this.ruleMessage} |
| | | class={this.getWrapperClass} |
| | | ref="elRef" |
| | | onChange={this.handleChange} |
| | | onOptionsChange={this.handleOptionsChange} |
| | | onPressEnter={this.handleEnter} |
| | | /> |
| | | {!this.getRowEditable && ( |
| | | <div class={`${this.prefixCls}__action`}> |
| | | <CheckOutlined |
| | | class={[`${this.prefixCls}__icon`, 'mx-2']} |
| | | onClick={this.handleSubmitClick} |
| | | /> |
| | | <CloseOutlined class={`${this.prefixCls}__icon `} onClick={this.handleCancel} /> |
| | | </div> |
| | | )} |
| | | </div> |
| | | </Spin> |
| | | )} |
| | | </div> |
| | | ); |
| | | }, |
| | | }); |
| | | </script> |
| | | <style lang="less"> |