<template>
  <div class="x-toolbar">
    <div class="x-toolbar__left">
      <Item v-for="(item,name) in leftDataMap"
            :key="`item-left-${name}`"
            v-bind="item"
            :size="size"
            :mode="mode">
        <template v-if="item.type === 'custom'" #[item.name]="scope">
          <slot :name="item.name" v-bind="scope"></slot>
        </template>
      </Item>
    </div>
    <div class="x-toolbar__right">
      <Item v-for="(item,name) in rightDataMap"
            :key="`item-right-${name}`"
            v-bind="getValue(item)"
            :size="size"
            :mode="mode">
        <template v-if="item.type === 'custom'" #[item.name]="scope">
          <slot :name="item.name" v-bind="scope"></slot>
        </template>
      </Item>
    </div>
  </div>
</template>

<script>
/**
 * 工具条组件
 * @module XToolbar
 */
import Item from './components/Item';
import defaultValue, { Names } from './defaults';
import merge from 'lodash-es/merge';
export default {
  name: 'XToolbar',
  Names: Object.keys(Names),
  provide() {
    return {
      $toolbar: this
    };
  },
  components: {
    Item
  },
  data() {
    return {
      currentMap: Object.create(null)
    };
  },
  /**
   * 属性参数
   * @member props
   * @property {Object[]|String[]} [left] 左侧工具按钮配置, 字符串可选值: exit,remove,refresh,edit,addRow,removeRow,clearAll,save,choose,list,search,print,create,confirm,delete,writeOff,import,export,file,back,backAll,log,next,prev,|
   * @property {string} [left.name] 按钮标识名称，必须要唯一，如果名称是可选值，即继承默认配置
   * @property {string} [left.label] 按钮显示文本
   * @property {string} [left.type] 按钮类型，可选值：button,divider,group,dropdown,custom
   * @property {boolean|string|function} [left.access] 权限控制，布尔值表示是否有权限，字符串由Access实例控制，函数用作自定义控制
   * @property {object} [left.props] 按钮组件参数选项对象
   * @property {function} [left.handler] 按钮点击回调函数
   * @property {Object[]|String[]} [right] 右侧工具按钮配置，设置方式与 left 一致，只是显示位置不同
   * @property {string} [size=mini] 按钮尺寸
   * @property {string} [mode=disabled] 权限控制时按钮的显示模式，可选值：disabled、visible
   * @property {object} [access] 权限配置对象，key为按钮name，如果按钮自身配置了access，优先取按钮自己的
   */
  props: {
    // [{name, label, type, access, props, children, handler}]
    left: {
      type: Array,
      default() {
        return [];
      }
    },
    right: {
      type: Array,
      default() {
        return [];
      }
    },
    size: {
      type: String,
      default: 'mini'
    },
    mode: {
      type: String,
      default: 'disabled',
      validator(v) {
        return ['disabled', 'visible'].includes(v);
      }
    },
    access: {
      type: Object,
      default() {
        return Object.create(null);
      }
    }
  },
  computed: {
    leftDataMap() {
      return this.getDataMap(this.left, 'left');
    },
    rightDataMap() {
      return this.getDataMap(this.right, 'right');
    }
  },
  methods: {
    getDataMap(list = [], type = 'left') {
      const map = Object.create(null);
      const currentMap = this.currentMap;
      list.forEach((key, index) => {
        const item = defaultValue(key);
        const name = item.name || `${type}${index}`;
        map[name] = Object.freeze(merge({ name }, item, currentMap[name] || {}));
      });
      return map;
    },
    /**
     * 更新按钮配置
     * @method update
     * @param {string} name 按钮名称标识
     * @param {object} config 按钮配置
     */
    update(name, config) {
      const cur = this.currentMap[name] || {};
      const value = merge(cur, config);
      delete this.currentMap[name];
      this.$set(this.currentMap, name, Object.freeze(value));
    },
    getValue(item) {
      return defaultValue(item);
    }
  }
};

/**
 * 按钮点击时触发
 * @event click
 * @param {object} e 按钮组件实例或按钮配置对象
 */
</script>
