All files / src/components/u-form-table-view.vue index.vue

52% Statements 13/25
10% Branches 2/20
11.11% Functions 1/9
54.16% Lines 13/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144      7x   7x     7x                                                                                                                                                                                                                                                                              
<template>
<div :class="$style.root" direction="vertical" gap="small" :size="size">
    <u-form-table :class="$style.table" :size="size" v-bind="$attrs">
        <thead><tr>
            <th ref="th" v-for="(columnVM, columnIndex) in columnVMs"
                :vusion-scope-id="columnVM.$vnode.context.$options._scopeId"
                :vusion-node-path="columnVM.$attrs['vusion-node-path']"
                :width="columnVM.width">
                <f-slot name="title" :vm="columnVM" :props="{ columnVM, columnIndex }">
                    <span>{{ columnVM.title }}</span>
                </f-slot>
            </th>
            <th :class="$style['last-column']" :dynamic="dynamic" :custom="!!$scopedSlots['last-column']" :style="lastColumnStyle"></th>
        </tr></thead>
        <tbody>
            <u-form-table-view-row :class="$style.row" v-for="(item, rowIndex) in currentData" :key="getKey(item, rowIndex)" :muted="muted">
                <template v-if="$env.VUE_APP_DESIGNER">
                    <td :class="$style.cell"
                        v-for="(columnVM, columnIndex) in columnVMs"
                        :is-sub="columnVM.$attrs['is-sub']"
                        :vusion-scope-id="columnVM.$vnode.context.$options._scopeId"
                        :vusion-node-path="columnVM.$attrs['vusion-node-path']"
                        :vusion-node-tag="columnVM.$attrs['vusion-node-tag']"
                        :ellipsis="columnVM.ellipsis"
                        v-ellipsis-title>
                        <div vusion-slot-name="cell" :plus-empty="columnVM.$attrs['plus-empty']">
                            <u-validator display="block" :label="columnVM.title" :action="columnVM.action"
                                :rules="columnVM.rules" :muted="columnVM.muted"
                                :ignore-validation="columnVM.ignoreValidation"
                                :validating-options="Object.assign({ data: currentData, item, rowIndex }, columnVM.validatingOptions)"
                                :validating-value="columnVM.validatingValue"
                                :validating-process="columnVM.validatingProcess">
                                <span v-if="columnVM.type === 'index'">{{ columnVM.startIndex + rowIndex }}</span>
                                <f-slot name="cell" :vm="columnVM" :props="{ item, value: $at(item, columnVM.field), columnVM, rowIndex, columnIndex }">
                                    <span>{{ columnVM.currentFormatter.format($at(item, columnVM.field)) }}</span>
                                </f-slot>
                            </u-validator>
                        </div>
                    </td>
                </template>
                <template v-else>
                    <td :class="$style.cell" v-for="(columnVM, columnIndex) in columnVMs" :ellipsis="columnVM.ellipsis" v-ellipsis-title>
                        <u-validator display="block" :label="columnVM.title" :action="columnVM.action"
                            :rules="columnVM.rules" :muted="columnVM.muted"
                            :ignore-validation="columnVM.ignoreValidation"
                            :validating-options="Object.assign({ data: currentData, item, rowIndex }, columnVM.validatingOptions)"
                            :validating-value="columnVM.validatingValue"
                            :validating-process="columnVM.validatingProcess">
                            <span v-if="columnVM.type === 'index'">{{ columnVM.startIndex + rowIndex }}</span>
                            <f-slot name="cell" :vm="columnVM" :props="{ item, value: $at(item, columnVM.field), columnVM, rowIndex, columnIndex }">
                                <span>{{ columnVM.currentFormatter.format($at(item, columnVM.field)) }}</span>
                            </f-slot>
                        </u-validator>
                    </td>
                </template>
                <template slot="last-column" v-if="dynamic">
                    <slot name="last-column" :item="item" :row-index="rowIndex">
                        <u-form-table-remove-button @click="remove(rowIndex)" :disabled="currentData.length <= minCount || item.disabled"></u-form-table-remove-button>
                    </slot>
                </template>
            </u-form-table-view-row>
        </tbody>
    </u-form-table>
    <u-form-table-add-button :class="$style['add-button']" v-if="showAddButton && dynamic" @click="add()" :disabled="currentData.length >= maxCount">{{ $tt('add') }}</u-form-table-add-button>
    <slot></slot>
</div>
</template>
 
<script>
import i18n from './i18n';
import MDynamic from '../m-dynamic.vue';
import UValidator from '../u-validator.vue';
import i18nMixin from '../../mixins/i18n';
 
export default {
    name: 'u-form-table-view',
    // i18n,
    mixins: [MDynamic, UValidator, i18nMixin('u-form-table-view')],
    props: {
        border: { type: Boolean, default: false },
        dynamic: { type: Boolean, default: false },
        validateOnAdd: { type: Boolean, default: true },
        size: String,
        showAddButton: { type: Boolean, default: true },
        muted: String,
        lastColumnStyle: Object,
    },
    data() {
        return { columnVMs: [] };
    },
    watch: {
        columnVMs(columnVMs) {
            this.$nextTick(() => {
                this.$refs.th
                    && this.$refs.th.forEach((thEl, index) => {
                        thEl.__vue__ = columnVMs[index];
                    });
            });
        },
    },
    created() {
        if (this.validateOnAdd)
            this.$on('add', () => this.validate());
    },
};
</script>
 
<style module>
.root {
    width: 580px;
}
 
.root[size="full"] {
    width: 100%;
}
 
.root[size="mini"] {
    width: auto;
}
 
.last-column {
    width: 0;
}
 
.last-column[dynamic] {
    width: 40px;
}
 
.last-column[custom] {
    width: auto;
}
 
.add-button {
    margin-top: var(--space-small);
}
 
.root[size="mini"] .add-button {
    height: var(--button-height-mini);
    line-height: calc(var(--button-height-mini) - var(--button-border-width) * 2 - var(--button-padding-y) * 2);
    padding: 0 var(--button-padding-x-mini);
    font-size: var(--button-font-size-mini);
}
</style>