// Presents existing information about the project to the user. // // Various elements of the page *may* be editable if the user has access. This // will likely be defined by our Project data. // // This class should only be relevant when the Location is set to a particular // project. var AppActions = require('../actions/AppActions'); var Autosuggest = require('react-autosuggest'); var Location = require('../stores/Location'); var Projects = require('../stores/Projects'); var React = require('react'); var ReactBootstrap = require('react-bootstrap'); var Button = ReactBootstrap.Button; var FormControls = ReactBootstrap.FormControls; var Input = ReactBootstrap.Input; var ListGroup = ReactBootstrap.ListGroup; var ListGroupItem = ReactBootstrap.ListGroupItem; var Panel = ReactBootstrap.Panel; var TabbedArea = ReactBootstrap.TabbedArea; var TabPane = ReactBootstrap.TabPane; // Tab pane keys var DETAILS = 1; var MEMBERS = 2; var ProjectDetails = React.createClass({ getInitialState: function () { return { project: Location.getLocation().project }; }, componentDidMount: function() { Projects.addMemberAddedListener(this.memberAdded); Projects.addMemberAddFailedListener(this.memberAddFailed); }, componentWillUnmount: function() { Projects.removeMemberAddedListener(this.memberAdded); Projects.removeMemberAddFailedListener(this.memberAddFailed); }, render: function () { var details = renderDetails(this); var members = renderMembers(this); return ( <Panel> <TabbedArea defaultActiveKey={DETAILS}> <TabPane eventKey={DETAILS} tab='Details'> {details} </TabPane> <TabPane eventKey={MEMBERS} tab='Members'> {members} </TabPane> </TabbedArea> </Panel> ); }, addUser: function() { var user = this.refs.newuser.getValue(); AppActions.addMemberToProject(this.state.project, user); }, memberAdded: function(project, login) { this.setState({ project: project }); }, memberAddFailed: function(project, login) { alert('Could not add member ' + login); } }); //----------------------------------------------------------------------------- // Local (private) methods //----------------------------------------------------------------------------- function renderDetails(comp) { var location = 'No location defined'; var branch = comp.state.project.branches[0]; if (branch) { if (comp.state.project.branches[0].stream) { location = comp.state.project.branches[0].stream; } else { location = comp.state.project.branches[0].view.depot_path; } } return ( <div> <FormControls.Static label='Project Name' value={comp.state.project.name}/> <FormControls.Static label='Description' value={comp.state.project.description}/> <FormControls.Static label='Location' value={location}/> </div> ); } //function getSuggestions(comp, members) { // return function (input, callback) { // var regex = new RegExp('^' + input, 'i'); // var items = members.filter(function (m) { // return regex.test(m); // }); // setTimeout(function () { // callback(null, items); // }); // } //} // TODO this might eventually be it's own component function renderMembers(comp) { // TODO eventually we want a 'users' store that pulls actual names var members = [comp.state.project.owner].concat(comp.state.project.members); members.sort(function (a, b) { return a.localeCompare(b); }); var memberItems = members.map(function (m) { return ( <ListGroupItem key={"member-" + m}>{m}</ListGroupItem> ); }); return ( <div> <ListGroup> {memberItems} </ListGroup> <Input ref='newuser' type='text' label='Add User' placeholder='Enter login' /> <Button right onClick={comp.addUser}>Add user</Button> </div> ); } module.exports = ProjectDetails;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 15688 | Doug Scheirer |
Populate -o //guest/perforce_software/helix-web-services/... //guest/doug_scheirer/helix-web-services/.... |
||
//guest/perforce_software/helix-web-services/main/source/helix_web_components/project_management/components/ProjectDetails.jsx | |||||
#1 | 15622 | tjuricek |
Move source code to 'source/' subdirectory of branch. build/ will remain where it is. |
||
//guest/perforce_software/helix-web-services/main/helix_web_components/project_management/components/ProjectDetails.jsx | |||||
#3 | 14176 | tjuricek |
Add a basic 'add member' function to the project details page. There appears to be some kind of funky caching issue with the components. The project data does get updated, so this UI is not 100% bug proof. Also, there's no autocomplete yet. |
||
#2 | 14175 | tjuricek |
Very basic read-only project details page. We're not going to display complete user detail information for a while. |
||
#1 | 13974 | tjuricek |
Moving 'ui/static' to 'helix_web_components' project, and altering some notes. Also, removed obsolete top-level Rake tasks. The "Helix Web Components" project will likely get moved elsewhere in the future. |
||
//guest/perforce_software/helix-web-services/main/ui/static/project_management/components/ProjectDetails.jsx | |||||
#2 | 13971 | tjuricek |
Add the ability for the header to display a "subnav" element. This is likely not our final UI, we may need to customize an individual nav-item to function like a breadcrumb. But functionally, it's working, the behavior should be the same. |
||
#1 | 13962 | tjuricek |
Add 'location' store and integrate "Jest" for unit testing. The location will trigger different views of the main ProjectManagement component. The Jest framework allows us to create headless tests of the React component logic. It's a little tricky, and right now has a dependency on node 0.10. |