<commit_before>var React = require('react');
var Glyphicon = require('react-bootstrap/lib/Glyphicon');
var Nav = require('react-bootstrap/lib/Nav');
var NavItem = require('react-bootstrap/lib/NavItem');
var Navbar = require('react-bootstrap/lib/Navbar');
var NavDropdown = require('react-bootstrap/lib/NavDropdown');
var MenuItem = require('react-bootstrap/lib/MenuItem');
var Modal = require('react-bootstrap/lib/Modal');
var Button = require('react-bootstrap/lib/Button');
var Input = require('react-bootstrap/lib/Input');

var MenuStore = require('../stores/MenuStore');

JarrNavBar = React.createClass({
    getInitialState: function() {
        return {is_admin: MenuStore._datas.is_admin,
                crawling_method: MenuStore._datas.crawling_method,
                showModal: false, modalType: null};
    },
    buttonFetch: function() {
        if(this.state.is_admin && this.state.crawling_method != 'http') {
            return (<NavItem eventKey={2} href="/fetch">
                        <Glyphicon glyph="import" />Fetch
                    </NavItem>);
        }
    },
    buttonAdmin: function() {
        if(this.state.is_admin) {
            return (<NavDropdown title={<Glyphicon glyph='cog' />}
                            id='admin-dropdown'>
                        <MenuItem href="/admin/dashboard">
                            <Glyphicon glyph="dashboard" />Dashboard
                        </MenuItem>
                    </NavDropdown>);
        }
    },
    getModal: function() {
        var heading = null;
        var action = null;
        var body = null;
        if(this.state.modalType == 'addFeed') {
            heading = 'Add a new feed';
            action = '/feed/bookmarklet';
            placeholder = "Site or feed url, we'll sort it out later ;)";
            body = <Input name="url" type="text" placeholder={placeholder} />;
        } else {
            heading = 'Add a new category';
            action = '/category/create';
            body = <Input name="name" type="text"
                          placeholder="Name, there isn't much more to it" />;
        }
        return (<Modal show={this.state.showModal} onHide={this.close}>
                  <form action={action} method="POST">
                    <Modal.Header closeButton>
                      <Modal.Title>{heading}</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                      {body}
                    </Modal.Body>
                    <Modal.Footer>
                      <Button type="submit">Add</Button>
                    </Modal.Footer>
                  </form>
                </Modal>);
    },
    close: function() {
        this.setState({showModal: false, modalType: null});
    },
    openAddFeed: function() {
        this.setState({showModal: true, modalType: 'addFeed'});
    },
    openAddCategory: function() {
        this.setState({showModal: true, modalType: 'addCategory'});
    },
    render: function() {
        return (<Navbar fixedTop inverse id="jarrnav">
                    {this.getModal()}
                    <Navbar.Header>
                        <Navbar.Brand>
                            JARR
                        </Navbar.Brand>
                        <Navbar.Toggle />
                    </Navbar.Header>

                        {this.buttonFetch()}
                        <NavItem className="jarrnavitem"
                                 onClick={this.openAddFeed} href="#">
                            <Glyphicon glyph="plus-sign" />Add a new feed
                        </NavItem>
                        <NavItem className="jarrnavitem"
                                 onClick={this.openAddCategory} href="#">
                            <Glyphicon glyph="plus-sign" />Add a new category
                        </NavItem>
                        <NavDropdown title="Feed" id="feed-dropdown">
                            <MenuItem href="/feeds/inactives">
                                Inactives
                            </MenuItem>
                            <MenuItem href="/articles/history">
                                History
                            </MenuItem>
                            <MenuItem href="/feeds/">
                                All
                            </MenuItem>
                        </NavDropdown>
                        {this.buttonAdmin()}
                        <NavDropdown title={<Glyphicon glyph='user' />}
                                id="user-dropdown">
                            <MenuItem href="/user/profile">
                                <Glyphicon glyph="user" />Profile
                            </MenuItem>
                            <MenuItem href="/user/management">
                                <Glyphicon glyph="cog" />Your data
                            </MenuItem>
                            <MenuItem href="/about">
                                <Glyphicon glyph="question-sign" />About
                            </MenuItem>
                            <MenuItem href="/logout">
                                <Glyphicon glyph="log-out" />Logout
                            </MenuItem>
                        </NavDropdown>

                </Navbar>
        );
    },
    componentDidMount: function() {
        MenuStore.addChangeListener(this._onChange);
    },
    componentWillUnmount: function() {
        MenuStore.removeChangeListener(this._onChange);
    },
    _onChange: function() {
        var datas = MenuStore.getAll();
        this.setState({is_admin: datas.is_admin,
                       crawling_method: datas.crawling_method});
    },
});

module.exports = JarrNavBar;
<commit_msg>Move the dashboard button in the user's menu.<commit_after>var React = require('react');
var Glyphicon = require('react-bootstrap/lib/Glyphicon');
var Nav = require('react-bootstrap/lib/Nav');
var NavItem = require('react-bootstrap/lib/NavItem');
var Navbar = require('react-bootstrap/lib/Navbar');
var NavDropdown = require('react-bootstrap/lib/NavDropdown');
var MenuItem = require('react-bootstrap/lib/MenuItem');
var Modal = require('react-bootstrap/lib/Modal');
var Button = require('react-bootstrap/lib/Button');
var Input = require('react-bootstrap/lib/Input');

var MenuStore = require('../stores/MenuStore');

JarrNavBar = React.createClass({
    getInitialState: function() {
        return {is_admin: MenuStore._datas.is_admin,
                crawling_method: MenuStore._datas.crawling_method,
                showModal: false, modalType: null};
    },
    buttonFetch: function() {
        if(this.state.is_admin && this.state.crawling_method != 'http') {
            return (<NavItem eventKey={2} href="/fetch">
                        <Glyphicon glyph="import" />Fetch
                    </NavItem>);
        }
    },
    sectionAdmin: function() {
        if(this.state.is_admin) {
            return (<MenuItem href="/admin/dashboard">
                        <Glyphicon glyph="dashboard" />Dashboard
                    </MenuItem>);
        }
    },
    getModal: function() {
        var heading = null;
        var action = null;
        var body = null;
        if(this.state.modalType == 'addFeed') {
            heading = 'Add a new feed';
            action = '/feed/bookmarklet';
            placeholder = "Site or feed url, we'll sort it out later ;)";
            body = <Input name="url" type="text" placeholder={placeholder} />;
        } else {
            heading = 'Add a new category';
            action = '/category/create';
            body = <Input name="name" type="text"
                          placeholder="Name, there isn't much more to it" />;
        }
        return (<Modal show={this.state.showModal} onHide={this.close}>
                  <form action={action} method="POST">
                    <Modal.Header closeButton>
                      <Modal.Title>{heading}</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                      {body}
                    </Modal.Body>
                    <Modal.Footer>
                      <Button type="submit">Add</Button>
                    </Modal.Footer>
                  </form>
                </Modal>);
    },
    close: function() {
        this.setState({showModal: false, modalType: null});
    },
    openAddFeed: function() {
        this.setState({showModal: true, modalType: 'addFeed'});
    },
    openAddCategory: function() {
        this.setState({showModal: true, modalType: 'addCategory'});
    },
    render: function() {
        return (<Navbar fixedTop inverse id="jarrnav">
                    {this.getModal()}
                    <Navbar.Header>
                        <Navbar.Brand>
                            JARR
                        </Navbar.Brand>
                        <Navbar.Toggle />
                    </Navbar.Header>

                        {this.buttonFetch()}
                        <NavItem className="jarrnavitem"
                                 onClick={this.openAddFeed} href="#">
                            <Glyphicon glyph="plus-sign" />Add a new feed
                        </NavItem>
                        <NavItem className="jarrnavitem"
                                 onClick={this.openAddCategory} href="#">
                            <Glyphicon glyph="plus-sign" />Add a new category
                        </NavItem>
                        <NavDropdown title="Feed" id="feed-dropdown">
                            <MenuItem href="/feeds/inactives">
                                Inactives
                            </MenuItem>
                            <MenuItem href="/articles/history">
                                History
                            </MenuItem>
                            <MenuItem href="/feeds/">
                                All
                            </MenuItem>
                        </NavDropdown>
                        <NavDropdown title={<Glyphicon glyph='user' />}
                                id="user-dropdown">
                            <MenuItem href="/user/profile">
                                <Glyphicon glyph="user" />Profile
                            </MenuItem>
                            <MenuItem href="/user/management">
                                <Glyphicon glyph="cog" />Your data
                            </MenuItem>
                            <MenuItem href="/about">
                                <Glyphicon glyph="question-sign" />About
                            </MenuItem>
                            {this.sectionAdmin()}
                            <MenuItem href="/logout">
                                <Glyphicon glyph="log-out" />Logout
                            </MenuItem>
                        </NavDropdown>

                </Navbar>
        );
    },
    componentDidMount: function() {
        MenuStore.addChangeListener(this._onChange);
    },
    componentWillUnmount: function() {
        MenuStore.removeChangeListener(this._onChange);
    },
    _onChange: function() {
        var datas = MenuStore.getAll();
        this.setState({is_admin: datas.is_admin,
                       crawling_method: datas.crawling_method});
    },
});

module.exports = JarrNavBar;
<|endoftext|>


<commit_before>/*
 * Copyright  1999-2005 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
/* $Id$ */

/* Helper method to add all request parameters to a usecase */
function passRequestParameters(flowHelper, usecase) {
    var names = cocoon.request.getParameterNames();
    while (names.hasMoreElements()) {
        var name = names.nextElement();
        if (!name.equals("lenya.usecase")
            && !name.equals("lenya.continuation")
            && !name.equals("submit")) {

            var value = flowHelper.getRequest(cocoon).get(name);

            var string = new Packages.java.lang.String();
            if (string.getClass().isInstance(value)) {
                usecase.setParameter(name, value);
            }
            else {
                usecase.setPart(name, value);
            }

        }
    }
}

/* Returns the query string to attach to the target URL. This is used in the site area. */
function getTargetQueryString(usecaseName) {
    var isTabUsecase = new Packages.java.lang.String(usecaseName).startsWith('tab');
    var queryString = "";
    if (isTabUsecase) {
        queryString = "?lenya.usecase=" + usecaseName;
    }
    return queryString;
}

function executeUsecase() {
    var usecaseName = cocoon.request.getParameter("lenya.usecase");
    var view;
    var proxy;
    var menu = "nomenu";

    var usecaseResolver;
    var usecase;

    if (cocoon.log.isDebugEnabled())
       cocoon.log.debug("usecases.js::executeUsecase() called, parameter lenya.usecase = [" + usecaseName + "]");

    try {
        usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
        usecase = usecaseResolver.resolve(usecaseName);

        var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
        var request = flowHelper.getRequest(cocoon);
        var sourceUrl = Packages.org.apache.lenya.util.ServletHelper.getWebappURI(request);
        usecase.setSourceURL(sourceUrl);
        usecase.setName(usecaseName);
        view = usecase.getView();
        if (view && view.showMenu()) {
            menu = "menu";
        }

        passRequestParameters(flowHelper, usecase);
        usecase.checkPreconditions();
        usecase.lockInvolvedObjects();
        proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
    }
    finally {
        /* done with usecase component, tell usecaseResolver to release it */
        if (usecaseResolver != null) {
            if (usecase != null) {
                usecaseResolver.release(usecase);
                usecase = undefined;
            }
            cocoon.releaseComponent(usecaseResolver);
        }
    }

    var success = false;
    var targetUrl;

    if (view) {
        var ready = false;
        while (!ready) {

            cocoon.sendPageAndWait("view/" + menu + "/" + view.getTemplateURI(), {
                "usecase" : proxy
            });

            try {
                usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
                usecase = usecaseResolver.resolve(usecaseName);
                proxy.setup(usecase);

                passRequestParameters(flowHelper, usecase);
                usecase.advance();

                if (cocoon.request.getParameter("submit")) {
                    usecase.checkExecutionConditions();
                    if (usecase.getErrorMessages().isEmpty()) {
                        usecase.execute();
                        if (usecase.getErrorMessages().isEmpty()) {
                            usecase.checkPostconditions();
                            if (usecase.getErrorMessages().isEmpty()) {
                                ready = true;
                                success = true;
                            }
                        }
                    }
                }
                else if (cocoon.request.getParameter("cancel")) {
                    usecase.cancel();
                    ready = true;
                }
                proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
                targetUrl = usecase.getTargetURL(success);
            }
            finally {
                usecaseResolver.release(usecase);
                usecase = undefined;
                cocoon.releaseComponent(usecaseResolver);
            }
        }
    }
    else {
        try {
            usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
            usecase = usecaseResolver.resolve(usecaseName);
            proxy.setup(usecase);

            usecase.execute();
            if (usecase.getErrorMessages().isEmpty()) {
                usecase.checkPostconditions();
                if (usecase.getErrorMessages().isEmpty()) {
                    success = true;
                }
            }
            targetUrl = usecase.getTargetURL(success);
        }
        finally {
            usecaseResolver.release(usecase);
            usecase = undefined;
            cocoon.releaseComponent(usecaseResolver);
        }
    }

    var url = request.getContextPath() + targetUrl + getTargetQueryString(usecaseName);
    cocoon.redirectTo(url);

}
<commit_msg>[minor change] added some debug log messages and documentation<commit_after>/*
 * Copyright  1999-2005 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
/* $Id$ */

/* Helper method to add all request parameters to a usecase */
function passRequestParameters(flowHelper, usecase) {
    var names = cocoon.request.getParameterNames();
    while (names.hasMoreElements()) {
        var name = names.nextElement();
        if (!name.equals("lenya.usecase")
            && !name.equals("lenya.continuation")
            && !name.equals("submit")) {

            var value = flowHelper.getRequest(cocoon).get(name);

            var string = new Packages.java.lang.String();
            if (string.getClass().isInstance(value)) {
                usecase.setParameter(name, value);
            }
            else {
                usecase.setPart(name, value);
            }

        }
    }
}

/* Returns the query string to attach to the target URL. This is used in the site area. */
function getTargetQueryString(usecaseName) {
    var isTabUsecase = new Packages.java.lang.String(usecaseName).startsWith('tab');
    var queryString = "";
    if (isTabUsecase) {
        queryString = "?lenya.usecase=" + usecaseName;
    }
    return queryString;
}

/*
 * Main function to execute a usecase.
 *
 * Uses request parameter "lenya.usecase" to determine what
 * usecase to execute.
 *
 */
function executeUsecase() {
    var usecaseName = cocoon.request.getParameter("lenya.usecase");
    var view;
    var proxy;
    var menu = "nomenu";

    var usecaseResolver;
    var usecase;

    if (cocoon.log.isDebugEnabled())
       cocoon.log.debug("usecases.js::executeUsecase() called, parameter lenya.usecase = [" + usecaseName + "]");

    try {
        usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
        usecase = usecaseResolver.resolve(usecaseName);

        var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
        var request = flowHelper.getRequest(cocoon);
        var sourceUrl = Packages.org.apache.lenya.util.ServletHelper.getWebappURI(request);
        usecase.setSourceURL(sourceUrl);
        usecase.setName(usecaseName);
        view = usecase.getView();
        if (view && view.showMenu()) {
            menu = "menu";
        }

        passRequestParameters(flowHelper, usecase);
        usecase.checkPreconditions();
        usecase.lockInvolvedObjects();
        proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
    }
    finally {
        /* done with usecase component, tell usecaseResolver to release it */
        if (usecaseResolver != null) {
            if (usecase != null) {
                usecaseResolver.release(usecase);
                usecase = undefined;
            }
            cocoon.releaseComponent(usecaseResolver);
        }
    }

    var success = false;
    var targetUrl;

    /*
     * If the usecase has a view, this means we want to display something
     * to the user before proceeding. This also means the usecase consists
     * several steps; repeated until the user chooses to submit or cancel.
     *
     * If the usecase does not have a view, it is simply executed.
     */

    if (view) {
        var ready = false;
        while (!ready) {

            var viewUri = "view/" + menu + "/" + view.getTemplateURI();
            if (cocoon.log.isDebugEnabled())
               cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", creating view, calling Cocoon with viewUri = [" + viewUri + "]");

            cocoon.sendPageAndWait(viewUri, {
                "usecase" : proxy
            });

            if (cocoon.log.isDebugEnabled())
               cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", after view, now advancing in usecase");

            try {
                usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
                usecase = usecaseResolver.resolve(usecaseName);
                proxy.setup(usecase);

                passRequestParameters(flowHelper, usecase);
                usecase.advance();

                if (cocoon.request.getParameter("submit")) {
                    usecase.checkExecutionConditions();
                    if (usecase.getErrorMessages().isEmpty()) {
                        usecase.execute();
                        if (usecase.getErrorMessages().isEmpty()) {
                            usecase.checkPostconditions();
                            if (usecase.getErrorMessages().isEmpty()) {
                                ready = true;
                                success = true;
                            }
                        }
                    }
                }
                else if (cocoon.request.getParameter("cancel")) {
                    usecase.cancel();
                    ready = true;
                }
                proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
                targetUrl = usecase.getTargetURL(success);
            }
            finally {
                usecaseResolver.release(usecase);
                usecase = undefined;
                cocoon.releaseComponent(usecaseResolver);
            }
        }
    }
    else {
        try {
            usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
            usecase = usecaseResolver.resolve(usecaseName);
            proxy.setup(usecase);

            usecase.execute();
            if (usecase.getErrorMessages().isEmpty()) {
                usecase.checkPostconditions();
                if (usecase.getErrorMessages().isEmpty()) {
                    success = true;
                }
            }
            targetUrl = usecase.getTargetURL(success);
        }
        finally {
            usecaseResolver.release(usecase);
            usecase = undefined;
            cocoon.releaseComponent(usecaseResolver);
        }
    }

    var url = request.getContextPath() + targetUrl + getTargetQueryString(usecaseName);

    if (cocoon.log.isDebugEnabled())
       cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", completed, redirecting to url = [" + url + "]");

    cocoon.redirectTo(url);

}
<|endoftext|>


<commit_before>/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';

import { newDataTableStyles } from '../../globalStyles';

import Row from './Row';
import EditableCell from './EditableCell';
import Cell from './Cell';
import CheckableCell from './CheckableCell';
import { NewExpiryDateInput } from '../NewExpiryDateInput';

import {
  CheckedComponent,
  UncheckedComponent,
  DisabledCheckedComponent,
  DisabledUncheckedComponent,
} from '../icons';

/**
 * Wrapper component for a mSupply DataTable page row.
 * Wraps Row component with a contained RenderCells, which
 * will generate the appropriate cell for a given columnKey.
 * Doesn't need to be used, but is a convenience component.
 *
 * @param {Object} rowData  Data object for a row i.e. ItemBatch object
 * @param {Object} rowState State object for a row, see: Row.js
 * @param {Object} style    Style object the be passed to inner Row
 * @param {String} rowKey   Unique key for a row
 * @param {Array} columns   Array of column objects, see: columns.js
 * @param {Bool} isFinalised    Boolean indicating if the DataTable page is finalised.
 * @param {Func} focusCellAction    Action for focusing a cell.
 * @param {Func} focusNextAction    Action for focusing the next cell.
 * @param {Func} dispatch   Dispatch function for containing reducer.
 * @param {Func} getAction  Function to return an action for a cell
 *                          (colKey, propName) => actionObject
 */
const DataTableRow = React.memo(
  ({
    rowData,
    rowState,
    rowKey,
    style,
    columns,
    isFinalised,
    dispatch,
    focusCellAction,
    focusNextAction,
    getAction,
    onPress,
  }) => {
    // Key of the current column focused.
    const focusedColumnKey = rowState && rowState.focusedColumn;

    // Callback for rendering a row of cells. A cell is
    const renderCells = useCallback(() => {
      const {
        cellText,
        cellContainer,
        touchableCellContainer,
        editableCellText,
        editableCellTextView,
        editableCellUnfocused,
      } = newDataTableStyles;

      // Map each column to an appropriate cell for a given row.
      return columns.map(({ key: columnKey, type, width, alignText }, index) => {
        const isLastCell = index === columns.length - 1;
        const isDisabled = isFinalised || (rowState && rowState.isDisabled);
        const isFocused = focusedColumnKey === columnKey;
        const cellAlignment = alignText || 'left';

        switch (type) {
          case 'editable':
            return (
              <EditableCell
                key={columnKey}
                value={rowData[columnKey]}
                rowKey={rowKey}
                columnKey={columnKey}
                editAction={getAction(columnKey)}
                isFocused={isFocused}
                isDisabled={isDisabled}
                focusAction={focusCellAction}
                focusNextAction={focusNextAction}
                dispatch={dispatch}
                width={width}
                viewStyle={cellContainer[cellAlignment]}
                textViewStyle={editableCellTextView}
                isLastCell={isLastCell}
                keyboardType="numeric"
                textInputStyle={cellText[cellAlignment]}
                textStyle={editableCellUnfocused[cellAlignment]}
                cellTextStyle={editableCellText}
              />
            );

          case 'checkable':
            return (
              <CheckableCell
                key={columnKey}
                rowKey={rowKey}
                columnKey={columnKey}
                isChecked={rowState && rowState.isSelected}
                isDisabled={isDisabled}
                CheckedComponent={CheckedComponent}
                UncheckedComponent={UncheckedComponent}
                DisabledCheckedComponent={DisabledCheckedComponent}
                DisabledUncheckedComponent={DisabledUncheckedComponent}
                onCheckAction={getAction(columnKey, 'onCheckAction')}
                onUncheckAction={getAction(columnKey, 'onUncheckAction')}
                dispatch={dispatch}
                containerStyle={touchableCellContainer}
                width={width}
                isLastCell={isLastCell}
              />
            );

          case 'date':
            return (
              <NewExpiryDateInput
                key={columnKey}
                value={rowData[columnKey]}
                rowKey={rowKey}
                columnKey={columnKey}
                editAction={getAction(columnKey)}
                isFocused={isFocused}
                isDisabled={isDisabled}
                focusAction={focusCellAction}
                focusNextAction={focusNextAction}
                dispatch={dispatch}
                width={width}
                isLastCell={isLastCell}
              />
            );

          default:
            return (
              <Cell
                key={columnKey}
                value={rowData[columnKey]}
                width={width}
                viewStyle={cellContainer[cellAlignment]}
                textStyle={cellText[cellAlignment]}
                isLastCell={isLastCell}
              />
            );
        }
      });
    }, [isFinalised, focusedColumnKey, rowState]);

    return (
      <Row
        onPress={onPress}
        style={style}
        renderCells={renderCells}
        debug
        rowKey={rowKey}
        rowData={rowData}
        rowState={rowState}
      />
    );
  }
);

DataTableRow.defaultProps = {
  isFinalised: false,
  focusCellAction: null,
  focusNextAction: null,
  getAction: null,
  onPress: null,
  rowState: null,
};
DataTableRow.propTypes = {
  onPress: PropTypes.func,
  rowData: PropTypes.object.isRequired,
  rowState: PropTypes.object,
  rowKey: PropTypes.string.isRequired,
  style: PropTypes.object.isRequired,
  columns: PropTypes.array.isRequired,
  dispatch: PropTypes.func.isRequired,
  isFinalised: PropTypes.bool,
  focusCellAction: PropTypes.func,
  focusNextAction: PropTypes.func,
  getAction: PropTypes.func,
};

export default DataTableRow;
<commit_msg>Add update to DataTableRow  case statement adding status and entryDate<commit_after>/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';

import { newDataTableStyles } from '../../globalStyles';

import Row from './Row';
import EditableCell from './EditableCell';
import Cell from './Cell';
import CheckableCell from './CheckableCell';
import { NewExpiryDateInput } from '../NewExpiryDateInput';

import {
  CheckedComponent,
  UncheckedComponent,
  DisabledCheckedComponent,
  DisabledUncheckedComponent,
} from '../icons';
import { formatStatus } from '../../utilities/index';

/**
 * Wrapper component for a mSupply DataTable page row.
 * Wraps Row component with a contained RenderCells, which
 * will generate the appropriate cell for a given columnKey.
 * Doesn't need to be used, but is a convenience component.
 *
 * @param {Object} rowData  Data object for a row i.e. ItemBatch object
 * @param {Object} rowState State object for a row, see: Row.js
 * @param {Object} style    Style object the be passed to inner Row
 * @param {String} rowKey   Unique key for a row
 * @param {Array} columns   Array of column objects, see: columns.js
 * @param {Bool} isFinalised    Boolean indicating if the DataTable page is finalised.
 * @param {Func} focusCellAction    Action for focusing a cell.
 * @param {Func} focusNextAction    Action for focusing the next cell.
 * @param {Func} dispatch   Dispatch function for containing reducer.
 * @param {Func} getAction  Function to return an action for a cell
 *                          (colKey, propName) => actionObject
 */
const DataTableRow = React.memo(
  ({
    rowData,
    rowState,
    rowKey,
    style,
    columns,
    isFinalised,
    dispatch,
    focusCellAction,
    focusNextAction,
    getAction,
    onPress,
  }) => {
    // Key of the current column focused.
    const focusedColumnKey = rowState && rowState.focusedColumn;

    // Callback for rendering a row of cells. A cell is
    const renderCells = useCallback(() => {
      const {
        cellText,
        cellContainer,
        touchableCellContainer,
        editableCellText,
        editableCellTextView,
        editableCellUnfocused,
      } = newDataTableStyles;

      // Map each column to an appropriate cell for a given row.
      return columns.map(({ key: columnKey, type, width, alignText }, index) => {
        const isLastCell = index === columns.length - 1;
        const isDisabled = isFinalised || (rowState && rowState.isDisabled);
        const isFocused = focusedColumnKey === columnKey;
        const cellAlignment = alignText || 'left';

        switch (type) {
          case 'editable':
            return (
              <EditableCell
                key={columnKey}
                value={rowData[columnKey]}
                rowKey={rowKey}
                columnKey={columnKey}
                editAction={getAction(columnKey)}
                isFocused={isFocused}
                isDisabled={isDisabled}
                focusAction={focusCellAction}
                focusNextAction={focusNextAction}
                dispatch={dispatch}
                width={width}
                viewStyle={cellContainer[cellAlignment]}
                textViewStyle={editableCellTextView}
                isLastCell={isLastCell}
                keyboardType="numeric"
                textInputStyle={cellText[cellAlignment]}
                textStyle={editableCellUnfocused[cellAlignment]}
                cellTextStyle={editableCellText}
              />
            );

          case 'checkable':
            return (
              <CheckableCell
                key={columnKey}
                rowKey={rowKey}
                columnKey={columnKey}
                isChecked={rowState && rowState.isSelected}
                isDisabled={isDisabled}
                CheckedComponent={CheckedComponent}
                UncheckedComponent={UncheckedComponent}
                DisabledCheckedComponent={DisabledCheckedComponent}
                DisabledUncheckedComponent={DisabledUncheckedComponent}
                onCheckAction={getAction(columnKey, 'onCheckAction')}
                onUncheckAction={getAction(columnKey, 'onUncheckAction')}
                dispatch={dispatch}
                containerStyle={touchableCellContainer}
                width={width}
                isLastCell={isLastCell}
              />
            );

          case 'date':
            return (
              <NewExpiryDateInput
                key={columnKey}
                value={rowData[columnKey]}
                rowKey={rowKey}
                columnKey={columnKey}
                editAction={getAction(columnKey)}
                isFocused={isFocused}
                isDisabled={isDisabled}
                focusAction={focusCellAction}
                focusNextAction={focusNextAction}
                dispatch={dispatch}
                width={width}
                isLastCell={isLastCell}
              />
            );

          case 'status':
            return (
              <Cell
                key={columnKey}
                value={formatStatus(rowData[columnKey])}
                width={width}
                viewStyle={cellContainer[cellAlignment]}
                textStyle={cellText[cellAlignment]}
                isLastCell={isLastCell}
              />
            );
          case 'entryDate':
            return (
              <Cell
                key={columnKey}
                value={rowData[columnKey] && rowData[columnKey].toDateString()}
                width={width}
                viewStyle={cellContainer[cellAlignment]}
                textStyle={cellText[cellAlignment]}
                isLastCell={isLastCell}
              />
            );

          default:
            return (
              <Cell
                key={columnKey}
                value={rowData[columnKey]}
                width={width}
                viewStyle={cellContainer[cellAlignment]}
                textStyle={cellText[cellAlignment]}
                isLastCell={isLastCell}
              />
            );
        }
      });
    }, [isFinalised, focusedColumnKey, rowState]);

    return (
      <Row
        onPress={onPress}
        style={style}
        renderCells={renderCells}
        debug
        rowKey={rowKey}
        rowData={rowData}
        rowState={rowState}
      />
    );
  }
);

DataTableRow.defaultProps = {
  isFinalised: false,
  focusCellAction: null,
  focusNextAction: null,
  getAction: null,
  onPress: null,
  rowState: null,
};
DataTableRow.propTypes = {
  onPress: PropTypes.func,
  rowData: PropTypes.object.isRequired,
  rowState: PropTypes.object,
  rowKey: PropTypes.string.isRequired,
  style: PropTypes.object.isRequired,
  columns: PropTypes.array.isRequired,
  dispatch: PropTypes.func.isRequired,
  isFinalised: PropTypes.bool,
  focusCellAction: PropTypes.func,
  focusNextAction: PropTypes.func,
  getAction: PropTypes.func,
};

export default DataTableRow;
<|endoftext|>


<commit_before>/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';

import { dataTableStyles } from '../../globalStyles';

import Row from './Row';
import Cell from './Cell';

import CheckableCell from './CheckableCell';
import TouchableCell from './TouchableCell';
import DropDownCell from '../DropDownCell';

import { ExpiryDateInput } from '../ExpiryDateInput';

import {
  CheckedComponent,
  UncheckedComponent,
  DisabledCheckedComponent,
  DisabledUncheckedComponent,
  OpenModal,
} from '../icons';
import TextInputCell from './TextInputCell';

import { formatStatus } from '../../utilities';

import { COLUMN_TYPES, COLUMN_NAMES } from '../../pages/dataTableUtilities';
import { tableStrings } from '../../localization/index';

/**
 * Wrapper component for a mSupply DataTable page row.
 * Wraps Row component with a contained RenderCells, which
 * will generate the appropriate cell for a given columnKey.
 * Doesn't need to be used, but is a convenience component.
 *
 * @param {Object} rowData     Data object for a row i.e. ItemBatch object
 * @param {Object} rowState    State object for a row, see: Row.js
 * @param {Object} style       Style object the be passed to inner Row
 * @param {String} rowKey      Unique key for a row
 * @param {Array}  columns     Array of column objects, see: columns.js
 * @param {Bool}   isFinalised Boolean indicating if the DataTable page is finalised.
 * @param {Func}   dispatch    Dispatch function for containing reducer.
 * @param {Func}   rowIndex    index of this row.
 * @param {Func}   onPress     On press callback for the row itself.
 * @param {Func}   getAction   Function to return an action for a cell
 *                             (colKey, propName) => actionObject
 */
const DataTableRow = React.memo(
  ({ rowData, rowState, rowKey, columns, isFinalised, dispatch, getAction, onPress, rowIndex }) => {
    const {
      cellText,
      cellContainer,
      touchableCellContainer,
      editableCellText,
      editableCellTextView,
      editableCellUnfocused,
      selectedRow: selectedRowStyle,
      alternateRow: alternateRowStyle,
      row: basicRowStyle,
      iconCell,
    } = dataTableStyles;

    const { isSelected = false } = rowState || {};
    // If the row is selected, use selectedRow style, otherwise alternate row style on index.
    const rowStyle = isSelected
      ? selectedRowStyle
      : (rowIndex % 2 === 0 && alternateRowStyle) || basicRowStyle;

    // Callback for rendering a row of cells.
    const renderCells = useCallback(
      () =>
        // Map each column to an appropriate cell for a given row.
        columns.map(({ key: columnKey, type, width, alignText }, index) => {
          // Indicator if the right hand border should be removed from styles for this cell.
          const isLastCell = index === columns.length - 1;

          // This cell is disabled if the pageObject is finalised, the row has been explicitly set
          // as disabled, or the rowData is disabled (i.e. data is an invoice),
          const isDisabled =
            isFinalised || (rowState && rowState.isDisabled) || rowData.isFinalised;

          // Alignment of this particular column. Default to left hand ide.
          const cellAlignment = alignText || 'left';

          switch (type) {
            case COLUMN_TYPES.EDITABLE_STRING:
            case COLUMN_TYPES.EDITABLE_NUMERIC: {
              // Special condition for stocktake counted total quantity cells.
              // Use the placeholder 'Not counted' when a stocktake item or batch
              // has not been counted yet.
              let placeholder = '';
              if (columnKey === COLUMN_NAMES.COUNTED_TOTAL_QUANTITY) {
                placeholder = rowData.hasBeenCounted ? '' : tableStrings.not_counted;
              }

              return (
                <TextInputCell
                  key={columnKey}
                  value={rowData[columnKey]}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  editAction={getAction(columnKey)}
                  isDisabled={isDisabled}
                  dispatch={dispatch}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textViewStyle={editableCellTextView}
                  isLastCell={isLastCell}
                  keyboardType={type === COLUMN_TYPES.EDITABLE_NUMERIC ? 'numeric' : 'default'}
                  textInputStyle={cellText[cellAlignment]}
                  textStyle={editableCellUnfocused[cellAlignment]}
                  cellTextStyle={editableCellText}
                  rowIndex={rowIndex}
                  placeholder={placeholder}
                />
              );
            }
            case COLUMN_TYPES.EDITABLE_EXPIRY_DATE:
              return (
                <ExpiryDateInput
                  key={columnKey}
                  value={rowData[columnKey]}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  editAction={getAction(columnKey)}
                  isDisabled={isDisabled}
                  dispatch={dispatch}
                  width={width}
                  isLastCell={isLastCell}
                  rowIndex={rowIndex}
                />
              );

            case COLUMN_TYPES.CHECKABLE:
              return (
                <CheckableCell
                  key={columnKey}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  isChecked={rowState && rowState.isSelected}
                  isDisabled={isDisabled}
                  CheckedComponent={CheckedComponent}
                  UncheckedComponent={UncheckedComponent}
                  DisabledCheckedComponent={DisabledCheckedComponent}
                  DisabledUncheckedComponent={DisabledUncheckedComponent}
                  onCheckAction={getAction(columnKey, 'onCheckAction')}
                  onUncheckAction={getAction(columnKey, 'onUncheckAction')}
                  dispatch={dispatch}
                  containerStyle={touchableCellContainer}
                  width={width}
                  isLastCell={isLastCell}
                />
              );

            case COLUMN_TYPES.STRING: {
              const value = rowData[columnKey];
              const displayValue = columnKey === 'status' ? formatStatus(value) : value;
              return (
                <Cell
                  key={columnKey}
                  value={displayValue}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );
            }

            case COLUMN_TYPES.NUMERIC: {
              return (
                <Cell
                  key={columnKey}
                  value={Math.round(rowData[columnKey])}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );
            }

            case COLUMN_TYPES.DATE:
              return (
                <Cell
                  key={columnKey}
                  value={rowData[columnKey] && rowData[columnKey].toDateString()}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );

            case COLUMN_TYPES.ICON:
              return (
                <TouchableCell
                  key={columnKey}
                  renderChildren={OpenModal}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  onPressAction={getAction(columnKey)}
                  dispatch={dispatch}
                  width={width}
                  isLastCell={isLastCell}
                  containerStyle={iconCell}
                />
              );

            case COLUMN_TYPES.DROP_DOWN:
              return (
                <DropDownCell
                  key={columnKey}
                  isDisabled={isFinalised}
                  dispatch={dispatch}
                  onPressAction={getAction(columnKey)}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  value={rowData[columnKey]}
                  isLastCell={isLastCell}
                  width={width}
                />
              );

            default: {
              return (
                <Cell
                  key={columnKey}
                  value={rowData[columnKey]}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );
            }
          }
        }),
      [isFinalised, rowState, rowData, rowIndex]
    );

    return (
      <Row
        onPress={onPress}
        style={rowStyle}
        renderCells={renderCells}
        debug
        rowKey={rowKey}
        rowData={rowData}
        rowState={rowState}
        rowIndex={rowIndex}
      />
    );
  }
);

DataTableRow.defaultProps = {
  isFinalised: false,
  getAction: null,
  onPress: null,
  rowState: null,
};

DataTableRow.propTypes = {
  onPress: PropTypes.func,
  rowData: PropTypes.object.isRequired,
  rowState: PropTypes.object,
  rowKey: PropTypes.string.isRequired,
  columns: PropTypes.array.isRequired,
  dispatch: PropTypes.func.isRequired,
  isFinalised: PropTypes.bool,
  getAction: PropTypes.func,
  rowIndex: PropTypes.number.isRequired,
};

export default DataTableRow;
<commit_msg>Fix stocktake difference for uncounted quantities<commit_after>/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';

import { dataTableStyles } from '../../globalStyles';

import Row from './Row';
import Cell from './Cell';

import CheckableCell from './CheckableCell';
import TouchableCell from './TouchableCell';
import DropDownCell from '../DropDownCell';

import { ExpiryDateInput } from '../ExpiryDateInput';

import {
  CheckedComponent,
  UncheckedComponent,
  DisabledCheckedComponent,
  DisabledUncheckedComponent,
  OpenModal,
} from '../icons';
import TextInputCell from './TextInputCell';

import { formatStatus } from '../../utilities';

import { COLUMN_TYPES, COLUMN_NAMES } from '../../pages/dataTableUtilities';
import { generalStrings, tableStrings } from '../../localization/index';

/**
 * Wrapper component for a mSupply DataTable page row.
 * Wraps Row component with a contained RenderCells, which
 * will generate the appropriate cell for a given columnKey.
 * Doesn't need to be used, but is a convenience component.
 *
 * @param {Object} rowData     Data object for a row i.e. ItemBatch object
 * @param {Object} rowState    State object for a row, see: Row.js
 * @param {Object} style       Style object the be passed to inner Row
 * @param {String} rowKey      Unique key for a row
 * @param {Array}  columns     Array of column objects, see: columns.js
 * @param {Bool}   isFinalised Boolean indicating if the DataTable page is finalised.
 * @param {Func}   dispatch    Dispatch function for containing reducer.
 * @param {Func}   rowIndex    index of this row.
 * @param {Func}   onPress     On press callback for the row itself.
 * @param {Func}   getAction   Function to return an action for a cell
 *                             (colKey, propName) => actionObject
 */
const DataTableRow = React.memo(
  ({ rowData, rowState, rowKey, columns, isFinalised, dispatch, getAction, onPress, rowIndex }) => {
    const {
      cellText,
      cellContainer,
      touchableCellContainer,
      editableCellText,
      editableCellTextView,
      editableCellUnfocused,
      selectedRow: selectedRowStyle,
      alternateRow: alternateRowStyle,
      row: basicRowStyle,
      iconCell,
    } = dataTableStyles;

    const { isSelected = false } = rowState || {};
    // If the row is selected, use selectedRow style, otherwise alternate row style on index.
    const rowStyle = isSelected
      ? selectedRowStyle
      : (rowIndex % 2 === 0 && alternateRowStyle) || basicRowStyle;

    // Callback for rendering a row of cells.
    const renderCells = useCallback(
      () =>
        // Map each column to an appropriate cell for a given row.
        columns.map(({ key: columnKey, type, width, alignText }, index) => {
          // Indicator if the right hand border should be removed from styles for this cell.
          const isLastCell = index === columns.length - 1;

          // This cell is disabled if the pageObject is finalised, the row has been explicitly set
          // as disabled, or the rowData is disabled (i.e. data is an invoice),
          const isDisabled =
            isFinalised || (rowState && rowState.isDisabled) || rowData.isFinalised;

          // Alignment of this particular column. Default to left hand ide.
          const cellAlignment = alignText || 'left';

          switch (type) {
            case COLUMN_TYPES.EDITABLE_STRING:
            case COLUMN_TYPES.EDITABLE_NUMERIC: {
              // Special condition for stocktake counted total quantity cells.
              // Use the placeholder 'Not counted' when a stocktake item or batch
              // has not been counted yet.
              let placeholder = '';
              if (columnKey === COLUMN_NAMES.COUNTED_TOTAL_QUANTITY) {
                placeholder = rowData.hasBeenCounted ? '' : tableStrings.not_counted;
              }

              return (
                <TextInputCell
                  key={columnKey}
                  value={rowData[columnKey]}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  editAction={getAction(columnKey)}
                  isDisabled={isDisabled}
                  dispatch={dispatch}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textViewStyle={editableCellTextView}
                  isLastCell={isLastCell}
                  keyboardType={type === COLUMN_TYPES.EDITABLE_NUMERIC ? 'numeric' : 'default'}
                  textInputStyle={cellText[cellAlignment]}
                  textStyle={editableCellUnfocused[cellAlignment]}
                  cellTextStyle={editableCellText}
                  rowIndex={rowIndex}
                  placeholder={placeholder}
                />
              );
            }
            case COLUMN_TYPES.EDITABLE_EXPIRY_DATE:
              return (
                <ExpiryDateInput
                  key={columnKey}
                  value={rowData[columnKey]}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  editAction={getAction(columnKey)}
                  isDisabled={isDisabled}
                  dispatch={dispatch}
                  width={width}
                  isLastCell={isLastCell}
                  rowIndex={rowIndex}
                />
              );

            case COLUMN_TYPES.CHECKABLE:
              return (
                <CheckableCell
                  key={columnKey}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  isChecked={rowState && rowState.isSelected}
                  isDisabled={isDisabled}
                  CheckedComponent={CheckedComponent}
                  UncheckedComponent={UncheckedComponent}
                  DisabledCheckedComponent={DisabledCheckedComponent}
                  DisabledUncheckedComponent={DisabledUncheckedComponent}
                  onCheckAction={getAction(columnKey, 'onCheckAction')}
                  onUncheckAction={getAction(columnKey, 'onUncheckAction')}
                  dispatch={dispatch}
                  containerStyle={touchableCellContainer}
                  width={width}
                  isLastCell={isLastCell}
                />
              );

            case COLUMN_TYPES.STRING: {
              const value = rowData[columnKey];
              const displayValue = columnKey === 'status' ? formatStatus(value) : value;
              return (
                <Cell
                  key={columnKey}
                  value={displayValue}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );
            }

            case COLUMN_TYPES.NUMERIC: {
              // Special condition for stocktake difference cells.
              // Use the placeholder 'Not counted' when a stocktake item or batch
              // has not been counted yet.
              const value =
                columnKey === COLUMN_NAMES.DIFFERENCE && !rowData.hasBeenCounted
                  ? generalStrings.not_available
                  : Math.round(rowData[columnKey]);

              return (
                <Cell
                  key={columnKey}
                  value={value}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );
            }

            case COLUMN_TYPES.DATE:
              return (
                <Cell
                  key={columnKey}
                  value={rowData[columnKey] && rowData[columnKey].toDateString()}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );

            case COLUMN_TYPES.ICON:
              return (
                <TouchableCell
                  key={columnKey}
                  renderChildren={OpenModal}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  onPressAction={getAction(columnKey)}
                  dispatch={dispatch}
                  width={width}
                  isLastCell={isLastCell}
                  containerStyle={iconCell}
                />
              );

            case COLUMN_TYPES.DROP_DOWN:
              return (
                <DropDownCell
                  key={columnKey}
                  isDisabled={isFinalised}
                  dispatch={dispatch}
                  onPressAction={getAction(columnKey)}
                  rowKey={rowKey}
                  columnKey={columnKey}
                  value={rowData[columnKey]}
                  isLastCell={isLastCell}
                  width={width}
                />
              );

            default: {
              return (
                <Cell
                  key={columnKey}
                  value={rowData[columnKey]}
                  width={width}
                  viewStyle={cellContainer[cellAlignment]}
                  textStyle={cellText[cellAlignment]}
                  isLastCell={isLastCell}
                />
              );
            }
          }
        }),
      [isFinalised, rowState, rowData, rowIndex]
    );

    return (
      <Row
        onPress={onPress}
        style={rowStyle}
        renderCells={renderCells}
        debug
        rowKey={rowKey}
        rowData={rowData}
        rowState={rowState}
        rowIndex={rowIndex}
      />
    );
  }
);

DataTableRow.defaultProps = {
  isFinalised: false,
  getAction: null,
  onPress: null,
  rowState: null,
};

DataTableRow.propTypes = {
  onPress: PropTypes.func,
  rowData: PropTypes.object.isRequired,
  rowState: PropTypes.object,
  rowKey: PropTypes.string.isRequired,
  columns: PropTypes.array.isRequired,
  dispatch: PropTypes.func.isRequired,
  isFinalised: PropTypes.bool,
  getAction: PropTypes.func,
  rowIndex: PropTypes.number.isRequired,
};

export default DataTableRow;
<|endoftext|>


<commit_before>
var View = function View(options) {
    'use strict';
    // Set options to an empty object if passed options is empty
    if (typeof options !== 'object') {
        options = {};
    }
    // Create a new instance if object is not a instance of Base
    if (!(this instanceof View)) {
        return new View(options);
    }
    // Defined pre-default values
    this.attributes = {};
    // Set options to `this.attributes` object
    for (var i in options) {
        this.attributes[i] = options[i];
    }
    // Set debugging mode
    this.set('debugging', true);
    // Set intialized status
    this.set('initialized', false);
    // Patch view
    if (typeof this.patch === 'function') {
        this.patch();
    }
    // Return self object
    if (typeof this.controller === 'function') {
        this.controller();
    }
    return this;
};

View.prototype.constructor = View;

View.prototype.id = function() {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof this.get('_id') !== 'string' || (typeof this.get('_id') && this.get('_id').trim().length === 0)) {
        this.set('_id', Math.random().toString(36).substring(7));
    }
    return this.get('_id');
};

View.prototype.self = View.prototype.instance = function() {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    return this;
};

View.prototype.get = function(key) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string') {
        return this.attributes[key];
    }
    return this.attributes;
};

View.prototype.set = function(key, value) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string') {
        this.attributes[key] = value;
    }
    return this;
};

View.prototype.unset = function(key) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string') {
        delete this.attributes[key];
    }
    return this;
};

View.prototype.append = function(key, value) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string' && typeof value === 'string') {
        if (typeof this.attributes[key] !== 'string') {
            this.attributes[key] = '';
        }
        this.attributes[key] += value;
    }
    return this.attributes[key];
};

View.prototype.on = function(event, cb) {
    require('electron').ipcRenderer.on(event, cb.bind(this));
};

View.prototype.off = View.prototype.removeListener = function(event, cb) {
    require('electron').ipcRenderer.removeListener(event, cb.bind(this));
};

View.prototype.emit = function(event) {
    var ipc = require('electron').ipcRenderer;
    if (typeof event !== 'string') {
        this.throw('missing event name');
    }
    ipc.send.apply(ipc, arguments);
};

View.prototype.send = View.prototype.emit;

View.prototype.log = function(str) {
    if (this.get('debugging') === true) {
        var args;
        if ((typeof str === 'string' && str.indexOf('{0}') == -1) || (typeof str !== 'string')) {
            args = ['[' + this.constructor.name + ']'];
            for (var i = 0; i < arguments.length; i++) {
                args.push(arguments[i]);
            }
            console.log(args.join(' '));
        } else if (typeof str === 'string' && str.indexOf('{0}') > -1) {
            args = arguments;
            str = str.replace(/\{([0-9]+)\}/g, function (match, index) {
                return args[parseInt(index) + 1];
            });
            console.log('[' + this.constructor.name + ']', str);
        }
    }
    return this;
};

View.prototype.throw = function(str) {
    var args;
    if ((typeof str === 'string' && str.indexOf('{0}') == -1) || (typeof str !== 'string')) {
        args = ['[' + this.constructor.name + ']'];
        for (var i = 0; i < arguments.length; i++) {
            args.push(arguments[i]);
        }
        throw args.join(' ');
    } else if (typeof str === 'string' && str.indexOf('{0}') > -1) {
        args = arguments;
        str = str.replace(/\{([0-9]+)\}/g, function (match, index) {
            return args[parseInt(index) + 1];
        });
        throw ('[' + this.constructor.name + ']' + str);
    }
};

View.prototype.component = function(options) {
    if (typeof options !== 'object') {
        options = {};
    }
    for (var i in options) {
        this.attributes[i] = options[i];
    }
};

View.prototype.patch = function() {
    // Patch targets
    var targets = [ 'controller', 'view' ],
        prototypes = Object.keys(View.prototype);
    for (var i = 0; i < targets.length; i++) {
        var target = targets[i];
        if (typeof this[target] === 'function') {
            for (var j = 0; j < prototypes.length; j++) {
                this[target].prototype[prototypes[j]] = this[prototypes[j]].bind(this);
            }
        }
    }
};

View.prototype.stylesheet = function(list) {
    var args = [];
    if (list instanceof Array) {
        args = list;
    } else {
        args = arguments;
    }
    for (var i = 0; i < args.length; i++) {
        // Get stylesheet path
        var path  = [ '..', 'styles', 'dist', args[i] ].join('/'),
            links = document.head.querySelectorAll('link[href="' + path + '"]');
        // Only link css if stylesheet is not present in the current html
        if (links.length === 0) {
            // Generate a link element
            var link = document.createElement('link');
            link.setAttribute('href', path);
            link.setAttribute('rel', 'stylesheet');
            // Append the stylesheet to html head
            document.head.appendChild(link);
        }
    }
};

View.prototype.autoconfig = function() {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof this.unload === 'function') {
        context.onunload = this.unload.call(this);
    }
};

App.Common.View = View;

<commit_msg>default unload action and bug fix<commit_after>
var View = function View(options) {
    'use strict';
    // Set options to an empty object if passed options is empty
    if (typeof options !== 'object') {
        options = {};
    }
    // Create a new instance if object is not a instance of Base
    if (!(this instanceof View)) {
        return new View(options);
    }
    // Defined pre-default values
    this.attributes = {};
    // Set options to `this.attributes` object
    for (var i in options) {
        this.attributes[i] = options[i];
    }
    // Set debugging mode
    this.set('debugging', true);
    // Set intialized status
    this.set('initialized', false);
    // Patch view
    if (typeof this.patch === 'function') {
        this.patch();
    }
    // Return self object
    if (typeof this.controller === 'function') {
        this.controller();
    }
    return this;
};

View.prototype.constructor = View;

View.prototype.id = function() {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof this.get('_id') !== 'string' || (typeof this.get('_id') && this.get('_id').trim().length === 0)) {
        this.set('_id', Math.random().toString(36).substring(7));
    }
    return this.get('_id');
};

View.prototype.self = View.prototype.instance = function() {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    return this;
};

View.prototype.get = function(key) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string') {
        return this.attributes[key];
    }
    return this.attributes;
};

View.prototype.set = function(key, value) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string') {
        this.attributes[key] = value;
    }
    return this;
};

View.prototype.unset = function(key) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string') {
        delete this.attributes[key];
    }
    return this;
};

View.prototype.append = function(key, value) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof key === 'string' && typeof value === 'string') {
        if (typeof this.attributes[key] !== 'string') {
            this.attributes[key] = '';
        }
        this.attributes[key] += value;
    }
    return this.attributes[key];
};

View.prototype.on = function(event, cb) {
    require('electron').ipcRenderer.on(event, cb.bind(this));
};

View.prototype.off = View.prototype.removeListener = function(event, cb) {
    require('electron').ipcRenderer.removeListener(event, cb.bind(this));
};

View.prototype.emit = function(event) {
    var ipc = require('electron').ipcRenderer;
    if (typeof event !== 'string') {
        this.throw('missing event name');
    }
    ipc.send.apply(ipc, arguments);
};

View.prototype.send = View.prototype.emit;

View.prototype.log = function(str) {
    if (this.get('debugging') === true) {
        var args;
        if ((typeof str === 'string' && str.indexOf('{0}') == -1) || (typeof str !== 'string')) {
            args = ['[' + this.constructor.name + ']'];
            for (var i = 0; i < arguments.length; i++) {
                args.push(arguments[i]);
            }
            console.log(args.join(' '));
        } else if (typeof str === 'string' && str.indexOf('{0}') > -1) {
            args = arguments;
            str = str.replace(/\{([0-9]+)\}/g, function (match, index) {
                return args[parseInt(index) + 1];
            });
            console.log('[' + this.constructor.name + ']', str);
        }
    }
    return this;
};

View.prototype.throw = function(str) {
    var args;
    if ((typeof str === 'string' && str.indexOf('{0}') == -1) || (typeof str !== 'string')) {
        args = ['[' + this.constructor.name + ']'];
        for (var i = 0; i < arguments.length; i++) {
            args.push(arguments[i]);
        }
        throw args.join(' ');
    } else if (typeof str === 'string' && str.indexOf('{0}') > -1) {
        args = arguments;
        str = str.replace(/\{([0-9]+)\}/g, function (match, index) {
            return args[parseInt(index) + 1];
        });
        throw ('[' + this.constructor.name + ']' + str);
    }
};

View.prototype.component = function(options) {
    if (typeof options !== 'object') {
        options = {};
    }
    for (var i in options) {
        this.attributes[i] = options[i];
    }
};

View.prototype.patch = function() {
    // Patch targets
    var targets = [ 'controller', 'view' ],
        prototypes = Object.keys(View.prototype);
    for (var i = 0; i < targets.length; i++) {
        var target = targets[i];
        if (typeof this[target] === 'function') {
            for (var j = 0; j < prototypes.length; j++) {
                this[target].prototype[prototypes[j]] = this[prototypes[j]].bind(this);
            }
        }
    }
};

View.prototype.stylesheet = function(list) {
    var args = [];
    if (list instanceof Array) {
        args = list;
    } else {
        args = arguments;
    }
    for (var i = 0; i < args.length; i++) {
        // Get stylesheet path
        var path  = [ '..', 'styles', 'dist', args[i] ].join('/'),
            links = document.head.querySelectorAll('link[href="' + path + '"]');
        // Only link css if stylesheet is not present in the current html
        if (links.length === 0) {
            // Generate a link element
            var link = document.createElement('link');
            link.setAttribute('href', path);
            link.setAttribute('rel', 'stylesheet');
            // Append the stylesheet to html head
            document.head.appendChild(link);
        }
    }
};

View.prototype.autoconfig = function(element, isInit, context) {
    if (!(this instanceof View)) {
        View.prototype.throw.call(this, 'NOT_VIEW_INSTANCE');
    }
    if (typeof this.unload === 'function') {
        context.onunload = this.unload.call(this);
    }
};

View.prototype.unload = function() {
    this.set('initialized', false);
};

App.Common.View = View;

<|endoftext|>


<commit_before>$(function(){
  $(document).ready(function() {
	  $("a[rel*=leanModal]").leanModal();

    $("body").append('

 <input class="schematic" height="150" width="150" id="schematic_editor" name="schematic" type="hidden" value=""/> <button type="button" id="circuit_save_btn">save</button>

');

    //This is the editor that pops up as a modal
    var editorCircuit = $("#schematic_editor").get(0);
    //This is the circuit that they last clicked. The one being edited.
    var editingCircuit = null;
    //Notice we use live, because new circuits can be inserted
    $(".schematic_open").live("click", function() {
      //Find the new editingCircuit. Transfer its contents to the editorCircuit
      editingCircuit = $(this).children("input.schematic").get(0);

      editingCircuit.schematic.update_value();
      var circuit_so_far = $(editingCircuit).val();

	    var n = editorCircuit.schematic.components.length;
	    for (var i = 0; i < n; i++)
		    editorCircuit.schematic.components[n - 1 - i].remove();

      editorCircuit.schematic.load_schematic(circuit_so_far, "");
    });

    $("#circuit_save_btn").click(function () {
      //Take the circuit from the editor and put it back into editingCircuit
      editorCircuit.schematic.update_value();
      var saving_circuit = $(editorCircuit).val();

	    var n = editingCircuit.schematic.components.length;
	    for (var i = 0; i < n; i++)
		    editingCircuit.schematic.components[n - 1 - i].remove();

      editingCircuit.schematic.load_schematic(saving_circuit, "");

      if (editingCircuit.codeMirrorLine) {
        editingCircuit.codeMirrorLine.replace(0, null, "circuit-schematic:" + saving_circuit);
      }

      $(".modal_close").first().click();
    });
  });
});

CodeMirror.defineMode("mitx_markdown", function(cmCfg, modeCfg) {

  var htmlMode = CodeMirror.getMode(cmCfg, { name: 'xml', htmlMode: true });

  var header   = 'header'
  ,   code     = 'comment'
  ,   quote    = 'quote'
  ,   list     = 'string'
  ,   hr       = 'hr'
  ,   linktext = 'link'
  ,   linkhref = 'string'
  ,   em       = 'em'
  ,   strong   = 'strong'
  ,   emstrong = 'emstrong';

  function escapeHtml(unsafe) {
      return unsafe
           .replace(/&/g, "&")
           .replace(/</g, "<")
           .replace(/>/g, ">")
           .replace(/"/g, """)
           .replace(/'/g, "'");
   }

  var circuit_formatter = {
    creator: function(text) {
      var circuit_value = text.match(circuitRE)[1]

      circuit_value = escapeHtml(circuit_value);

      var html = "" +
                  "<input type='hidden' parts='' value='" + circuit_value + "' width='150' height='148' analyses='' class='schematic ctrls'/>";

      return html;
    },
    size: function(text) {
      return {width: 150, height:152};
    },
    callback: function(node, line) {
      update_schematics();
      var schmInput = node.firstChild;
      schmInput.codeMirrorLine = line;
      schmInput.schematic.always_draw_grid = true;
      schmInput.schematic.redraw_background();
      $(node).leanModal();
    }
  };

  var hrRE = /^[*-=_]/
  ,   ulRE = /^[*-+]\s+/
  ,   olRE = /^[0-9]+\.\s+/
  ,   headerRE = /^(?:\={3,}|-{3,})$/
  ,   codeRE = /^(k:\t|\s{4,})/
  ,   textRE = /^[^\[*_\\<>`]+/
  ,   circuitRE = /^circuit-schematic:(.*)$/;

  function switchInline(stream, state, f) {
    state.f = state.inline = f;
    return f(stream, state);
  }

  function switchBlock(stream, state, f) {
    state.f = state.block = f;
    return f(stream, state);
  }

  // Blocks

  function blockNormal(stream, state) {
    var match;
    if (stream.match(circuitRE)) {
      stream.skipToEnd();
      return circuit_formatter;
    } else if (stream.match(codeRE)) {
      stream.skipToEnd();
      return code;
    } else if (stream.eatSpace()) {
      return null;
    } else if (stream.peek() === '#' || stream.match(headerRE)) {
      state.header = true;
    } else if (stream.eat('>')) {
      state.indentation++;
      state.quote = true;
    } else if (stream.peek() === '[') {
      return switchInline(stream, state, footnoteLink);
    } else if (hrRE.test(stream.peek())) {
      var re = new RegExp('(?:\s*['+stream.peek()+']){3,}$');
      if (stream.match(re, true)) {
        return hr;
      }
    } else if (match = stream.match(ulRE, true) || stream.match(olRE, true)) {
      state.indentation += match[0].length;
      return list;
    }

    return switchInline(stream, state, state.inline);
  }

  function htmlBlock(stream, state) {
    var style = htmlMode.token(stream, state.htmlState);
    if (style === 'tag' && state.htmlState.type !== 'openTag' && !state.htmlState.context) {
      state.f = inlineNormal;
      state.block = blockNormal;
    }
    return style;
  }

  // Inline
  function getType(state) {

    // Set defaults
    returnValue = '';

    // Strong / Emphasis
    if(state.strong){
      if(state.em){
        returnValue += (returnValue ? ' ' : '') + emstrong;
      } else {
        returnValue += (returnValue ? ' ' : '') + strong;
      }
    } else {
      if(state.em){
        returnValue += (returnValue ? ' ' : '') + em;
      }
    }

    // Header
    if(state.header){
      returnValue += (returnValue ? ' ' : '') + header;
    }

    // Quotes
    if(state.quote){
      returnValue += (returnValue ? ' ' : '') + quote;
    }

    // Check valud and return
    if(!returnValue){
      returnValue = null;
    }
    return returnValue;

  }

  function handleText(stream, state) {
    if (stream.match(textRE, true)) {
      return getType(state);
    }
    return undefined;
  }

  function inlineNormal(stream, state) {
    var style = state.text(stream, state)
    if (typeof style !== 'undefined')
      return style;

    var ch = stream.next();

    if (ch === '\\') {
      stream.next();
      return getType(state);
    }
    if (ch === '`') {
      return switchInline(stream, state, inlineElement(code, '`'));
    }
    if (ch === '[') {
      return switchInline(stream, state, linkText);
    }
    if (ch === '<' && stream.match(/^\w/, false)) {
      stream.backUp(1);
      return switchBlock(stream, state, htmlBlock);
    }

    var t = getType(state);
    if (ch === '*' || ch === '_') {
      if (stream.eat(ch)) {
        return (state.strong = !state.strong) ? getType(state) : t;
      }
      return (state.em = !state.em) ? getType(state) : t;
    }

    return getType(state);
  }

  function linkText(stream, state) {
    while (!stream.eol()) {
      var ch = stream.next();
      if (ch === '\\') stream.next();
      if (ch === ']') {
        state.inline = state.f = linkHref;
        return linktext;
      }
    }
    return linktext;
  }

  function linkHref(stream, state) {
    stream.eatSpace();
    var ch = stream.next();
    if (ch === '(' || ch === '[') {
      return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']'));
    }
    return 'error';
  }

  function footnoteLink(stream, state) {
    if (stream.match(/^[^\]]*\]:/, true)) {
      state.f = footnoteUrl;
      return linktext;
    }
    return switchInline(stream, state, inlineNormal);
  }

  function footnoteUrl(stream, state) {
    stream.eatSpace();
    stream.match(/^[^\s]+/, true);
    state.f = state.inline = inlineNormal;
    return linkhref;
  }

  function inlineRE(endChar) {
    if (!inlineRE[endChar]) {
      // match any not-escaped-non-endChar and any escaped char
      // then match endChar or eol
      inlineRE[endChar] = new RegExp('^(?:[^\\\\\\' + endChar + ']|\\\\.)*(?:\\' + endChar + '|$)');
    }
    return inlineRE[endChar];
  }

  function inlineElement(type, endChar, next) {
    next = next || inlineNormal;
    return function(stream, state) {
      stream.match(inlineRE(endChar));
      state.inline = state.f = next;
      return type;
    };
  }

  return {
    startState: function() {
      return {
        f: blockNormal,

        block: blockNormal,
        htmlState: htmlMode.startState(),
        indentation: 0,

        inline: inlineNormal,
        text: handleText,
        em: false,
        strong: false,
        header: false,
        quote: false
      };
    },

    copyState: function(s) {
      return {
        f: s.f,

        block: s.block,
        htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
        indentation: s.indentation,

        inline: s.inline,
        text: s.text,
        em: s.em,
        strong: s.strong,
        header: s.header,
        quote: s.quote
      };
    },

    token: function(stream, state) {
      if (stream.sol()) {
        // Reset EM state
        state.em = false;
        // Reset STRONG state
        state.strong = false;
        // Reset state.header
        state.header = false;
        // Reset state.quote
        state.quote = false;

        state.f = state.block;
        var previousIndentation = state.indentation
        ,   currentIndentation = 0;
        while (previousIndentation > 0) {
          if (stream.eat(' ')) {
            previousIndentation--;
            currentIndentation++;
          } else if (previousIndentation >= 4 && stream.eat('\t')) {
            previousIndentation -= 4;
            currentIndentation += 4;
          } else {
            break;
          }
        }
        state.indentation = currentIndentation;

        if (currentIndentation > 0) return null;
      }
      return state.f(stream, state);
    },

    getType: getType
  };

});

CodeMirror.defineMIME("text/x-markdown", "markdown");
<commit_msg>Changed some css properties for proper sizing of elements.<commit_after>var schematic_height = 153;
var schematic_width = 400;

$(function(){
  $(document).ready(function() {
	  $("a[rel*=leanModal]").leanModal();

    $("body").append('

'+
      '<input class="schematic" height="' + schematic_height + '" width="' + schematic_width + '" id="schematic_editor" name="schematic" type="hidden" value=""/>' +
      '<button type="button" id="circuit_save_btn">save</button>

');

    //This is the editor that pops up as a modal
    var editorCircuit = $("#schematic_editor").get(0);
    //This is the circuit that they last clicked. The one being edited.
    var editingCircuit = null;
    //Notice we use live, because new circuits can be inserted
    $(".schematic_open").live("click", function() {
      //Find the new editingCircuit. Transfer its contents to the editorCircuit
      editingCircuit = $(this).children("input.schematic").get(0);

      editingCircuit.schematic.update_value();
      var circuit_so_far = $(editingCircuit).val();

	    var n = editorCircuit.schematic.components.length;
	    for (var i = 0; i < n; i++)
		    editorCircuit.schematic.components[n - 1 - i].remove();

      editorCircuit.schematic.load_schematic(circuit_so_far, "");
    });

    $("#circuit_save_btn").click(function () {
      //Take the circuit from the editor and put it back into editingCircuit
      editorCircuit.schematic.update_value();
      var saving_circuit = $(editorCircuit).val();

	    var n = editingCircuit.schematic.components.length;
	    for (var i = 0; i < n; i++)
		    editingCircuit.schematic.components[n - 1 - i].remove();

      editingCircuit.schematic.load_schematic(saving_circuit, "");

      if (editingCircuit.codeMirrorLine) {
        editingCircuit.codeMirrorLine.replace(0, null, "circuit-schematic:" + saving_circuit);
      }

      $(".modal_close").first().click();
    });
  });
});

CodeMirror.defineMode("mitx_markdown", function(cmCfg, modeCfg) {

  var htmlMode = CodeMirror.getMode(cmCfg, { name: 'xml', htmlMode: true });

  var header   = 'header'
  ,   code     = 'comment'
  ,   quote    = 'quote'
  ,   list     = 'string'
  ,   hr       = 'hr'
  ,   linktext = 'link'
  ,   linkhref = 'string'
  ,   em       = 'em'
  ,   strong   = 'strong'
  ,   emstrong = 'emstrong';

  function escapeHtml(unsafe) {
      return unsafe
           .replace(/&/g, "&")
           .replace(/</g, "<")
           .replace(/>/g, ">")
           .replace(/"/g, """)
           .replace(/'/g, "'");
   }

   var circuit_formatter = {
     creator: function(text) {
       var circuit_value = text.match(circuitRE)[1]

       circuit_value = escapeHtml(circuit_value);

       var html = "
" +
                   "<input type='hidden' parts='' value='" + circuit_value + "' width='" + schematic_width + "' height='" + schematic_height + "' analyses='' class='schematic ctrls'/>
";

       return html;
     },
     size: function(text) {
       return {width: schematic_width, height:schematic_height};
     },
     callback: function(node, line) {
       update_schematics();
       var schmInput = node.firstChild.firstChild;
       schmInput.codeMirrorLine = line;
       if (schmInput.schematic) { //This is undefined if there was an error making the schematic
         schmInput.schematic.canvas.style.display = "block"; //Otherwise, it gets line height and is a weird size
         schmInput.schematic.always_draw_grid = true;
         schmInput.schematic.redraw_background();
       }
       $(node.firstChild).leanModal();
     }
   };

  var hrRE = /^[*-=_]/
  ,   ulRE = /^[*-+]\s+/
  ,   olRE = /^[0-9]+\.\s+/
  ,   headerRE = /^(?:\={3,}|-{3,})$/
  ,   codeRE = /^(k:\t|\s{4,})/
  ,   textRE = /^[^\[*_\\<>`]+/
  ,   circuitRE = /^circuit-schematic:(.*)$/;

  function switchInline(stream, state, f) {
    state.f = state.inline = f;
    return f(stream, state);
  }

  function switchBlock(stream, state, f) {
    state.f = state.block = f;
    return f(stream, state);
  }

  // Blocks

  function blockNormal(stream, state) {
    var match;
    if (stream.match(circuitRE)) {
      stream.skipToEnd();
      return circuit_formatter;
    } else if (stream.match(codeRE)) {
      stream.skipToEnd();
      return code;
    } else if (stream.eatSpace()) {
      return null;
    } else if (stream.peek() === '#' || stream.match(headerRE)) {
      state.header = true;
    } else if (stream.eat('>')) {
      state.indentation++;
      state.quote = true;
    } else if (stream.peek() === '[') {
      return switchInline(stream, state, footnoteLink);
    } else if (hrRE.test(stream.peek())) {
      var re = new RegExp('(?:\s*['+stream.peek()+']){3,}$');
      if (stream.match(re, true)) {
        return hr;
      }
    } else if (match = stream.match(ulRE, true) || stream.match(olRE, true)) {
      state.indentation += match[0].length;
      return list;
    }

    return switchInline(stream, state, state.inline);
  }

  function htmlBlock(stream, state) {
    var style = htmlMode.token(stream, state.htmlState);
    if (style === 'tag' && state.htmlState.type !== 'openTag' && !state.htmlState.context) {
      state.f = inlineNormal;
      state.block = blockNormal;
    }
    return style;
  }

  // Inline
  function getType(state) {

    // Set defaults
    returnValue = '';

    // Strong / Emphasis
    if(state.strong){
      if(state.em){
        returnValue += (returnValue ? ' ' : '') + emstrong;
      } else {
        returnValue += (returnValue ? ' ' : '') + strong;
      }
    } else {
      if(state.em){
        returnValue += (returnValue ? ' ' : '') + em;
      }
    }

    // Header
    if(state.header){
      returnValue += (returnValue ? ' ' : '') + header;
    }

    // Quotes
    if(state.quote){
      returnValue += (returnValue ? ' ' : '') + quote;
    }

    // Check valud and return
    if(!returnValue){
      returnValue = null;
    }
    return returnValue;

  }

  function handleText(stream, state) {
    if (stream.match(textRE, true)) {
      return getType(state);
    }
    return undefined;
  }

  function inlineNormal(stream, state) {
    var style = state.text(stream, state)
    if (typeof style !== 'undefined')
      return style;

    var ch = stream.next();

    if (ch === '\\') {
      stream.next();
      return getType(state);
    }
    if (ch === '`') {
      return switchInline(stream, state, inlineElement(code, '`'));
    }
    if (ch === '[') {
      return switchInline(stream, state, linkText);
    }
    if (ch === '<' && stream.match(/^\w/, false)) {
      stream.backUp(1);
      return switchBlock(stream, state, htmlBlock);
    }

    var t = getType(state);
    if (ch === '*' || ch === '_') {
      if (stream.eat(ch)) {
        return (state.strong = !state.strong) ? getType(state) : t;
      }
      return (state.em = !state.em) ? getType(state) : t;
    }

    return getType(state);
  }

  function linkText(stream, state) {
    while (!stream.eol()) {
      var ch = stream.next();
      if (ch === '\\') stream.next();
      if (ch === ']') {
        state.inline = state.f = linkHref;
        return linktext;
      }
    }
    return linktext;
  }

  function linkHref(stream, state) {
    stream.eatSpace();
    var ch = stream.next();
    if (ch === '(' || ch === '[') {
      return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']'));
    }
    return 'error';
  }

  function footnoteLink(stream, state) {
    if (stream.match(/^[^\]]*\]:/, true)) {
      state.f = footnoteUrl;
      return linktext;
    }
    return switchInline(stream, state, inlineNormal);
  }

  function footnoteUrl(stream, state) {
    stream.eatSpace();
    stream.match(/^[^\s]+/, true);
    state.f = state.inline = inlineNormal;
    return linkhref;
  }

  function inlineRE(endChar) {
    if (!inlineRE[endChar]) {
      // match any not-escaped-non-endChar and any escaped char
      // then match endChar or eol
      inlineRE[endChar] = new RegExp('^(?:[^\\\\\\' + endChar + ']|\\\\.)*(?:\\' + endChar + '|$)');
    }
    return inlineRE[endChar];
  }

  function inlineElement(type, endChar, next) {
    next = next || inlineNormal;
    return function(stream, state) {
      stream.match(inlineRE(endChar));
      state.inline = state.f = next;
      return type;
    };
  }

  return {
    startState: function() {
      return {
        f: blockNormal,

        block: blockNormal,
        htmlState: htmlMode.startState(),
        indentation: 0,

        inline: inlineNormal,
        text: handleText,
        em: false,
        strong: false,
        header: false,
        quote: false
      };
    },

    copyState: function(s) {
      return {
        f: s.f,

        block: s.block,
        htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
        indentation: s.indentation,

        inline: s.inline,
        text: s.text,
        em: s.em,
        strong: s.strong,
        header: s.header,
        quote: s.quote
      };
    },

    token: function(stream, state) {
      if (stream.sol()) {
        // Reset EM state
        state.em = false;
        // Reset STRONG state
        state.strong = false;
        // Reset state.header
        state.header = false;
        // Reset state.quote
        state.quote = false;

        state.f = state.block;
        var previousIndentation = state.indentation
        ,   currentIndentation = 0;
        while (previousIndentation > 0) {
          if (stream.eat(' ')) {
            previousIndentation--;
            currentIndentation++;
          } else if (previousIndentation >= 4 && stream.eat('\t')) {
            previousIndentation -= 4;
            currentIndentation += 4;
          } else {
            break;
          }
        }
        state.indentation = currentIndentation;

        if (currentIndentation > 0) return null;
      }
      return state.f(stream, state);
    },

    getType: getType
  };

});

CodeMirror.defineMIME("text/x-markdown", "markdown");
<|endoftext|>


<commit_before>import Canvas, {Image as DOMImage, ImageData} from 'canvas';
import {readFile, createWriteStream, writeFile} from 'fs';

const env = 'node';

export function isDifferentOrigin() {
    return false;
}

export function fetchBinary(path) {
    return new Promise(function (resolve, reject) {
        readFile(path, function (err, data) {
            if (err) reject(err);
            else resolve(data.buffer);
        });
    });
}

export {env, Canvas, ImageData, DOMImage, createWriteStream, writeFile};
<commit_msg>allow the library to be loaded without canvas<commit_after>let Canvas, DOMImage, ImageData;
try {
    const canvas = require('canvas');
    Canvas = canvas;
    DOMImage = canvas.Image;
    ImageData = canvas.ImageData;
} catch (e) {
    // eslint-disable-next-line no-console
    console.error('image-js could not load the canvas library. Some methods may not work.');
    Canvas = function () {
        throw new Error('Canvas requires the canvas library');
    };
    DOMImage = function () {
        throw new Error('DOMImage requires the canvas library');
    };
    ImageData = function () {
        throw new Error('ImageData requires the canvas library');
    };
}

import {readFile, createWriteStream, writeFile} from 'fs';

const env = 'node';

export function isDifferentOrigin() {
    return false;
}

export function fetchBinary(path) {
    return new Promise(function (resolve, reject) {
        readFile(path, function (err, data) {
            if (err) reject(err);
            else resolve(data.buffer);
        });
    });
}

export {env, Canvas, ImageData, DOMImage, createWriteStream, writeFile};
<|endoftext|>


<commit_before>import $ from 'jquery';
import { clearStyles } from '../util';

export default function () {
    let jews = {};
    jews.title = $('.top_title').text();
    jews.subtitle = $('.sub_title1').text();
    jews.content = (function () {
        let c = $('#article_body .art_txt')[0].cloneNode(true);
        $('#google_dfp_MC_250x250', c).remove();
        return clearStyles(c).innerHTML;
    })();
    {
        let $a = $('.news_title_author');
        let t = $('.lasttime', $a).text().replace(/\s+/g, ' ').replace('입력 :', '').split('수정 :');
        jews.timestamp = {
            created: new Date(t[0].replace(/\./g, '/')),
            lastModified: new Date(t[1].replace(/\./g, '/'))
        };
        jews.reporters = [{ name: $('.author', $a).text() }];
    }
    return jews;
}
<commit_msg>매일경제 일부 기사에서 본문이 안보이는 문제 수정<commit_after>import $ from 'jquery';
import { clearStyles } from '../util';

export default function () {
    let jews = {};
    jews.title = $('.top_title').text();
    jews.subtitle = $('.sub_title1').text();
    jews.content = (function () {
        let d = $('<div>');
        let c = $('#article_body .art_txt, #article_body img, #article_body figure');
        c.each(function(index, el) {
            $('#google_dfp_MC_250x250', el).remove();
            d.append(el);
        });
        $('img[alt="사진설명"]', d).remove();
        $('script', d).remove();
        return clearStyles(d[0]).innerHTML;
    })();
    {
        let $a = $('.news_title_author');
        let t = $('.lasttime', $a).text().replace(/\s+/g, ' ').replace('입력 :', '').split('수정 :');
        jews.timestamp = {
            created: new Date(t[0].replace(/\./g, '/')),
            lastModified: new Date(t[1].replace(/\./g, '/'))
        };
        jews.reporters = [{ name: $('.author', $a).text() }];
    }
    return jews;
}
<|endoftext|>