zhongrj
2025-11-25 b89962006164a462404b79a738bee8cbb6d7fe7e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import React from 'react';
import PropTypes from 'prop-types';
import './css/Dashboard.scss';
import ProjectList from './components/ProjectList';
import EditProjectDialog from './components/EditProjectDialog';
import Utils from './classes/Utils';
import {
  BrowserRouter as Router,
  Route
} from 'react-router-dom';
import $ from 'jquery';
import { _ } from './classes/gettext';
 
class Dashboard extends React.Component {
  static defaultProps = {
    permissions: []
  };
  static propTypes = {
    permissions: PropTypes.array.isRequired,
  };
 
  constructor(props){
    super(props);
 
    this.handleAddProject = this.handleAddProject.bind(this);
    this.addNewProject = this.addNewProject.bind(this);
  }
 
  handleAddProject(){
    this.projectDialog.show();
  }
 
  addNewProject(project){
    if (!project.name) return (new $.Deferred()).reject(_("Name field is required"));
 
    return $.ajax({
          url: `/api/projects/`,
          type: 'POST',
          contentType: 'application/json',
          data: JSON.stringify({
            name: project.name,
            description: project.descr,
            tags: project.tags
          })
      }).done(() => {
        this.projectList.refresh();
      });
    }
    
  render() {
    const projectList = ({ location, history }) => {
      let q = Utils.queryParams(location);
      if (q.page === undefined) q.page = 1;
      else q.page = parseInt(q.page);
 
      return <ProjectList
                source={`/api/projects/${Utils.toSearchQuery(q)}`}
                ref={(domNode) => { this.projectList = domNode; }} 
                currentPage={q.page}
                currentSearch={q.search}
                history={history}
                />;
    };
 
 
    return (
      <Router basename="/dashboard">
        <div>
          {this.props.permissions.indexOf("add_project") !== -1 ? 
          <div className="text-right add-button">
             <button type="button" 
                    className="btn btn-primary btn-sm"
                    onClick={this.handleAddProject}>
              <i className="glyphicon glyphicon-plus"></i>
              {_("Add Project")}
            </button>
          </div> : ""}
 
          <EditProjectDialog 
            saveAction={this.addNewProject}
            ref={(domNode) => { this.projectDialog = domNode; }}
            />
          <Route path="/" component={projectList} />
        </div>
      </Router>
    );
  }
}
 
$(function(){
    $("[data-dashboard]").each(function(){
        let props = $(this).data();
        delete(props.dashboard);
        window.ReactDOM.render(<Dashboard {...props}/>, $(this).get(0));
    });
 
    // Warn users if there's any sort of work in progress before
    // they press the back button on the browser
    // Yes it's a hack. No we're not going to track state in React just
    // for this.
    window.onbeforeunload = function() {
        let found = false; 
        $(".progress-bar:visible").each(function(){ 
            try{
                let value = parseFloat($(this).text());
                if (!isNaN(value) && value > 0 && value < 100) found = true;
            }catch(e){
                // Do nothing
            }
        });
        return found ? _("Your changes will be lost. Are you sure you want to leave?") : undefined; 
    };
});
 
export default Dashboard;