<template>
    <div
        class="sql-grid"
        style="width: 100%; height: 100%; display: flex; flex-direction: column"
    >
        <ActionPane
            :actions="actions"
            :func-map="funcMap"
            class="action"
            ref="actionPane"
            v-show="showActionPane && this.gridGuid && this.actions.length > 0"
        ></ActionPane>
        <FilterPane
            :columns="columns"
            :filters="filters"
            @on-filter="filterTable"
            class="filter"
            v-if="showFilterPane && this.gridGuid"
            v-show="isLoaded"
        ></FilterPane>
        <div v-if="currExtendMap">
            <component
                :is="currExtendMap.componentName"
                :whereItems="whereItems"
            ></component>
        </div>
        <VTable
            :cell-edit-done="cellEditDone"
            :columns="columns"
            :height="height"
            :is-loading="isLoading"
            :is-vertical-resize="isVerticalResize"
            :paging-index="(pageIndex - 1) * pageSize"
            :row-click="rowClick"
            :row-dblclick="rowDblClick"
            :row-height="rowHeight"
            :select-all="changeItem"
            :select-change="changeItem"
            :table-data="data"
            :title-rows="titleRows"
            :vertical-resize-offset="verticalResizeOffset"
            class="grid"
            column-width-drag
            even-bg-color="#f8f8f9"
            is-horizontal-resize
            ref="mainTable"
            row-click-color="#ebf7ff"
            row-hover-color="#ebf7ff"
            style="width: 100%"
            title-bg-color="#f8f8f9"
            v-if="this.gridGuid"
        ></VTable>
        <div class="pager" v-if="showPagerPane && this.gridGuid">
            <div class="tool-buttons">
                <span
                    class="info-func"
                    v-html="infoFuncHtml"
                    v-if="infoFunc"
                ></span>
                <Button
                    :title="exportExcelTitle"
                    @click.native="exportXlsx"
                    icon="md-download"
                    shape="circle"
                    type="success"
                ></Button>
                <Button
                    :icon="showDetailIcon"
                    :title="showDetailTitle"
                    @click.native="showDetail"
                    shape="circle"
                    style="margin-left: 6px"
                    type="success"
                    v-if="showDetailButton & !canPagerSelect"
                ></Button>
                <Button
                    title="调整网格"
                    @click.native="setTable"
                    icon="md-build"
                    style="margin-left: 6px"
                    shape="circle"
                    type="success"
                ></Button>
            </div>
            <div style="line-height: 32px; flex: 1; margin-left: 8px">
                <div v-if="canPagerSelect">
                    <span>
                        已选中
                        <span
                            style="
                                margin: 0 5px;
                                font-size: 14px;
                                font-weight: bold;
                            "
                            >{{ pagerSelectedItems.length }}</span
                        >
                        项
                    </span>
                    <a
                        @click.self.stop="cleanPagerSelected"
                        style="margin-left: 10px"
                        title="清除选中项"
                        >清除</a
                    >
                    <span>
                        <a
                            @click.self.stop="selectAllPager"
                            style="margin-left: 10px"
                            title="选择所有"
                            v-if="!isSelectingAll"
                            >全选</a
                        >
                        <img
                            src="../../assets/images/loading_min.gif"
                            style="height: 12px; margin-left: 10px"
                            v-if="isSelectingAll"
                        />
                    </span>
                </div>
            </div>
            <VPagination
                :layout="['total', 'prev', 'pager', 'next', 'sizer', 'jumper']"
                :page-index="pageIndex"
                :page-size="pageSize"
                :page-size-option="[10, 20, 50, 100, 200, 400]"
                :total="total"
                @page-change="pageChange"
                @page-size-change="pageSizeChange"
                v-if="calcTotal"
                v-show="isLoaded"
            ></VPagination>
            <VPagination
                :layout="['prev', 'next', 'sizer', 'jumper']"
                :page-index="pageIndex"
                :page-size="pageSize"
                :page-size-option="[10, 20, 50, 100, 200, 400]"
                :total="total"
                @page-change="pageChange"
                @page-size-change="pageSizeChange"
                v-if="!calcTotal"
                v-show="isLoaded"
            ></VPagination>
        </div>
    </div>
</template>
<script>
import DataApi from '../../data/grid-sql'
import ColumnUtils from './column-utils'
import FilterPane from '../../components/filter-pane'
import ActionPane from './action-pane'
import ImageViewer from '../../libs/image-viewer'
import GridInfoFuncs from '../../extern/grid-info-funcs'
import VTable from '../../v-table/v-table/index'
import VPagination from '../../v-table/v-pagination/index'
import '../../v-table/themes-base/index.css'
import TableSetting from '../../components/table-setting'
export default {
    name: 'Grid',
    data() {
        return {
            // 重置按钮权
            // a: [{ name: '1' }, { name: '2' }],
            // rowBtnLimit: [],
            configVersion: 0,
            pageIndex: 1,
            pageSize: 20,
            total: 0,
            data: undefined,
            actions: [],
            filters: [],
            whereItems: [],
            isLoading: false,
            isLoaded: false,
            selectItems: [],
            selectItem: undefined,
            // 是否初始化完成
            isInitialized: false,
            imageViewer: null,
            // 计算总页数
            calcTotal: true,
            // 显示额外信息
            infoFunc: false,
            infoFuncHtml: '',
            cellEditFunc: '',
            // 明细是否可见
            detailVisible: true,
            // 分页保存的数据
            pagerSelectedItems: [],
            // 是否显示所有
            isSelectingAll: false,
            /**
             * 事件监听器，事件监听器包括名称，及监听函数列表，为了避免出错，一个事件只能有一个监听
             * @deprecated: 使用fnMaps;
             */
            eventListeners: {},

            /**
             * 插件函数映射，所有函数只支持一个JSONObject参数
             */
            pluginFnMaps: {},
        }
    },
    provide() {
        return {
            isHavePermision: this.isHavePermision,
        }
    },
    mixins: [ColumnUtils],
    props: {
        /*是否自动初始化,在某些情况下，不希望自动初始化*/
        autoInit: {
            type: Boolean,
            default: true,
        },
        /*是否显示Action面板*/
        showActionPane: {
            type: Boolean,
            default: true,
        },

        /* 是否显示FilterPane */
        showFilterPane: {
            type: Boolean,
            default: true,
        },
        /* 是否显示分页 */
        showPagerPane: {
            type: Boolean,
            default: true,
        },
        /*GridGuid*/
        gridGuid: {
            type: String,
        },
        /**
         * 主网格GUID，主子网格需要
         */
        mainGuid: {
            type: [String, Number],
        },

        /* guid field */
        guidField: {
            type: String,
            default: 'guid',
        },
        /**/
        funcMap: {
            type: Object,
        },

        extendMap: {
            type: Object,
        },
        height: {
            type: Number,
            default: 0,
        },
        isVerticalResize: {
            type: Boolean,
            default: true,
        },
        verticalResizeOffset: {
            type: Number,
            default: 46,
        },

        propActions: {
            type: Array,
        },

        /* 请求的不同的service */
        queryUrl: {
            type: String,
            default: '/data-service',
        },

        gridType: {
            type: String,
        },

        showDetailButton: {
            type: Boolean,
            default: false,
        },

        /**
         * 行数据，在一些弹出应用中，可以通过这个传递主网格中显示的数据
         */
        rowData: {
            type: Object,
        },

        /**
         * 是否可分页选择
         */
        canPagerSelect: {
            type: Boolean,
            default: false,
        },

        defaultPagerSelectedItems: {
            type: Array,
        },

        /**
         * 默认条件，KV对
         */
        defaultWhere: {
            type: Object,
            default: () => {
                return {}
            },
        },

        /**
         * 默认条件，会增加到where条件中
         *  有主网格GUID时无效
         */
        defaultWhereItems: {
            type: Array,
            default: () => {
                return []
            },
        },
        /**
         * 初始化完成事件
         */
        afterInit: {
            type: Function,
        },

        /**
         * rowData中guid以参数传递
         */
        receipt_guid: {
            type: String || Number,
        },

        hiddenExpTip: {
            type: Boolean,
            default: false,
        },
    },
    watch: {
        mainGuid: {
            handler(newVal) {
                if (newVal) {
                    this.refresh()
                }
            },

            immediate: true,
        },
        data(newVal) {
            if (this.canPagerSelect) {
                console.log(this.pagerSelectedItems)
                // 选中设置项
                newVal.forEach((item) => {
                    let fIndex = this.pagerSelectedItems.indexOf(item.guid)
                    if (~fIndex) {
                        item['_checked'] = true
                    }
                })
            }
        },
    },
    components: {
        FilterPane,
        ActionPane,
        VTable,
        VPagination,
    },
    computed: {
        exportExcelTitle() {
            return this.$t('it.grid.exportExcelTitle')
        },

        /*上部扩展组件*/
        currExtendMap() {
            if (this.extendMap) {
                return this.extendMap[this.gridGuid]
            }

            return ''
        },

        /**
         * 明细按钮图标
         */
        showDetailIcon() {
            if (this.detailVisible) {
                return 'md-arrow-round-down'
            } else {
                return 'md-arrow-round-up'
            }
        },

        /**
         * 明细标题
         */
        showDetailTitle() {
            if (this.detailVisible) {
                return '关闭明细'
            } else {
                return '显示明细'
            }
        },
    },
    methods: {
        utf8_to_b64(str) {
            return window.btoa(unescape(encodeURIComponent(str)))
        },

        b64_to_utf8(str) {
            return decodeURIComponent(escape(window.atob(str)))
        },
        /**
         * 设置默认条件
         */
        setDefaultWhere(defaultWhere) {
            this.defaultWhere = defaultWhere
        },
        /*确认是单选*/
        ensureSingleSelect() {
            if (this.selectItems.length == 0) {
                this.$Modal.warning({
                    title: this.$t('it.grid.warning'),
                    content: this.$t('it.grid.selectone'),
                })

                return false
            } else if (this.selectItems.length > 1) {
                this.$Modal.warning({
                    title: this.$t('it.grid.warning'),
                    content: this.$t('it.grid.onlyone'),
                })

                return false
            }

            return true
        },

        /*确认是多选*/
        ensureMultiSelect() {
            if (this.selectItems.length == 0) {
                this.$Modal.warning({
                    title: this.$t('it.grid.warning'),
                    content: this.$t('it.grid.select'),
                })

                return false
            }

            return true
        },

        /*提供给外部使用的函数*/
        /*获取所有数据*/
        getData() {
            return this.data
        },

        /**
         * 获取选中项对应字段的值
         * @param field 对应字段名 默认guid
         */
        getSelect(field = 'guid') {
            return new Promise((resolve, reject) => {
                if (!this.ensureSingleSelect()) {
                    return
                }

                resolve(this.selectItem[field])
            })
        },
        getRowData() {
            return this.selectItem
        },
        /**获取多选的 rowData */
        getMultiRowData(){
            return this.selectItems
        },
        /**
         * 获取所有选中项对应字段的值
         * @param field 对应字段名 默认guid
         * @param must 必须选 默认 true
         */
        getMultiSelect(field = 'guid', must = true) {
            return new Promise((resolve, reject) => {
                if (must && !this.ensureMultiSelect()) {
                    return
                }

                let rs = []
                this.selectItems.forEach((item) => {
                    rs.push(item[field])
                })

                resolve(rs)
            })
        },

        execWithWhere(field) {
            let data = {
                where: this._getWhere(),
            }
            return new Promise((resolve, reject) => {
                if (field in data) {
                    resolve(data[field])
                }
            })
        },

        /**
         * 获取过滤数据数组
         */
        getFilterArray() {
            return this.whereItems
        },

        //获取指定过滤值
        getFilterValue(name) {
            return new Promise((resolve, reject) => {
                let f = this.whereItems.find((item) => {
                    return item.code === name
                })

                if (f) {
                    resolve(f.value)
                } else {
                    this.$Notice.error({
                        title: `${name}` + this.$t('it.grid.valueIsEmpty'),
                    })

                    reject()
                }
            })
        },

        /**
         * 加载当前页，不跳转，保留当前页状态
         */
        reloadCurrPage() {
            let model = this.getQueryModel(true)
            this.isLoading = true
            return new Promise((resolve, reject) => {
                DataApi.queryData(this.queryUrl, model, this.gridType)
                    .then((res) => {
                        this.data = res.data
                        this.refreshImage()
                        this.total = res.total
                        if (this.total === -999) {
                            // 如果不能获取总页数，返回-999处理
                            this.calcTotal = false
                            this.total = 999999
                        }
                        this.isLoading = false
                        resolve()
                    })
                    .catch(() => {
                        this.isLoading = false
                        reject()
                    })

                //去掉过滤中的选中项
                this.selectItems = []
                this.selectItem = undefined
            })
        },

        /*刷新数据*/
        refresh() {
            this.pageIndex = 1
            let model = this.getQueryModel(true)
            this.isLoading = true
            DataApi.queryData(this.queryUrl, model, this.gridType)
                .then((res) => {
                    this.data = res.data.map((item) => {
                        item._disabled = item._disabled == 1 ? true : false
                        return item
                    })
                    this.refreshImage()
                    this.total = res.total
                    if (this.total === -999) {
                        // 如果不能获取总页数，返回-999处理
                        this.calcTotal = false
                        this.total = 999999
                    }
                    this.isLoading = false
                })
                .catch(() => {
                    this.isLoading = false
                })

            //去掉过滤中的选中项
            this.selectItems = []
            this.selectItem = undefined
        },

        pageChange(pageIndex) {
            this.pageIndex = pageIndex
            this.getTableData()
        },

        pageSizeChange(pageSize) {
            this.pageIndex = 1
            this.pageSize = pageSize
            this.getTableData()
        },

        rowClick(rowIndex, rowData, column) {
            const guid = rowData[this.guidField]
            if (guid) {
                this.$emit('on-select-guid', guid)
            }
        },

        rowDblClick(rowIndex, rowData, column) {
            const guid = rowData[this.guidField]
            if (guid) {
                this.$emit('on-force-select-guid', guid)

                this.$refs.actionPane.doDblClickFunc(rowData)
            }
        },

        changeItem(selection) {
            this.selectItems = [].concat(selection)

            if (this.selectItems.length > 0) {
                this.selectItem = this.selectItems[0]
            } else {
                this.selectItem = null
            }

            // 更新分页选中信息
            if (this.canPagerSelect) {
                this.data.forEach((item) => {
                    if (
                        this.selectItems.some((ifind) => {
                            return ifind.guid === item.guid
                        })
                    ) {
                        //遍历当前所有数据，如果是选中的，则判断是否在 this.pagerSelectedItems中，如果不在，则增加
                        let fIndex = this.pagerSelectedItems.indexOf(item.guid)
                        if (fIndex === -1) {
                            this.pagerSelectedItems.push(item.guid)
                        }
                    } else {
                        //遍历当前所有数据，如果是选中的，则判断是否在 this.pagerSelectedItems中，如果在，则删除
                        let fIndex = this.pagerSelectedItems.indexOf(item.guid)

                        if (fIndex != -1) {
                            this.pagerSelectedItems.splice(fIndex, 1)
                        }
                    }
                })
            }
        },

        /**
         * 获取分页选中项
         */
        getPagerSelectedItems() {
            return this.pagerSelectedItems
        },

        /*点击过滤*/
        filterTable(fa) {
            this.whereItems = this.wrapperWhereItems(fa)

            this.refresh()
        },

        wrapperWhereItems(fa) {
            let where = [].concat(fa)

            return where
        },

        getTableData() {
            this.isLoading = true
            DataApi.queryData(
                this.queryUrl,
                this.getQueryModel(),
                this.gridType
            )
                .then((res) => {
                    this.data = res.data
                    this.refreshImage()
                    this.isLoading = false
                })
                .catch(() => {
                    this.isLoading = false
                })
            //去掉过滤中的选中项
            this.selectItems = []
            this.selectItem = undefined
        },

        refreshImage() {
            this.$nextTick(() => {
                this.imageViewer.reset()
            })
        },
        setupActions(conf) {
            let actions = []
            let confActions = conf.actions.filter((item) => {
                if (item.permisions) {
                    return this.propActions.includes(item.permisions)
                } else {
                    return true
                }
            })
            for (let a of confActions) {
                let act = {
                    caption: a.caption,
                    action: a.func_guid,
                    isDblClickFunc: a.is_dbl_click_func,
                }

                actions.push(act)
            }
            this.actions = actions
        },
        // 行内按钮权限限制
        isHavePermision(conf) {
            return this.propActions.includes(conf)
        },
        setupFilters(conf) {
            let filters = []
            for (let f of conf.filters) {
                let filter = {
                    editor: f.editor,
                    type: f.type,
                    label: f.caption,
                    code: f.field,
                    op: f.operator,
                    width: f.width,
                    ds: f.ds,
                    defValue: f.def_value,
                    can_clear: f.can_clear,
                }
                filters.push(filter)
            }

            this.filters = filters
        },

        /**
         * 构造查询模型
         * @param withTotal 是否获取总页数
         */
        getQueryModel(withTotal) {
            return {
                guid: this.gridGuid,
                with_total: withTotal,
                page_index: this.pageIndex,
                page_size: this.pageSize,
                _where: this._getWhere(),
                // 这个数据在单文件中显示
                default_where: Object.assign(
                    {},
                    this.defaultWhere,
                    this.$$defaultWhere
                ),
                row_data: this.rowData,
                permissionType: this.$roleName,
            }
        },

        _getWhere() {
            if (this.mainGuid) {
                return JSON.stringify(
                    this.whereItems.concat({
                        code: '__main_guid__',
                        op: 'equal',
                        value: this.mainGuid,
                    })
                )
            } else if (this.receipt_guid) {
                return JSON.stringify(
                    this.whereItems.concat({
                        code: 'receipt_guid',
                        value: this.receipt_guid,
                        asParam: true,
                    })
                )
            } else {
                return JSON.stringify(
                    this.whereItems.concat(this.defaultWhereItems)
                )
            }
        },

        setInfoFunc(infoFunc) {
            if (!infoFunc) {
                return
            }

            this.infoFunc = infoFunc

            if (GridInfoFuncs[this.infoFunc]) {
                this.infoFuncHtml = GridInfoFuncs[this.infoFunc]()
            } else {
                console.log(`unimpleted function: ${infoFunc}`)
            }
        },

        init() {
            if (!this.gridGuid) {
                return
            }

            if (this.isInitialized) {
                return
            }

            this.isInitialized = true
            this.isLoading = true
            DataApi.queryConfig(this.queryUrl, this.gridGuid, this.gridType)
                .then((config) => {
                    this.isLoaded = true
                    this.configVersion = config.version
                    this.setupActions(config)
                    this.setupColumns(config)
                    this.setupFilters(config)
                    this.setInfoFunc(config.info_func)
                    this.cellEditFunc = config.cell_edit_func || ''

                    if (!this.showFilterPane) {
                        // 没有显示filterPane，不能直接查询数据
                        this.isLoading = false
                    }
                    if (this.defaultPagerSelectedItems) {
                        this.pagerSelectedItems = [].concat(
                            this.defaultPagerSelectedItems
                        )
                    }
                })
                .catch(() => {
                    this.isLoading = false
                })
        },

        // 单元格编辑完成响应
        cellEditDone(newVal, oldVal, rowIndex, rowData, field) {
            if (newVal === oldVal) return
            let FP = this.cellEditFunc.split('.')
            let M = this.funcMap[FP[0]]
            M().then((module) => {
                let F = module[FP[1]]
                if (!F) {
                    this.$Notice.error({
                        title: `未知操作:${FP[0]}.${FP[1]}`,
                    })
                    return
                }
                F.call(this, newVal, oldVal, rowIndex, rowData, field)
                // rowData[field] = newVal
            })
        },

        exportXlsx() {
            let where = this._getWhere()
            let model = {
                grid_guid: this.gridGuid,
                grid_type: this.gridType,
                tenant_id: this.$tenantId, //外部注入
                _where: where,
                row_data: this.rowData,
                emp_guid: this.$empGuid,
            }

            console.log(model)
            let params = encodeURIComponent(
                this.utf8_to_b64(JSON.stringify(model))
            )
            console.log(params)

            let xlsxUrl = `/data-service/sql-grid/xlsx?params=${params}&token=${this.$token}`
            // 通知父级点击了下载
            if (this.$animation) {
                this.$animation.show()
            } else {
                this.$emit('on-down')
            }
            // fra-public 在应用中统一定义
            document.getElementById('fra-public').setAttribute('src', xlsxUrl)

            if (this.gridType === 'COMM-FORM') {
                // 通用表单，直接导出
                return
            }

            if (!this.hiddenExpTip) {
                this.$Message.success('导出请求已经完成，请在“任务列表”中查看')
            }
        },

        exportImg() {
            this.$emit('on-down')
        },

        showDetail() {
            this.detailVisible = !this.detailVisible
            this.$emit('on-show-detail-grid', this.detailVisible)
            this.$nextTick((_) => {
                this.$refs['mainTable'].resize()
            })
        },

        /**
         * 清除所有已选中的分页
         */
        cleanPagerSelected() {
            this.pagerSelectedItems.splice(0)
            this.reloadCurrPage()
        },

        /**
         * 选择所有
         */
        selectAllPager() {
            this.isSelectingAll = true
            this.fetchAllDataGuids()
        },

        /**
         * 获取所有数据Guid
         */
        fetchAllDataGuids(cb) {
            let model = this.getQueryModel(true)
            DataApi.queryAllGuids(this.queryUrl, model, this.gridType)
                .then((res) => {
                    this.pagerSelectedItems.splice(0)
                    this.pagerSelectedItems = res

                    // 选中当前所有项
                    this.data.forEach((item) => {
                        // item['_checked'] = true
                        this.$set(item, '_checked', true)
                    })

                    this.isSelectingAll = false
                    cb && cb()
                })
                .catch(() => {})
        },

        /**
         * 调整网格
         */
        setTable() {
            TableSetting.show(
                this.configVersion,
                this.columns,
                this.gridGuid,
                () => {
                    this.isInitialized = false
                    this.init()
                }
            )
        },

        /**
         * 添加事件监听
         * @param name 监听名
         * @param fn 监听函数
         */
        addEventListener(name, fn) {
            if (this.eventListeners[name]) {
                alert('监听已经存在，不能添加：' + this.eventListeners[name])

                return
            }

            this.eventListeners[name] = fn
        },

        /**
         * 触发事件
         */
        fireEvent(name, params) {
            const fn = this.eventListeners[name]

            if (fn) {
                fn(params)
            } else {
                console.log(`不存在的${name}监听,是否无用事件？`)
            }
        },

        /**
         * 注册插件函数
         * @param {String} fnName 函数名
         * @param {JSONObject} fn 函数对象，函数参数传递必须为JSONObject， this对象为当前Grid
         */
        registerPluginFn(fnName, fn) {
            if (this.pluginFnMaps[fnName]) {
                alert(`函数${fnName}已经注册,函数体:` + fn)

                return
            }
            this.pluginFnMaps[fnName] = fn
        },

        /**
         * 执行插件函数
         * @param {String} fnName 函数名
         * @param {JSONObject} params 参数
         */
        execPluginFn(fnName, params) {
            if (this.pluginFnMaps[fnName]) {
                this.pluginFnMaps[fnName](params)
            } else {
                alert(`函数${fnName}没有注册`)
            }
        },
    },
    beforeDestroy() {
        this.$off('refresh-current-page', this.reloadCurrPage)
    },
    mounted() {
        this.imageViewer = new ImageViewer(() => {
            return this.$el.querySelectorAll(
                '.grid-image-big,.grid-image-small'
            )
        })

        if (!this.showPagerPane) {
            // 如果不显示分页，最多显示1000行。不加默认显示20行
            this.pageSize = 1000
        }
        // if (this.autoInit) {
        //     this.init()
        // }

        if (this.defaultPagerSelectedItems) {
            this.pagerSelectedItems = [].concat(this.defaultPagerSelectedItems)
        }

        this.$nextTick(() => {
            let height = this.hasImage ? '100px' : '40px'
            if (document.querySelectorAll('.v-table-body td')) {
                document
                    .querySelectorAll('.v-table-body td')
                    .forEach((item) => {
                        item.style.height = height
                    })
            }
        })

        this.$on('refresh-current-page', this.reloadCurrPage)
        this.afterInit && this.afterInit()
    },
    created() {
        if (this.autoInit) {
            this.init()
        }
    },
}
</script>
<style lang="less">
.sql-grid {
    .action {
        padding: 8px 8px 8px 20px;
    }

    .filter {
        padding: 8px 8px 8px 20px;
    }

    .grid {
        flex: 1;
        padding-bottom: -8px;
    }

    .pager {
        padding: 8px 8px 8px 10px;
        display: flex;

        .tool-buttons {
            .info-func {
                margin-right: 20px;
            }
        }
    }

    .grid-image-big {
        img {
            margin: 4px;
            width: 80px;
            height: 80px;
            border-radius: 4px;
        }
    }

    .grid-image-small {
        img {
            margin: 2px;
            width: 36px;
            height: 36px;
            border-radius: 4px;
        }
    }

    .titleEdit {
        background: url(../../assets/edit.png) right no-repeat;
        background-size: 12px;
        background-position: 92% 44%;
    }
}
</style>
