<commit_before>/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/
(function($) {

    /*
    ======== A Handy Little QUnit Reference ========
    http://docs.jquery.com/QUnit

    Test methods:
    expect(numAssertions)
    stop(increment)
    start(decrement)
    Test assertions:
    ok(value, [message])
    equal(actual, expected, [message])
    notEqual(actual, expected, [message])
    deepEqual(actual, expected, [message])
    notDeepEqual(actual, expected, [message])
    strictEqual(actual, expected, [message])
    notStrictEqual(actual, expected, [message])
    raises(block, [expected], [message])
    */

    module("ivle (initialization)");

    test("ivle is added into window", function() {
        notEqual(window.ivle, undefined, "should be defined");
    });

    module("ivle (static methods)");

    test("ivle getToken will return the token from string", function() {
        equal(ivle.getToken("aaa"), undefined, "invalid token will return undefined");
        equal(ivle.getToken("test?token=aaa"), "aaa", "return valid token");
        equal(ivle.getToken("test?TOKEN=aaa"), "aaa", "return valid token ignore case");
    });

    test("ivle login will return the login url", function() {
        equal(ivle.login("a", "url"),
            "https://ivle.nus.edu.sg/api/login/?apikey=a&url=url",
            "return valid login url");
    });

    module("ivle (user generate)");

    test("ivle get user", function() {
        var user = (new ivle("key")).User("token");

        equal(user.KEY, "key", "user will has the key");
        equal(user.TOKEN, "token", "user will has the auth token");
    });

    var userA, _ajax;

    module("user identities", {
        setup: function() {
            // save a copy of the actual $.ajax
            _ajax = $.ajax;
            // keep a count
            var count = 0;
            // customized ajax
            function ajax(url) {
                count++;

                this.count = function() { return count; };

                this.success = function(callback) {
                    callback(url);
                };

                this.error = function(callback) {
                    callback(url);
                };
            }
            // substitude $.ajax with another one
            $.ajax = function(options) {
                return new ajax(options.url);
            };

            // create a user
            userA = (new ivle("key").User("token"));
        },
        teardown: function() {
            // return the original ajax
            $.ajax = _ajax;
            // destroy user
            userA = undefined;
        }
    });

    test("get user id", function() {
        var ajax = $.ajax({url:"empty"});

        equal(ajax.count(), 1, "starting ajax count = 1");

        // user id
        userA.id(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserID_Get?APIKey=key&Token=token&output=json",
                "get user id");
        });

        equal(ajax.count(), 2, "call to get id -> ajax count = 2");

        userA.id(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserID_Get?APIKey=key&Token=token&output=json",
                "get user id again");
        });

        equal(ajax.count(), 2, "call to get id is cached -> ajax count = 2");
    });

    test("get user name", function() {
        var ajax = $.ajax({url:"empty"});

        equal(ajax.count(), 1, "starting ajax count = 1");

        userA.name(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserName_Get?APIKey=key&Token=token&output=json",
                "get user name");
        });

        equal(ajax.count(), 2, "call to get name -> ajax count = 2");

        userA.name(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserName_Get?APIKey=key&Token=token&output=json",
                "get user name again");
        });

        equal(ajax.count(), 2, "call to get name is cached -> ajax count = 2");
    });

    test("get user email", function() {
        var ajax = $.ajax({url:"empty"});

        equal(ajax.count(), 1, "starting ajax count = 1");

        userA.email(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserEmail_Get?APIKey=key&Token=token&output=json",
                "get user email");
        });

        equal(ajax.count(), 2, "call to get email -> ajax count = 2");

        userA.email(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserEmail_Get?APIKey=key&Token=token&output=json",
                "get user email again");
        });

        equal(ajax.count(), 2, "call to get email -> ajax count = 2");
    });

}(jQuery));
<commit_msg>organize test module names<commit_after>/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/
(function($) {

    /*
    ======== A Handy Little QUnit Reference ========
    http://docs.jquery.com/QUnit

    Test methods:
    expect(numAssertions)
    stop(increment)
    start(decrement)
    Test assertions:
    ok(value, [message])
    equal(actual, expected, [message])
    notEqual(actual, expected, [message])
    deepEqual(actual, expected, [message])
    notDeepEqual(actual, expected, [message])
    strictEqual(actual, expected, [message])
    notStrictEqual(actual, expected, [message])
    raises(block, [expected], [message])
    */

    module("ivle base");

    test("ivle is added into window", function() {
        notEqual(window.ivle, undefined, "should be defined");
    });

    test("ivle getToken will return the token from string", function() {
        equal(ivle.getToken("aaa"), undefined, "invalid token will return undefined");
        equal(ivle.getToken("test?token=aaa"), "aaa", "return valid token");
        equal(ivle.getToken("test?TOKEN=aaa"), "aaa", "return valid token ignore case");
    });

    test("ivle login will return the login url", function() {
        equal(ivle.login("a", "url"),
            "https://ivle.nus.edu.sg/api/login/?apikey=a&url=url",
            "return valid login url");
    });

    var userA, _ajax;

    module("ivle.User", {
        setup: function() {
            // save a copy of the actual $.ajax
            _ajax = $.ajax;
            // keep a count
            var count = 0;
            // customized ajax
            function ajax(url) {
                count++;

                this.count = function() { return count; };

                this.success = function(callback) {
                    callback(url);
                };

                this.error = function(callback) {
                    callback(url);
                };
            }
            // substitude $.ajax with another one
            $.ajax = function(options) {
                return new ajax(options.url);
            };

            // create a user
            userA = (new ivle("key").User("token"));
        },
        teardown: function() {
            // return the original ajax
            $.ajax = _ajax;
            // destroy user
            userA = undefined;
        }
    });

    test("ivle can create user", function() {
        var user = (new ivle("key")).User("token");

        equal(user.KEY, "key", "user will has the key");
        equal(user.TOKEN, "token", "user will has the auth token");
    });

    test("get user id", function() {
        var ajax = $.ajax({url:"empty"});

        equal(ajax.count(), 1, "starting ajax count = 1");

        // user id
        userA.id(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserID_Get?APIKey=key&Token=token&output=json",
                "get user id");
        });

        equal(ajax.count(), 2, "call to get id -> ajax count = 2");

        userA.id(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserID_Get?APIKey=key&Token=token&output=json",
                "get user id again");
        });

        equal(ajax.count(), 2, "call to get id is cached -> ajax count = 2");
    });

    test("get user name", function() {
        var ajax = $.ajax({url:"empty"});

        equal(ajax.count(), 1, "starting ajax count = 1");

        userA.name(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserName_Get?APIKey=key&Token=token&output=json",
                "get user name");
        });

        equal(ajax.count(), 2, "call to get name -> ajax count = 2");

        userA.name(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserName_Get?APIKey=key&Token=token&output=json",
                "get user name again");
        });

        equal(ajax.count(), 2, "call to get name is cached -> ajax count = 2");
    });

    test("get user email", function() {
        var ajax = $.ajax({url:"empty"});

        equal(ajax.count(), 1, "starting ajax count = 1");

        userA.email(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserEmail_Get?APIKey=key&Token=token&output=json",
                "get user email");
        });

        equal(ajax.count(), 2, "call to get email -> ajax count = 2");

        userA.email(function(data) {
            equal(data,
                "https://ivle.nus.edu.sg/api/lapi.svc/UserEmail_Get?APIKey=key&Token=token&output=json",
                "get user email again");
        });

        equal(ajax.count(), 2, "call to get email -> ajax count = 2");
    });

}(jQuery));
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] &&<commit_msg>Updated the readme<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && <|endoftext|>


<commit_before>/**
 * Created by yangyang on 2017/9/4.
 */
import React from 'react'
import {connect} from 'react-redux'
import {
  Menu,
  Icon,
  Button,
} from 'antd'
import {withRouter, Link} from 'react-router-dom'
import {selector as authSelector} from '../util/auth/'
import {PERMISSION_CODE} from '../util/rolePermission/'

const SubMenu = Menu.SubMenu

class SiderMenu extends React.Component {
  constructor(props) {
    super(props)
  }

  state = {
    current: '1',
    openKeys: [],
  };

  handleClick = (e) => {
    console.log('Clicked: ', e);
    this.setState({ current: e.key });
  };

  onOpenChange = (openKeys) => {
    const state = this.state;
    const latestOpenKey = openKeys.find(key => !(state.openKeys.indexOf(key) > -1));
    const latestCloseKey = state.openKeys.find(key => !(openKeys.indexOf(key) > -1));

    let nextOpenKeys = [];
    if (latestOpenKey) {
      nextOpenKeys = this.getAncestorKeys(latestOpenKey).concat(latestOpenKey);
    }
    if (latestCloseKey) {
      nextOpenKeys = this.getAncestorKeys(latestCloseKey);
    }
    this.setState({ openKeys: nextOpenKeys });
  };

  getAncestorKeys = (key) => {
    const map = {
      sub3: ['sub2'],
    };
    return map[key] || [];
  };

  renderQueryDeviceMenu() {
    let {queryDeviceVisible} = this.props
    if (queryDeviceVisible) {
      return (
        <Menu.SubMenu key="/device" title={<Icon type="laptop" />干衣柜综合管理}>
          <Menu.Item key="/device_list"><Link to="/device_list">干衣柜信息管理</Link></Menu.Item>
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderStationMenu() {
    let {stationQueryVisible, stationInvestorVisible} = this.props
    if (stationQueryVisible || stationInvestorVisible) {
      let items = []
      if (stationQueryVisible) {
        items.push(<Menu.Item key="/site_list"><Link to="/site_list">服务点信息管理</Link></Menu.Item>)
      }
      if (stationInvestorVisible) {
        items.push(<Menu.Item key="/site_investor"><Link to="/site_investor">投资人信息管理</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/site" title={<Icon type="laptop" />服务点综合管理}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderRechargeOrderMenu() {
    let {orderVisible, rechargeVisible} = this.props
    if (orderVisible || rechargeVisible) {
      let items = []
      if (orderVisible) {
        items.push(<Menu.Item key="/order_list"><Link to="/order_list">订单信息管理</Link></Menu.Item>)
      }
      if (rechargeVisible) {
        items.push(<Menu.Item key="/order_recharge"><Link to="/order_recharge">用户充值管理</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/order" title={<Icon type="notification" />充值与订单管理}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderAccountMenu() {
    let {accountStationVisible, accountDepartmentVisible, accountInvestorVisible} = this.props
    if (accountStationVisible || accountDepartmentVisible || accountInvestorVisible) {
      let items = []
      if (accountStationVisible) {
        items.push(<Menu.Item key="/settlement_list"><Link to="/settlement_list">服务点分成统计</Link></Menu.Item>)
      }
      if (accountDepartmentVisible) {
        items.push(<Menu.Item key="/settlement_site"><Link to="/settlement_site">服务单位分成结算</Link></Menu.Item>)
      }
      if (accountInvestorVisible) {
        items.push(<Menu.Item key="/settlement_investor"><Link to="/settlement_investor">投资人分成结算</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/settlement" title={<Icon type="notification" />结算报表}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderMarkingMenu() {
    let {marketManVisible, marketRechargeVisible, marketCreditVisible, marketRedPacketsVisible, marketCreditExchangeVisible} = this.props
    if (marketManVisible || marketRechargeVisible || marketCreditVisible || marketRedPacketsVisible || marketCreditExchangeVisible) {
      let items = []
      if (marketManVisible) {
        items.push(<Menu.Item key="/promotion_list"><Link to="/promotion_list">活动管理</Link></Menu.Item>)
      }
      if (marketRechargeVisible) {
        items.push(<Menu.Item key="/promotion_recharge"><Link to="/promotion_recharge">发布充值活动</Link></Menu.Item>)
      }
      if (marketCreditVisible) {
        items.push(<Menu.Item key="/promotion_score"><Link to="/promotion_score">发布积分倍率活动</Link></Menu.Item>)
      }
      if (marketCreditExchangeVisible) {
        items.push(<Menu.Item key="/promotion_scoreExchange"><Link to="/promotion_scoreExchange">发布积分兑换活动</Link></Menu.Item>)
      }
      if (marketRedPacketsVisible) {
        items.push(<Menu.Item key="/promotion_redEnvelope"><Link to="/promotion_redEnvelope">发布红包活动</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/promotion" title={<Icon type="notification" />营销活动}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderSysManMenu() {
    if (this.props.sysUserVisible || this.props.sysLogVisible) {
      const items = [];
      if (this.props.sysUserVisible) {
        items.push(<Menu.Item key='/system_user'><Link to='/system_user'>用户与角色管理</Link></Menu.Item>);
      }
      if (this.props.sysLogVisible) {
        items.push(<Menu.Item key='/system_log'><Link to='/system_log'>操作日志管理</Link></Menu.Item>);
      }
      return (
        <Menu.SubMenu key="/system" title={<Icon type="notification"/>系统管理}>
          {items}
        </Menu.SubMenu>
      );
    }
    return null
  }

  renderProfitMenu() {
    let {profitVisible} = this.props
    if (profitVisible) {
      return (
        <Menu.SubMenu key="/profit" title={<Icon type="notification" />投资收益}>
          <Menu.Item key="/profit_list"><Link to="/profit_list">投资收益管理</Link></Menu.Item>
        </Menu.SubMenu>
      )
    }
    return null
  }

  render() {
    return (
      <Menu
        theme="dark"
        mode="inline"
        openKeys={this.state.openKeys}
        selectedKeys={[this.state.current]}
        onOpenChange={this.onOpenChange}
        onClick={this.handleClick}
        className="app-sider-menu"
      >
        {this.renderQueryDeviceMenu()}
        {this.renderStationMenu()}
        {this.renderRechargeOrderMenu()}
        {this.renderAccountMenu()}
        {this.renderMarkingMenu()}
        <Menu.SubMenu key="/user" title={<Icon type="notification" />用户管理}>
          <Menu.Item key="/user_list"><Link to="/user_list">用户信息管理</Link></Menu.Item>
        </Menu.SubMenu>
        <Menu.SubMenu key="/message" title={<Icon type="notification" />消息推送}>
          <Menu.Item key="/message_system"><Link to="/message_system">系统消息</Link></Menu.Item>
          <Menu.Item key="/message_promotion"><Link to="/message_promotion">营销类消息</Link></Menu.Item>
        </Menu.SubMenu>
        {this.renderSysManMenu()}
        {this.renderProfitMenu()}
      </Menu>
    )
  }
}

const mapStateToProps = (appState, ownProps) => {
  const queryDeviceVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.DEVICE_QUERY_INFO])

  const stationQueryVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.STATION_QUERY_WHOLE, PERMISSION_CODE.STATION_QUERY_PART])
  const stationInvestorVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.STATION_INVESTOR_QUERY_WHOLE, PERMISSION_CODE.STATION_INVESTOR_QUERY_PART])

  const orderVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.RECHARGE_ORDER_QUERY])
  const rechargeVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.RECHARGE_MAN_USER_PAID])

  const accountStationVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.ACCOUNT_STAT_STATION_DIVIDEND])
  const accountDepartmentVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.ACCOUNT_STATION_DEPARTMENT_DIVIDEND])
  const accountInvestorVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.ACCOUNT_INVESTOR_DIVIDEND])

  const marketManVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_MAN_ACTIVITY])
  const marketRechargeVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_RECHARGE])
  const marketCreditVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_CREDIT])
  const marketRedPacketsVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_RED_PACKETS])
  const marketCreditExchangeVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_CREDIT_EXCHANGE])

  const sysUserVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.SYSMAN_MAN_USER_ROLE]);
  const sysLogVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.SYSMAN_MAN_OPER_LOG]);

  const profitVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.INVEST_PROFIT_MANAGER])

  return {
    queryDeviceVisible,
    stationQueryVisible,
    stationInvestorVisible,
    orderVisible,
    rechargeVisible,
    accountStationVisible,
    accountDepartmentVisible,
    accountInvestorVisible,
    marketManVisible,
    marketRechargeVisible,
    marketCreditVisible,
    marketRedPacketsVisible,
    marketCreditExchangeVisible,
    sysUserVisible,
    sysLogVisible,
    profitVisible,
  };
};

export default withRouter(connect(mapStateToProps, null)(SiderMenu))
<commit_msg>add manage user permission<commit_after>/**
 * Created by yangyang on 2017/9/4.
 */
import React from 'react'
import {connect} from 'react-redux'
import {
  Menu,
  Icon,
  Button,
} from 'antd'
import {withRouter, Link} from 'react-router-dom'
import {selector as authSelector} from '../util/auth/'
import {PERMISSION_CODE} from '../util/rolePermission/'

const SubMenu = Menu.SubMenu

class SiderMenu extends React.Component {
  constructor(props) {
    super(props)
  }

  state = {
    current: '1',
    openKeys: [],
  };

  handleClick = (e) => {
    console.log('Clicked: ', e);
    this.setState({ current: e.key });
  };

  onOpenChange = (openKeys) => {
    const state = this.state;
    const latestOpenKey = openKeys.find(key => !(state.openKeys.indexOf(key) > -1));
    const latestCloseKey = state.openKeys.find(key => !(openKeys.indexOf(key) > -1));

    let nextOpenKeys = [];
    if (latestOpenKey) {
      nextOpenKeys = this.getAncestorKeys(latestOpenKey).concat(latestOpenKey);
    }
    if (latestCloseKey) {
      nextOpenKeys = this.getAncestorKeys(latestCloseKey);
    }
    this.setState({ openKeys: nextOpenKeys });
  };

  getAncestorKeys = (key) => {
    const map = {
      sub3: ['sub2'],
    };
    return map[key] || [];
  };

  renderQueryDeviceMenu() {
    let {queryDeviceVisible} = this.props
    if (queryDeviceVisible) {
      return (
        <Menu.SubMenu key="/device" title={<Icon type="laptop" />干衣柜综合管理}>
          <Menu.Item key="/device_list"><Link to="/device_list">干衣柜信息管理</Link></Menu.Item>
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderStationMenu() {
    let {stationQueryVisible, stationInvestorVisible} = this.props
    if (stationQueryVisible || stationInvestorVisible) {
      let items = []
      if (stationQueryVisible) {
        items.push(<Menu.Item key="/site_list"><Link to="/site_list">服务点信息管理</Link></Menu.Item>)
      }
      if (stationInvestorVisible) {
        items.push(<Menu.Item key="/site_investor"><Link to="/site_investor">投资人信息管理</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/site" title={<Icon type="laptop" />服务点综合管理}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderRechargeOrderMenu() {
    let {orderVisible, rechargeVisible} = this.props
    if (orderVisible || rechargeVisible) {
      let items = []
      if (orderVisible) {
        items.push(<Menu.Item key="/order_list"><Link to="/order_list">订单信息管理</Link></Menu.Item>)
      }
      if (rechargeVisible) {
        items.push(<Menu.Item key="/order_recharge"><Link to="/order_recharge">用户充值管理</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/order" title={<Icon type="notification" />充值与订单管理}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderAccountMenu() {
    let {accountStationVisible, accountDepartmentVisible, accountInvestorVisible} = this.props
    if (accountStationVisible || accountDepartmentVisible || accountInvestorVisible) {
      let items = []
      if (accountStationVisible) {
        items.push(<Menu.Item key="/settlement_list"><Link to="/settlement_list">服务点分成统计</Link></Menu.Item>)
      }
      if (accountDepartmentVisible) {
        items.push(<Menu.Item key="/settlement_site"><Link to="/settlement_site">服务单位分成结算</Link></Menu.Item>)
      }
      if (accountInvestorVisible) {
        items.push(<Menu.Item key="/settlement_investor"><Link to="/settlement_investor">投资人分成结算</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/settlement" title={<Icon type="notification" />结算报表}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderMarkingMenu() {
    let {marketManVisible, marketRechargeVisible, marketCreditVisible, marketRedPacketsVisible, marketCreditExchangeVisible} = this.props
    if (marketManVisible || marketRechargeVisible || marketCreditVisible || marketRedPacketsVisible || marketCreditExchangeVisible) {
      let items = []
      if (marketManVisible) {
        items.push(<Menu.Item key="/promotion_list"><Link to="/promotion_list">活动管理</Link></Menu.Item>)
      }
      if (marketRechargeVisible) {
        items.push(<Menu.Item key="/promotion_recharge"><Link to="/promotion_recharge">发布充值活动</Link></Menu.Item>)
      }
      if (marketCreditVisible) {
        items.push(<Menu.Item key="/promotion_score"><Link to="/promotion_score">发布积分倍率活动</Link></Menu.Item>)
      }
      if (marketCreditExchangeVisible) {
        items.push(<Menu.Item key="/promotion_scoreExchange"><Link to="/promotion_scoreExchange">发布积分兑换活动</Link></Menu.Item>)
      }
      if (marketRedPacketsVisible) {
        items.push(<Menu.Item key="/promotion_redEnvelope"><Link to="/promotion_redEnvelope">发布红包活动</Link></Menu.Item>)
      }
      return (
        <Menu.SubMenu key="/promotion" title={<Icon type="notification" />营销活动}>
          {items}
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderManUserMenu() {
    let {manUserVisible} = this.props
    if (manUserVisible) {
      return (
        <Menu.SubMenu key="/user" title={<Icon type="notification" />用户管理}>
          <Menu.Item key="/user_list"><Link to="/user_list">用户信息管理</Link></Menu.Item>
        </Menu.SubMenu>
      )
    }
    return null
  }

  renderSysManMenu() {
    if (this.props.sysUserVisible || this.props.sysLogVisible) {
      const items = [];
      if (this.props.sysUserVisible) {
        items.push(<Menu.Item key='/system_user'><Link to='/system_user'>用户与角色管理</Link></Menu.Item>);
      }
      if (this.props.sysLogVisible) {
        items.push(<Menu.Item key='/system_log'><Link to='/system_log'>操作日志管理</Link></Menu.Item>);
      }
      return (
        <Menu.SubMenu key="/system" title={<Icon type="notification"/>系统管理}>
          {items}
        </Menu.SubMenu>
      );
    }
    return null
  }

  renderProfitMenu() {
    let {profitVisible} = this.props
    if (profitVisible) {
      return (
        <Menu.SubMenu key="/profit" title={<Icon type="notification" />投资收益}>
          <Menu.Item key="/profit_list"><Link to="/profit_list">投资收益管理</Link></Menu.Item>
        </Menu.SubMenu>
      )
    }
    return null
  }

  render() {
    return (
      <Menu
        theme="dark"
        mode="inline"
        openKeys={this.state.openKeys}
        selectedKeys={[this.state.current]}
        onOpenChange={this.onOpenChange}
        onClick={this.handleClick}
        className="app-sider-menu"
      >
        {this.renderQueryDeviceMenu()}
        {this.renderStationMenu()}
        {this.renderRechargeOrderMenu()}
        {this.renderAccountMenu()}
        {this.renderMarkingMenu()}
        {this.renderManUserMenu()}
        <Menu.SubMenu key="/message" title={<Icon type="notification" />消息推送}>
          <Menu.Item key="/message_system"><Link to="/message_system">系统消息</Link></Menu.Item>
          <Menu.Item key="/message_promotion"><Link to="/message_promotion">营销类消息</Link></Menu.Item>
        </Menu.SubMenu>
        {this.renderSysManMenu()}
        {this.renderProfitMenu()}
      </Menu>
    )
  }
}

const mapStateToProps = (appState, ownProps) => {
  const queryDeviceVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.DEVICE_QUERY_INFO])

  const stationQueryVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.STATION_QUERY_WHOLE, PERMISSION_CODE.STATION_QUERY_PART])
  const stationInvestorVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.STATION_INVESTOR_QUERY_WHOLE, PERMISSION_CODE.STATION_INVESTOR_QUERY_PART])

  const orderVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.RECHARGE_ORDER_QUERY])
  const rechargeVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.RECHARGE_MAN_USER_PAID])

  const accountStationVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.ACCOUNT_STAT_STATION_DIVIDEND])
  const accountDepartmentVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.ACCOUNT_STATION_DEPARTMENT_DIVIDEND])
  const accountInvestorVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.ACCOUNT_INVESTOR_DIVIDEND])

  const marketManVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_MAN_ACTIVITY])
  const marketRechargeVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_RECHARGE])
  const marketCreditVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_CREDIT])
  const marketRedPacketsVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_RED_PACKETS])
  const marketCreditExchangeVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.MARKETING_PUBLISH_CREDIT_EXCHANGE])

  const manUserVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.USER_MAN_USER_PROFILE])

  const sysUserVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.SYSMAN_MAN_USER_ROLE]);
  const sysLogVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.SYSMAN_MAN_OPER_LOG]);

  const profitVisible = authSelector.selectValidPermissions(appState, [PERMISSION_CODE.INVEST_PROFIT_MANAGER])

  return {
    queryDeviceVisible,
    stationQueryVisible,
    stationInvestorVisible,
    orderVisible,
    rechargeVisible,
    accountStationVisible,
    accountDepartmentVisible,
    accountInvestorVisible,
    marketManVisible,
    marketRechargeVisible,
    marketCreditVisible,
    marketRedPacketsVisible,
    marketCreditExchangeVisible,
    manUserVisible,
    sysUserVisible,
    sysLogVisible,
    profitVisible,
  };
};

export default withRouter(connect(mapStateToProps, null)(SiderMenu))
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import Button from 'fyndiq-component-button'

import Modal from './modal'

// Proptype checker: checks that the element is of a specific Component type
// FIXME: this declaration should be in its own package, like fyndiq-utils
// or fyndiq-prop-types or something
export const ElementOfType = type => (props, propName, componentName) => {
  const prop = props[propName]
  if (React.isValidElement(prop) && prop.type === type) return null

  // Otherwise, return Error
  return new Error(
    `Invalid prop \`${propName}\` supplied to` +
      ` \`${componentName}\`. Must be of type ${type.displayName || type.name}`,
  )
}

class ModalButton extends React.Component {
  static propTypes = {
    button: PropTypes.oneOfType([PropTypes.string, ElementOfType(Button)]),
    children: PropTypes.oneOfType([PropTypes.node, ElementOfType(Modal)]),
  }

  static defaultProps = {
    button: 'Open Modal',
    children: null,
  }

  constructor(props) {
    super(props)
    this.state = { open: false }

    this.openModal = this.openModal.bind(this)
    this.closeModal = this.closeModal.bind(this)
  }

  getButton() {
    const { button } = this.props
    if (React.isValidElement(button) && button.type === Button) {
      return React.cloneElement(button, {
        onClick: this.openModal,
      })
    }

    return <Button onClick={this.openModal}>{button}</Button>
  }

  getModal() {
    const { children } = this.props

    const modalProps = {
      open: this.state.open,
      onClose: this.closeModal,
    }
    if (React.isValidElement(children) && children.type === Modal) {
      return React.cloneElement(this.props.children, modalProps)
    }

    return <Modal {...modalProps}>{children}</Modal>
  }

  closeModal() {
    this.setState({ open: false })
  }

  openModal() {
    this.setState({ open: true })
  }

  render() {
    return (

        {this.getButton()}
        {this.getModal()}

    )
  }
}

export default ModalButton
<commit_msg>:bug: Handle cases when it's not the same version<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import Button from 'fyndiq-component-button'

import Modal from './modal'

const isSameType = (element, component) =>
  React.isValidElement(element) &&
  (element.type === component || element.type.displayName === component.name)

// Proptype checker: checks that the element is of a specific Component type
// FIXME: this declaration should be in its own package, like fyndiq-utils
// or fyndiq-prop-types or something
export const ElementOfType = type => (props, propName, componentName) => {
  const prop = props[propName]
  if (isSameType(prop, type)) return null

  // Otherwise, return Error
  return new Error(
    `Invalid prop \`${propName}\` supplied to` +
      ` \`${componentName}\`. Must be of type ${type.displayName || type.name}`,
  )
}

class ModalButton extends React.Component {
  static propTypes = {
    button: PropTypes.oneOfType([PropTypes.string, ElementOfType(Button)]),
    children: PropTypes.oneOfType([PropTypes.node, ElementOfType(Modal)]),
  }

  static defaultProps = {
    button: 'Open Modal',
    children: null,
  }

  constructor(props) {
    super(props)
    this.state = { open: false }

    this.openModal = this.openModal.bind(this)
    this.closeModal = this.closeModal.bind(this)
  }

  getButton() {
    const { button } = this.props
    console.log(button.type.displayName, Button.name)
    if (isSameType(button, Button)) {
      return React.cloneElement(button, {
        onClick: this.openModal,
      })
    }

    return <Button onClick={this.openModal}>{button}</Button>
  }

  getModal() {
    const { children } = this.props

    const modalProps = {
      open: this.state.open,
      onClose: this.closeModal,
    }
    if (isSameType(children, Modal)) {
      return React.cloneElement(this.props.children, modalProps)
    }

    return <Modal {...modalProps}>{children}</Modal>
  }

  closeModal() {
    this.setState({ open: false })
  }

  openModal() {
    this.setState({ open: true })
  }

  render() {
    return (

        {this.getButton()}
        {this.getModal()}

    )
  }
}

export default ModalButton
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.read<commit_msg>Almost there<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readF<|endoftext|>


<commit_before>import React from 'react';
import { FormattedNumber } from 'react-intl';

const Currency = ({value, currency, precision=0}) => (
  <FormattedNumber
    value={value / 100}
    currency={currency}
    style="currency"
    currencyDisplay="symbol"
    minimumFractionDigits={precision}
    maximumFractionDigits={precision}
    />
);

export default Currency;
<commit_msg>feat(components/Currency): add abbreviate prop, return styled Span<commit_after>import React from 'react';
import { FormattedNumber } from 'react-intl';

import { abbreviateNumber } from '../lib/utils';

import { Span } from './Text';

const Currency = ({
  abbreviate = false,
  currency,
  precision = 0,
  value,
  ...styles,
}) => (
  <FormattedNumber
    value={value / 100}
    currency={currency}
    style="currency"
    currencyDisplay="symbol"
    minimumFractionDigits={precision}
    maximumFractionDigits={precision}
  >
    {formattedNumber => abbreviate ?
      {formattedNumber.slice(0, 1)}{abbreviateNumber(value/100)}
      : {formattedNumber}
    }
  </FormattedNumber>
);

export default Currency;
<|endoftext|>


<commit_before><commit_msg>chore(gatsby-plugin-mdx): refactored to use createContentDigest (#8805) (#19885)<commit_after><|endoftext|>


<commit_before>import React      from 'react'
import PropTypes  from 'prop-types'
import Radium from 'radium'
import responsive from '../../styles/responsive'

const styles = {
  [responsive.xs]: {
    display: 'block'
  },

  [responsive.sm]: {
    display: 'grid',
    gridTemplateColumns: `repeat(6, ${responsive.columnWidth}px)`
  },

  [responsive.md]: {
    display: 'grid',
    gridTemplateColumns: `repeat(8, ${responsive.columnWidth}px)`
  },

  [responsive.mdLg]: {
    display: 'grid',
    gridTemplateColumns: `repeat(10, ${responsive.columnWidth}px)`
  },

  [responsive.lg]: {
    display: 'grid',
    gridTemplateColumns: `repeat(12, ${responsive.columnWidth}px)`
  },

  [responsive.xl]: {
    display: 'grid',
    gridTemplateColumns: `repeat(14, ${responsive.columnWidth}px)`
  }
}

const Row = props => {
  const getMaxColumnsStyles = () => {
    const { maxColumns } = props

    const override = {
      gridTemplateColumns: `repeat(${maxColumns}, ${responsive.columnWidth}px)`,
      justifyContent: 'center'
    }

    if (maxColumns <= 6) {
      return {
        [responsive.md]: override,
        [responsive.mdLg]: override,
        [responsive.lg]: override,
        [responsive.xl]: override
      }
    } else if (maxColumns <= 8) {
      return {
        [responsive.mdLg]: override,
        [responsive.lg]: override,
        [responsive.xl]: override
      }
    } else if (maxColumns <= 10) {
      return {
        [responsive.lg]:override,
        [responsive.xl]: override
      }
    } else if (maxColumns <= 12) {
      return {
        [responsive.xl]: override
      }
    }

    return {}
  }

  const getFullWidthStyles = () => {
    const { screenWidths } = responsive
    if (!props.forceFullPage) { return {} }

    return {
      width: '100vw',
      justifyContent: 'center',
      [responsive.xs]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.xs}px))`
      },

      [responsive.sm]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.sm}px))`
      },

      [responsive.md]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.md}px))`
      },

      [responsive.mdLg]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.mdLg}px))`
      },

      [responsive.lg]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.lg}px))`
      },

      [responsive.xl]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.xl}px))`
      }
    }
  }

  return (
    <div
      style={[
        styles,
        getMaxColumnsStyles(),
        getFullWidthStyles(),
        props.styles
      ]}
    >
      { props.children }
    </div>
  )
}

Row.propTypes = {
  /** Force Row to width of 100vw -- Snacks will add negative margin */
  forceFullPage: PropTypes.bool,
  /** Maximum number of columns this Row should grow to as screen width increases. Cannot exceed 14. */
  maxColumns: PropTypes.number,
  /** Optional style overrides */
  styles: PropTypes.object
}

Row.defaultProps = {
  maxColumns: 14
}

export default Radium(Row)
<commit_msg>Final fix for full page rows.<commit_after>import React      from 'react'
import PropTypes  from 'prop-types'
import Radium from 'radium'
import responsive from '../../styles/responsive'

const styles = {
  [responsive.xs]: {
    display: 'block'
  },

  [responsive.sm]: {
    display: 'grid',
    gridTemplateColumns: `repeat(6, ${responsive.columnWidth}px)`
  },

  [responsive.md]: {
    display: 'grid',
    gridTemplateColumns: `repeat(8, ${responsive.columnWidth}px)`
  },

  [responsive.mdLg]: {
    display: 'grid',
    gridTemplateColumns: `repeat(10, ${responsive.columnWidth}px)`
  },

  [responsive.lg]: {
    display: 'grid',
    gridTemplateColumns: `repeat(12, ${responsive.columnWidth}px)`
  },

  [responsive.xl]: {
    display: 'grid',
    gridTemplateColumns: `repeat(14, ${responsive.columnWidth}px)`
  }
}

const Row = props => {
  const getMaxColumnsStyles = () => {
    const { maxColumns } = props

    const override = {
      gridTemplateColumns: `repeat(${maxColumns}, ${responsive.columnWidth}px)`,
      justifyContent: 'center'
    }

    if (maxColumns <= 6) {
      return {
        [responsive.md]: override,
        [responsive.mdLg]: override,
        [responsive.lg]: override,
        [responsive.xl]: override
      }
    } else if (maxColumns <= 8) {
      return {
        [responsive.mdLg]: override,
        [responsive.lg]: override,
        [responsive.xl]: override
      }
    } else if (maxColumns <= 10) {
      return {
        [responsive.lg]:override,
        [responsive.xl]: override
      }
    } else if (maxColumns <= 12) {
      return {
        [responsive.xl]: override
      }
    }

    return {}
  }

  const getFullWidthStyles = () => {
    const { screenWidths } = responsive
    if (!props.forceFullPage) { return {} }

    return {
      width: '100vw',
      justifyContent: 'center',
      display: 'block',
      [responsive.xs]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.xs}px) / 2)`
      },

      [responsive.sm]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.sm}px) / 2)`
      },

      [responsive.md]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.md}px) / 2)`
      },

      [responsive.mdLg]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.mdLg}px) / 2)`
      },

      [responsive.lg]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.lg}px) / 2)`
      },

      [responsive.xl]: {
        margin: `0 calc(-1 * (100vw - ${screenWidths.xl}px) / 2)`
      }
    }
  }

  return (
    <div
      style={[
        styles,
        getMaxColumnsStyles(),
        getFullWidthStyles(),
        props.styles
      ]}
    >
      { props.children }
    </div>
  )
}

Row.propTypes = {
  /** Force Row to width of 100vw -- Snacks will add negative margin */
  forceFullPage: PropTypes.bool,
  /** Maximum number of columns this Row should grow to as screen width increases. Cannot exceed 14. */
  maxColumns: PropTypes.number,
  /** Optional style overrides */
  styles: PropTypes.object
}

Row.defaultProps = {
  maxColumns: 14
}

export default Radium(Row)
<|endoftext|>


<commit_before>/*
 *
 * (c) Copyright Ascensio System Limited 2010-2017
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
 * EU, LV-1021.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
*/
/**
 *  SignSettingsDialog.js
 *
 *  Created by Julia Radzhabova on 5/19/17
 *  Copyright (c) 2017 Ascensio System SIA. All rights reserved.
 *
 */

if (Common === undefined)
    var Common = {};

define([
    'common/main/lib/util/utils',
    'common/main/lib/component/InputField',
    'common/main/lib/component/CheckBox',
    'common/main/lib/component/Window'
], function () { 'use strict';

    DE.Views.SignSettingsDialog = Common.UI.Window.extend(_.extend({
        options: {
            width: 350,
            style: 'min-width: 350px;',
            cls: 'modal-dlg'
        },

        initialize : function(options) {
            _.extend(this.options, {
                title: this.textTitle
            }, options || {});

            this.template = [
                '
',
                    '
',
                        '' + this.textInfo + '',
                    '
',
                    '
',
                        '' + this.textInfoName + '',
                    '
',
                    '

',
                    '
',
                        '' + this.textInfoTitle + '',
                    '
',
                    '

',
                    '
',
                        '' + this.textInfoEmail + '',
                    '
',
                    '

',
                    '
',
                        '' + this.textInstructions + '',
                    '
',
                    '<textarea id="id-dlg-sign-settings-instructions" class="form-control" style="width: 100%;height: 35px;margin-bottom: 10px;resize: none;"></textarea>',
                    '

',
                    '

',
                '
',
                '
',
                    '<button class="btn normal dlg-btn primary" result="ok" style="margin-right: 10px;">' + this.okButtonText + '</button>',
                    '<button class="btn normal dlg-btn" result="cancel">' + this.cancelButtonText + '</button>',
                '
'
            ].join('');

            this.options.tpl = _.template(this.template)(this.options);
            this.api = this.options.api;

            Common.UI.Window.prototype.initialize.call(this, this.options);
        },

        render: function() {
            Common.UI.Window.prototype.render.call(this);

            var me = this,
                $window = this.getChild();

            me.inputName = new Common.UI.InputField({
                el          : $('#id-dlg-sign-settings-name'),
                style       : 'width: 100%;'
            });

            me.inputTitle = new Common.UI.InputField({
                el          : $('#id-dlg-sign-settings-title'),
                style       : 'width: 100%;'
            });

            me.inputEmail = new Common.UI.InputField({
                el          : $('#id-dlg-sign-settings-email'),
                style       : 'width: 100%;'
            });

            me.textareaInstructions = this.$window.find('textarea');
            me.textareaInstructions.keydown(function (event) {
                if (event.keyCode == Common.UI.Keys.RETURN) {
                    event.stopPropagation();
                }
            });

            this.chComment = new Common.UI.CheckBox({
                el: $('#id-dlg-sign-settings-comment'),
                labelText: this.textAllowComment
            });

            this.chDate = new Common.UI.CheckBox({
                el: $('#id-dlg-sign-settings-date'),
                labelText: this.textShowDate
            });

            $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this));
            $window.find('input').on('keypress', _.bind(this.onKeyPress, this));
        },

        show: function() {
            Common.UI.Window.prototype.show.apply(this, arguments);

            var me = this;
            _.delay(function(){
                me.inputName.cmpEl.find('input').focus();
            },500);
        },

        setSettings: function (props) {
            if (props) {
                var me = this;

                // var value = props.asc_getName();
                // me.inputName.setValue(value ? value : '');
                // value = props.asc_getTitle();
                // me.inputTitle.setValue(value ? value : '');
                // value = props.asc_getEmail();
                // me.inputEmail.setValue(value ? value : '');
                // value = props.asc_getInstructions();
                // me.textareaInstructions.val(value ? value : '');
                // me.chComment.setValue(props.asc_getAllowComment());
                // me.chDate.setValue(props.asc_getDate());
            }
        },

        getSettings: function () {
            var me      = this, props;

            // props.asc_putName(me.inputName.getValue());
            // props.asc_putTitile(me.inputTitle.getValue());
            // props.asc_putEmail(me.inputEmail.getValue());
            // props.asc_putInstructions(me.textareaInstructions.val());
            // props.asc_putAllowComment(me.chComment.getValue()=='checked');
            // props.asc_putDate(me.chDate.getValue()=='checked');

            return props;
        },

        onBtnClick: function(event) {
            this._handleInput(event.currentTarget.attributes['result'].value);
        },

        onKeyPress: function(event) {
            if (event.keyCode == Common.UI.Keys.RETURN) {
                this._handleInput('ok');
                return false;
            }
        },

        _handleInput: function(state) {
            if (this.options.handler)
                this.options.handler.call(this, this, state);
            this.close();
        },

        textInfo:           'Signer Info',
        textInfoName:       'Name',
        textInfoTitle:      'Title',
        textInfoEmail:      'E-mail',
        textInstructions:   'Instructions for Signer',
        cancelButtonText:   'Cancel',
        okButtonText:       'Ok',
        txtEmpty:           'This field is required',
        textAllowComment:   'Allow signer to add comment in the signature dialog',
        textShowDate:       'Show sign date in signature line',
        textTitle:          'Signature Settings'
    }, DE.Views.SignSettingsDialog || {}))
});<commit_msg>[DE] Change layout for signature settings.<commit_after>/*
 *
 * (c) Copyright Ascensio System Limited 2010-2017
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
 * EU, LV-1021.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
*/
/**
 *  SignSettingsDialog.js
 *
 *  Created by Julia Radzhabova on 5/19/17
 *  Copyright (c) 2017 Ascensio System SIA. All rights reserved.
 *
 */

if (Common === undefined)
    var Common = {};

define([
    'common/main/lib/util/utils',
    'common/main/lib/component/InputField',
    'common/main/lib/component/CheckBox',
    'common/main/lib/component/Window'
], function () { 'use strict';

    DE.Views.SignSettingsDialog = Common.UI.Window.extend(_.extend({
        options: {
            width: 350,
            style: 'min-width: 350px;',
            cls: 'modal-dlg'
        },

        initialize : function(options) {
            _.extend(this.options, {
                title: this.textTitle
            }, options || {});

            this.template = [
                '
',
                    '
',
                        '' + this.textInfo + '',
                    '
',
                    '
',
                        '' + this.textInfoName + '',
                    '
',
                    '

',
                    '
',
                        '' + this.textInfoTitle + '',
                    '
',
                    '

',
                    '
',
                        '' + this.textInfoEmail + '',
                    '
',
                    '

',
                    '
',
                        '' + this.textInstructions + '',
                    '
',
                    '<textarea id="id-dlg-sign-settings-instructions" class="form-control" style="width: 100%;height: 35px;margin-bottom: 10px;resize: none;"></textarea>',
                    '

',
                    '

',
                '
',
                '
',
                    '<button class="btn normal dlg-btn primary" result="ok" style="margin-right: 10px;">' + this.okButtonText + '</button>',
                    '<button class="btn normal dlg-btn" result="cancel">' + this.cancelButtonText + '</button>',
                '
'
            ].join('');

            this.options.tpl = _.template(this.template)(this.options);
            this.api = this.options.api;

            Common.UI.Window.prototype.initialize.call(this, this.options);
        },

        render: function() {
            Common.UI.Window.prototype.render.call(this);

            var me = this,
                $window = this.getChild();

            me.inputName = new Common.UI.InputField({
                el          : $('#id-dlg-sign-settings-name'),
                style       : 'width: 100%;'
            });

            me.inputTitle = new Common.UI.InputField({
                el          : $('#id-dlg-sign-settings-title'),
                style       : 'width: 100%;'
            });

            me.inputEmail = new Common.UI.InputField({
                el          : $('#id-dlg-sign-settings-email'),
                style       : 'width: 100%;'
            });

            me.textareaInstructions = this.$window.find('textarea');
            me.textareaInstructions.keydown(function (event) {
                if (event.keyCode == Common.UI.Keys.RETURN) {
                    event.stopPropagation();
                }
            });

            this.chComment = new Common.UI.CheckBox({
                el: $('#id-dlg-sign-settings-comment'),
                labelText: this.textAllowComment
            });

            this.chDate = new Common.UI.CheckBox({
                el: $('#id-dlg-sign-settings-date'),
                labelText: this.textShowDate
            });

            $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this));
            $window.find('input').on('keypress', _.bind(this.onKeyPress, this));
        },

        show: function() {
            Common.UI.Window.prototype.show.apply(this, arguments);

            var me = this;
            _.delay(function(){
                me.inputName.cmpEl.find('input').focus();
            },500);
        },

        setSettings: function (props) {
            if (props) {
                var me = this;

                // var value = props.asc_getName();
                // me.inputName.setValue(value ? value : '');
                // value = props.asc_getTitle();
                // me.inputTitle.setValue(value ? value : '');
                // value = props.asc_getEmail();
                // me.inputEmail.setValue(value ? value : '');
                // value = props.asc_getInstructions();
                // me.textareaInstructions.val(value ? value : '');
                // me.chComment.setValue(props.asc_getAllowComment());
                // me.chDate.setValue(props.asc_getDate());
            }
        },

        getSettings: function () {
            var me      = this, props;

            // props.asc_putName(me.inputName.getValue());
            // props.asc_putTitile(me.inputTitle.getValue());
            // props.asc_putEmail(me.inputEmail.getValue());
            // props.asc_putInstructions(me.textareaInstructions.val());
            // props.asc_putAllowComment(me.chComment.getValue()=='checked');
            // props.asc_putDate(me.chDate.getValue()=='checked');

            return props;
        },

        onBtnClick: function(event) {
            this._handleInput(event.currentTarget.attributes['result'].value);
        },

        onKeyPress: function(event) {
            if (event.keyCode == Common.UI.Keys.RETURN) {
                this._handleInput('ok');
                return false;
            }
        },

        _handleInput: function(state) {
            if (this.options.handler)
                this.options.handler.call(this, this, state);
            this.close();
        },

        textInfo:           'Signer Info',
        textInfoName:       'Name',
        textInfoTitle:      'Title',
        textInfoEmail:      'E-mail',
        textInstructions:   'Instructions for Signer',
        cancelButtonText:   'Cancel',
        okButtonText:       'Ok',
        txtEmpty:           'This field is required',
        textAllowComment:   'Allow signer to add comment in the signature dialog',
        textShowDate:       'Show sign date in signature line',
        textTitle:          'Signature Settings'
    }, DE.Views.SignSettingsDialog || {}))
});<|endoftext|>


<commit_before>'use strict';

var chai = require('chai');
var expect = chai.expect;

var Database = require('../../lib/database');
var ModelQuery = require('../../lib/query/model');
var FakeAdapter = require('../fakes/adapter');

var db,
  adapter;

describe('ModelQuery', function() {
  before(function() {
    adapter = FakeAdapter.create({});
    db = Database.create({ adapter: adapter });
  });

  it('cannot be created directly', function() {
    expect(function() {
      ModelQuery.create();
    }).to.throw(/ModelQuery must be spawned/i);
  });

  it('gives a useful error when bad relation is used for `with`', function() {
    expect(function() {
      db.query.bindModel(db.model('user')).with('streets');
    }).to.throw(/no relation.*"streets".*user query/i);
  });
});
<commit_msg>Switched to beforeEach.<commit_after>'use strict';

var chai = require('chai');
var expect = chai.expect;

var Database = require('../../lib/database');
var ModelQuery = require('../../lib/query/model');
var FakeAdapter = require('../fakes/adapter');

var db,
  adapter;

describe('ModelQuery', function() {
  beforeEach(function() {
    adapter = FakeAdapter.create({});
    db = Database.create({ adapter: adapter });
  });

  it('cannot be created directly', function() {
    expect(function() {
      ModelQuery.create();
    }).to.throw(/ModelQuery must be spawned/i);
  });

  it('gives a useful error when bad relation is used for `with`', function() {
    expect(function() {
      db.query.bindModel(db.model('user')).with('streets');
    }).to.throw(/no relation.*"streets".*user query/i);
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { cx, css } from 'react-emotion';
import { List, Map } from 'immutable';
import { partial } from 'lodash';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import { ObjectControl } from 'netlify-cms-widget-object';
import {
  ListItemTopBar,
  ObjectWidgetTopBar,
  colors,
  lengths,
  components,
} from 'netlify-cms-ui-default';

function valueToString(value) {
  return value ? value.join(',').replace(/,([^\s]|$)/g, ', $1') : '';
}

const ListItem = styled.div();

const SortableListItem = SortableElement(ListItem);

const StyledListItemTopBar = styled(ListItemTopBar)`
  background-color: ${colors.textFieldBorder};
`;

const NestedObjectLabel = styled.div`
  display: ${props => (props.collapsed ? 'block' : 'none')};
  border-top: 0;
  background-color: ${colors.textFieldBorder};
  padding: 13px;
  border-radius: 0 0 ${lengths.borderRadius} ${lengths.borderRadius};
`;

const styles = {
  collapsedObjectControl: css`
    display: none;
  `,
  listControlItem: css`
    margin-top: 18px;

    &:first-of-type {
      margin-top: 26px;
    }
  `,
  listControlItemCollapsed: css`
    padding-bottom: 0;
  `,
};

const SortableList = SortableContainer(({ items, renderItem }) => {
  return
{items.map(renderItem)}
;
});

const valueTypes = {
  SINGLE: 'SINGLE',
  MULTIPLE: 'MULTIPLE',
};

export default class ListControl extends React.Component {
  static propTypes = {
    metadata: ImmutablePropTypes.map,
    onChange: PropTypes.func.isRequired,
    onChangeObject: PropTypes.func.isRequired,
    value: ImmutablePropTypes.list,
    field: PropTypes.object,
    forID: PropTypes.string,
    mediaPaths: ImmutablePropTypes.map.isRequired,
    getAsset: PropTypes.func.isRequired,
    onOpenMediaLibrary: PropTypes.func.isRequired,
    onAddAsset: PropTypes.func.isRequired,
    onRemoveInsertedMedia: PropTypes.func.isRequired,
    classNameWrapper: PropTypes.string.isRequired,
    setActiveStyle: PropTypes.func.isRequired,
    setInactiveStyle: PropTypes.func.isRequired,
    editorControl: PropTypes.func.isRequired,
    resolveWidget: PropTypes.func.isRequired,
  };

  static defaultProps = {
    value: List(),
  };

  constructor(props) {
    super(props);
    const { field, value } = props;
    const allItemsCollapsed = field.get('collapsed', true);
    const itemsCollapsed = value && Array(value.size).fill(allItemsCollapsed);

    this.state = {
      itemsCollapsed: List(itemsCollapsed),
      value: valueToString(value),
    };
  }

  getValueType = () => {
    const { field } = this.props;
    if (field.get('fields')) {
      return valueTypes.MULTIPLE;
    } else if (field.get('field')) {
      return valueTypes.SINGLE;
    } else {
      return null;
    }
  };

  /**
   * Always update so that each nested widget has the option to update. This is
   * required because ControlHOC provides a default `shouldComponentUpdate`
   * which only updates if the value changes, but every widget must be allowed
   * to override this.
   */
  shouldComponentUpdate() {
    return true;
  }

  handleChange = e => {
    const { onChange } = this.props;
    const oldValue = this.state.value;
    const newValue = e.target.value;
    const listValue = e.target.value.split(',');
    if (newValue.match(/,$/) && oldValue.match(/, $/)) {
      listValue.pop();
    }

    const parsedValue = valueToString(listValue);
    this.setState({ value: parsedValue });
    onChange(listValue.map(val => val.trim()));
  };

  handleFocus = () => {
    this.props.setActiveStyle();
  };

  handleBlur = e => {
    const listValue = e.target.value
      .split(',')
      .map(el => el.trim())
      .filter(el => el);
    this.setState({ value: valueToString(listValue) });
    this.props.setInactiveStyle();
  };

  handleAdd = e => {
    e.preventDefault();
    const { value, onChange } = this.props;
    const parsedValue = this.getValueType() === valueTypes.SINGLE ? null : Map();
    this.setState({ itemsCollapsed: this.state.itemsCollapsed.push(false) });
    onChange((value || List()).push(parsedValue));
  };

  /**
   * In case the `onChangeObject` function is frozen by a child widget implementation,
   * e.g. when debounced, always get the latest object value instead of using
   * `this.props.value` directly.
   */
  getObjectValue = idx => this.props.value.get(idx) || Map();

  handleChangeFor(index) {
    return (fieldName, newValue, newMetadata) => {
      const { value, metadata, onChange, field } = this.props;
      const collectionName = field.get('name');
      const newObjectValue =
        this.getValueType() === valueTypes.MULTIPLE
          ? this.getObjectValue(index).set(fieldName, newValue)
          : newValue;
      const parsedMetadata = {
        [collectionName]: Object.assign(
          metadata ? metadata.toJS() : {},
          newMetadata ? newMetadata[collectionName] : {},
        ),
      };
      onChange(value.set(index, newObjectValue), parsedMetadata);
    };
  }

  handleRemove = (index, event) => {
    event.preventDefault();
    const { itemsCollapsed } = this.state;
    const { value, metadata, onChange, field } = this.props;
    const collectionName = field.get('name');
    const isSingleField = this.valueType === valueTypes.SINGLE;

    const metadataRemovePath = isSingleField ? value.get(index) : value.get(index).valueSeq();
    const parsedMetadata = metadata && { [collectionName]: metadata.removeIn(metadataRemovePath) };

    this.setState({ itemsCollapsed: itemsCollapsed.delete(index) });

    onChange(value.remove(index), parsedMetadata);
  };

  handleItemCollapseToggle = (index, event) => {
    event.preventDefault();
    const { itemsCollapsed } = this.state;
    const collapsed = itemsCollapsed.get(index);
    this.setState({ itemsCollapsed: itemsCollapsed.set(index, !collapsed) });
  };

  handleCollapseAllToggle = e => {
    e.preventDefault();
    const { value } = this.props;
    const { itemsCollapsed } = this.state;
    const allItemsCollapsed = itemsCollapsed.every(val => val === true);
    this.setState({ itemsCollapsed: List(Array(value.size).fill(!allItemsCollapsed)) });
  };

  objectLabel(item) {
    const { field } = this.props;
    const multiFields = field.get('fields');
    const singleField = field.get('field');
    const labelField = (multiFields && multiFields.first()) || singleField;
    const value = multiFields
      ? item.get(multiFields.first().get('name'))
      : singleField.get('label');
    return (value || `No ${labelField.get('name')}`).toString();
  }

  onSortEnd = ({ oldIndex, newIndex }) => {
    const { value } = this.props;
    const { itemsCollapsed } = this.state;

    // Update value
    const item = value.get(oldIndex);
    const newValue = value.delete(oldIndex).insert(newIndex, item);
    this.props.onChange(newValue);

    // Update collapsing
    const collapsed = itemsCollapsed.get(oldIndex);
    const updatedItemsCollapsed = itemsCollapsed.delete(oldIndex).insert(newIndex, collapsed);
    this.setState({ itemsCollapsed: updatedItemsCollapsed });
  };

  renderItem = (item, index) => {
    const { field, classNameWrapper, editorControl, resolveWidget } = this.props;
    const { itemsCollapsed } = this.state;
    const collapsed = itemsCollapsed.get(index);

    return (
      <SortableListItem
        className={cx(styles.listControlItem, { [styles.listControlItemCollapsed]: collapsed })}
        index={index}
        key={`item-${index}`}
      >


<commit_before>import React from "react";
import kofi from "kofi";
import {highlightStr} from "codecake/highlight.js";

//Export live code component
export const LiveCode = props => {
    let codeChildren = props.children; //Code children
    const codeProps = {};
    const lang = (props.className || "").replace("language-", "").replace("javascript", "js");
    const codeClass = "siimple-code has-bg-coolgray-700 has-text-white";
    if (["html", "css", "scss", "js"].includes(lang)) {
        codeProps["dangerouslySetInnerHTML"] = {
            "__html": highlight(props.children, lang),
        };
        codeChildren = null; //Ignore children
    }
    //Check for no live preview --> render the code wrapped in a
 element
    if (props.live !== "true") {
        return <pre className={`${codeClass} has-mb-6`} {...codeProps}>{codeChildren}
;
    }
    //const {padding, bg, color} = props;
    const demoClass = kofi.classNames("has-mb-6 has-radius has-overflow-x-hidden", [
        `has-p-${props.padding}`,
        // `has-bg-${props.bg}`,
        "has-bg-coolgray-100",
        `has-text-${props.color}`,
    ]);
    const contentClass = classNames("has-w-full has-overflow-y", {
        "has-d-flex has-items-center has-justify-center": props.centered === "true",
    });
    return (

            {/* Live code block */}

            {/* Code */}
            <pre className={`${codeClass} has-my-0`} {...codeProps}>{codeChildren}

            {/*
{props.children}
 */}

    );
}

//Live code default props
LiveCode.defaultProps = {
    "align": "left",
    "bg": "coolgray-100",
    "bold": "false",
    "color": "dark",
    "live": "false",
    "padding": "6"
};
<commit_msg>Fix minor bug in LiceCode component<commit_after>import React from "react";
import kofi from "kofi";
import {highlightStr} from "codecake/highlight.js";

//Export live code component
export const LiveCode = props => {
    let codeChildren = props.children; //Code children
    const codeProps = {};
    const lang = (props.className || "").replace("language-", "").replace("javascript", "js");
    const codeClass = "siimple-code has-bg-coolgray-700 CodeCake-dark";
    if (["html", "css", "scss", "js"].includes(lang)) {
        codeProps["dangerouslySetInnerHTML"] = {
            "__html": highlightStr(props.children, lang),
        };
        codeChildren = null; //Ignore children
    }
    //Check for no live preview --> render the code wrapped in a
 element
    if (props.live !== "true") {
        return <pre className={`${codeClass} has-mb-6`} {...codeProps}>{codeChildren}
;
    }
    //const {padding, bg, color} = props;
    const demoClass = kofi.classNames("has-mb-6 has-radius has-overflow-x-hidden", [
        `has-p-${props.padding}`,
        // `has-bg-${props.bg}`,
        "has-bg-coolgray-100",
        `has-text-${props.color}`,
    ]);
    const contentClass = kofi.classNames("has-w-full has-overflow-y", {
        "has-d-flex has-items-center has-justify-center": props.centered === "true",
    });
    return (

            {/* Live code block */}

            {/* Code */}
            <pre className={`${codeClass} has-my-0`} {...codeProps}>{codeChildren}

            {/*
{props.children}
 */}

    );
}

//Live code default props
LiveCode.defaultProps = {
    "align": "left",
    "bg": "coolgray-100",
    "bold": "false",
    "color": "dark",
    "live": "false",
    "padding": "6"
};
<|endoftext|>


<commit_before>document.observe('dom:loaded', function()
{
	// redmine uses prototype so use it.

	var links = $$('a.icon-attachment');
	for (var i = 0; i < links.length; i++)
	{
		var link = links[i];
		link.target = '_blank';
	}
});
<commit_msg>Open all links on issue description in new window too<commit_after>document.observe('dom:loaded', function()
{
	// redmine uses prototype so use it.

	var links = $$('div.issue.details div.wiki a, div.issue.details div.attachments a');
	for (var i = 0; i < links.length; i++)
	{
		var link = links[i];
		link.target = '_blank';
	}
});
<|endoftext|>


<commit_before>var assert = require("assert");
var {absolute, join} = require("fs");
var strings = require("ringo/utils/strings");

exports.setup = function(exports, path, repo) {

    exports.testGetResource = function() {
        var res = repo.getResource("test.txt");
        assert.strictEqual(res.name, "test.txt");
        assert.isTrue(res.exists());
        assert.strictEqual(res.baseName, "test");
        assert.strictEqual(res.path, absolute(join(path, "test.txt")));
        assert.strictEqual(res.content, "hello world!");
    };

    exports.testGetNestedResource = function() {
        var res = repo.getResource("nested/nested.txt");
        assert.strictEqual(res.name, "nested.txt");
        assert.isTrue(res.exists());
        assert.strictEqual(res.baseName, "nested");
        assert.strictEqual(res.path, absolute(join(path, "nested", "nested.txt")));
        assert.strictEqual(res.length, 2240);
        assert.strictEqual(res.content.length, 2240);
        assert.isTrue(strings.startsWith(res.content, "Lorem ipsum dolor sit amet"));
        assert.isTrue(strings.endsWith(res.content.trim(), "id est laborum."));
    };

    exports.testNonExistingResource = function() {
        var res = repo.getResource("doesNotExist.txt");
        assert.isNotNull(res);
        assert.isFalse(res.exists());
        assert.throws(function() {res.content});
    };

    exports.testNestedNonExistingResource = function() {
        var res = repo.getResource("foo/bar/doesNotExist.txt");
        assert.isNotNull(res);
        assert.isFalse(res.exists());
        assert.throws(function() {res.content});
    };

    exports.testGetRepositories = function() {
        var repos = repo.getRepositories();
        assert.strictEqual(repos.length, 1);
        assert.strictEqual(repos[0].name, "nested");
    }

    exports.testGetResources = function() {
        var res = repo.getResources();
        assert.strictEqual(res.length, 1);
        assert.strictEqual(res[0].name, "test.txt");
    }

    exports.testGetRecursiveResources = function() {
        var res = repo.getResources(true);
        assert.strictEqual(res.length, 2);
        res = res.sort(function(a, b) a.length - b.length);
        assert.strictEqual(res[0].name, "test.txt");
        assert.strictEqual(res[0].relativePath, "test.txt");
        assert.strictEqual(res[0].path, absolute(join(path, "test.txt")));
        assert.strictEqual(res[1].name, "nested.txt");
        assert.strictEqual(res[1].relativePath, "nested/nested.txt");
        assert.strictEqual(res[1].path, absolute(join(path, "nested/nested.txt")));
    }

    exports.testGetNestedResources = function() {
        var res = repo.getResources("nested", false);
        assert.strictEqual(res.length, 1);
        assert.strictEqual(res[0].name, "nested.txt");
        assert.strictEqual(res[0].relativePath, "nested/nested.txt");
    }

};
<commit_msg>Fixing some tests which will fail under Windows.<commit_after>var assert = require("assert");
var {absolute, join} = require("fs");
var strings = require("ringo/utils/strings");
var {separator} = java.io.File;

exports.setup = function(exports, path, repo) {

    exports.testGetResource = function() {
        var res = repo.getResource("test.txt");
        assert.strictEqual(res.name, "test.txt");
        assert.isTrue(res.exists());
        assert.strictEqual(res.baseName, "test");
        // Regardless of OS, when resolving paths inside an archive file the separator is '/'.
        var comparePath = /\.zip$|\.jar$/.test(path) ? absolute(path) + "/test.txt" : absolute(join(path, "test.txt"));
        assert.strictEqual(res.path, comparePath);
        assert.strictEqual(res.content, "hello world!");
    };

    exports.testGetNestedResource = function() {
        var res = repo.getResource("nested/nested.txt");
        assert.strictEqual(res.name, "nested.txt");
        assert.isTrue(res.exists());
        assert.strictEqual(res.baseName, "nested");
        // Regardless of OS, when resolving paths inside an archive file the separator is '/'.
        var comparePath = /\.zip$|\.jar$/.test(path)
                ? absolute(path) + "/nested/nested.txt"
                : absolute(join(path, "nested", "nested.txt"));
        assert.strictEqual(res.path, comparePath);
        // Windows uses two bytes for EOL while other OS's use one byte.
        var len = /^windows/.test(java.lang.System.getProperty("os.name", "generic").toLowerCase()) ? 2274 : 2240;
        // Except when in an archive, then it depends on what OS the archive was created, ugh.
        if (/\.zip$|\.jar$/.test(path)) len = 2240;
        assert.strictEqual(res.length, len);
        assert.strictEqual(res.content.length, len);
        assert.isTrue(strings.startsWith(res.content, "Lorem ipsum dolor sit amet"));
        assert.isTrue(strings.endsWith(res.content.trim(), "id est laborum."));
    };

    exports.testNonExistingResource = function() {
        var res = repo.getResource("doesNotExist.txt");
        assert.isNotNull(res);
        assert.isFalse(res.exists());
        assert.throws(function() {res.content});
    };

    exports.testNestedNonExistingResource = function() {
        var res = repo.getResource("foo/bar/doesNotExist.txt");
        assert.isNotNull(res);
        assert.isFalse(res.exists());
        assert.throws(function() {res.content});
    };

    exports.testGetRepositories = function() {
        var repos = repo.getRepositories();
        assert.strictEqual(repos.length, 1);
        assert.strictEqual(repos[0].name, "nested");
    }

    exports.testGetResources = function() {
        var res = repo.getResources();
        assert.strictEqual(res.length, 1);
        assert.strictEqual(res[0].name, "test.txt");
    }

    exports.testGetRecursiveResources = function() {
        var res = repo.getResources(true);
        assert.strictEqual(res.length, 2);
        res = res.sort(function(a, b) a.length - b.length);
        assert.strictEqual(res[0].name, "test.txt");
        assert.strictEqual(res[0].relativePath, "test.txt");
        // Regardless of OS, when resolving paths inside an archive file the separator is '/'.
        var comparePath = /\.zip$|\.jar$/.test(path) ? absolute(path) + "/test.txt" : absolute(join(path, "test.txt"));
        assert.strictEqual(res[0].path, comparePath);
        assert.strictEqual(res[1].name, "nested.txt");
        assert.strictEqual(res[1].relativePath, "nested/nested.txt");
        // Regardless of OS, when resolving paths inside an archive file the separator is '/'.
        var comparePath = /\.zip$|\.jar$/.test(path) ? absolute(path) + "/nested/nested.txt" : absolute(join(path, "nested/nested.txt"));
        assert.strictEqual(res[1].path, comparePath);
    }

    exports.testGetNestedResources = function() {
        var res = repo.getResources("nested", false);
        assert.strictEqual(res.length, 1);
        assert.strictEqual(res[0].name, "nested.txt");
        assert.strictEqual(res[0].relativePath, "nested/nested.txt");
    }

};
<|endoftext|>