Example #1
0
  it('gets flux from either props or context', () => {
    const flux = new Flux();
    let contextComponent, propsComponent;

    const ContextComponent = addContext(
      ComponentWithFluxMixin,
      { flux },
      { flux: React.PropTypes.instanceOf(Flummox) }
    );

    const tree = TestUtils.renderIntoDocument(
      <ContextComponent />
    );

    contextComponent = TestUtils.findRenderedComponentWithType(
      tree, ComponentWithFluxMixin
    );

    propsComponent = TestUtils.renderIntoDocument(
      <ComponentWithFluxMixin flux={flux} />
    );

    expect(contextComponent.flux).to.be.an.instanceof(Flummox);
    expect(propsComponent.flux).to.be.an.instanceof(Flummox);
  });
Example #2
0
define(function (require) {

  var React = require('react/addons'),
    Moment = require('moment');

  return React.createClass({
    displayName: "Time",

    propTypes: {
      date: React.PropTypes.instanceOf(Date),
      showAbsolute: React.PropTypes.bool,
      showRelative: React.PropTypes.bool
    },

    getDefaultProps: function () {
      return {
        showAbsolute: true,
        showRelative: true
      };
    },

    render: function () {
      var title = Moment(this.props.date).format(),
        dateTime = Moment(this.props.date).utc().format(),
        text = "",
        moment = Moment(this.props.date),
        absoluteText = moment.format("MMM D, YYYY"),
        relativeText = moment.fromNow();

      if (this.props.showAbsolute) {
        text += absoluteText;
        if (this.props.showRelative)
          text += " (" + relativeText + ")";
      } else if (this.props.showRelative) {
        text += relativeText;
      }

      return (
        <time title={title} dateTime={dateTime}>
          {text}
        </time>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    TagMultiSelect = require('components/common/tags/TagMultiSelect.react');

  var ENTER_KEY = 13;

  return React.createClass({
    displayName: "ActualEditTagsView",

    propTypes: {
      activeTags: React.PropTypes.instanceOf(Backbone.Collection).isRequired,
      tags: React.PropTypes.instanceOf(Backbone.Collection).isRequired,
      onTagAdded: React.PropTypes.func.isRequired,
      onTagRemoved: React.PropTypes.func.isRequired,
      onCreateNewTag: React.PropTypes.func.isRequired
    },

    getInitialState: function () {
      return {
        query: ""
      }
    },

    onEnterKeyPressed: function (e) {
      e.preventDefault();
      var text = e.target.value;
      if (e.which === ENTER_KEY && text.trim()) {
        this.props.onCreateNewTag(text);
      }
    },

    onCreateNewEmptyTag: function (e) {
      e.preventDefault();
      this.props.onCreateNewTag("");
    },

    onQueryChange: function (query) {
      this.setState({query: query});
    },

    render: function () {
      var query = this.state.query,
        tags;

      if (query) {
        tags = this.props.tags.filter(function (tag) {
          return tag.get('name').toLowerCase().indexOf(query.toLowerCase()) >= 0;
        });
        tags = new Backbone.Collection(tags);
      }

      return (
        <div className="resource-tags">
          <a className="btn btn-primary new-tag" href="#" onClick={this.onCreateNewEmptyTag}>+ New tag</a>
          <TagMultiSelect
            models={tags}
            activeModels={this.props.activeTags}
            onModelAdded={this.props.onTagAdded}
            onModelRemoved={this.props.onTagRemoved}
            onCreateNewTag={this.props.onCreateNewTag}
            onEnterKeyPressed={this.onEnterKeyPressed}
            onQueryChange={this.onQueryChange}
            placeholderText="Search by tag name..."
            />
        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    PreviewPanel = require('./PreviewPanel.react'),
    ButtonBar = require('./ButtonBar.react'),
    ExternalLinkList = require('./link/ExternalLinkList.react'),
    ImageList = require('./image/ImageList.react'),
    InstanceList = require('./instance/InstanceList.react'),
    VolumeList = require('./volume/VolumeList.react'),
    modals = require('modals'),
    stores = require('stores'),
    actions = require('actions'),
    ExternalLink = require('models/ExternalLink');
    Image = require('models/Image'),
    Instance = require('models/Instance'),
    Volume = require('models/Volume');

  return React.createClass({
    displayName: "ProjectDetails",

    propTypes: {
      project: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    getInitialState: function () {
      return {
        previewedResource: null,
        selectedResources: new Backbone.Collection()
      }
    },

    onResourceSelected: function (resource) {
      var selectedResources = this.state.selectedResources;

      // Add the resource to the list of selected resources
      selectedResources.push(resource);

      this.setState({
        previewedResource: resource,
        selectedResources,
      });
    },

    deselectAllResources: function() {
        var selectedResources = this.state.selectedResources;
        selectedResources.reset();
        this.setState({ selectedResources });
    },

    onResourceDeselected: function (resource) {
      var selectedResources = this.state.selectedResources,
          previewedResource = this.state.previewedResource;

      // Remove the resources from the list of selected resources
      selectedResources.remove(resource);

      // Replace preview, with another
      if (previewedResource == resource) {
        previewedResource = selectedResources.last();
      }

      this.setState({
        previewedResource,
        selectedResources,
      });
    },

    onPreviewResource: function () {
        this.deselectAllResources();
    },

    onMoveSelectedResources: function () {
        var attachedResources = stores.VolumeStore.getAttachedResources(),
            anyAttached;

        anyAttached = this.state.selectedResources.some(function(selected) {
            return attachedResources.includes(selected.get('uuid'));
        });

        if (anyAttached){
            modals.ProjectModals.cantMoveAttached();
        } else {
            // On submit of move resources, reset (remove all) from selected collection
            modals.ProjectModals.moveResources(
                this.state.selectedResources,
                this.props.project,
                this.deselectAllResources
            );
        }
    },
    onDeleteSelectedResources: function () {
      actions.ProjectActions.deleteResources(
        this.state.selectedResources,
        this.props.project
      );
    },

    onReportSelectedResources: function () {
      actions.ProjectActions.reportResources(
        this.props.project,
        this.state.selectedResources
      );
    },

    onRemoveSelectedResources: function () {
      modals.ProjectModals.removeResources(
        this.state.selectedResources,
        this.props.project
      );
    },

    render: function () {
      var project = this.props.project,
        projectExternalLinks = stores.ProjectExternalLinkStore.getExternalLinksFor(project),
        projectInstances = stores.ProjectInstanceStore.getInstancesFor(project),
        projectVolumes = stores.ProjectVolumeStore.getVolumesFor(project),
        projectImages = stores.ProjectImageStore.getImagesFor(project),
        previewedResource = this.state.previewedResource,
        selectedResources = this.state.selectedResources,
        selectedResource = this.state.selectedResource,
        isButtonBarVisible;

      if (!projectInstances || !projectImages || !projectExternalLinks || !projectVolumes)
          return <div className="loading"></div>;

      // Only show the action button bar if the user has selected resources
      isButtonBarVisible = this.state.selectedResources.length > 0;

      return (
        <div className="project-content clearfix">
          <ButtonBar
            isVisible={isButtonBarVisible}
            onMoveSelectedResources={this.onMoveSelectedResources}
            onDeleteSelectedResources={this.onDeleteSelectedResources}
            onReportSelectedResources={this.onReportSelectedResources}
            onRemoveSelectedResources={this.onRemoveSelectedResources}
            previewedResource={previewedResource}
            multipleSelected={selectedResources && selectedResources.length > 1}
            onUnselect={this.onResourceDeselected}
            project={project}
            />

          <div className="resource-list clearfix">
            <div className="scrollable-content" style={{borderTop: "solid 1px #E1E1E1"}}>
              <InstanceList
                instances={projectInstances}
                onResourceSelected={this.onResourceSelected}
                onResourceDeselected={this.onResourceDeselected}
                onPreviewResource={this.onPreviewResource}
                previewedResource={previewedResource}
                selectedResources={selectedResources}
                />
              <VolumeList
                volumes={projectVolumes}
                onResourceSelected={this.onResourceSelected}
                onResourceDeselected={this.onResourceDeselected}
                onPreviewResource={this.onPreviewResource}
                previewedResource={previewedResource}
                selectedResources={selectedResources}
                />
              <ImageList
                images={projectImages}
                onResourceSelected={this.onResourceSelected}
                onResourceDeselected={this.onResourceDeselected}
                onPreviewResource={this.onPreviewResource}
                previewedResource={previewedResource}
                selectedResources={selectedResources}
                />
              <ExternalLinkList
                external_links={projectExternalLinks}
                onResourceSelected={this.onResourceSelected}
                onResourceDeselected={this.onResourceDeselected}
                onPreviewResource={this.onPreviewResource}
                previewedResource={previewedResource}
                selectedResources={selectedResources}
                />
            </div>
            <PreviewPanel resource={previewedResource}/>
          </div>
        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
      Backbone = require('backbone'),
      ChosenDropdownMembership = require('./ChosenDropdownMembership.react'),
      ChosenSelectedMembership = require('./ChosenSelectedMembership.react'),
      ChosenMixin = require('components/mixins/ChosenMixinExternal.react');

  return React.createClass({
    displayName: "MembershipMultiSelect",

    mixins: [ChosenMixin],

    propTypes: {
      memberships: React.PropTypes.instanceOf(Backbone.Collection),
      activeModels: React.PropTypes.instanceOf(Backbone.Collection).isRequired,
      onQueryChange: React.PropTypes.func.isRequired,
      onModelAdded: React.PropTypes.func.isRequired,
      onModelRemoved: React.PropTypes.func.isRequired
    },

    getNoResultsPhrase: function(query){
      return 'No memberships found matching "' + query + '". Press enter to create a new membership.';
    },

    getNoDataPhrase: function(){
      return "No memberships exist";
    },

    getAllResultsAddedPhrase: function(){
      return "All memberships have been added";
    },

    getAllAddedMatchingQueryPhrase: function(query){
      return 'All memberships matching "' + query + '" have been added'
    },

    renderModel: function(membership){
      return (
        <ChosenDropdownMembership
          key={membership.id}
          membership={membership}
          propertyName={'name'}
          onMembershipSelected={this.onModelAdded}
        />
      )
    },

    renderSelectedModel: function(membership){
      return (
        <ChosenSelectedMembership
          key={membership.id}
          membership={membership}
          propertyName={'name'}
          onRemoveMembership={this.props.onModelRemoved}
        />
      )
    },
    render: function() {
      return this.renderChosenSearchSelect();
    }


  })

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    Provider = require('../components/Provider.react'),
    stores = require('stores');

  return React.createClass({
    displayName: "ImageWizard-ProviderStep",

    propTypes: {
      instance: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    getInitialState: function () {
      var instance = this.props.instance;
      return {
        providerId: this.props.providerId || instance.get('provider').id,
        minCPU: "0",
        minMem: "0"
      }
    },

    isSubmittable: function () {
      var hasProviderId = !!this.state.providerId;
      return hasProviderId;
    },

    onPrevious: function () {
      this.props.onPrevious({
        providerId: this.state.providerId
      });
    },

    onNext: function () {
      this.props.onNext({
        minCPU: this.state.minCPU,
        minMem: this.state.minMem,
        providerId: this.state.providerId
      });
    },

    onProviderChange: function (newProviderId) {
      this.setState({
        providerId: newProviderId
      });
    },

    handleCPUChange: function(e){
      this.setState({minCPU: e.target.value});
    },

    handleMemChange: function(e){
      this.setState({minMem: e.target.value});
    },

    renderProvider: function (instance) {
      return (
        <div>
          <Provider
            providerId={this.state.providerId}
            onChange={this.onProviderChange}/>
        </div>
      );
    },

    renderRequirementsStep: function(){
      return (
        <div id="min-requirements" className="min-requirements collapse">
          <div className="min-cpu clearfix">
            # of CPUs: {this.state.minCPU}
            <input type = "range" className = "slider"
              value = {this.state.minCPU}
              min = "0"
              max = "16"
              step = "1"
              onChange = {this.handleCPUChange} />
            <span className="pull-left">0</span> 
            <span className="pull-right">16</span>
          </div>

          <div className="min-mem">
            Memory: {this.state.minMem} GB
            <input type = "range" className = "slider"
              value = {this.state.minMem}
              min = "0"
              max = "16"
              step = "2"
              onChange = {this.handleMemChange} />
            <span className="pull-left">0</span> 
            <span className="pull-right">16</span>
          </div>
        </div>
      );
    },

    render: function () {
      var instance = this.props.instance;

      return (
        <div>
          <div className="modal-body">
            {this.renderProvider(instance)}
            <a role="button" data-toggle="collapse" href="#min-requirements" aria-expanded="true">
              Minimum Requirements (optional)
            </a>
            {this.renderRequirementsStep()}
          </div>
          <div className="modal-footer">
            <button type="button" className="btn btn-default cancel-button pull-left" onClick={this.onPrevious}>
              <span className="glyphicon glyphicon-chevron-left"></span>
              Back
            </button>
            <button type="button" className="btn btn-primary cancel-button" onClick={this.onNext}
                    disabled={!this.isSubmittable()}>
              Next
            </button>
          </div>
        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    Glyphicon = require('components/common/Glyphicon.react'),
    modals = require('modals'),
    actions = require('actions');

  return React.createClass({
    displayName: "ExternalLinkActions",

    propTypes: {
      link: React.PropTypes.instanceOf(Backbone.Model).isRequired,
      project: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    onDelete: function () {
      var project = this.props.project,
        external_link = this.props.link;

      modals.ExternalLinkModals.destroy({
        project,
        external_link
      });
    },

    handleReport: function () {
      modals.ExternalLinkModals.report({link: this.props.link});
    },

    render: function () {
      var link = this.props.link;
      var linksArray = [
        {label: 'Actions', icon: null},
        {label: 'Go To Link', icon: 'globe', target:"_blank", href: link.get('link'), onClick: this.handleReport}
      ];
      //DEVNOTE: The 'links' referenced in the comments below are related to the general component of 'LinkActions' and not 'ExternalLink' models.
      // Add in the conditional links based on current machine state
      linksArray = linksArray.concat([
        {label: 'Delete', icon: 'remove', onClick: this.onDelete, isDangerLink: true}
      ]);

      var links = linksArray.map(function (ext_link) {
        // Links without icons are generally section headings
        if (!ext_link.icon) return (
          <li key={ext_link.label} className="section-label">{ext_link.label}</li>
        );

        var className = "section-link";
        if (ext_link.isDangerLink) className += " danger";

        // Some actions have hrefs, because they redirect to actual pages (and are
        // not actions in need of confirmation).  While we *could* call
        // Backbone.history.navigate from an onClick callback, we want all url
        // changes to pass through our Backbone catcher in main.js that we can use
        // to log requests to Google Analytics
        if (ext_link.href) return (
          <li key={ext_link.label} className={className + " link"}>
            <a href={ext_link.href} target={ext_link.target ? ext_link.target : "_self"}>
            <span>
              <Glyphicon name={ext_link.icon}/>{ext_link.label}
            </span>
            </a>
          </li>
        );

        // Links with onClick callbacks will typically trigger modals requiring
        // confirmation before continuing
        return (
          <li key={ext_link.label} className={className} onClick={ext_link.onClick}>
            <span>
              <Glyphicon name={ext_link.icon}/>{ext_link.label}
            </span>
          </li>
        );
      });

      return (
        <div className="resource-actions">
          <ul>
            {links}
          </ul>
        </div>

      );
    }

  });

});
Example #8
0
    getShortUID = function () {
        return ("0000" + (Math.random()*Math.pow(36,4) << 0).toString(36)).slice(-4)
    },
    getNewItem = function () {
        return {
            key: getShortUID()
        }
    };


var Item = React.createClass({

    mixins: [ImmutableOptimizations(['model'])],

    propTypes: {
        model: React.PropTypes.instanceOf(Cursor).isRequired
    },

    addNew: function(event) {
        event.preventDefault();
        var key = this.refs.keyInput.getDOMNode().value.trim(),
            value = this.refs.valueInput.getDOMNode().value.trim();

        if (!key || !value) {
            return;
        }

        var newPair = {};
        newPair[key] = value;
        this.props.model.merge(newPair);
    },
Example #9
0
            </li>
            {statusPageEl}
            <li>
              <a id="logout_link" href="/logout?force=true&airport_ui=false">Sign out</a>
            </li>
          </ul>
        </li>
      );
    }
  });

let Header = React.createClass({
    displayName: "Header",

    propTypes: {
      profile: React.PropTypes.instanceOf(Backbone.Model),
      currentRoute: React.PropTypes.array.isRequired
    },

    // We need the screen size for handling the opening and closing of our menu on small screens
    //See navLinks below for implementation.

    getInitialState: function() {
        return {windowWidth: window.innerWidth};
    },

    handleResize: function(e) {
        this.setState({windowWidth: window.innerWidth});
    },

    componentDidMount: function() {
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    Time = require('components/common/Time.react'),
    EditableInputField = require('components/common/EditableInputField.react'),
    actions = require('actions'),
    stores = require('stores'),
    CryptoJS = require('crypto-js'),
    Gravatar = require('components/common/Gravatar.react');

  return React.createClass({
    displayName: "VolumeInfoSection",

    propTypes: {
      volume: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    getInitialState: function () {
      var volume = this.props.volume;

      return {
        name: volume.get('name'),
        isEditing: false
      }
    },

    onEnterEditMode: function (e) {
      this.setState({isEditing: true});
    },

    onDoneEditing: function (text) {
      var volume = this.props.volume;

      this.setState({
        name: text,
        isEditing: false
      });
      actions.VolumeActions.update(volume, {name: text})
    },

    render: function () {
      var volume = this.props.volume,
        profile = stores.ProfileStore.get(),
        type = profile.get('icon_set'),
        instanceHash = CryptoJS.MD5((volume.id || volume.cid).toString()).toString(),
        iconSize = 113,
        nameContent;

      if (this.state.isEditing) {
        nameContent = (
          <EditableInputField text={this.state.name} onDoneEditing={this.onDoneEditing}/>
        );
      } else {
        nameContent = (
          <h4 onClick={this.onEnterEditMode}>
            {this.state.name}
            <i className="glyphicon glyphicon-pencil"></i>
          </h4>
        );
      }

      return (
        <div className="resource-info-section section clearfix">

          <div className="resource-image">
            <Gravatar hash={instanceHash} size={iconSize} type={type}/>
          </div>

          <div className="resource-info">
            <div className="resource-name editable">
              {nameContent}
            </div>
            <div className="resource-launch-date">
              Launched on <Time date={volume.get('start_date')}/>
            </div>
          </div>

        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    Router = require('react-router'),
    modals = require('modals'),
    Glyphicon = require('components/common/Glyphicon.react'),
    actions = require('actions'),
    stores = require('stores');

  return React.createClass({
    displayName: "SecondaryProjectNavigation",

    propTypes: {
      project: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    onDeleteProject: function (e) {
      e.preventDefault();

      var project = this.props.project,
        projectInstances = stores.ProjectInstanceStore.getInstancesFor(project),
        projectImages = stores.ProjectImageStore.getImagesFor(project),
        projectExternalLinks = stores.ProjectExternalLinkStore.getExternalLinksFor(project),
        projectVolumes = stores.ProjectVolumeStore.getVolumesFor(project);

      if (projectInstances.length > 0 || projectImages.length > 0  || projectExternalLinks.length > 0 || projectVolumes.length > 0) {
        modals.ProjectModals.explainProjectDeleteConditions();
      } else {
        modals.ProjectModals.destroy(project);
      }
    },

    renderRoute: function (name, linksTo, icon, params) {
      return (
        <li key={name}>
          <Router.Link to={linksTo} params={params}>
            <Glyphicon name={icon}/>
            <span>{name}</span>
          </Router.Link>
        </li>
      )
    },

    render: function () {
      var project = this.props.project;

      return (
        <div>
          <div className="secondary-nav">
            <div className="container">


              <ul className="secondary-nav-links">
                {this.renderRoute("Resources", "project-resources", "th", {projectId: project.id})}
                {this.renderRoute("Details", "project-details", "list-alt", {projectId: project.id})}
              </ul>

              <ul className="options-bar navbar-nav navbar-right">
                <li className="dropdown">
                  <a href="#" className="dropdown-toggle" data-toggle="dropdown">
                    <i className="glyphicon glyphicon-cog"/>
                    Options
                    <b className="caret"></b>
                  </a>
                  <ul className="dropdown-menu">
                    <li>
                      <a href="#" className="danger" onClick={this.onDeleteProject}>
                        <i className="glyphicon glyphicon-trash"/>
                        Delete Project
                      </a>
                    </li>
                  </ul>
                </li>
              </ul>

            </div>
          </div>
              <div className="project-name container">
                <h1>
                  {project.get('name')}
                </h1>
              </div>
        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    Glyphicon = require('components/common/Glyphicon.react'),
    modals = require('modals'),
    actions = require('actions');

  return React.createClass({
    displayName: "VolumeActionsAndLinks",

    propTypes: {
      volume: React.PropTypes.instanceOf(Backbone.Model).isRequired,
      project: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    onAttach: function () {
      modals.InstanceVolumeModals.attach(this.props.volume, this.props.project);
    },

    onDetach: function () {
      modals.InstanceVolumeModals.detach(this.props.volume);
    },

    onDelete: function () {
      var project = this.props.project,
        volume = this.props.volume;

      modals.VolumeModals.destroy({
        volume: this.props.volume,
        project: this.props.project
      });
    },

    handleReport: function () {
      modals.VolumeModals.report({volume: this.props.volume});
    },

    render: function () {
      var volume = this.props.volume,
        status = volume.get('state').get('status');

      var linksArray = [
        {label: 'Actions', icon: null},
        {label: 'Report', icon: 'inbox', onClick: this.handleReport}
      ];

      // Add in the conditional links based on current machine state
      if (status === "available") {
        linksArray.push({label: 'Attach', icon: 'save', onClick: this.onAttach});
      } else if (status === "in-use") {
        linksArray.push({label: 'Detach', icon: 'open', onClick: this.onDetach});
      }

      linksArray = linksArray.concat([
        {label: 'Delete', icon: 'remove', onClick: this.onDelete, isDangerLink: true}
      ]);

      var links = linksArray.map(function (link) {
        // Links without icons are generally section headings
        if (!link.icon) return (
          <li key={link.label} className="section-label">{link.label}</li>
        );

        var className = "section-link";
        if (link.isDangerLink) className += " danger";
        // todo: This isn't implemented well at all.  We should be disabling these
        // buttons if there isn't a valid href for the link, or (perhaps) not even
        // showing the buttons at all...but I think it's better communication to
        // disable the buttons with a message explaining why on rollover.
        //
        if (link.openInNewWindow) {
          var style = {};
          if (!link.href) style.cursor = 'not-allowed';
          return (
            <li key={link.label} className={className + " link"} style={style}>
              <a href={link.href} target="_blank">
                <span>
                  <Glyphicon name={link.icon}/>{link.label}
                </span>
              </a>
            </li>
          );
        }

        // Some actions have hrefs, because they redirect to actual pages (and are
        // not actions in need of confirmation).  While we *could* call
        // Backbone.history.navigate from an onClick callback, we want all url
        // changes to pass through our Backbone catcher in main.js that we can use
        // to log requests to Google Analytics
        if (link.href) return (
          <li key={link.label} className={className + " link"}>
            <a href={link.href}>
            <span>
              <Glyphicon name={link.icon}/>{link.label}
            </span>
            </a>
          </li>
        );

        // Links with onClick callbacks will typically trigger modals requiring
        // confirmation before continuing
        return (
          <li key={link.label} className={className} onClick={link.onClick}>
            <span>
              <Glyphicon name={link.icon}/>{link.label}
            </span>
          </li>
        );
      });

      return (
        <div className="resource-actions">
          <ul>
            {links}
          </ul>
        </div>

      );
    }

  });

});
Example #13
0
var React = require('react/addons');
var HotKey = require('react-hotkey');

HotKey.activate('keydown');

var isTextInputElement = require('react/lib/isTextInputElement');

var MPDiscoController = require('../mpdisco_controller.js');

var tree = require('../mpdisco_model.js').tree;

var PlayerMixin = {
    mixins: [HotKey.Mixin('handleKeyboard'), tree.mixin],

    propTypes: {
        controller: React.PropTypes.instanceOf(MPDiscoController).isRequired
    },

    cursors: {
        song: ['currentsong'],
        status: ['status']
    },

    getInitialState: function() {
        return {
            animations: false,
            time: 0,
            indicatorAppear: false,
            indicatorState: null
        };
    },
Example #14
0
  }
};

configure.setDateLocalizer(localizer);

// configure.setAnimate((element, props, duration, ease, callback) => {
//   return jquery(element).animate(props, duration, callback)
// })

var DatePicker = React.createClass({
  displayName: 'DatePicker',

  propTypes: {
    onChange: React.PropTypes.func,
    culture: React.PropTypes.string,
    defaultValue: React.PropTypes.instanceOf(Date),
    max: React.PropTypes.instanceOf(Date),
    min: React.PropTypes.instanceOf(Date),
    twoDigitYearFormats: React.PropTypes.shape({
      en: React.PropTypes.string,
      nb: React.PropTypes.string
    }),
    twoDigitYearBreakpoint: React.PropTypes.number,
    native: React.PropTypes.bool,
    calendarButtonFocusedClass: React.PropTypes.string,
    errorClass: React.PropTypes.string,
    id: React.PropTypes.string.isRequired,
    empty: React.PropTypes.bool
  },

  getInitialState: function getInitialState() {
define(function (require) {

  var React = require('react/addons'),
      Backbone = require('backbone'),
      EditDescriptionView = require('components/images/detail/description/EditDescriptionView.react'),
      LicenseMultiSelect = require('./LicenseMultiSelectAndCreate.react');

  var ENTER_KEY = 13;

  return React.createClass({
    displayName: "EditLicenseView",

    propTypes: {
      image_version: React.PropTypes.instanceOf(Backbone.Model),
      activeLicenses: React.PropTypes.instanceOf(Backbone.Collection),
      licenses: React.PropTypes.instanceOf(Backbone.Collection),
      onLicenseAdded: React.PropTypes.func.isRequired,
      onLicenseRemoved: React.PropTypes.func.isRequired,
      onCreateNewLicense: React.PropTypes.func.isRequired,
      label: React.PropTypes.string.isRequired
    },

    getDefaultProps: function() {
      return {
        activeLicenses: new Backbone.Collection(),
        licenses: new Backbone.Collection()
      }
    },
    getInitialState: function(){
      return {
        query: "",
      }
    },
    onQueryChange: function(query){
      this.setState({query: query});
    },
    onCreateLicense: function(params) {
      this.props.onCreateNewLicense(params);
    },

    render: function () {
      var query = this.state.query,
          link,
          licenseView,
          licenses = this.props.licenses;

      if(query){
        licenses = this.props.licenses.filter(function(license){
          return license.get('title').toLowerCase().indexOf(query.toLowerCase()) >= 0;
        });
        licenses = new Backbone.Collection(licenses);
      }

        licenseView = (
          <LicenseMultiSelect
            models={licenses}
            activeModels={this.props.activeLicenses}
            onModelAdded={this.props.onLicenseAdded}
            onModelRemoved={this.props.onLicenseRemoved}
            onModelCreated={this.onCreateLicense}
            onQueryChange={this.onQueryChange}
            propertyName={"title"}
            showButtonText="Create New License"
            placeholderText="Search by License title..."
          />
        );

      return (
        <div className="resource-users">
          {
            //<span className='user-title'>{this.props.label}</span>
          }
          {licenseView}
        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    Time = require('components/common/Time.react'),
    EditableInputField = require('components/common/EditableInputField.react'),
    EditableTextAreaField = require('components/common/EditableTextAreaField.react'),
    actions = require('actions'),
    stores = require('stores'),
    CryptoJS = require('crypto-js'),
    Gravatar = require('components/common/Gravatar.react');

  return React.createClass({
    displayName: "ExternalLinkInfoSection",

    propTypes: {
      link: React.PropTypes.instanceOf(Backbone.Model).isRequired
    },

    getInitialState: function () {
      var link = this.props.link;

      return {
        name: link.get('title'),
        description: link.get('description'),
        link: link.get('link'), // The URL -not- the object.
        isEditingName: false,
        isEditingDescription: false,
        isEditingLink: false
      }
    },

    onEnterEditName: function (e) {
      this.setState({isEditingName: true});
    },

    onEnterEditDescription: function (e) {
      this.setState({isEditingDescription: true});
    },

    onEnterEditLink: function (e) {
      this.setState({isEditingLink: true});
    },

    onDoneEditingDescription: function (text) {
      var link = this.props.link;

      this.setState({
        description: text,
        isEditingDescription: false
      });
      actions.ExternalLinkActions.update(link, {description: text})
    },

    onDoneEditingLink: function (text) {
      var link = this.props.link;

      this.setState({
        link: text,
        isEditingLink: false
      });
      actions.ExternalLinkActions.update(link, {link: text})
    },

    onDoneEditingName: function (text) {
      var link = this.props.link;

      this.setState({
        name: text,
        isEditingName: false
      });
      actions.ExternalLinkActions.update(link, {title: text})
    },

    render: function () {
      var link = this.props.link,
        profile = stores.ProfileStore.get(),
        type = profile.get('icon_set'),
        instanceHash = CryptoJS.MD5((link.id || link.cid).toString()).toString(),
        iconSize = 113,
        nameContent, descriptionContent, linkContent;

      if (this.state.isEditingDescription) {
        descriptionContent = (
          <EditableTextAreaField text={this.state.description} onDoneEditing={this.onDoneEditingDescription}/>
        );
      } else {
        descriptionContent = (
          <h4 onClick={this.onEnterEditDescription}>
            {this.state.description}
            <i className="glyphicon glyphicon-pencil"></i>
          </h4>
        );
      }

      if (this.state.isEditingLink) {
        linkContent = (
          <EditableInputField text={this.state.link} onDoneEditing={this.onDoneEditingLink}/>
        );
      } else {
        linkContent = (
          <h4 onClick={this.onEnterEditLink}>
            {this.state.link}
            <i className="glyphicon glyphicon-pencil"></i>
          </h4>
        );
      }

      if (this.state.isEditingName) {
        nameContent = (
          <EditableInputField text={this.state.name} onDoneEditing={this.onDoneEditingName}/>
        );
      } else {
        nameContent = (
          <h4 onClick={this.onEnterEditName}>
            {this.state.name}
            <i className="glyphicon glyphicon-pencil"></i>
          </h4>
        );
      }

      return (
        <div className="resource-info-section section clearfix">

          <div className="resource-info">
            <h2>Name</h2>
            <div className="resource-name editable">
              {nameContent}
            </div>
            <h2>Description</h2>
            <div className="resource-name editable">
              {descriptionContent}
            </div>
            <h2>Link</h2>
            <div className="resource-name editable">
              {linkContent}
            </div>
          </div>

        </div>
      );
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    ExternalLinkRow = require('./ExternalLinkRow.react'),
    SelectableTable = require('../SelectableTable.react');

  return React.createClass({
    displayName: "ExternalLinkTable",

    propTypes: {
      external_links: React.PropTypes.instanceOf(Backbone.Collection).isRequired,
      onResourceSelected: React.PropTypes.func.isRequired,
      onResourceDeselected: React.PropTypes.func.isRequired,
      onPreviewResource: React.PropTypes.func.isRequired,
      previewedResource: React.PropTypes.instanceOf(Backbone.Model),
      selectedResources: React.PropTypes.instanceOf(Backbone.Collection)
    },

    getInitialState: function () {
      return {
        isChecked: false
      }
    },

    toggleCheckbox: function (e) {
      this.setState({isChecked: !this.state.isChecked});
    },

    getExternalLinkRows: function (external_links) {
      var previewedResource = this.props.previewedResource,
        selectedResources = this.props.selectedResources;

      return external_links.map(function (external_link) {
        var isPreviewed = (previewedResource === external_link),
          isChecked = selectedResources.get(external_link) ? true : false;

        return (
          <ExternalLinkRow
            key={external_link.id || external_link.cid}
            external_link={external_link}
            onResourceSelected={this.props.onResourceSelected}
            onResourceDeselected={this.props.onResourceDeselected}
            onPreviewResource={this.props.onPreviewResource}
            isPreviewed={isPreviewed}
            isChecked={isChecked}
            />
        );
      }.bind(this));
    },

    render: function () {
      var external_links = this.props.external_links,
        linkRows = this.getExternalLinkRows(external_links);

      return (
        <SelectableTable
          resources={external_links}
          selectedResources={this.props.selectedResources}
          resourceRows={linkRows}
          onResourceSelected={this.props.onResourceSelected}
          onResourceDeselected={this.props.onResourceDeselected}
          >
          <th className="sm-header">Name</th>
        </SelectableTable>
      )
    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    _ = require('underscore'),
    $ = require('jquery'),
    Backbone = require('backbone');

  var ENTER_KEY = 13;

  return {
    getInitialState: function(){
      return {
        showOptions: false,
        query: ""
      }
    },

    propTypes: {
      placeholderText: React.PropTypes.string,
      models: React.PropTypes.instanceOf(Backbone.Collection),
      activeModels: React.PropTypes.instanceOf(Backbone.Collection),
      requiredModels: React.PropTypes.array,
      onModelAdded: React.PropTypes.func.isRequired,
      onModelRemoved: React.PropTypes.func.isRequired,
      onEnterKeyPressed: React.PropTypes.func,
      width: React.PropTypes.string
    },

    getDefaultProps: function(){
      return {
        models: new Backbone.Collection(),
        activeModels: new Backbone.Collection(),
        requiredModels: [],
        placeholderText: "Search..."
      }
    },

    closeDropdown: function() {
      this.setState({showOptions: false});
    },

    onEnterOptions: function (e) {
      this.setState({showOptions: true});

      $(document).bind("mouseup", this._checkIfApplies);
    },

    _checkIfApplies: function (e) {
      if (this.isOutsideClick(e)) {
        this.onLeaveOptions();
        $(document).unbind("mouseup", this._checkIfApplies);
      }
    },

    onLeaveOptions: function (e) {
      this.closeDropdown();
    },

    isOutsideClick: function(e){
      if(!this.isMounted()) {
        return false;
      }

      var node = this.getDOMNode();
      var $node = $(node);
      var container = $node;//.find('.chosen-container');

      if (!container.is(e.target) // if the target of the click isn't the container...
        && container.has(e.target).length === 0) // ... nor a descendant of the container
      {
        return true;
      }
      return false;
    },

    onEnter: function(e){
      if(e.which !== ENTER_KEY) return;
      var value = e.target.value;
      if(this.onEnterKeyPressed) {
        this.onEnterKeyPressed(value);
      } else if(this.props.onEnterKeyPressed) {
        this.props.onEnterKeyPressed(e);
      } else {
        //Enter does nothing if neither value is defined..
        return;
      }
      //After callback, assume action Completed clear search.
      this.clearSearchField();
    },
    getFilteredResults: function(models, activeModels) {
      var filteredResults = models.filter(function(model){
        return activeModels.filter(function(activeModel){
            return model.id === activeModel.id;
          }).length === 0;
      });
      return filteredResults;
    },

    filterSearchResults: function () {
      var node = this.getDOMNode();
      var $node = $(node);
      var search_field = $node.find('input');
      var query = search_field.val();
      this.setState({query: query});
      this.props.onQueryChange(query);
    },

    onModelAdded: function (model) {
      this.props.onModelAdded(model);
      this.clearSearchField();
    },

    clearSearchField: function(){
      var query = "",
        input = this.refs.searchField.getDOMNode();
      input.value = query;
      input.focus();
      this.setState({query: query});
      this.props.onQueryChange(query);
    },

    //
    // Result render helpers
    //

    renderLoadingListItem: function (query) {
      return (
        <li className="no-results">Searching for "{query}"...</li>
      )
    },

    renderNoResultsForQueryListItem: function (query) {
      var phrase = 'No results found matching "' + query + '"';
      if (this.getNoResultsPhrase) phrase = this.getNoResultsPhrase(query);
      return <li className="no-results">{phrase}</li>;
    },

    renderAlreadyAddedAllUsersMatchingQueryListItem: function (query) {
      var phrase = 'All results matching "' + query + '" have been added';
      if (this.getAllAddedMatchingQueryPhrase) phrase = this.getAllAddedMatchingQueryPhrase(query);
      return <li className="no-results">{phrase}</li>;
    },

    renderNoDataListItem: function () {
      var phrase = 'No results exist';
      if (this.getNoDataPhrase) phrase = this.getNoDataPhrase();
      return <li className="no-results">{phrase}</li>;
    },

    renderAllAddedListItem: function () {
      var phrase = 'All results have been added';
      if (this.getAllResultsAddedPhrase) phrase = this.getAllResultsAddedPhrase();
      return <li className="no-results">{phrase}</li>;
    },
    _mergeModels: function(required_models, active_models) {
      //Required models is a list, active models is a collection..
      //ChosenMixinExternal will expect a collection.
      if(!required_models || required_models.length == 0) {
        if (this.props.activeModels instanceof Array)
            return new Backbone.Collection(activeModels);
        else
            return active_models;
      }

      var activeModels = _.union(
            this.props.requiredModels,
            (this.props.activeModels instanceof Array) ? this.props.activeModels : this.props.activeModels.toJSON()
        ),
      activeCollection = new Backbone.Collection(activeModels);
      return activeCollection;
    },
    //
    // Render
    //
    renderChosenSearchSelect: function () {
      var models = this.props.models,
          query = this.state.query,
          activeCollection = this._mergeModels(
              this.props.requiredModels,
              this.props.activeModels),
          selectedModels = activeCollection.map(this.renderSelectedModel),
          placeholderText = this.props.placeholderText,
          filteredModels,
          classes = React.addons.classSet({
            'chosen-container-external': true,
            'chosen-container-external-multi': true,
            'chosen-with-drop': this.state.showOptions && query,
            'chosen-container-external-active': this.state.showOptions
          }),
          results;

      if (!models) {
        results = this.renderLoadingListItem(query);
      } else if (query && models.length < 1) {
        results = this.renderNoResultsForQueryListItem(query);
      } else if (selectedModels.length === 0 && models.length < 1) {
        results = this.renderNoDataListItem();
      } else if (selectedModels.length > 0 && models.length < 1) {
        results = this.renderAllAddedListItem();
      } else {
        // filter out results that have already been added
        filteredModels = models.filter(function(model){
          return activeCollection.filter(function(activeModel){
            return model.id === activeModel.id;
          }).length === 0;
        });
        if (models.length > 0 && filteredModels.length === 0) {
          results = this.renderAlreadyAddedAllUsersMatchingQueryListItem(query);
        } else {
          results = filteredModels.map(this.renderModel);
        }
      }

      return (
        <div className={classes}>
          <ul className="chosen-choices clearfix" onFocus={this.onEnterOptions}>
            {selectedModels}
          </ul>
          <div className="form-group">
            <input
              type="text"
              ref="searchField"
              className="form-control"
              placeholder={placeholderText}
              autoComplete="off"
              onKeyDown={this.onEnter}
              onKeyUp={this.filterSearchResults}
              onFocus={this.onEnterOptions}
            />
            <div className="chosen-drop">
              <ul className="chosen-results">
                {results}
              </ul>
            </div>
          </div>
        </div>
      );
    }

  };

});
Example #19
0
/** @jsx React.DOM */
var _ = require('underscore'),
    d3 = require('d3'),
    React = require('react/addons'),
    idiogrammatik = require('idiogrammatik.js');


var PositionType = React.PropTypes.shape({
  start: React.PropTypes.oneOfType([
    React.PropTypes.number,
    React.PropTypes.instanceOf(null)
  ]),
  end: React.PropTypes.oneOfType([
    React.PropTypes.number,
    React.PropTypes.instanceOf(null)
  ]),
  chromosome: React.PropTypes.oneOfType([
    React.PropTypes.string,
    React.PropTypes.instanceOf(idiogrammatik.ALL_CHROMOSOMES)
  ])
}).isRequired;

var VCFTable = React.createClass({
  propTypes: {
    // Array of attribute names from the INFO field of the VCF's records
    attrs: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
    // Subset of attrs which are currently selected.
    selectedAttrs: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
    // Function which takes a chart attribute name and propagates the change up
    handleChartChange: React.PropTypes.func.isRequired,
    // List of chromosomes found in the VCF
define(function (require) {

  var React = require('react/addons'),
      Backbone = require('backbone'),
      $ = require('jquery'),
      Router = require('react-router'),
      //Router = require('router'),
      // plugin: required but not used directly
      bootstrap = require('bootstrap');

  return React.createClass({
    displayName: "Membership",

    propTypes: {
      membership: React.PropTypes.instanceOf(Backbone.Model).isRequired,
      renderLinks: React.PropTypes.bool
    },

    getDefaultProps: function(){
      return {
        renderLinks: true
      }
    },

    componentDidMount: function(){
      var el = this.getDOMNode(),
          $el = $(el),
          membership = this.props.membership;

      $el.tooltip({
        title: membership.get('name')
      });
    },

    onClick: function(){
      Router.getInstance().transitionTo("search", {}, {q: this.props.membership.get('name')});
    },

    render: function () {
      var membership = this.props.membership,
          membershipName = membership.get('name'),
          link;

      if(this.props.renderLinks){
        link = (
          <Router.Link to="search" query={{q: membershipName}}>
            {membershipName}
          </Router.Link>
        );
      }else{
        link = (
          <a href="javascript:void(0)">{membershipName}</a>
        )
      }

      return (
        <li className="membership">
          {link}
        </li>
      );

    }

  });

});
define(function (require) {

  var React = require('react/addons'),
    Backbone = require('backbone'),
    SelectableRow = require('../SelectableRow.react'),
    Name = require('../tableData/volume/Name.react'),
    Status = require('../tableData/volume/Status.react'),
    Size = require('../tableData/volume/Size.react'),
    Provider = require('../tableData/volume/Provider.react'),
    stores = require('stores'),
    CryptoJS = require('crypto-js'),
    Gravatar = require('components/common/Gravatar.react');

  return React.createClass({
    displayName: "VolumeRow",

    propTypes: {
      volume: React.PropTypes.instanceOf(Backbone.Model).isRequired,
      onResourceSelected: React.PropTypes.func.isRequired,
      onResourceDeselected: React.PropTypes.func.isRequired,
      onPreviewResource: React.PropTypes.func.isRequired,
      isPreviewed: React.PropTypes.bool,
      isChecked: React.PropTypes.bool
    },

    render: function () {
      var volume = this.props.volume,
        volumeHash = CryptoJS.MD5((volume.id || volume.cid).toString()).toString(),
        type = stores.ProfileStore.get().get('icon_set'),
        iconSize = 18;

      return (
        <SelectableRow
          isActive={this.props.isPreviewed}
          isSelected={this.props.isChecked}
          onResourceSelected={this.props.onResourceSelected}
          onResourceDeselected={this.props.onResourceDeselected}
          onPreviewResource={this.props.onPreviewResource}
          resource={volume}
          >
          <td className="image-preview sm-cell" data-label="Name">
            <Gravatar
              hash={volumeHash}
              size={iconSize}
              type={type}
              />
            <Name volume={volume}/>
          </td>
          <td className="sm-cell" data-label="Status">
            <Status volume={volume}/>
          </td>
          <td className="sm-cell" data-label="Size">
            <Size volume={volume}/>
          </td>
          <td className="sm-cell" data-label="Provider">
            <Provider volume={volume}/>
          </td>
        </SelectableRow>
      );
    }

  });

});