Javascript 在我的组件的功能中使用较少人为设计的代码来对存储中更改的数据作出反应,建议采用什么方法?

Javascript 在我的组件的功能中使用较少人为设计的代码来对存储中更改的数据作出反应,建议采用什么方法?,javascript,reactjs,flux,reactjs-flux,Javascript,Reactjs,Flux,Reactjs Flux,我有一个React/Flux web应用程序,希望遵循体系结构最佳实践: 我将集中讨论我的问题的一个视图,即用于插入/更新实体(发生中的用户)的组件 这段代码一切正常,但我的问题的核心是关于我的AdminUserDetail组件中的onUserDetailChanged函数,我发现它太过做作和混乱 我问题的核心 我想重构在我的组件中找到的代码: // ALL OF THIS IS UGLY onUserDetailChanged: function() { var data = Adm

我有一个React/Flux web应用程序,希望遵循体系结构最佳实践:

我将集中讨论我的问题的一个视图,即用于插入/更新实体(发生中的用户)的组件

这段代码一切正常,但我的问题的核心是关于我的
AdminUserDetail
组件中的
onUserDetailChanged
函数,我发现它太过做作和混乱

我问题的核心 我想重构在我的组件中找到的代码:

// ALL OF THIS IS UGLY
onUserDetailChanged: function() {
    var data = AdminUserDetailStore.getData();
    GuiHelper.blockGuiLoading(false);

    // Check first if there is a feedback message
    if (typeof data.FeedbackMessage !== 'undefined') {
        if (data.FeedbackMessage === ActionConstants.ERROR) {
            // Unexpected error
            GuiHelper.unexpectedError();
        }
        else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
            // User saved successfully
            GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
        }
    }
    // If there is no feedback message, check for errors
    else {
        if (data.Errors !== null && data.Errors.length > 0) {
            // Errors
            GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
        }
        else {
            // No errors, data changed (either from initial load or from user input)
            this.setState({ entity: data.Data });

            // Load the user permissions if required
            // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
            var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
            if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                this.loadUserPermissions(data.Data.Username);
            }
        }
    }
},
我不喜欢这个体系结构,因为所有的api调用(
getUserDetail(userId)
getUserDetailPermissions(username)
postUserDetail(requestData)
)最终都会调用这个函数,我发现如何将api调用的结果通知给用户很困惑。此外,该函数甚至会在用户输入导致的每次数据更改时调用,因此我发现所有内容都混淆了

可能的结果均由该人为代码支持:

  • getUserDetail(userId)
    可以在出现意外错误(例如api服务器没有响应)时,以
    SUCCESS
    ERROR
    结束
  • getUserDetailPermissions(username)
    可以在出现意外错误(例如api服务器没有响应)时,以
    SUCCESS
    ERROR
    结束
  • postaserdetail(requestData)
    有点复杂,因为在发布的数据上有服务器验证。与其他调用一样,它可以以
    SUCCESS
    ERROR
    结束,但它也可以返回必须向用户显示的验证错误列表
例如,我可以使用不同的
onChange
函数来区分每个API调用类型和由用户输入引起的数据更改吗

WebApiClient.js

import request from 'superagent';
var Promise = require('es6-promise').Promise;

module.exports = {
    get: function (url) {
        return new Promise(function (resolve, reject) {
            request
                .get(url)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    },

    post: function (url, data) {
        return new Promise(function (resolve, reject) {
            request
                .post(url)
                .send(data)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    }
}
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var Promise = require('es6-promise').Promise;
var Api = require('../Util/WebApiClient');

var ActionCreator = {
    apiServer: 'http://localhost:55010/api',

    getUserDetail: function (userId) {
        Api.get(this.apiServer + '/v1/User/' + userId)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    getUserDetailPermissions: function (username) {
        Api.get(this.apiServer + '/v1/Permission/ForUser?username=' + username)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USERPERMISSIONS, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    postUserDetail: function (requestData) {
        Api.post(this.apiServer + '/v1/User/', requestData)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.POST_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    }
};

module.exports = ActionCreator;
module.exports = {
  GET_USER: 'GET_USER',
  GET_USERPERMISSIONS: 'GET_USERPERMISSIONS',
  POST_USER: 'POST_USER',

  ERROR: 'ERROR',
  SUCCESS: 'SUCCESS'
};
var Dispatcher = require('flux').Dispatcher;

// Create dispatcher instance
var Dispatcher = new Dispatcher();

// Convenience method to handle dispatch requests
Dispatcher.handleAction = function(action) {
    this.dispatch({
        source: 'VIEW_ACTION',
        action: action
    });
}

module.exports = Dispatcher;
var Dispatcher = require('../Core/Dispatcher');
var ActionConstants = require('../Core/ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var AdminUserDetailStore = assign({}, EventEmitter.prototype, {
    data: {},

    // Called after the initial GET to load the initial User entity
    // or from user input
    setData: function(data, doEmitChange) {
        this.data = data;

        if (typeof doEmitChange !== 'undefined' && doEmitChange) {
            this.emitChange();
        }
    },

    // Called from a POST when trying to save the User entity
    // or when getting an unexpected error (e.g. api server unavailable)
    setFeedbackMessage: function(data, message) {
        if (typeof message !== 'undefined')
            this.data.FeedbackMessage = message;
        else {
            if (data.Errors.length > 0)
                this.data.Errors = data.Errors;
            else
                this.data.FeedbackMessage = ActionConstants.SUCCESS;
        }
    },

    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },

    getData: function () {
        return this.data;
    }
});

Dispatcher.register(function(payload) {
    var action = payload.action;

    switch(action.actionType) {
        case ActionConstants.ERROR:
            // Force a feedback message
            AdminUserDetailStore.setFeedbackMessage(null, ActionConstants.ERROR);
            break;
        case ActionConstants.GET_USER:
            AdminUserDetailStore.setData(action.data);
            break;
        case ActionConstants.POST_USER:
            // Check for errors wthin the data object and set a SUCCESS feedback message if none are found
            AdminUserDetailStore.setFeedbackMessage(action.data);
            break;
        default:
            return true;
    }

    AdminUserDetailStore.emitChange();
    return true;
});

module.exports = AdminUserDetailStore;
import React from 'react';
import ReactDOM from 'react-dom';
import ActionCreator from '../../Core/ActionCreator';
import ActionConstants from '../../Core/ActionConstants';

import AdminUserDetailStore  from '../../Stores/AdminUserDetailStore';
import AdminUserDetailPermissionsStore  from '../../Stores/AdminUserDetailPermissionsStore';

import LanguageLoader from '../../Util/LanguageLoader';
import GuiHelper from '../../Util/GuiHelper';
import BootstrapDialog from 'bootstrap-dialog';

import blockUI from '../../../Content/js/jquery.blockUI.js';

import {AgGridReact} from 'ag-grid-react';
import BoolCellEditor from '../AgGrid/BoolCellEditor';

$ = window.$ = window.jQuery = require('jquery');

var AdminUserDetail = React.createClass({
    getInitialState: function () {
        return {
            entity: {
                Id: 0,
                Username: '',
                Email: ''
            },

            userPermissions: null,
            userPermissionsColumns: [
                { headerName: LanguageLoader.langDict.lblRole, field: 'role' },
                { headerName: LanguageLoader.langDict.lblPermission, field: 'permission' },
                { headerName: LanguageLoader.langDict.lblDescription, field: 'description', width:600 }
            ],

            gridOptions: {
                context: this,
                singleClickEdit: true,
                enableColResize: true,
                onGridReady: function(event) {
                    //event.api.autoSizeColumns();
                },
            },
        };
    },

    getDefaultProps: function () {
        return { };
    },

    componentWillMount: function () {
        AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
    },

    componentWillUnmount: function () {
        AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
    },

    // ALL OF THIS IS UGLY
    onUserDetailChanged: function() {
        var data = AdminUserDetailStore.getData();
        GuiHelper.blockGuiLoading(false);

        // Check first if there is a feedback message
        if (typeof data.FeedbackMessage !== 'undefined') {
            if (data.FeedbackMessage === ActionConstants.ERROR) {
                // Unexpected error
                GuiHelper.unexpectedError();
            }
            else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
                // User saved successfully
                GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
            }
        }
        // If there is no feedback message, check for errors
        else {
            if (data.Errors !== null && data.Errors.length > 0) {
                // Errors
                GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
            }
            else {
                // No errors, data changed (either from initial load or from user input)
                this.setState({ entity: data.Data });

                // Load the user permissions if required
                // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
                var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
                if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                    this.loadUserPermissions(data.Data.Username);
                }
            }
        }
    },

    onUserDetailPermissionsChanged: function() {
        var data = AdminUserDetailPermissionsStore.getData();
        GuiHelper.blockGuiLoading(false);

        if (typeof data.FeedbackMessage !== 'undefined' && data.FeedbackMessage === ActionConstants.ERROR) {
            GuiHelper.unexpectedError();
        }
        else {
            var userPermissions = data.Data.map(function(i, idx) {
                return { role: i.Key, permission: i.Value, description: LanguageLoader.langDict['P_' + i.Value] };
            });
            this.setState({ userPermissions: userPermissions });
        }
    },

    componentDidMount: function () {
        // Initialize/clear the stores
        AdminUserDetailStore.setData({});
        AdminUserDetailPermissionsStore.setData({});

        if (this.props.id !== null) {
            GuiHelper.blockGuiLoading(true);
            ActionCreator.getUserDetail(this.props.id);
        }
    },

    loadUserPermissions :function(username) {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.getUserDetailPermissions(username);
    },

    saveUser: function () {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.postUserDetail(this.state.entity);
    },

    onUsernameChanged: function(e) {
        var entity = this.state.entity;
        entity.Username = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    onEmailChanged: function(e) {
        var entity = this.state.entity;
        entity.Email = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    render: function () {
        return (
            <div>
                <h1>{LanguageLoader.langDict.lblUserDetail}</h1>

                <form>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userUsername">{LanguageLoader.langDict.lblUsername}</label>
                                <input type="text" className="form-control" id="userUsername" value={this.state.entity.Username} placeholder={LanguageLoader.langDict.lblUsername} onChange={this.onUsernameChanged} />
                            </div>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userEmail">{LanguageLoader.langDict.lblEmailAddress}</label>
                                <input type="text" className="form-control" id="userEmail" value={this.state.entity.Email} placeholder={LanguageLoader.langDict.lblEmail} onChange={this.onEmailChanged} />
                            </div>
                        </div>
                    </div>
                </form>

                <div className={this.state.userPermissions === null ? 'hidden' : ''}>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label>{LanguageLoader.langDict.lblPermissionsFromRole}</label>
                                <div style={{height: 400}} className="ag-fresh">
                                    <AgGridReact gridOptions={this.state.gridOptions} columnDefs={this.state.userPermissionsColumns} rowData={this.state.userPermissions} />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        );
    }
});

module.exports = AdminUserDetail;
ActionsCreator.js

import request from 'superagent';
var Promise = require('es6-promise').Promise;

module.exports = {
    get: function (url) {
        return new Promise(function (resolve, reject) {
            request
                .get(url)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    },

    post: function (url, data) {
        return new Promise(function (resolve, reject) {
            request
                .post(url)
                .send(data)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    }
}
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var Promise = require('es6-promise').Promise;
var Api = require('../Util/WebApiClient');

var ActionCreator = {
    apiServer: 'http://localhost:55010/api',

    getUserDetail: function (userId) {
        Api.get(this.apiServer + '/v1/User/' + userId)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    getUserDetailPermissions: function (username) {
        Api.get(this.apiServer + '/v1/Permission/ForUser?username=' + username)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USERPERMISSIONS, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    postUserDetail: function (requestData) {
        Api.post(this.apiServer + '/v1/User/', requestData)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.POST_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    }
};

module.exports = ActionCreator;
module.exports = {
  GET_USER: 'GET_USER',
  GET_USERPERMISSIONS: 'GET_USERPERMISSIONS',
  POST_USER: 'POST_USER',

  ERROR: 'ERROR',
  SUCCESS: 'SUCCESS'
};
var Dispatcher = require('flux').Dispatcher;

// Create dispatcher instance
var Dispatcher = new Dispatcher();

// Convenience method to handle dispatch requests
Dispatcher.handleAction = function(action) {
    this.dispatch({
        source: 'VIEW_ACTION',
        action: action
    });
}

module.exports = Dispatcher;
var Dispatcher = require('../Core/Dispatcher');
var ActionConstants = require('../Core/ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var AdminUserDetailStore = assign({}, EventEmitter.prototype, {
    data: {},

    // Called after the initial GET to load the initial User entity
    // or from user input
    setData: function(data, doEmitChange) {
        this.data = data;

        if (typeof doEmitChange !== 'undefined' && doEmitChange) {
            this.emitChange();
        }
    },

    // Called from a POST when trying to save the User entity
    // or when getting an unexpected error (e.g. api server unavailable)
    setFeedbackMessage: function(data, message) {
        if (typeof message !== 'undefined')
            this.data.FeedbackMessage = message;
        else {
            if (data.Errors.length > 0)
                this.data.Errors = data.Errors;
            else
                this.data.FeedbackMessage = ActionConstants.SUCCESS;
        }
    },

    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },

    getData: function () {
        return this.data;
    }
});

Dispatcher.register(function(payload) {
    var action = payload.action;

    switch(action.actionType) {
        case ActionConstants.ERROR:
            // Force a feedback message
            AdminUserDetailStore.setFeedbackMessage(null, ActionConstants.ERROR);
            break;
        case ActionConstants.GET_USER:
            AdminUserDetailStore.setData(action.data);
            break;
        case ActionConstants.POST_USER:
            // Check for errors wthin the data object and set a SUCCESS feedback message if none are found
            AdminUserDetailStore.setFeedbackMessage(action.data);
            break;
        default:
            return true;
    }

    AdminUserDetailStore.emitChange();
    return true;
});

module.exports = AdminUserDetailStore;
import React from 'react';
import ReactDOM from 'react-dom';
import ActionCreator from '../../Core/ActionCreator';
import ActionConstants from '../../Core/ActionConstants';

import AdminUserDetailStore  from '../../Stores/AdminUserDetailStore';
import AdminUserDetailPermissionsStore  from '../../Stores/AdminUserDetailPermissionsStore';

import LanguageLoader from '../../Util/LanguageLoader';
import GuiHelper from '../../Util/GuiHelper';
import BootstrapDialog from 'bootstrap-dialog';

import blockUI from '../../../Content/js/jquery.blockUI.js';

import {AgGridReact} from 'ag-grid-react';
import BoolCellEditor from '../AgGrid/BoolCellEditor';

$ = window.$ = window.jQuery = require('jquery');

var AdminUserDetail = React.createClass({
    getInitialState: function () {
        return {
            entity: {
                Id: 0,
                Username: '',
                Email: ''
            },

            userPermissions: null,
            userPermissionsColumns: [
                { headerName: LanguageLoader.langDict.lblRole, field: 'role' },
                { headerName: LanguageLoader.langDict.lblPermission, field: 'permission' },
                { headerName: LanguageLoader.langDict.lblDescription, field: 'description', width:600 }
            ],

            gridOptions: {
                context: this,
                singleClickEdit: true,
                enableColResize: true,
                onGridReady: function(event) {
                    //event.api.autoSizeColumns();
                },
            },
        };
    },

    getDefaultProps: function () {
        return { };
    },

    componentWillMount: function () {
        AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
    },

    componentWillUnmount: function () {
        AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
    },

    // ALL OF THIS IS UGLY
    onUserDetailChanged: function() {
        var data = AdminUserDetailStore.getData();
        GuiHelper.blockGuiLoading(false);

        // Check first if there is a feedback message
        if (typeof data.FeedbackMessage !== 'undefined') {
            if (data.FeedbackMessage === ActionConstants.ERROR) {
                // Unexpected error
                GuiHelper.unexpectedError();
            }
            else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
                // User saved successfully
                GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
            }
        }
        // If there is no feedback message, check for errors
        else {
            if (data.Errors !== null && data.Errors.length > 0) {
                // Errors
                GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
            }
            else {
                // No errors, data changed (either from initial load or from user input)
                this.setState({ entity: data.Data });

                // Load the user permissions if required
                // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
                var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
                if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                    this.loadUserPermissions(data.Data.Username);
                }
            }
        }
    },

    onUserDetailPermissionsChanged: function() {
        var data = AdminUserDetailPermissionsStore.getData();
        GuiHelper.blockGuiLoading(false);

        if (typeof data.FeedbackMessage !== 'undefined' && data.FeedbackMessage === ActionConstants.ERROR) {
            GuiHelper.unexpectedError();
        }
        else {
            var userPermissions = data.Data.map(function(i, idx) {
                return { role: i.Key, permission: i.Value, description: LanguageLoader.langDict['P_' + i.Value] };
            });
            this.setState({ userPermissions: userPermissions });
        }
    },

    componentDidMount: function () {
        // Initialize/clear the stores
        AdminUserDetailStore.setData({});
        AdminUserDetailPermissionsStore.setData({});

        if (this.props.id !== null) {
            GuiHelper.blockGuiLoading(true);
            ActionCreator.getUserDetail(this.props.id);
        }
    },

    loadUserPermissions :function(username) {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.getUserDetailPermissions(username);
    },

    saveUser: function () {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.postUserDetail(this.state.entity);
    },

    onUsernameChanged: function(e) {
        var entity = this.state.entity;
        entity.Username = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    onEmailChanged: function(e) {
        var entity = this.state.entity;
        entity.Email = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    render: function () {
        return (
            <div>
                <h1>{LanguageLoader.langDict.lblUserDetail}</h1>

                <form>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userUsername">{LanguageLoader.langDict.lblUsername}</label>
                                <input type="text" className="form-control" id="userUsername" value={this.state.entity.Username} placeholder={LanguageLoader.langDict.lblUsername} onChange={this.onUsernameChanged} />
                            </div>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userEmail">{LanguageLoader.langDict.lblEmailAddress}</label>
                                <input type="text" className="form-control" id="userEmail" value={this.state.entity.Email} placeholder={LanguageLoader.langDict.lblEmail} onChange={this.onEmailChanged} />
                            </div>
                        </div>
                    </div>
                </form>

                <div className={this.state.userPermissions === null ? 'hidden' : ''}>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label>{LanguageLoader.langDict.lblPermissionsFromRole}</label>
                                <div style={{height: 400}} className="ag-fresh">
                                    <AgGridReact gridOptions={this.state.gridOptions} columnDefs={this.state.userPermissionsColumns} rowData={this.state.userPermissions} />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        );
    }
});

module.exports = AdminUserDetail;
ActionConstants.js

import request from 'superagent';
var Promise = require('es6-promise').Promise;

module.exports = {
    get: function (url) {
        return new Promise(function (resolve, reject) {
            request
                .get(url)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    },

    post: function (url, data) {
        return new Promise(function (resolve, reject) {
            request
                .post(url)
                .send(data)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    }
}
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var Promise = require('es6-promise').Promise;
var Api = require('../Util/WebApiClient');

var ActionCreator = {
    apiServer: 'http://localhost:55010/api',

    getUserDetail: function (userId) {
        Api.get(this.apiServer + '/v1/User/' + userId)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    getUserDetailPermissions: function (username) {
        Api.get(this.apiServer + '/v1/Permission/ForUser?username=' + username)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USERPERMISSIONS, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    postUserDetail: function (requestData) {
        Api.post(this.apiServer + '/v1/User/', requestData)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.POST_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    }
};

module.exports = ActionCreator;
module.exports = {
  GET_USER: 'GET_USER',
  GET_USERPERMISSIONS: 'GET_USERPERMISSIONS',
  POST_USER: 'POST_USER',

  ERROR: 'ERROR',
  SUCCESS: 'SUCCESS'
};
var Dispatcher = require('flux').Dispatcher;

// Create dispatcher instance
var Dispatcher = new Dispatcher();

// Convenience method to handle dispatch requests
Dispatcher.handleAction = function(action) {
    this.dispatch({
        source: 'VIEW_ACTION',
        action: action
    });
}

module.exports = Dispatcher;
var Dispatcher = require('../Core/Dispatcher');
var ActionConstants = require('../Core/ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var AdminUserDetailStore = assign({}, EventEmitter.prototype, {
    data: {},

    // Called after the initial GET to load the initial User entity
    // or from user input
    setData: function(data, doEmitChange) {
        this.data = data;

        if (typeof doEmitChange !== 'undefined' && doEmitChange) {
            this.emitChange();
        }
    },

    // Called from a POST when trying to save the User entity
    // or when getting an unexpected error (e.g. api server unavailable)
    setFeedbackMessage: function(data, message) {
        if (typeof message !== 'undefined')
            this.data.FeedbackMessage = message;
        else {
            if (data.Errors.length > 0)
                this.data.Errors = data.Errors;
            else
                this.data.FeedbackMessage = ActionConstants.SUCCESS;
        }
    },

    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },

    getData: function () {
        return this.data;
    }
});

Dispatcher.register(function(payload) {
    var action = payload.action;

    switch(action.actionType) {
        case ActionConstants.ERROR:
            // Force a feedback message
            AdminUserDetailStore.setFeedbackMessage(null, ActionConstants.ERROR);
            break;
        case ActionConstants.GET_USER:
            AdminUserDetailStore.setData(action.data);
            break;
        case ActionConstants.POST_USER:
            // Check for errors wthin the data object and set a SUCCESS feedback message if none are found
            AdminUserDetailStore.setFeedbackMessage(action.data);
            break;
        default:
            return true;
    }

    AdminUserDetailStore.emitChange();
    return true;
});

module.exports = AdminUserDetailStore;
import React from 'react';
import ReactDOM from 'react-dom';
import ActionCreator from '../../Core/ActionCreator';
import ActionConstants from '../../Core/ActionConstants';

import AdminUserDetailStore  from '../../Stores/AdminUserDetailStore';
import AdminUserDetailPermissionsStore  from '../../Stores/AdminUserDetailPermissionsStore';

import LanguageLoader from '../../Util/LanguageLoader';
import GuiHelper from '../../Util/GuiHelper';
import BootstrapDialog from 'bootstrap-dialog';

import blockUI from '../../../Content/js/jquery.blockUI.js';

import {AgGridReact} from 'ag-grid-react';
import BoolCellEditor from '../AgGrid/BoolCellEditor';

$ = window.$ = window.jQuery = require('jquery');

var AdminUserDetail = React.createClass({
    getInitialState: function () {
        return {
            entity: {
                Id: 0,
                Username: '',
                Email: ''
            },

            userPermissions: null,
            userPermissionsColumns: [
                { headerName: LanguageLoader.langDict.lblRole, field: 'role' },
                { headerName: LanguageLoader.langDict.lblPermission, field: 'permission' },
                { headerName: LanguageLoader.langDict.lblDescription, field: 'description', width:600 }
            ],

            gridOptions: {
                context: this,
                singleClickEdit: true,
                enableColResize: true,
                onGridReady: function(event) {
                    //event.api.autoSizeColumns();
                },
            },
        };
    },

    getDefaultProps: function () {
        return { };
    },

    componentWillMount: function () {
        AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
    },

    componentWillUnmount: function () {
        AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
    },

    // ALL OF THIS IS UGLY
    onUserDetailChanged: function() {
        var data = AdminUserDetailStore.getData();
        GuiHelper.blockGuiLoading(false);

        // Check first if there is a feedback message
        if (typeof data.FeedbackMessage !== 'undefined') {
            if (data.FeedbackMessage === ActionConstants.ERROR) {
                // Unexpected error
                GuiHelper.unexpectedError();
            }
            else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
                // User saved successfully
                GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
            }
        }
        // If there is no feedback message, check for errors
        else {
            if (data.Errors !== null && data.Errors.length > 0) {
                // Errors
                GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
            }
            else {
                // No errors, data changed (either from initial load or from user input)
                this.setState({ entity: data.Data });

                // Load the user permissions if required
                // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
                var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
                if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                    this.loadUserPermissions(data.Data.Username);
                }
            }
        }
    },

    onUserDetailPermissionsChanged: function() {
        var data = AdminUserDetailPermissionsStore.getData();
        GuiHelper.blockGuiLoading(false);

        if (typeof data.FeedbackMessage !== 'undefined' && data.FeedbackMessage === ActionConstants.ERROR) {
            GuiHelper.unexpectedError();
        }
        else {
            var userPermissions = data.Data.map(function(i, idx) {
                return { role: i.Key, permission: i.Value, description: LanguageLoader.langDict['P_' + i.Value] };
            });
            this.setState({ userPermissions: userPermissions });
        }
    },

    componentDidMount: function () {
        // Initialize/clear the stores
        AdminUserDetailStore.setData({});
        AdminUserDetailPermissionsStore.setData({});

        if (this.props.id !== null) {
            GuiHelper.blockGuiLoading(true);
            ActionCreator.getUserDetail(this.props.id);
        }
    },

    loadUserPermissions :function(username) {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.getUserDetailPermissions(username);
    },

    saveUser: function () {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.postUserDetail(this.state.entity);
    },

    onUsernameChanged: function(e) {
        var entity = this.state.entity;
        entity.Username = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    onEmailChanged: function(e) {
        var entity = this.state.entity;
        entity.Email = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    render: function () {
        return (
            <div>
                <h1>{LanguageLoader.langDict.lblUserDetail}</h1>

                <form>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userUsername">{LanguageLoader.langDict.lblUsername}</label>
                                <input type="text" className="form-control" id="userUsername" value={this.state.entity.Username} placeholder={LanguageLoader.langDict.lblUsername} onChange={this.onUsernameChanged} />
                            </div>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userEmail">{LanguageLoader.langDict.lblEmailAddress}</label>
                                <input type="text" className="form-control" id="userEmail" value={this.state.entity.Email} placeholder={LanguageLoader.langDict.lblEmail} onChange={this.onEmailChanged} />
                            </div>
                        </div>
                    </div>
                </form>

                <div className={this.state.userPermissions === null ? 'hidden' : ''}>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label>{LanguageLoader.langDict.lblPermissionsFromRole}</label>
                                <div style={{height: 400}} className="ag-fresh">
                                    <AgGridReact gridOptions={this.state.gridOptions} columnDefs={this.state.userPermissionsColumns} rowData={this.state.userPermissions} />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        );
    }
});

module.exports = AdminUserDetail;
Dispatcher.js

import request from 'superagent';
var Promise = require('es6-promise').Promise;

module.exports = {
    get: function (url) {
        return new Promise(function (resolve, reject) {
            request
                .get(url)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    },

    post: function (url, data) {
        return new Promise(function (resolve, reject) {
            request
                .post(url)
                .send(data)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    }
}
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var Promise = require('es6-promise').Promise;
var Api = require('../Util/WebApiClient');

var ActionCreator = {
    apiServer: 'http://localhost:55010/api',

    getUserDetail: function (userId) {
        Api.get(this.apiServer + '/v1/User/' + userId)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    getUserDetailPermissions: function (username) {
        Api.get(this.apiServer + '/v1/Permission/ForUser?username=' + username)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USERPERMISSIONS, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    postUserDetail: function (requestData) {
        Api.post(this.apiServer + '/v1/User/', requestData)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.POST_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    }
};

module.exports = ActionCreator;
module.exports = {
  GET_USER: 'GET_USER',
  GET_USERPERMISSIONS: 'GET_USERPERMISSIONS',
  POST_USER: 'POST_USER',

  ERROR: 'ERROR',
  SUCCESS: 'SUCCESS'
};
var Dispatcher = require('flux').Dispatcher;

// Create dispatcher instance
var Dispatcher = new Dispatcher();

// Convenience method to handle dispatch requests
Dispatcher.handleAction = function(action) {
    this.dispatch({
        source: 'VIEW_ACTION',
        action: action
    });
}

module.exports = Dispatcher;
var Dispatcher = require('../Core/Dispatcher');
var ActionConstants = require('../Core/ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var AdminUserDetailStore = assign({}, EventEmitter.prototype, {
    data: {},

    // Called after the initial GET to load the initial User entity
    // or from user input
    setData: function(data, doEmitChange) {
        this.data = data;

        if (typeof doEmitChange !== 'undefined' && doEmitChange) {
            this.emitChange();
        }
    },

    // Called from a POST when trying to save the User entity
    // or when getting an unexpected error (e.g. api server unavailable)
    setFeedbackMessage: function(data, message) {
        if (typeof message !== 'undefined')
            this.data.FeedbackMessage = message;
        else {
            if (data.Errors.length > 0)
                this.data.Errors = data.Errors;
            else
                this.data.FeedbackMessage = ActionConstants.SUCCESS;
        }
    },

    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },

    getData: function () {
        return this.data;
    }
});

Dispatcher.register(function(payload) {
    var action = payload.action;

    switch(action.actionType) {
        case ActionConstants.ERROR:
            // Force a feedback message
            AdminUserDetailStore.setFeedbackMessage(null, ActionConstants.ERROR);
            break;
        case ActionConstants.GET_USER:
            AdminUserDetailStore.setData(action.data);
            break;
        case ActionConstants.POST_USER:
            // Check for errors wthin the data object and set a SUCCESS feedback message if none are found
            AdminUserDetailStore.setFeedbackMessage(action.data);
            break;
        default:
            return true;
    }

    AdminUserDetailStore.emitChange();
    return true;
});

module.exports = AdminUserDetailStore;
import React from 'react';
import ReactDOM from 'react-dom';
import ActionCreator from '../../Core/ActionCreator';
import ActionConstants from '../../Core/ActionConstants';

import AdminUserDetailStore  from '../../Stores/AdminUserDetailStore';
import AdminUserDetailPermissionsStore  from '../../Stores/AdminUserDetailPermissionsStore';

import LanguageLoader from '../../Util/LanguageLoader';
import GuiHelper from '../../Util/GuiHelper';
import BootstrapDialog from 'bootstrap-dialog';

import blockUI from '../../../Content/js/jquery.blockUI.js';

import {AgGridReact} from 'ag-grid-react';
import BoolCellEditor from '../AgGrid/BoolCellEditor';

$ = window.$ = window.jQuery = require('jquery');

var AdminUserDetail = React.createClass({
    getInitialState: function () {
        return {
            entity: {
                Id: 0,
                Username: '',
                Email: ''
            },

            userPermissions: null,
            userPermissionsColumns: [
                { headerName: LanguageLoader.langDict.lblRole, field: 'role' },
                { headerName: LanguageLoader.langDict.lblPermission, field: 'permission' },
                { headerName: LanguageLoader.langDict.lblDescription, field: 'description', width:600 }
            ],

            gridOptions: {
                context: this,
                singleClickEdit: true,
                enableColResize: true,
                onGridReady: function(event) {
                    //event.api.autoSizeColumns();
                },
            },
        };
    },

    getDefaultProps: function () {
        return { };
    },

    componentWillMount: function () {
        AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
    },

    componentWillUnmount: function () {
        AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
    },

    // ALL OF THIS IS UGLY
    onUserDetailChanged: function() {
        var data = AdminUserDetailStore.getData();
        GuiHelper.blockGuiLoading(false);

        // Check first if there is a feedback message
        if (typeof data.FeedbackMessage !== 'undefined') {
            if (data.FeedbackMessage === ActionConstants.ERROR) {
                // Unexpected error
                GuiHelper.unexpectedError();
            }
            else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
                // User saved successfully
                GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
            }
        }
        // If there is no feedback message, check for errors
        else {
            if (data.Errors !== null && data.Errors.length > 0) {
                // Errors
                GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
            }
            else {
                // No errors, data changed (either from initial load or from user input)
                this.setState({ entity: data.Data });

                // Load the user permissions if required
                // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
                var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
                if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                    this.loadUserPermissions(data.Data.Username);
                }
            }
        }
    },

    onUserDetailPermissionsChanged: function() {
        var data = AdminUserDetailPermissionsStore.getData();
        GuiHelper.blockGuiLoading(false);

        if (typeof data.FeedbackMessage !== 'undefined' && data.FeedbackMessage === ActionConstants.ERROR) {
            GuiHelper.unexpectedError();
        }
        else {
            var userPermissions = data.Data.map(function(i, idx) {
                return { role: i.Key, permission: i.Value, description: LanguageLoader.langDict['P_' + i.Value] };
            });
            this.setState({ userPermissions: userPermissions });
        }
    },

    componentDidMount: function () {
        // Initialize/clear the stores
        AdminUserDetailStore.setData({});
        AdminUserDetailPermissionsStore.setData({});

        if (this.props.id !== null) {
            GuiHelper.blockGuiLoading(true);
            ActionCreator.getUserDetail(this.props.id);
        }
    },

    loadUserPermissions :function(username) {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.getUserDetailPermissions(username);
    },

    saveUser: function () {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.postUserDetail(this.state.entity);
    },

    onUsernameChanged: function(e) {
        var entity = this.state.entity;
        entity.Username = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    onEmailChanged: function(e) {
        var entity = this.state.entity;
        entity.Email = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    render: function () {
        return (
            <div>
                <h1>{LanguageLoader.langDict.lblUserDetail}</h1>

                <form>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userUsername">{LanguageLoader.langDict.lblUsername}</label>
                                <input type="text" className="form-control" id="userUsername" value={this.state.entity.Username} placeholder={LanguageLoader.langDict.lblUsername} onChange={this.onUsernameChanged} />
                            </div>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userEmail">{LanguageLoader.langDict.lblEmailAddress}</label>
                                <input type="text" className="form-control" id="userEmail" value={this.state.entity.Email} placeholder={LanguageLoader.langDict.lblEmail} onChange={this.onEmailChanged} />
                            </div>
                        </div>
                    </div>
                </form>

                <div className={this.state.userPermissions === null ? 'hidden' : ''}>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label>{LanguageLoader.langDict.lblPermissionsFromRole}</label>
                                <div style={{height: 400}} className="ag-fresh">
                                    <AgGridReact gridOptions={this.state.gridOptions} columnDefs={this.state.userPermissionsColumns} rowData={this.state.userPermissions} />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        );
    }
});

module.exports = AdminUserDetail;
AdminUserDetailStore.js

import request from 'superagent';
var Promise = require('es6-promise').Promise;

module.exports = {
    get: function (url) {
        return new Promise(function (resolve, reject) {
            request
                .get(url)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    },

    post: function (url, data) {
        return new Promise(function (resolve, reject) {
            request
                .post(url)
                .send(data)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    }
}
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var Promise = require('es6-promise').Promise;
var Api = require('../Util/WebApiClient');

var ActionCreator = {
    apiServer: 'http://localhost:55010/api',

    getUserDetail: function (userId) {
        Api.get(this.apiServer + '/v1/User/' + userId)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    getUserDetailPermissions: function (username) {
        Api.get(this.apiServer + '/v1/Permission/ForUser?username=' + username)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USERPERMISSIONS, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    postUserDetail: function (requestData) {
        Api.post(this.apiServer + '/v1/User/', requestData)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.POST_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    }
};

module.exports = ActionCreator;
module.exports = {
  GET_USER: 'GET_USER',
  GET_USERPERMISSIONS: 'GET_USERPERMISSIONS',
  POST_USER: 'POST_USER',

  ERROR: 'ERROR',
  SUCCESS: 'SUCCESS'
};
var Dispatcher = require('flux').Dispatcher;

// Create dispatcher instance
var Dispatcher = new Dispatcher();

// Convenience method to handle dispatch requests
Dispatcher.handleAction = function(action) {
    this.dispatch({
        source: 'VIEW_ACTION',
        action: action
    });
}

module.exports = Dispatcher;
var Dispatcher = require('../Core/Dispatcher');
var ActionConstants = require('../Core/ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var AdminUserDetailStore = assign({}, EventEmitter.prototype, {
    data: {},

    // Called after the initial GET to load the initial User entity
    // or from user input
    setData: function(data, doEmitChange) {
        this.data = data;

        if (typeof doEmitChange !== 'undefined' && doEmitChange) {
            this.emitChange();
        }
    },

    // Called from a POST when trying to save the User entity
    // or when getting an unexpected error (e.g. api server unavailable)
    setFeedbackMessage: function(data, message) {
        if (typeof message !== 'undefined')
            this.data.FeedbackMessage = message;
        else {
            if (data.Errors.length > 0)
                this.data.Errors = data.Errors;
            else
                this.data.FeedbackMessage = ActionConstants.SUCCESS;
        }
    },

    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },

    getData: function () {
        return this.data;
    }
});

Dispatcher.register(function(payload) {
    var action = payload.action;

    switch(action.actionType) {
        case ActionConstants.ERROR:
            // Force a feedback message
            AdminUserDetailStore.setFeedbackMessage(null, ActionConstants.ERROR);
            break;
        case ActionConstants.GET_USER:
            AdminUserDetailStore.setData(action.data);
            break;
        case ActionConstants.POST_USER:
            // Check for errors wthin the data object and set a SUCCESS feedback message if none are found
            AdminUserDetailStore.setFeedbackMessage(action.data);
            break;
        default:
            return true;
    }

    AdminUserDetailStore.emitChange();
    return true;
});

module.exports = AdminUserDetailStore;
import React from 'react';
import ReactDOM from 'react-dom';
import ActionCreator from '../../Core/ActionCreator';
import ActionConstants from '../../Core/ActionConstants';

import AdminUserDetailStore  from '../../Stores/AdminUserDetailStore';
import AdminUserDetailPermissionsStore  from '../../Stores/AdminUserDetailPermissionsStore';

import LanguageLoader from '../../Util/LanguageLoader';
import GuiHelper from '../../Util/GuiHelper';
import BootstrapDialog from 'bootstrap-dialog';

import blockUI from '../../../Content/js/jquery.blockUI.js';

import {AgGridReact} from 'ag-grid-react';
import BoolCellEditor from '../AgGrid/BoolCellEditor';

$ = window.$ = window.jQuery = require('jquery');

var AdminUserDetail = React.createClass({
    getInitialState: function () {
        return {
            entity: {
                Id: 0,
                Username: '',
                Email: ''
            },

            userPermissions: null,
            userPermissionsColumns: [
                { headerName: LanguageLoader.langDict.lblRole, field: 'role' },
                { headerName: LanguageLoader.langDict.lblPermission, field: 'permission' },
                { headerName: LanguageLoader.langDict.lblDescription, field: 'description', width:600 }
            ],

            gridOptions: {
                context: this,
                singleClickEdit: true,
                enableColResize: true,
                onGridReady: function(event) {
                    //event.api.autoSizeColumns();
                },
            },
        };
    },

    getDefaultProps: function () {
        return { };
    },

    componentWillMount: function () {
        AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
    },

    componentWillUnmount: function () {
        AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
    },

    // ALL OF THIS IS UGLY
    onUserDetailChanged: function() {
        var data = AdminUserDetailStore.getData();
        GuiHelper.blockGuiLoading(false);

        // Check first if there is a feedback message
        if (typeof data.FeedbackMessage !== 'undefined') {
            if (data.FeedbackMessage === ActionConstants.ERROR) {
                // Unexpected error
                GuiHelper.unexpectedError();
            }
            else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
                // User saved successfully
                GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
            }
        }
        // If there is no feedback message, check for errors
        else {
            if (data.Errors !== null && data.Errors.length > 0) {
                // Errors
                GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
            }
            else {
                // No errors, data changed (either from initial load or from user input)
                this.setState({ entity: data.Data });

                // Load the user permissions if required
                // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
                var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
                if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                    this.loadUserPermissions(data.Data.Username);
                }
            }
        }
    },

    onUserDetailPermissionsChanged: function() {
        var data = AdminUserDetailPermissionsStore.getData();
        GuiHelper.blockGuiLoading(false);

        if (typeof data.FeedbackMessage !== 'undefined' && data.FeedbackMessage === ActionConstants.ERROR) {
            GuiHelper.unexpectedError();
        }
        else {
            var userPermissions = data.Data.map(function(i, idx) {
                return { role: i.Key, permission: i.Value, description: LanguageLoader.langDict['P_' + i.Value] };
            });
            this.setState({ userPermissions: userPermissions });
        }
    },

    componentDidMount: function () {
        // Initialize/clear the stores
        AdminUserDetailStore.setData({});
        AdminUserDetailPermissionsStore.setData({});

        if (this.props.id !== null) {
            GuiHelper.blockGuiLoading(true);
            ActionCreator.getUserDetail(this.props.id);
        }
    },

    loadUserPermissions :function(username) {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.getUserDetailPermissions(username);
    },

    saveUser: function () {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.postUserDetail(this.state.entity);
    },

    onUsernameChanged: function(e) {
        var entity = this.state.entity;
        entity.Username = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    onEmailChanged: function(e) {
        var entity = this.state.entity;
        entity.Email = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    render: function () {
        return (
            <div>
                <h1>{LanguageLoader.langDict.lblUserDetail}</h1>

                <form>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userUsername">{LanguageLoader.langDict.lblUsername}</label>
                                <input type="text" className="form-control" id="userUsername" value={this.state.entity.Username} placeholder={LanguageLoader.langDict.lblUsername} onChange={this.onUsernameChanged} />
                            </div>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userEmail">{LanguageLoader.langDict.lblEmailAddress}</label>
                                <input type="text" className="form-control" id="userEmail" value={this.state.entity.Email} placeholder={LanguageLoader.langDict.lblEmail} onChange={this.onEmailChanged} />
                            </div>
                        </div>
                    </div>
                </form>

                <div className={this.state.userPermissions === null ? 'hidden' : ''}>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label>{LanguageLoader.langDict.lblPermissionsFromRole}</label>
                                <div style={{height: 400}} className="ag-fresh">
                                    <AgGridReact gridOptions={this.state.gridOptions} columnDefs={this.state.userPermissionsColumns} rowData={this.state.userPermissions} />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        );
    }
});

module.exports = AdminUserDetail;
AdminUserDetail.js

import request from 'superagent';
var Promise = require('es6-promise').Promise;

module.exports = {
    get: function (url) {
        return new Promise(function (resolve, reject) {
            request
                .get(url)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    },

    post: function (url, data) {
        return new Promise(function (resolve, reject) {
            request
                .post(url)
                .send(data)
                .end(function (err, res) {
                    if (err !== null) {
                        reject();
                    }
                    else {
                        if (res.status === 404) {
                            reject();
                        }
                        else {
                            resolve(JSON.parse(res.text));
                        }
                    }
                });
        });
    }
}
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var Promise = require('es6-promise').Promise;
var Api = require('../Util/WebApiClient');

var ActionCreator = {
    apiServer: 'http://localhost:55010/api',

    getUserDetail: function (userId) {
        Api.get(this.apiServer + '/v1/User/' + userId)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    getUserDetailPermissions: function (username) {
        Api.get(this.apiServer + '/v1/Permission/ForUser?username=' + username)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.GET_USERPERMISSIONS, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    },

    postUserDetail: function (requestData) {
        Api.post(this.apiServer + '/v1/User/', requestData)
            .then(function (responseData) { Dispatcher.handleAction({ actionType: ActionConstants.POST_USER, data: responseData }); })
            .catch(function () { Dispatcher.handleAction({ actionType: ActionConstants.ERROR }); });
    }
};

module.exports = ActionCreator;
module.exports = {
  GET_USER: 'GET_USER',
  GET_USERPERMISSIONS: 'GET_USERPERMISSIONS',
  POST_USER: 'POST_USER',

  ERROR: 'ERROR',
  SUCCESS: 'SUCCESS'
};
var Dispatcher = require('flux').Dispatcher;

// Create dispatcher instance
var Dispatcher = new Dispatcher();

// Convenience method to handle dispatch requests
Dispatcher.handleAction = function(action) {
    this.dispatch({
        source: 'VIEW_ACTION',
        action: action
    });
}

module.exports = Dispatcher;
var Dispatcher = require('../Core/Dispatcher');
var ActionConstants = require('../Core/ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var AdminUserDetailStore = assign({}, EventEmitter.prototype, {
    data: {},

    // Called after the initial GET to load the initial User entity
    // or from user input
    setData: function(data, doEmitChange) {
        this.data = data;

        if (typeof doEmitChange !== 'undefined' && doEmitChange) {
            this.emitChange();
        }
    },

    // Called from a POST when trying to save the User entity
    // or when getting an unexpected error (e.g. api server unavailable)
    setFeedbackMessage: function(data, message) {
        if (typeof message !== 'undefined')
            this.data.FeedbackMessage = message;
        else {
            if (data.Errors.length > 0)
                this.data.Errors = data.Errors;
            else
                this.data.FeedbackMessage = ActionConstants.SUCCESS;
        }
    },

    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },

    getData: function () {
        return this.data;
    }
});

Dispatcher.register(function(payload) {
    var action = payload.action;

    switch(action.actionType) {
        case ActionConstants.ERROR:
            // Force a feedback message
            AdminUserDetailStore.setFeedbackMessage(null, ActionConstants.ERROR);
            break;
        case ActionConstants.GET_USER:
            AdminUserDetailStore.setData(action.data);
            break;
        case ActionConstants.POST_USER:
            // Check for errors wthin the data object and set a SUCCESS feedback message if none are found
            AdminUserDetailStore.setFeedbackMessage(action.data);
            break;
        default:
            return true;
    }

    AdminUserDetailStore.emitChange();
    return true;
});

module.exports = AdminUserDetailStore;
import React from 'react';
import ReactDOM from 'react-dom';
import ActionCreator from '../../Core/ActionCreator';
import ActionConstants from '../../Core/ActionConstants';

import AdminUserDetailStore  from '../../Stores/AdminUserDetailStore';
import AdminUserDetailPermissionsStore  from '../../Stores/AdminUserDetailPermissionsStore';

import LanguageLoader from '../../Util/LanguageLoader';
import GuiHelper from '../../Util/GuiHelper';
import BootstrapDialog from 'bootstrap-dialog';

import blockUI from '../../../Content/js/jquery.blockUI.js';

import {AgGridReact} from 'ag-grid-react';
import BoolCellEditor from '../AgGrid/BoolCellEditor';

$ = window.$ = window.jQuery = require('jquery');

var AdminUserDetail = React.createClass({
    getInitialState: function () {
        return {
            entity: {
                Id: 0,
                Username: '',
                Email: ''
            },

            userPermissions: null,
            userPermissionsColumns: [
                { headerName: LanguageLoader.langDict.lblRole, field: 'role' },
                { headerName: LanguageLoader.langDict.lblPermission, field: 'permission' },
                { headerName: LanguageLoader.langDict.lblDescription, field: 'description', width:600 }
            ],

            gridOptions: {
                context: this,
                singleClickEdit: true,
                enableColResize: true,
                onGridReady: function(event) {
                    //event.api.autoSizeColumns();
                },
            },
        };
    },

    getDefaultProps: function () {
        return { };
    },

    componentWillMount: function () {
        AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
    },

    componentWillUnmount: function () {
        AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
        AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
    },

    // ALL OF THIS IS UGLY
    onUserDetailChanged: function() {
        var data = AdminUserDetailStore.getData();
        GuiHelper.blockGuiLoading(false);

        // Check first if there is a feedback message
        if (typeof data.FeedbackMessage !== 'undefined') {
            if (data.FeedbackMessage === ActionConstants.ERROR) {
                // Unexpected error
                GuiHelper.unexpectedError();
            }
            else if (data.FeedbackMessage === ActionConstants.SUCCESS) {
                // User saved successfully
                GuiHelper.infoDialog(BootstrapDialog.TYPE_SUCCESS, LanguageLoader.langDict.msgUserSaved);
            }
        }
        // If there is no feedback message, check for errors
        else {
            if (data.Errors !== null && data.Errors.length > 0) {
                // Errors
                GuiHelper.infoDialog(BootstrapDialog.TYPE_DANGER, GuiHelper.renderErrors(data.Errors));
            }
            else {
                // No errors, data changed (either from initial load or from user input)
                this.setState({ entity: data.Data });

                // Load the user permissions if required
                // (CAN I PLACE THIS CODE ELSEWHERE THAN IN THIS FUNCTION?)
                var userPermissions = AdminUserDetailPermissionsStore.getData().Data;
                if (this.state.entity.Id !== 0 && typeof userPermissions === 'undefined') {
                    this.loadUserPermissions(data.Data.Username);
                }
            }
        }
    },

    onUserDetailPermissionsChanged: function() {
        var data = AdminUserDetailPermissionsStore.getData();
        GuiHelper.blockGuiLoading(false);

        if (typeof data.FeedbackMessage !== 'undefined' && data.FeedbackMessage === ActionConstants.ERROR) {
            GuiHelper.unexpectedError();
        }
        else {
            var userPermissions = data.Data.map(function(i, idx) {
                return { role: i.Key, permission: i.Value, description: LanguageLoader.langDict['P_' + i.Value] };
            });
            this.setState({ userPermissions: userPermissions });
        }
    },

    componentDidMount: function () {
        // Initialize/clear the stores
        AdminUserDetailStore.setData({});
        AdminUserDetailPermissionsStore.setData({});

        if (this.props.id !== null) {
            GuiHelper.blockGuiLoading(true);
            ActionCreator.getUserDetail(this.props.id);
        }
    },

    loadUserPermissions :function(username) {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.getUserDetailPermissions(username);
    },

    saveUser: function () {
        GuiHelper.blockGuiLoading(true);
        ActionCreator.postUserDetail(this.state.entity);
    },

    onUsernameChanged: function(e) {
        var entity = this.state.entity;
        entity.Username = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    onEmailChanged: function(e) {
        var entity = this.state.entity;
        entity.Email = e.target.value;
        AdminUserDetailStore.setData({ Errors: null, Data: entity }, true);
    },

    render: function () {
        return (
            <div>
                <h1>{LanguageLoader.langDict.lblUserDetail}</h1>

                <form>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userUsername">{LanguageLoader.langDict.lblUsername}</label>
                                <input type="text" className="form-control" id="userUsername" value={this.state.entity.Username} placeholder={LanguageLoader.langDict.lblUsername} onChange={this.onUsernameChanged} />
                            </div>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label htmlFor="userEmail">{LanguageLoader.langDict.lblEmailAddress}</label>
                                <input type="text" className="form-control" id="userEmail" value={this.state.entity.Email} placeholder={LanguageLoader.langDict.lblEmail} onChange={this.onEmailChanged} />
                            </div>
                        </div>
                    </div>
                </form>

                <div className={this.state.userPermissions === null ? 'hidden' : ''}>
                    <div className="row">
                        <div className="col-lg-3 col-md-4 col-sm-6 col-xs-9 col-centered">
                            <div className="form-group">
                                <label>{LanguageLoader.langDict.lblPermissionsFromRole}</label>
                                <div style={{height: 400}} className="ag-fresh">
                                    <AgGridReact gridOptions={this.state.gridOptions} columnDefs={this.state.userPermissionsColumns} rowData={this.state.userPermissions} />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        );
    }
});

module.exports = AdminUserDetail;
从“React”导入React;
从“react dom”导入react dom;
从“../Core/ActionCreator”导入ActionCreator;
从“../../Core/ActionConstants”导入ActionConstants;
从“../../Stores/AdminUserDetailStore”导入AdminUserDetailStore;
从“../../Stores/AdminUserDetailPermissionsStore”导入AdminUserDetailPermissionsStore;
从“../../Util/LanguageLoader”导入LanguageLoader;
从“../../Util/GuiHelper”导入GuiHelper;
从“引导对话框”导入引导对话框;
从“../../Content/js/jquery.blockUI.js”导入blockUI;
从'ag grid react'导入{AgGridReact};
从“../AgGrid/BoolCellEditor”导入BoolCellEditor;
$=window.$=window.jQuery=require('jQuery');
var AdminUserDetail=React.createClass({
getInitialState:函数(){
返回{
实体:{
Id:0,
用户名:“”,
电子邮件:“”
},
userPermissions:null,
用户权限列:[
{headerName:LanguageLoader.langDict.lblRole,字段:'role'},
{headerName:LanguageLoader.langDict.lblPermission,字段:'permission'},
{headerName:LanguageLoader.langDict.lblDescription,字段:'description',宽度:600}
],
网格选项:{
背景:这,,
singleClickEdit:true,
enableColResize:true,
onGridReady:函数(事件){
//event.api.autoSizeColumns();
},
},
};
},
getDefaultProps:函数(){
返回{};
},
componentWillMount:函数(){
AdminUserDetailStore.addChangeListener(this.onUserDetailChanged);
AdminUserDetailPermissionsStore.addChangeListener(this.onUserDetailPermissionsChanged);
},
componentWillUnmount:函数(){
AdminUserDetailStore.removeChangeListener(this.onUserDetailChanged);
AdminUserDetailPermissionsStore.removeChangeListener(this.onUserDetailPermissionsChanged);
},
//所有这些都是丑陋的
onUserDetailChanged:函数(){
var data=AdminUserDetailStore.getData();
GuiHelper.blockGuiLoading(false);
//首先检查是否有反馈信息
if(type of data.FeedbackMessage!=“未定义”){
if(data.FeedbackMessage==ActionConstants.ERROR){
//意外错误
GuiHelper.unexpectedError();
}
else if(data.FeedbackMessage==ActionConstants.SUCCESS){
//用户已成功保存
infoDialog(BootstrapDialog.TYPE_SUCCESS,LanguageLoader.langDict.msgUserSaved);
}
}
//如果没有反馈消息,请检查错误
否则{
if(data.Errors!==null&&data.Errors.length>0){
//错误
infoDialog(BootstrapDialog.TYPE_-DANGER,GuiHelper.renderErrors(data.Errors));
}
否则{
//无错误,数据已更改(来自初始加载或用户输入)
this.setState({entity:data.data});
//如果需要,加载用户权限
//(我可以将此代码放置在此函数之外的其他位置吗?)
var userPermissions=AdminUserDetailPermissionsStore.getData().Data;
if(this.state.entity.Id!==0&&typeof userPermissions==='undefined'){
this.loadUserPermissions(data.data.Username);
}
}
}
},
onUserDetailPermissionsChanged:函数(){
var data=AdminUserDetailPermissionsStore.getData();
GuiHelper.blockGuiLoading(fals