﻿<template>
    <div v-if="data.model">
        <div class="row">
            <div class="col-sm-2">
            </div>
            <div class="col-sm-10">
                <h1 style="font-size:1.5rem;margin:.5em 0;">{{title}} {{data.erros}}</h1>
            </div>
        </div>
        <div class="row">
            <div class="col-12">
                <form class="form-horizontal query" ref="form" :action="action" @submit.prevent="onSubmit($event)">
                    <div class="card" v-if="this.anonymous||hasPermission()">
                        <div class="card-body">
                            <template v-if="data.errors">
                                <div class="form-group" v-for="error in getValidationSummary(true)">
                                    <div class="offset-sm-2 col-sm-10 ">
                                        <div style="color:#dc3545;">{{error}}</div>
                                    </div>
                                </div>
                            </template>
                            <input type="hidden" name="id" v-if="data.model.id" :value="data.model.id" />
                            <div class="form-group row" v-for="(value,key,index) in data.schema.properties" v-if="show(key,value)">
                                <label class="col-sm-2 col-form-label" :for="key">{{value.title}}:</label>
                                <div v-if="data.model" class="col-sm-6 form-control" style="border-color:transparent;height:auto;min-height:calc(2.25rem + 2px);">
                                    <template v-if="value.readOnly&&mode!=='add'">
                                        <input type="hidden" :name="key" :value="data.model[key]" />
                                        <component :is="getDisplayComponent(key)" :title="value.title" :name="key" :value="data.model[key]" :data="data.data" v-if="data.model" />
                                    </template>
                                    <template v-else>
                                        <component :is="getEditComponent(key)" mode="edit" :title="value.title" :name="key" :value.sync="data.model[key]" :data="data.data" :nullable="value.nullable" @change="change" />
                                    </template>
                                    <div style="height:1em;">
                                        <span v-if="hasErrors(key)" class="field-validation-error text-danger">{{getPropertyErrors(key)}}</span>
                                        <span v-else class="text-danger field-validation-valid"></span>
                                    </div>
                                </div>
                                <div class="col-sm-4">{{value.description}}</div>
                            </div>
                        </div>
                        <div class="card-footer">
                            <div class="row">
                                <div class="col-sm-2">
                                </div>
                                <div class="col-sm-10">
                                    <button type="submit" class="btn btn-primary">确定</button>
                                    <router-link :to="back" class="btn btn-default" v-if="back">返回</router-link>
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>

    </div>
</template>
<script>
    export default {
        name:'form',
        props: [
            'anonymous',
            'title',
            'url',
            'action',
            'back',
            'mode',
            'id',
            'callback',
            //
            'service',
            'area',
            'entity',
            'model',
            'id',
        ],
        data: function () {
            return {
                data: {
                    errors: [],
                    schema: null,
                    model: null,
                    data: null
                }
            }
        },
        mounted: function () {
            if (!this.anonymous) {
                this.anonymous = false;
            }
            if (!this.area) {
                this.area = 'platform';
            }
            if (!this.mode) {
                this.mode = 'edit';
            }
            if (!this.title) {
                this.title = (this.mode === 'edit' ? '编辑' : '新建') + this.name;
            }
            if (!this.url) {
                this.url = this.area + '/' + this.model + (this.mode === 'edit' ? ('?id=' + this.id) : '');
            }
            if (!this.action) {
                if (this.url) {
                    this.action = this.url + 'Api';
                }
                else {
                    this.action = this.area + '/' + this.model + '/' + this.mode + '/' + 'Api';
                }
            }
            if (!this.back) {
                if (this.entity) {
                    this.back = this.area + '/' + this.model +'/index.html'
                }
            }
            this.load();
        },
        computed: {
            name: function () {
                return this.data.schema ? this.data.schema.title : '';
            }
        },
        methods: {
            load: function () {
                var vm = this;
                axios.get(config.service(this.url)).then(function (response) {
                    vm.data = response.data;
                });
            },
            getSchema: function () {
                return this.data.schema;
            },
            getModel: function () {
                return this.data.model;
            },
            getErrors: function () {
                return this.data.errors;
            },
            hasErrors: function (key) {
                key = key.toLowerCase();
                return Enumerable.from(this.getErrors()).any(o => o.key.toLowerCase() === key);
            },
            getValidationSummary: function (excludePropertyErrors) {
                var query = Enumerable.from(this.getErrors());
                if (excludePropertyErrors) {
                    query = query.where(o => o.key === '')
                }
                return query.select(o => o.value.errors[0].errorMessage).toArray();
            },
            getPropertyErrors: function (key) {
                key = key.toLowerCase();
                return Enumerable.from(this.getErrors())
                    .where(o => o.key.toLowerCase() === key).selectMany(o => o.value.errors).select(o => o.errorMessage).toArray().join(',');
            },
            change: function (name) {
                return this.$validProperty(name);
            },
            hasPermission: function () {
                var permission = this.mode + '-' + this.entity;
                return Enumerable.from(store.state.permissions).any(o => o.toLowerCase() === permission.toLowerCase());
            },
            getEditComponent: function (key) {
                var property = this.data.schema.properties[key];
                var template = 'views-shared-edit-' + (property.ui || property.format || property.type);
                return template;
            },
            getDisplayComponent: function (key) {
                var property = this.data.schema.properties[key];
                var template = 'views-shared-display-' + (property.ui || property.format || property.type);
                return template;
            },
            show: function (key, value) {
                return key !== 'id';
            },
            onSubmit: function (e) {
                var vm = this;
                vm.$valid().then(function (value) {
                    if (vm.data.errors.length === 0) {
                        axios.post(e.target.action, vm.data.model).then(function (response) {
                            if (vm.callback) {
                                vm.callback(response);
                            }
                            else {
                                if (response.status === 204) {
                                    var url = vm.base + 'index.html?area=' + vm.area + '&entity=' + vm.entity + '&model=' + vm.model;
                                    setTimeout(function () {
                                        router.push(url);
                                    }, 1000);
                                }
                                else {
                                    vm.data = response.data;
                                }
                            }
                        });
                    }
                });
            }
        }
    }
</script>