<commit_before>Ext.define('FastUI.view.VTab', {
    extend:'Ext.Panel',
    alias:'widget.vtab',
    title:'All VTabs',
    vfactory:null,
    layout:"card",
    initComponent:function () {
        this.title = this.vfactory.getVData().title;
        this.restHelper = Ext.create('FastUI.view.RestHelper', this.vfactory.getVData().model_class);
        this.tbar = Ext.create('Ext.toolbar.Toolbar', {
            items:[
                {   text:'新建',
                    handler:function () {
                        this.cmdCreate();
                    },
                    scope:this
                },
                { text:'编辑',
                    handler:function () {
                        this.cmdEdit();
                    }, scope:this},
                { text:'列表',
                    handler:function () {
                        this.cmdList();
                    }, scope:this},
                { text:'保存',
                    handler:function () {
                        this.cmdSave();
                    }, scope:this},
                { text:'删除',
                    handler:function () {
                        this.cmdDelete();
                    }, scope:this},
                { text:'帮助',
                    handler:function () {
                        alert('帮助');
                    }, scope:this}
            ]
        });
        this.callParent();
    },
    listeners:{
        activate:function (tab, opts) {
            this.cmdList();
        }
    },
    cmdList:function () {
        if (!this.grid) {
            this.grid = Ext.create('FastUI.view.VGrid', {vfactory:this.vfactory});
            this.add(this.grid);
        }

        this.grid.getStore().reload(); // 不一定每次都要刷新 需修改
        this.getLayout().setActiveItem(this.grid.id);
    },
    cmdCreate:function () {
        if (!this.form) {
            this.form = Ext.create('FastUI.view.VForm', {vfactory:this.vfactory});
            this.add(this.form);
        }
        this.getLayout().setActiveItem(this.form.id);
        var form = this.form.getForm();
        form.url = this.restHelper.getPath('create');
        form.method = 'POST';
        form.reset();
    },
    cmdEdit:function () {
        var record = this.grid.getSelectionModel().getSelection();
        if (record) this.currentRecord = record[0];
        if (!this.form) {
            this.form = Ext.create('FastUI.view.VForm', {vfactory:this.vfactory});
            this.add(this.form);
        }

        var form = this.form.getForm();
        form.url = this.restHelper.getPath('update', this.currentRecord.get('id'));
        form.method = 'PUT';

        Ext.Ajax.request({
            url:this.restHelper.getPath('edit', this.currentRecord.get('id')),
            success:function (response) {
                var data = Ext.decode(response.responseText);
                var k, o = {};
                for (k in data) {
                    o[this.restHelper.getName() + '[' + k + ']'] = data[k];
                }
                form.setValues(o);
            }, scope:this
        });
        this.getLayout().setActiveItem(this.form.id);
    },
    cmdDelete:function () {
        var record = this.grid.getSelectionModel().getSelection();
        if (record) this.currentRecord = record[0];
        Ext.MessageBox.confirm('提示', '确定要删除此记录吗?', function (btn) {
            if (btn == 'yes') {
                Ext.Ajax.request({
                    url:this.restHelper.getPath('delete', this.currentRecord.get('id')),
                    method:'DELETE',
                    success:function () {
                        this.cmdList();
                        Ext.MessageBox.alert("提示", "操作成功！")
                    },
                    failure:function () {
                        Ext.MessageBox.alert("提示", "操作失败！")
                    },
                    scope:this
                });
            }
        }, this)

    },
    cmdSave:function () {
        if (this.form) {
            var form = this.form.getForm();
            if (form.isValid()) {
                form.submit({
                    scope:this,
                    success:function (form, action) {
                        Ext.Msg.alert('Success', action.result.msg);
                        this.cmdList();
                    },
                    failure:function (form, action) {
                        Ext.Msg.alert('Failed', action.result.msg);
                    }
                });
            }
        }
    }
});
<commit_msg>use mtabs each<commit_after>Ext.define('FastUI.view.VTab', {
    extend:'Ext.Panel',
    alias:'widget.vtab',
    title:'All VTabs',
    vfactory:null,
    layout:"card",
    initComponent:function () {
        this.title = this.vfactory.getVData().title;
        this.restHelper = Ext.create('FastUI.view.RestHelper', this.vfactory.getVData().model_class);
        this.tbar = Ext.create('Ext.toolbar.Toolbar', {
            items:[
                {   text:'新建',
                    handler:function () {
                        this.cmdCreate();
                    },
                    scope:this
                },
                { text:'编辑',
                    handler:function () {
                        this.cmdEdit();
                    }, scope:this},
                { text:'列表',
                    handler:function () {
                        this.cmdList();
                    }, scope:this},
                { text:'保存',
                    handler:function () {
                        this.cmdSave();
                    }, scope:this},
                { text:'删除',
                    handler:function () {
                        this.cmdDelete();
                    }, scope:this},
                { text:'帮助',
                    handler:function () {
                        alert('帮助');
                    }, scope:this}
            ]
        });
        this.callParent();
    },
    listeners:{
        activate:function (tab, opts) {
            this.cmdList();
        }
    },
    cmdList:function () {
        if (!this.grid) {
            this.grid = Ext.create('FastUI.view.VGrid', {vfactory:this.vfactory});
            this.add(this.grid);
        }

        this.grid.getStore().reload(); // 不一定每次都要刷新 需修改
        this.getLayout().setActiveItem(this.grid.id);
    },
    cmdCreate:function () {
        if (!this.form) {
            this.form = Ext.create('FastUI.view.VForm', {vfactory:this.vfactory});
            this.add(this.form);
        }
        this.getLayout().setActiveItem(this.form.id);
        var form = this.form.getForm();
        form.url = this.restHelper.getPath('create');
        form.method = 'POST';
        form.reset();
    },
    cmdEdit:function () {
        var record = this.grid.getSelectionModel().getSelection();
        if (record) this.currentRecord = record[0];
        if (!this.form) {
            this.form = Ext.create('FastUI.view.VForm', {vfactory:this.vfactory});
            this.add(this.form);
        }

        var form = this.form.getForm();
        form.url = this.restHelper.getPath('update', this.currentRecord.get('id'));
        form.method = 'PUT';

        Ext.Ajax.request({
            url:this.restHelper.getPath('edit', this.currentRecord.get('id')),
            success:function (response) {
                var data = Ext.decode(response.responseText);
                var k, o = {};
                for (k in data) {
                    o[this.restHelper.getName() + '[' + k + ']'] = data[k];
                }
                form.setValues(o);
            }, scope:this
        });
        this.getLayout().setActiveItem(this.form.id);
    },
    cmdDelete:function () {
        var record = this.grid.getSelectionModel().getSelection();
        if (record) this.currentRecord = record[0];
        Ext.MessageBox.confirm('提示', '确定要删除此记录吗?', function (btn) {
            if (btn == 'yes') {
                Ext.Ajax.request({
                    url:this.restHelper.getPath('delete', this.currentRecord.get('id')),
                    method:'DELETE',
                    success:function () {
                        this.cmdList();
                        Ext.MessageBox.alert("提示", "操作成功！")
                    },
                    failure:function () {
                        Ext.MessageBox.alert("提示", "操作失败！")
                    },
                    scope:this
                });
            }
        }, this)

    },
    cmdSave:function () {
        if (this.form) {
            var form = this.form.getForm();
            if (form.isValid()) {
//                form.submit({
//                    scope:this,
//                    success:function (form, action) {
//                        Ext.Msg.alert('Success', action.result.msg);
//                        this.cmdList();
//                    },
//                    failure:function (form, action) {
//                        Ext.Msg.alert('Failed', action.result.msg);
//                    }
//                });
                Ext.Ajax.request({
                    url:form.url,
                    method:form.method,
                    params:form.getValues(false, false,false),
                    success:function () {
                        this.cmdList();
                        Ext.MessageBox.alert("提示", "操作成功！")
                    },
                    failure:function () {
                        Ext.MessageBox.alert("提示", "操作失败！")
                    },
                    scope:this
                });
            }
        }
    },
    constructAjaxRequest:function(){

    }
});
<|endoftext|>


<commit_before>/*globals ChartSettings,D3BaseChart,DefaultSettings,Legend,LoadChartHelper,
PopOver,Quantity,StackTransformer,StrategyHelper,Transformer,WeekSelect*/

var D3LoadChart = (function () {
    'use strict';

    var xScale,  // Scales
        xScale2,
        yScale,
        yScale2,
        xAxis,   // Axis
        xAxis2,
        yAxis,
        context,
        svg,
        defs,
        brush,
        chartData,
        hoverLineGroup,

        brushMargin     = 40,
        weeksInYear     = (365 / 7.0),

        // This is assuming every LES has a length of 35040. Shorter LES's will
        // break because of this line.
        weekResolution   = 672,
        scaleCorrection  = 1.05,
        customTimeFormat = d3.time.format.utc.multi([
            ["%H:%M", function (d) { return d.getUTCMinutes(); }],
            ["%H:%M", function (d) { return d.getUTCHours(); }],
            ["%b %d", function (d) { return d.getUTCDate() !== 1; }],
            ["%d %b", function () { return true; }]
        ]),
        chartParts = {
            preview_issue: {
                line: undefined,
                colorArea: undefined,
                stackedArea: undefined
            },
            issue: {
                line: undefined,
                colorArea: undefined,
                stackedArea: undefined
            }
        };

    function setLesOptions() {
        var lesOptions;

        if (this.currentWeek !== 0) {
            lesOptions = {
                resolution:  'high',
                range_start: weekResolution * (this.currentWeek - 1),
                range_end:   weekResolution * this.currentWeek
            };
        } else {
            lesOptions = {
                resolution: 'low',
                range_start: 0,
                range_end:   weekResolution * weeksInYear
            };
        }

        $.extend(this.settings, lesOptions);
    }

    function renderWeek(scope) {
        var value = parseInt($(scope.target).val(), 10);

        this.currentWeek = value;

        scope.brush.clear();

        this.dateSelect.disable();

        if (this.settings.dateCallback) {
            this.settings.dateCallback(value);
        } else {
            setLesOptions.call(this);
            window.currentTree.update();
        }
    }

    function all() {
        var chained = [];
        this.forEach(function (d) {
            if (d.visible) {
                chained = chained.concat(d.values);
            }
        });
        return chained;
    }

    function setExtent(d) {
        var extent = brush.extent();

        if (brush.empty() || (extent[0] <= d.x && extent[1] >= d.x)) {
            if (this.settings.view_as === 'stacked') {
                return (d.y + d.offset) * scaleCorrection;
            } else {
                return d.y * scaleCorrection;
            }
        }
    }

    function setLine(d, scope) {
        if (d.visible && !(this.settings.view_as === 'stacked')) {
            return chartParts[scope].line(d.values);
        } else {
            return null;
        }
    }

    function setArea(d, scope) {
        if (d.visible && d.area) {
            if (this.settings.view_as === 'stacked') {
                return chartParts[scope].stackedArea(d.values);
            } else {
                return chartParts[scope].colorArea(d.values);
            }
        } else {
            return null;
        }
    }

    //for brusher of the slider bar at the bottom
    function brushed() {
        xScale.domain(brush.empty() ? xScale2.domain() : brush.extent());

        svg.select(".x.axis")
              .transition().duration(0)
              .call(xAxis);

        this.setYscaleDomain(true);
    }

    function roundDate(date) {
        var roundTo  = this.settings.resolution === 'high' ? 15 : 60 * 24,
            rounding = 1000 * 60 * roundTo;

        return new Date(Math.floor(date.getTime() / rounding) * rounding);
    }

    function fetchResults(graphX) {
        var results = {};

        chartData.forEach(function (d) {
            results[d.type] = {
                key:    d.key,
                color:  d.areaColor,
                values: d.values.find(function (val) {
                    return typeof (val.x.getTime) === 'function'
                        && graphX.getTime() === val.x.getTime();
                })
            };
        });

        return results;
    }

    function mousemove() {
        var mousePos   = d3.mouse(document.getElementById("mouse-tracker")),
            rawGraphX  = xScale.invert(mousePos[0]),
            graphX     = roundDate.call(this, rawGraphX),
            results    = fetchResults(graphX);

        this.popOver.show(mousePos[0] + 60, results);

        d3.select("#hover-line")
            .attr("x1", mousePos[0])
            .attr("x2", mousePos[0])
            .style("opacity", 1);
    }

    function generateLine(x, y) {
        return d3.svg.line()
            .interpolate('step-after')
            .x(function (d) { return x(d.x); })
            .y(function (d) { return y(d.y); })
            .defined(function (d) { return d.x; });
    }

    function generateColorArea(x, y) {
        return d3.svg.area()
            .interpolate('step-after')
            .x(function (d) { return x(d.x); })
            .y0(function () { return y(0);   })
            .y1(function (d) { return y(d.y); });
    }

    function generateStackedArea(x, y) {
        return d3.svg.area()
            .interpolate('step-after')
            .x(function (d) {  return x(d.x); })
            .y0(function (d) { return y(d.offset); })
            .y1(function (d) { return y(d.offset + d.y); });
    }

    function setShapes(scope, x, y) {
        chartParts[scope].line = generateLine(x, y);
        chartParts[scope].colorArea = generateColorArea(x, y);
        chartParts[scope].stackedArea = generateStackedArea(x, y);
    }

    function drawChartPart(scope, klass) {
        var part     = scope.selectAll(klass).data(chartData),
            clipName = klass.replace(/\./, '');

        part.enter().append("g")
            .attr("class", klass);

        part.append("path")
            .style("pointer-events", "none")
            .style("stroke", function (d) { return d.color; })
            .style("fill", "none")
            .attr("class", "line")
            .attr("clip-path", "url(#clip-" + clipName + ")")
            .attr("id", function (d) {
                return "line-" + d.type;
            })
            .attr("d", function (d) {
                return setLine.call(this, d, clipName);
            }.bind(this));

        part.append("path")
            .style("pointer-events", "none")
            .style("fill", function (d) {
                return d.areaColor;
            }.bind(this))
            .attr("clip-path", "url(#clip-" + clipName + ")")
            .attr("class", "line-bg")
            .attr("d", function (d) {
                return setArea.call(this, d, clipName);
            }.bind(this));

        part.exit().remove();

        return part;
    }

    function transformData() {
        var data = Transformer.transform(this);

        if (data.length < 1) { return false; }

        if (this.settings.view_as === 'stacked') {
            data = StackTransformer.transform(data);
        }

        return data;
    }

    function redrawPath(key) {
        var issue = this[key.camelize()];

        issue.select("path.line")
            .transition().duration(0)
            .attr("d", function (d) {
                return setLine.call(this, d, key);
            }.bind(this));

        issue.select("path.line-bg")
            .transition().duration(0)
            .attr("d", function (d) {
                return setArea.call(this, d, key);
            }.bind(this));
    }

    D3LoadChart.prototype = $.extend({}, D3BaseChart.prototype, {
        lastRequestedData: null,

        view: function (attr, newAttr) {
            this.settings[attr] = newAttr;

            return this;
        },

        getAxisLabel: function (data) {
            return ChartSettings.forChart(data.type || this.curveType)
                .axisLabel;
        },

        setYscaleDomain: function (mainOnly) {
            var ydomain = d3.extent(all.call(chartData), setExtent.bind(this));

            if (ydomain[0] > 0) { ydomain[0] = 0; }
            if (ydomain[1] < 0) { ydomain[1] = 0; }

            yScale.domain(ydomain).nice();

            if (!mainOnly) {
                yScale2.domain(ydomain).nice();
            }

            svg.select(".y.axis").transition().call(yAxis);

            this.redrawPaths();
        },

        redrawPaths: function () {
            Object.keys(chartParts).forEach(redrawPath.bind(this));

            svg.select("line.zero-line")
                .attr("y1", yScale(0))
                .attr("y2", yScale(0));
        },

        maxYvalue: function (data) {
            var chart, isVisible;

            return d3.max(window.currentTree.availableCharts()
                .map(function (chartType) {
                    chart     = data[chartType];
                    isVisible = ChartSettings.forChart(chartType).visible;

                    return (chart && chart.total && isVisible ? d3.max(chart.total) : 0);
                }));
        },

        getScaling: function (data) {
            var scaling;

            if (/^[a-zA-Z]?W$/.test(this.axisLabel)) {
                scaling = new Quantity(this.maxYvalue(data), this.axisLabel).smartScale();

                this.axisLabel = scaling.unit.name;
            }

            return scaling;
        },

        isRendered: function () {
            return $(this.chartClass).hasClass("rendered");
        },

        render: function (data) {
            var self = this;

            this.axisLabel = this.getAxisLabel(data);

            d3.select(this.chartClass).html('');

            $(this.chartClass).addClass("rendered");

            xScale  = d3.time.scale.utc().range([0, this.width]);
            xScale2 = d3.time.scale.utc().range([0, this.width]);
            yScale  = d3.scale.linear().range([this.height, 0]);
            yScale2 = d3.scale.linear().range([this.height2, 0]);

            xAxis   = d3.svg.axis().scale(xScale).orient("bottom")
                        .tickFormat(customTimeFormat)
                        .ticks(6);

            xAxis2  = d3.svg.axis().scale(xScale2).orient("bottom")
                        .tickFormat(customTimeFormat)
                        .ticks(6);

            yAxis   = d3.svg.axis().scale(yScale).orient("left");

            brush   = d3.svg.brush()
                        .x(xScale2)
                        .on("brush", brushed.bind(this));

            setShapes('issue', xScale, yScale);
            setShapes('preview_issue', xScale2, yScale2);

            this.legendDiv = d3.select(this.chartClass).append("div")
                .attr("class", "legend");

            svg = this.drawBaseSVG();

            // Create invisible rect for mouse tracking
            svg.append("rect")
                .attr("width", this.width)
                .attr("height", this.height)
                .attr("x", 0)
                .attr("y", 0)
                .attr("id", "mouse-tracker")
                .style("fill", "white");

            svg.append("line")
                .attr("class", "zero-line");

            ////for slider part------------------------------------------------
            context = svg.append("g") // Brushing context box container
                .attr("transform", "translate(0, " + (this.height + brushMargin) + ")")
                .attr("class", "context");

            context.append("g")
                .attr("class", "axis x-axis1")
                .attr("transform", "translate(0," + this.height2 + ")");

            defs = svg.append("defs");

            defs.append("clipPath")
                  .attr("id", "clip-issue")
                .append("rect")
                  .attr("width", this.width)
                  .attr("height", this.height);

            defs.append("clipPath")
                  .attr("id", "clip-preview_issue")
                .append("rect")
                  .attr("width", this.width)
                  .attr("height", this.height2);
            //end slider part--------------------------------------------------

            // draw line graph
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + this.height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("x", -10)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text(this.axisLabel);

            // Hover line
            hoverLineGroup = svg.append("g")
                  .attr("class", "hover-line");

            hoverLineGroup
                  .append("line")
                  .attr("id", "hover-line")
                  .attr("x1", 10).attr("x2", 10)
                  .attr("y1", 0).attr("y2", this.height + 10)
                  .style("pointer-events", "none")
                  .style("opacity", 1e-6);

            // Other elements
            this.popOver   = new PopOver(this.chartClass);
            this.popOver.initialize(mousemove.bind(this));

            this.legend = new Legend(this);

            this.dateSelect.initialize(this.currentWeek, function (e) {
                renderWeek.call(self, { target: e.target, brush: brush });
            });

            this.update(data);
        },

        update: function (data) {
            var contextArea;

            this.lastRequestedData = data || this.lastRequestedData;
            this.axisLabel         = this.getAxisLabel(this.lastRequestedData);
            this.scaling           = this.getScaling(this.lastRequestedData);

            chartData = transformData.call(this);

            if (this.chartDataCallback) {
                this.chartDataCallback(chartData);
            }

            if (!chartData) {
                return false;
            }

            xScale.domain(d3.extent(chartData[0].values, function (d) {
                return d.x;
            }));

            xScale2.domain(xScale.domain());
            yScale2.domain(yScale.domain());

            context.select(".x-axis1").call(xAxis2);

            svg.selectAll("path").remove();

            // Update the axisLabel
            svg.select(".y.axis > text").text(this.axisLabel);

            // Zero line ------------------------------------------------------
            svg.select("line.zero-line")
                .attr("x1", 0)
                .attr("x2", this.width)
                .attr("y1", yScale(0))
                .attr("y2", yScale(0));

            //for slider part--------------------------------------------------
            contextArea = d3.svg.area()
                .interpolate("step-after")
                .x(function (d) { return xScale2(d.x); })
                .y0(this.height2)
                .y1(0);

            context.append("path")
                .attr("class", "area")
                .attr("d", contextArea(chartData[0].values))
                .attr("fill", "#F1F1F2");

            //end slider part--------------------------------------------------
            this.previewIssue = drawChartPart.call(this, context, ".preview_issue");
            this.issue        = drawChartPart.call(this, svg, ".issue");

            context.append("g")
                .attr("class", "x brush")
                .call(brush)
                .selectAll("rect")
                .attr("height", this.height2)
                .attr("fill", "#060708");

            this.dateSelect.enable();
            this.setYscaleDomain(false);

            this.legend.draw(chartData);
        }
    });

    function D3LoadChart(chartClass, curveType, settings) {
        D3BaseChart.call(this, chartClass);

        this.curveType   = curveType || 'default';
        this.settings    = $.extend(DefaultSettings, settings);
        this.dateSelect  = new WeekSelect();
        this.width       = 500;
        this.height      = 410;
        this.height2     = 50;
        this.margin      = { top: 20, right: 0, bottom: 70, left: 75 };
        this.currentWeek = 1;
    }

    return D3LoadChart;
}());
<commit_msg>Respect brush extent when changing chart view options<commit_after>/*globals ChartSettings,D3BaseChart,DefaultSettings,Legend,LoadChartHelper,
PopOver,Quantity,StackTransformer,StrategyHelper,Transformer,WeekSelect*/

var D3LoadChart = (function () {
    'use strict';

    var xScale,  // Scales
        xScale2,
        yScale,
        yScale2,
        xAxis,   // Axis
        xAxis2,
        yAxis,
        context,
        svg,
        defs,
        brush,
        chartData,
        hoverLineGroup,

        brushMargin     = 40,
        weeksInYear     = (365 / 7.0),

        // This is assuming every LES has a length of 35040. Shorter LES's will
        // break because of this line.
        weekResolution   = 672,
        scaleCorrection  = 1.05,
        customTimeFormat = d3.time.format.utc.multi([
            ["%H:%M", function (d) { return d.getUTCMinutes(); }],
            ["%H:%M", function (d) { return d.getUTCHours(); }],
            ["%b %d", function (d) { return d.getUTCDate() !== 1; }],
            ["%d %b", function () { return true; }]
        ]),
        chartParts = {
            preview_issue: {
                line: undefined,
                colorArea: undefined,
                stackedArea: undefined
            },
            issue: {
                line: undefined,
                colorArea: undefined,
                stackedArea: undefined
            }
        };

    function setLesOptions() {
        var lesOptions;

        if (this.currentWeek !== 0) {
            lesOptions = {
                resolution:  'high',
                range_start: weekResolution * (this.currentWeek - 1),
                range_end:   weekResolution * this.currentWeek
            };
        } else {
            lesOptions = {
                resolution: 'low',
                range_start: 0,
                range_end:   weekResolution * weeksInYear
            };
        }

        $.extend(this.settings, lesOptions);
    }

    function renderWeek(scope) {
        var value = parseInt($(scope.target).val(), 10);

        this.currentWeek = value;

        scope.brush.clear();

        this.dateSelect.disable();

        if (this.settings.dateCallback) {
            this.settings.dateCallback(value);
        } else {
            setLesOptions.call(this);
            window.currentTree.update();
        }
    }

    function all() {
        var chained = [];
        this.forEach(function (d) {
            if (d.visible) {
                chained = chained.concat(d.values);
            }
        });
        return chained;
    }

    function setExtent(d) {
        var extent = brush.extent();

        if (brush.empty() || (extent[0] <= d.x && extent[1] >= d.x)) {
            if (this.settings.view_as === 'stacked') {
                return (d.y + d.offset) * scaleCorrection;
            } else {
                return d.y * scaleCorrection;
            }
        }
    }

    function setLine(d, scope) {
        if (d.visible && !(this.settings.view_as === 'stacked')) {
            return chartParts[scope].line(d.values);
        } else {
            return null;
        }
    }

    function setArea(d, scope) {
        if (d.visible && d.area) {
            if (this.settings.view_as === 'stacked') {
                return chartParts[scope].stackedArea(d.values);
            } else {
                return chartParts[scope].colorArea(d.values);
            }
        } else {
            return null;
        }
    }

    //for brusher of the slider bar at the bottom
    function brushed() {
        xScale.domain(brush.empty() ? xScale2.domain() : brush.extent());

        svg.select(".x.axis")
              .transition().duration(0)
              .call(xAxis);

        this.setYscaleDomain(true);
    }

    function roundDate(date) {
        var roundTo  = this.settings.resolution === 'high' ? 15 : 60 * 24,
            rounding = 1000 * 60 * roundTo;

        return new Date(Math.floor(date.getTime() / rounding) * rounding);
    }

    function fetchResults(graphX) {
        var results = {};

        chartData.forEach(function (d) {
            results[d.type] = {
                key:    d.key,
                color:  d.areaColor,
                values: d.values.find(function (val) {
                    return typeof (val.x.getTime) === 'function'
                        && graphX.getTime() === val.x.getTime();
                })
            };
        });

        return results;
    }

    function mousemove() {
        var mousePos   = d3.mouse(document.getElementById("mouse-tracker")),
            rawGraphX  = xScale.invert(mousePos[0]),
            graphX     = roundDate.call(this, rawGraphX),
            results    = fetchResults(graphX);

        this.popOver.show(mousePos[0] + 60, results);

        d3.select("#hover-line")
            .attr("x1", mousePos[0])
            .attr("x2", mousePos[0])
            .style("opacity", 1);
    }

    function generateLine(x, y) {
        return d3.svg.line()
            .interpolate('step-after')
            .x(function (d) { return x(d.x); })
            .y(function (d) { return y(d.y); })
            .defined(function (d) { return d.x; });
    }

    function generateColorArea(x, y) {
        return d3.svg.area()
            .interpolate('step-after')
            .x(function (d) { return x(d.x); })
            .y0(function () { return y(0);   })
            .y1(function (d) { return y(d.y); });
    }

    function generateStackedArea(x, y) {
        return d3.svg.area()
            .interpolate('step-after')
            .x(function (d) {  return x(d.x); })
            .y0(function (d) { return y(d.offset); })
            .y1(function (d) { return y(d.offset + d.y); });
    }

    function setShapes(scope, x, y) {
        chartParts[scope].line = generateLine(x, y);
        chartParts[scope].colorArea = generateColorArea(x, y);
        chartParts[scope].stackedArea = generateStackedArea(x, y);
    }

    function drawChartPart(scope, klass) {
        var part     = scope.selectAll(klass).data(chartData),
            clipName = klass.replace(/\./, '');

        part.enter().append("g")
            .attr("class", klass);

        part.append("path")
            .style("pointer-events", "none")
            .style("stroke", function (d) { return d.color; })
            .style("fill", "none")
            .attr("class", "line")
            .attr("clip-path", "url(#clip-" + clipName + ")")
            .attr("id", function (d) {
                return "line-" + d.type;
            })
            .attr("d", function (d) {
                return setLine.call(this, d, clipName);
            }.bind(this));

        part.append("path")
            .style("pointer-events", "none")
            .style("fill", function (d) {
                return d.areaColor;
            }.bind(this))
            .attr("clip-path", "url(#clip-" + clipName + ")")
            .attr("class", "line-bg")
            .attr("d", function (d) {
                return setArea.call(this, d, clipName);
            }.bind(this));

        part.exit().remove();

        return part;
    }

    function transformData() {
        var data = Transformer.transform(this);

        if (data.length < 1) { return false; }

        if (this.settings.view_as === 'stacked') {
            data = StackTransformer.transform(data);
        }

        return data;
    }

    function redrawPath(key) {
        var issue = this[key.camelize()];

        issue.select("path.line")
            .transition().duration(0)
            .attr("d", function (d) {
                return setLine.call(this, d, key);
            }.bind(this));

        issue.select("path.line-bg")
            .transition().duration(0)
            .attr("d", function (d) {
                return setArea.call(this, d, key);
            }.bind(this));
    }

    D3LoadChart.prototype = $.extend({}, D3BaseChart.prototype, {
        lastRequestedData: null,

        view: function (attr, newAttr) {
            this.settings[attr] = newAttr;

            return this;
        },

        getAxisLabel: function (data) {
            return ChartSettings.forChart(data.type || this.curveType)
                .axisLabel;
        },

        setYscaleDomain: function (mainOnly) {
            var ydomain = d3.extent(all.call(chartData), setExtent.bind(this));

            if (ydomain[0] > 0) { ydomain[0] = 0; }
            if (ydomain[1] < 0) { ydomain[1] = 0; }

            yScale.domain(ydomain).nice();

            if (!mainOnly) {
                yScale2.domain(ydomain).nice();
            }

            svg.select(".y.axis").transition().call(yAxis);

            this.redrawPaths();
        },

        redrawPaths: function () {
            Object.keys(chartParts).forEach(redrawPath.bind(this));

            svg.select("line.zero-line")
                .attr("y1", yScale(0))
                .attr("y2", yScale(0));
        },

        maxYvalue: function (data) {
            var chart, isVisible;

            return d3.max(window.currentTree.availableCharts()
                .map(function (chartType) {
                    chart     = data[chartType];
                    isVisible = ChartSettings.forChart(chartType).visible;

                    return (chart && chart.total && isVisible ? d3.max(chart.total) : 0);
                }));
        },

        getScaling: function (data) {
            var scaling;

            if (/^[a-zA-Z]?W$/.test(this.axisLabel)) {
                scaling = new Quantity(this.maxYvalue(data), this.axisLabel).smartScale();

                this.axisLabel = scaling.unit.name;
            }

            return scaling;
        },

        isRendered: function () {
            return $(this.chartClass).hasClass("rendered");
        },

        render: function (data) {
            var self = this;

            this.axisLabel = this.getAxisLabel(data);

            d3.select(this.chartClass).html('');

            $(this.chartClass).addClass("rendered");

            xScale  = d3.time.scale.utc().range([0, this.width]);
            xScale2 = d3.time.scale.utc().range([0, this.width]);
            yScale  = d3.scale.linear().range([this.height, 0]);
            yScale2 = d3.scale.linear().range([this.height2, 0]);

            xAxis   = d3.svg.axis().scale(xScale).orient("bottom")
                        .tickFormat(customTimeFormat)
                        .ticks(6);

            xAxis2  = d3.svg.axis().scale(xScale2).orient("bottom")
                        .tickFormat(customTimeFormat)
                        .ticks(6);

            yAxis   = d3.svg.axis().scale(yScale).orient("left");

            brush   = d3.svg.brush()
                        .x(xScale2)
                        .on("brush", brushed.bind(this));

            setShapes('issue', xScale, yScale);
            setShapes('preview_issue', xScale2, yScale2);

            this.legendDiv = d3.select(this.chartClass).append("div")
                .attr("class", "legend");

            svg = this.drawBaseSVG();

            // Create invisible rect for mouse tracking
            svg.append("rect")
                .attr("width", this.width)
                .attr("height", this.height)
                .attr("x", 0)
                .attr("y", 0)
                .attr("id", "mouse-tracker")
                .style("fill", "white");

            svg.append("line")
                .attr("class", "zero-line");

            ////for slider part------------------------------------------------
            context = svg.append("g") // Brushing context box container
                .attr("transform", "translate(0, " + (this.height + brushMargin) + ")")
                .attr("class", "context");

            context.append("g")
                .attr("class", "axis x-axis1")
                .attr("transform", "translate(0," + this.height2 + ")");

            defs = svg.append("defs");

            defs.append("clipPath")
                  .attr("id", "clip-issue")
                .append("rect")
                  .attr("width", this.width)
                  .attr("height", this.height);

            defs.append("clipPath")
                  .attr("id", "clip-preview_issue")
                .append("rect")
                  .attr("width", this.width)
                  .attr("height", this.height2);
            //end slider part--------------------------------------------------

            // draw line graph
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + this.height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("x", -10)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text(this.axisLabel);

            // Hover line
            hoverLineGroup = svg.append("g")
                  .attr("class", "hover-line");

            hoverLineGroup
                  .append("line")
                  .attr("id", "hover-line")
                  .attr("x1", 10).attr("x2", 10)
                  .attr("y1", 0).attr("y2", this.height + 10)
                  .style("pointer-events", "none")
                  .style("opacity", 1e-6);

            // Other elements
            this.popOver   = new PopOver(this.chartClass);
            this.popOver.initialize(mousemove.bind(this));

            this.legend = new Legend(this);

            this.dateSelect.initialize(this.currentWeek, function (e) {
                renderWeek.call(self, { target: e.target, brush: brush });
            });

            this.update(data);
        },

        update: function (data) {
            var contextArea;

            this.lastRequestedData = data || this.lastRequestedData;
            this.axisLabel         = this.getAxisLabel(this.lastRequestedData);
            this.scaling           = this.getScaling(this.lastRequestedData);

            chartData = transformData.call(this);

            if (this.chartDataCallback) {
                this.chartDataCallback(chartData);
            }

            if (!chartData) {
                return false;
            }

            xScale.domain(d3.extent(chartData[0].values, function (d) {
                return d.x;
            }));

            xScale2.domain(xScale.domain());
            yScale2.domain(yScale.domain());

            context.select(".x-axis1").call(xAxis2);

            svg.selectAll("path").remove();

            // Update the axisLabel
            svg.select(".y.axis > text").text(this.axisLabel);

            // Zero line ------------------------------------------------------
            svg.select("line.zero-line")
                .attr("x1", 0)
                .attr("x2", this.width)
                .attr("y1", yScale(0))
                .attr("y2", yScale(0));

            //for slider part--------------------------------------------------
            contextArea = d3.svg.area()
                .interpolate("step-after")
                .x(function (d) { return xScale2(d.x); })
                .y0(this.height2)
                .y1(0);

            context.append("path")
                .attr("class", "area")
                .attr("d", contextArea(chartData[0].values))
                .attr("fill", "#F1F1F2");

            //end slider part--------------------------------------------------
            this.previewIssue = drawChartPart.call(this, context, ".preview_issue");
            this.issue        = drawChartPart.call(this, svg, ".issue");

            context.append("g")
                .attr("class", "x brush")
                .call(brush)
                .selectAll("rect")
                .attr("height", this.height2)
                .attr("fill", "#060708");

            this.dateSelect.enable();
            this.setYscaleDomain(false);

            brushed.call(this);

            this.legend.draw(chartData);
        }
    });

    function D3LoadChart(chartClass, curveType, settings) {
        D3BaseChart.call(this, chartClass);

        this.curveType   = curveType || 'default';
        this.settings    = $.extend(DefaultSettings, settings);
        this.dateSelect  = new WeekSelect();
        this.width       = 500;
        this.height      = 410;
        this.height2     = 50;
        this.margin      = { top: 20, right: 0, bottom: 70, left: 75 };
        this.currentWeek = 1;
    }

    return D3LoadChart;
}());
<|endoftext|>


<commit_before>/**
 *  @ngdoc overview
 *  @name multiSelectList
 *  @scope
 *  @description Does some stuff
 *
 *  @ngdoc directive
 *  @name multiSelectList.directive:multiSelectList
 *  @description
 *      The `multiSelectList` directive works in conjunction with the
 *      `selectListItem` and (optionally) the `selectAll` directives to
 *      render checkboxes with list items and tracking the selected state
 *      of each item. The `selectListItem` directive renders a checkbox,
 *      and the `multiSelectList` directive tracks the selected state
 *      of list items. The `selectAll` directive renders a checkbox that
 *      will select/deselect all items in the list.
 *
 *
 *      This directive exposes a special object on its local scope called
 *      `selection` that is used to access the current selection state.
 *      The following properties on `selection` are available:
 *
 *      | Property          | Type            | Details                                                      |
 *      |-------------------|-----------------|-------------------------------------------------------------|
 *      | `selectedItems`   | {@type array}   | The items that are currently selected                        |
 *      | `deselectedItem`  | {@type array}   | The items that are currently _not_ selected                  |
 *      | `isExtended`      | {@type boolean} | Indicates that the user has requested an extended selection |
 *      | `length`          | {@type number}  | The length of the selected items array                      |
 *
 *      Use the `multi-select-list` directive to indicate that you want
 *      to allow users to select items in a list. To display a checkbox
 *      next to each item, use the {@link multiSelectList.directive:selectListItem `select-list-item`} directive.
 *
 *      # Rendering a basic multi-select list
 *
 *      @example
 *
 *      This example creates a list of names and then
 *      uses `multiSelectList` to make the names
 *      selectable:
 *
       <example module="multiSelectList">
           <file name="index.html">

                       <select-list-item item="item"></select-list-item>
                       {{item.name}}

           </file>

      </example>
 *
*/
import controller from './multi-select-list.controller';

export default
[   function() {
    return {
            restrict: 'A',
            scope: {
            },
            controller: controller
        };
    }];
<commit_msg>Add example for tracking button state with multi-select-list<commit_after>/**
 *  @ngdoc overview
 *  @name multiSelectList
 *  @scope
 *  @description Does some stuff
 *
 *  @ngdoc directive
 *  @name multiSelectList.directive:multiSelectList
 *  @description
 *      The `multiSelectList` directive works in conjunction with the
 *      `selectListItem` and (optionally) the `selectAll` directives to
 *      render checkboxes with list items and tracking the selected state
 *      of each item. The `selectListItem` directive renders a checkbox,
 *      and the `multiSelectList` directive tracks the selected state
 *      of list items. The `selectAll` directive renders a checkbox that
 *      will select/deselect all items in the list.
 *
 *
 *      This directive exposes a special object on its local scope called
 *      `selection` that is used to access the current selection state.
 *      The following properties on `selection` are available:
 *
 *      | Property          | Type            | Details                                                      |
 *      |-------------------|-----------------|-------------------------------------------------------------|
 *      | `selectedItems`   | {@type array}   | The items that are currently selected                        |
 *      | `deselectedItem`  | {@type array}   | The items that are currently _not_ selected                  |
 *      | `isExtended`      | {@type boolean} | Indicates that the user has requested an extended selection |
 *      | `length`          | {@type number}  | The length of the selected items array                      |
 *
 *      Use the `multi-select-list` directive to indicate that you want
 *      to allow users to select items in a list. To display a checkbox
 *      next to each item, use the {@link multiSelectList.directive:selectListItem `select-list-item`} directive.
 *
 *      # Rendering a basic multi-select list
 *
 *      @example
 *
 *      This example creates a list of names and then
 *      uses `multiSelectList` to make the names
 *      selectable:
 *
       <example module="multiSelectList">
           <file name="index.html">

                       <select-list-item item="item"></select-list-item>
                       {{item.name}}

           </file>

      </example>

    # Making other elements respond to the state of the selction

    In this example, we'll see how to make a button that enables/disables
    itself based on some property of the selection.

    <example module="stateTrackingExample">
       <file name="controller.js">
            angular.module('stateTrackingExample', ['multiSelectList'])
                .controller('namesController', ['$scope', function($scope) {
                        $scope.names =
                          [ { name: 'John'
                            },
                            { name: 'Jared'
                            },
                            { name: 'Joe'
                            },
                            { name: 'James'
                            },
                            { name: 'Matt'
                            },
                            { name: 'Luke'
                            },
                            { name: 'Chris'
                            }
                          ];

                        // Initial logic for buttons
                        $scope.noSelections = true;
                        $scope.atLeastOneSelection = false;
                        $scope.exactlyTwoSelections = false;

                        var cleanup = $scope.$on('multiSelectList.selectionChanged', function(e, selection) {
                            // Recalculate logic for buttons whenever selections change
                            $scope.noSelections = selection.length == 0;
                            $scope.atLeastOneSelection = selection.length >= 1;
                            $scope.exactlyTwoSelections = selection.length == 2;
                        });
                }]);
       </file>
       <file name="index.html">

               <button ng-if="noSelections">
                    Create
               </button>
               <button ng-if="atLeastOneSelection">
                    Delete
               </button>
               <button ng-if="exactlyTwoSelections">
                    Compare
               </button>

                   <select-list-item item="item"></select-list-item>
                   {{item.name}}

       </file>

    </example>

 *
*/
import controller from './multi-select-list.controller';

export default
[   function() {
    return {
            restrict: 'A',
            scope: {
            },
            controller: controller
        };
    }];
<|endoftext|>


<commit_before>(function () {
    cola(function (model) {

        var service = {
            load: "./service/user/load",
            add: "./service/user/add",
            remove: "./service/user/remove/:username",
            modify: "./service/user/modify",
            hasUser: "./service/user/exist/:username",
            loadRoles: "./service/role/load",
            addRole: "./service/authority/add",
            removeRole: "./service/authority/remove/:id"
        };

        window.closeModifyUserModal = function() {
            $(".edit-modal").dimmer("hide");
        };

        $.fn.form.settings.rules.userIsExist = function(username) {
            var result = true;
            if (username) {
                $.ajax({
                    method: "GET",
                    async: false,
                    url: service.hasUser.replace(":username", username)
                }).done(function(data) {
                    result = data;
                });
            }

            return result;
        };

        var options = {
            on: "blur",
            fields: {
                nickname: {
                    identifier: "nickname",
                    rules: [
                        {
                            type: "empty",
                            prompt: "请输入昵称"
                        }
                    ]
                },
                username: {
                    identifier: 'username',
                    rules: [
                        {
                            type: "empty",
                            prompt: "请输入用户名"
                        },
                        {
                            type: "userIsExist",
                            prompt: '用户名已存在'
                        }
                    ]
                }
            }
        };
        if (passwordProp) {
            options.fields.password = {
                identifier: 'password',
                rules: [
                    {
                        type: "empty",
                        prompt: "请输入密码"
                    }
                ]
            };
        }
        $("#addUserForm").form(options);

        $("#editUserForm").form({
            on: "blur",
            fields: {
                nickname: {
                    identifier: "nickname",
                    rules: [
                        {
                            type: "empty",
                            prompt: "请输入昵称"
                        }
                    ]
                }
            }
        });

        model.describe("users", {
            provider: {
                url: service.load,
                pageSize: 18,
                parameter: {
                    searchKey: "{{searchKey}}"
                },
                success: function(self, arg) {
                    var ids = [];
                    for(var i = 0; i< arg.result.length; i++) {
                        ids.push("#user_" + arg.result[i][usernameProp]);
                    }
                    $(ids).transition({
                        animation : 'pulse',
                        reverse  : "auto",
                        interval  : 50,
                        displayType: "flex",
                        onComplete: function() {
                            if (arg.result.length !== self.get("pageSize")) {
                                return;
                            }
                            $("#userCards").visibility({
                                once: true,
                                observeChanges: true,
                                onBottomVisible: function() {
                                    model.get("users").nextPage()
                                }
                            });

                            $("#userTable").visibility({
                                once: true,
                                observeChanges: true,
                                onBottomVisible: function() {
                                    model.get("users").nextPage()
                                }
                            });
                        }
                    });

                }
            }
        });

        model.describe("roles", {
            provider: {
                url: service.loadRoles,
                pageSize: 30,
                parameter: {
                    searchKey: "{{searchRoleKey}}"
                },
                success: function(self, arg) {
                    model.action("initSelectedRole")(function() {
                        if (arg.result.length !== self.get("pageSize")) {
                            return;
                        }
                        $("#userCards").visibility({
                            once: true,
                            observeChanges: true,
                            onBottomVisible: function () {
                                model.get("roles").nextPage()
                            }
                        });
                    });
                }
            }
        });

        model.set("addUser", {
            accountNonExpired: true,
            accountNonLocked: true,
            credentialsNonExpired: true,
            enabled: true
        });

        model.set("showStyleIcon", $.cookie('showStyleIcon'));

        model.action({
            toggleStyle: function() {
                var icon;
                icon = model.get("showStyleIcon");
                if (!icon) {
                    icon = "grid layout";
                }
                if (icon === "grid layout") {
                    model.set({
                        showStyleIcon: "list layout",
                        showStyleTip: "切换为表格"
                    });
                    $("#userTable").hide();
                    $("#userCards").show();
                    $.cookie('showStyleIcon', "grid layout", { expires: 10000000 });
                } else {
                    model.set({
                        showStyleIcon: "grid layout",
                        showStyleTip: "切换为卡片"
                    });
                    $("#userCards").hide();
                    $("#userTable").show();
                    $.cookie('showStyleIcon', "list layout", { expires: 10000000 });
                }
            },
            search: function () {
                return model.flush("users");
            },
            searchRole: function () {
                return model.flush("roles");
            },
            showAddModal: function() {
                $("#addModal").modal('setting', 'closable', false).modal("show");
            },
            showEditModal: function(entity) {
                if (modifyUserUrl) {
                    $(".edit-modal iframe").attr("src", modifyUserUrl + "?username=" + entity.get(usernameProp));
                    $(".edit-modal").dimmer("show");
                } else {
                    model.set("editUser", entity.toJSON());
                    model.get("users").setCurrent(entity);
                    $("#editModal")
                        .modal('setting', 'closable', false)
                        .modal("show");
                }

                return false;

            },
            edit: function () {
                var options, entity, data;
                entity = model.get("editUser");
                $("#editUserForm").form("validate form");
                if (!$("#editUserForm").form("is valid")) {
                    return;
                }
                data = entity.toJSON();
                options = {
                    contentType: "application/json",
                    data: JSON.stringify(data),
                    type: "PUT",
                    url: service.modify
                };
                $.ajax(options).done(function () {
                    model.get("users").current.set(data).setState(cola.Entity.STATE_NONE);
                });
                $("#editModal").modal("hide");
            },
            add: function () {
                var options, entity, data;
                entity = model.get("addUser");
                $("#addUserForm").form("validate form");
                if (!$("#addUserForm").form("is valid")) {
                    return;
                }
                data = entity.toJSON();
                options = {
                    contentType: "application/json",
                    data: JSON.stringify(data),
                    type: "POST",
                    url: service.add
                };
                $.ajax(options).done(function () {
                    model.set("addUser", {});
                    model.get("users").insert(data, "begin").setState(cola.Entity.STATE_NONE);
                    $("#addModal").modal("hide");
                    $("#user_" + data[usernameProp]).transition({
                        animation : 'jiggle',
                        duration  : 800,
                        interval  : 50,
                        displayType: "flex"
                    });
                });
            },
            confirmRemove: function(entity) {
                model.get("users").setCurrent(entity);
                $("#removeConfirmModal").modal("show");
                return false;
            },
            remove: function () {
                var entity = model.get("users").current;
                return $.ajax({
                    async: true,
                    type: "DELETE",
                    url: service.remove.replace(":username", entity.get(usernameProp))
                }).done(function () {
                    $("#user_" + entity.get(usernameProp)).transition({
                        animation:'scale',
                        onComplete: function() {
                            entity.remove(true);
                        }
                    });
                });
            },
            showRoleModal: function(user) {
                var roles = user.get("roles");
                if (!roles) {
                    user.set("roles", []);
                    roles = user.get("roles");
                }
                model.set("selectedRoles", roles);
                model.set("currentUser", user);

                $("#roleModal")
                    .modal('setting', 'closable', false)
                    .modal("show");
                model.action("initSelectedRole")();
                return false;
            },
            initSelectedRole: function (callback) {
                var user, roles, ids;
                user = model.get("currentUser");
                if (user) {
                    roles = user.get("roles");
                    ids = [];
                    $("#roleCards .ui.card.added")
                        .removeClass("added")
                        .find(".ui.button")
                        .removeClass("disabled")
                        .html(" 添加角色 ");
                    if (!roles) {
                        return;
                    }
                    roles.each(function(r) {
                        ids.push("#" + r.get("id"));
                        $("#" + r.get("id"))
                            .addClass("added")
                            .find(".ui.button")
                            .addClass("disabled")
                            .html(" 已添加 ");
                    });
                    $(ids).transition({
                        animation : 'jiggle',
                        duration  : 800,
                        interval  : 0,
                        displayType: "flex",
                        onComplete: function() {
                           if (callback) {
                               callback();
                           }
                        }
                    });
                }

            },
            clickUserCard: function (user) {
                $("#user_" + user.get(usernameProp)).transition({
                    animation : 'jiggle',
                    duration  : 800,
                    interval  : 200,
                    displayType: "flex"
                });
            },
            clickRoleCard: function (role) {
                $("#selected_" + role.get("id")).transition({
                    animation : 'jiggle',
                    duration  : 800,
                    interval  : 200,
                    displayType: "flex"
                });
            },
            addRole: function(role) {
                var user = model.get("currentUser");
                $.ajax({
                    contentType: "application/json",
                    type: "POST",
                    data: JSON.stringify({
                        actorId: user.get(usernameProp),
                        roleId: role.get("id")
                    }),
                    url: service.addRole
                }).done(function(id) {
                    var data = role.toJSON();
                    data.rgaId = id;
                    model.get("selectedRoles").insert(data);
                    model.set("selectedRoles", model.get("selectedRoles"));
                    role.set("added", true);
                    $("#" + role.get("id"))
                        .addClass("added")
                        .find(".ui.button")
                        .addClass("disabled")
                        .html(" 已添加 ");

                    $("#selected_" + role.get("id")).transition({
                        animation : 'jiggle',
                        duration  : 800,
                        interval  : 200,
                        displayType: "flex"
                    });

                });
            },
            removeRole: function(role) {
                $.ajax({
                    type: "DELETE",
                    url: service.removeRole.replace(":id", role.get("rgaId"))
                }).done(function() {
                    $("#selected_" + role.get("id")).transition({
                        animation:'scale',
                        onComplete: function() {
                            role.remove();
                            $("#" + role.get("id"))
                                .removeClass("added")
                                .find(".ui.button")
                                .removeClass("disabled")
                                .html(" 添加角色 ");
                        }
                    });

                });
            }
        });

        model.action("toggleStyle")();
    });

}).call(this);
<commit_msg>修复第二次添加默认值不正确BUG<commit_after>(function () {
    cola(function (model) {

        var service = {
            load: "./service/user/load",
            add: "./service/user/add",
            remove: "./service/user/remove/:username",
            modify: "./service/user/modify",
            hasUser: "./service/user/exist/:username",
            loadRoles: "./service/role/load",
            addRole: "./service/authority/add",
            removeRole: "./service/authority/remove/:id"
        };

        window.closeModifyUserModal = function() {
            $(".edit-modal").dimmer("hide");
        };

        $.fn.form.settings.rules.userIsExist = function(username) {
            var result = true;
            if (username) {
                $.ajax({
                    method: "GET",
                    async: false,
                    url: service.hasUser.replace(":username", username)
                }).done(function(data) {
                    result = data;
                });
            }

            return result;
        };

        var options = {
            on: "blur",
            fields: {
                nickname: {
                    identifier: "nickname",
                    rules: [
                        {
                            type: "empty",
                            prompt: "请输入昵称"
                        }
                    ]
                },
                username: {
                    identifier: 'username',
                    rules: [
                        {
                            type: "empty",
                            prompt: "请输入用户名"
                        },
                        {
                            type: "userIsExist",
                            prompt: '用户名已存在'
                        }
                    ]
                }
            }
        };
        if (passwordProp) {
            options.fields.password = {
                identifier: 'password',
                rules: [
                    {
                        type: "empty",
                        prompt: "请输入密码"
                    }
                ]
            };
        }
        $("#addUserForm").form(options);

        $("#editUserForm").form({
            on: "blur",
            fields: {
                nickname: {
                    identifier: "nickname",
                    rules: [
                        {
                            type: "empty",
                            prompt: "请输入昵称"
                        }
                    ]
                }
            }
        });

        model.describe("users", {
            provider: {
                url: service.load,
                pageSize: 18,
                parameter: {
                    searchKey: "{{searchKey}}"
                },
                success: function(self, arg) {
                    var ids = [];
                    for(var i = 0; i< arg.result.length; i++) {
                        ids.push("#user_" + arg.result[i][usernameProp]);
                    }
                    $(ids).transition({
                        animation : 'pulse',
                        reverse  : "auto",
                        interval  : 50,
                        displayType: "flex",
                        onComplete: function() {
                            if (arg.result.length !== self.get("pageSize")) {
                                return;
                            }
                            $("#userCards").visibility({
                                once: true,
                                observeChanges: true,
                                onBottomVisible: function() {
                                    model.get("users").nextPage()
                                }
                            });

                            $("#userTable").visibility({
                                once: true,
                                observeChanges: true,
                                onBottomVisible: function() {
                                    model.get("users").nextPage()
                                }
                            });
                        }
                    });

                }
            }
        });

        model.describe("roles", {
            provider: {
                url: service.loadRoles,
                pageSize: 30,
                parameter: {
                    searchKey: "{{searchRoleKey}}"
                },
                success: function(self, arg) {
                    model.action("initSelectedRole")(function() {
                        if (arg.result.length !== self.get("pageSize")) {
                            return;
                        }
                        $("#userCards").visibility({
                            once: true,
                            observeChanges: true,
                            onBottomVisible: function () {
                                model.get("roles").nextPage()
                            }
                        });
                    });
                }
            }
        });

        model.set("addUser", {
            accountNonExpired: true,
            accountNonLocked: true,
            credentialsNonExpired: true,
            enabled: true
        });

        model.set("showStyleIcon", $.cookie('showStyleIcon'));

        model.action({
            toggleStyle: function() {
                var icon;
                icon = model.get("showStyleIcon");
                if (!icon) {
                    icon = "grid layout";
                }
                if (icon === "grid layout") {
                    model.set({
                        showStyleIcon: "list layout",
                        showStyleTip: "切换为表格"
                    });
                    $("#userTable").hide();
                    $("#userCards").show();
                    $.cookie('showStyleIcon', "grid layout", { expires: 10000000 });
                } else {
                    model.set({
                        showStyleIcon: "grid layout",
                        showStyleTip: "切换为卡片"
                    });
                    $("#userCards").hide();
                    $("#userTable").show();
                    $.cookie('showStyleIcon', "list layout", { expires: 10000000 });
                }
            },
            search: function () {
                return model.flush("users");
            },
            searchRole: function () {
                return model.flush("roles");
            },
            showAddModal: function() {
                $("#addModal").modal('setting', 'closable', false).modal("show");
            },
            showEditModal: function(entity) {
                if (modifyUserUrl) {
                    $(".edit-modal iframe").attr("src", modifyUserUrl + "?username=" + entity.get(usernameProp));
                    $(".edit-modal").dimmer("show");
                } else {
                    model.set("editUser", entity.toJSON());
                    model.get("users").setCurrent(entity);
                    $("#editModal")
                        .modal('setting', 'closable', false)
                        .modal("show");
                }

                return false;

            },
            edit: function () {
                var options, entity, data;
                entity = model.get("editUser");
                $("#editUserForm").form("validate form");
                if (!$("#editUserForm").form("is valid")) {
                    return;
                }
                data = entity.toJSON();
                options = {
                    contentType: "application/json",
                    data: JSON.stringify(data),
                    type: "PUT",
                    url: service.modify
                };
                $.ajax(options).done(function () {
                    model.get("users").current.set(data).setState(cola.Entity.STATE_NONE);
                });
                $("#editModal").modal("hide");
            },
            add: function () {
                var options, entity, data;
                entity = model.get("addUser");
                $("#addUserForm").form("validate form");
                if (!$("#addUserForm").form("is valid")) {
                    return;
                }
                data = entity.toJSON();
                options = {
                    contentType: "application/json",
                    data: JSON.stringify(data),
                    type: "POST",
                    url: service.add
                };
                $.ajax(options).done(function () {
                    model.set("addUser", {
                        accountNonExpired: true,
                        accountNonLocked: true,
                        credentialsNonExpired: true,
                        enabled: true
                    });
                    model.get("users").insert(data, "begin").setState(cola.Entity.STATE_NONE);
                    $("#addModal").modal("hide");
                    $("#user_" + data[usernameProp]).transition({
                        animation : 'jiggle',
                        duration  : 800,
                        interval  : 50,
                        displayType: "flex"
                    });
                });
            },
            confirmRemove: function(entity) {
                model.get("users").setCurrent(entity);
                $("#removeConfirmModal").modal("show");
                return false;
            },
            remove: function () {
                var entity = model.get("users").current;
                return $.ajax({
                    async: true,
                    type: "DELETE",
                    url: service.remove.replace(":username", entity.get(usernameProp))
                }).done(function () {
                    $("#user_" + entity.get(usernameProp)).transition({
                        animation:'scale',
                        onComplete: function() {
                            entity.remove(true);
                        }
                    });
                });
            },
            showRoleModal: function(user) {
                var roles = user.get("roles");
                if (!roles) {
                    user.set("roles", []);
                    roles = user.get("roles");
                }
                model.set("selectedRoles", roles);
                model.set("currentUser", user);

                $("#roleModal")
                    .modal('setting', 'closable', false)
                    .modal("show");
                model.action("initSelectedRole")();
                return false;
            },
            initSelectedRole: function (callback) {
                var user, roles, ids;
                user = model.get("currentUser");
                if (user) {
                    roles = user.get("roles");
                    ids = [];
                    $("#roleCards .ui.card.added")
                        .removeClass("added")
                        .find(".ui.button")
                        .removeClass("disabled")
                        .html(" 添加角色 ");
                    if (!roles) {
                        return;
                    }
                    roles.each(function(r) {
                        ids.push("#" + r.get("id"));
                        $("#" + r.get("id"))
                            .addClass("added")
                            .find(".ui.button")
                            .addClass("disabled")
                            .html(" 已添加 ");
                    });
                    $(ids).transition({
                        animation : 'jiggle',
                        duration  : 800,
                        interval  : 0,
                        displayType: "flex",
                        onComplete: function() {
                           if (callback) {
                               callback();
                           }
                        }
                    });
                }

            },
            clickUserCard: function (user) {
                $("#user_" + user.get(usernameProp)).transition({
                    animation : 'jiggle',
                    duration  : 800,
                    interval  : 200,
                    displayType: "flex"
                });
            },
            clickRoleCard: function (role) {
                $("#selected_" + role.get("id")).transition({
                    animation : 'jiggle',
                    duration  : 800,
                    interval  : 200,
                    displayType: "flex"
                });
            },
            addRole: function(role) {
                var user = model.get("currentUser");
                $.ajax({
                    contentType: "application/json",
                    type: "POST",
                    data: JSON.stringify({
                        actorId: user.get(usernameProp),
                        roleId: role.get("id")
                    }),
                    url: service.addRole
                }).done(function(id) {
                    var data = role.toJSON();
                    data.rgaId = id;
                    model.get("selectedRoles").insert(data);
                    model.set("selectedRoles", model.get("selectedRoles"));
                    role.set("added", true);
                    $("#" + role.get("id"))
                        .addClass("added")
                        .find(".ui.button")
                        .addClass("disabled")
                        .html(" 已添加 ");

                    $("#selected_" + role.get("id")).transition({
                        animation : 'jiggle',
                        duration  : 800,
                        interval  : 200,
                        displayType: "flex"
                    });

                });
            },
            removeRole: function(role) {
                $.ajax({
                    type: "DELETE",
                    url: service.removeRole.replace(":id", role.get("rgaId"))
                }).done(function() {
                    $("#selected_" + role.get("id")).transition({
                        animation:'scale',
                        onComplete: function() {
                            role.remove();
                            $("#" + role.get("id"))
                                .removeClass("added")
                                .find(".ui.button")
                                .removeClass("disabled")
                                .html(" 添加角色 ");
                        }
                    });

                });
            }
        });

        model.action("toggleStyle")();
    });

}).call(this);
<|endoftext|>