Split viewing and editing a project

[?]
Feb 21, 2013, 12:12 AM
JY7BXXOP3EZCDT5RSMVE4Y6IECXGYL4GEBJOZHR7H3Z35XZ3NIVQC

Dependencies

  • [2] 2VBQRQ2Q Fix some XML well-formedness problems
  • [3] PZL3SZM3 Give every page a consistent title
  • [4] Q4VDOA76 Replace last 5 builds on jobset page with last 5 evaluations. Moved hide/unhide and evaluate options to jobset topmenu.
  • [5] SGNXIOI4 Hydra/32: Add option to force evaluation of a certain jobset via web interface (for admins only)
  • [6] UWVMQIAC * Refactoring.
  • [7] CVWQXYKM use newer icons consistently
  • [8] 3PNG7NIB Remove trailing whitespace
  • [9] OEPUOUNB Using twitter bootstrap for more consistent looks for Hydra
  • [10] 7YBYT2LQ
  • [11] 6UESWI2Q Ensure that the first tab is selected
  • [12] FPK5LF53 * Put the project-related actions in a separate controller. Put the
  • [13] AKAXJDMW * Disable the statistics on the project, jobset and job pages for now
  • [14] W6DC6K4I * Happy Javascript hacking.
  • [15] 6VPKJTKN * hdyra: remove debug thing
  • [16] YTSIRIMK * Separate job status and all builds pages.
  • [17] FGQPXZIX hydra: make nr of build to keep configurable per jobset
  • [18] JARRBLZD Bootstrapify the Hydra forms (except the project and jobset edit pages)
  • [19] US27ZTX5 * HydraFrontend -> Hydra.
  • [20] HEZ2V5NU order jobset in project view
  • [21] ODNCGFQ5 * Improved the navigation bar: don't include all projects (since that
  • [22] 5QE3TIHP hydra: add status icon per jobset on project page
  • [23] S66BOMVU * Added authentication.
  • [24] 6LTPI6B2
  • [25] D5QIOJGP * Move everything up one directory.
  • [26] C6ENW2KX Add time to evaluation error tab. Fixes #21.
  • [27] PUIJ66FV add some stats to jobsets in project view
  • [28] 6KIJX24R Get rid of unnecessary [%- and -%] tags
  • [29] 2AUODJBT
  • [30] BHJ62LYE * Allow authorised users to create projects.
  • [31] ZI535LI6 * hydra: 'new' UI for project/jobset/job/build
  • [32] PC6UOHH7 add some stats to jobsets in project view
  • [33] IK53RV4V
  • [*] 4WZQW2N6 Fix indentation and get rid of some unnecessary whitespace in the output

Change contents

  • replacement in src/lib/Hydra/Controller/Project.pm at line 37
    [4.2076][4.2076:2118]()
    $c->stash->{template} = 'project.tt';
    [4.2076]
    [4.2118]
    $c->stash->{template} = 'edit-project.tt';
  • replacement in src/lib/Hydra/Controller/Project.pm at line 102
    [4.2994][4.2994:3036]()
    $c->stash->{template} = 'project.tt';
    [4.2994]
    [4.3036]
    $c->stash->{template} = 'edit-project.tt';
  • edit in src/root/common.tt at line 239
    [35.4168]
    [35.4168]
    BLOCK editString;
    IF edit %]
    <input type="text" class="string" [% HTML.attributes(id => param, name => param, value => value) %] />
    [% ELSE;
    HTML.escape(value);
    END;
    END;
  • file addition: edit-project.tt (----------)
    [4.1486]
    [% WRAPPER layout.tt title=(create ? "New Project" : "Editing project $project.name") %]
    [% PROCESS common.tt %]
    <form action="[% IF create %][% c.uri_for('/create-project/submit') %][% ELSE %][% c.uri_for('/project' project.name 'submit') %][% END %]" method="post">
    <table class="layoutTable">
    <tr>
    <th>Identifier:</th>
    <td><tt>[% INCLUDE editString param="name" value=project.name %]</tt></td>
    </tr>
    <tr>
    <th>Display name:</th>
    <td>[% INCLUDE editString param="displayname" value=project.displayname %]</td>
    </tr>
    <tr>
    <th>Description:</th>
    <td>[% INCLUDE editString param="description" value=project.description %]</td>
    </tr>
    <tr>
    <th>Homepage:</th>
    <td>
    [% INCLUDE editString param="homepage" value=project.homepage %]
    </td>
    </tr>
    <tr>
    <th>Owner:</th>
    <td><tt>[% INCLUDE editString param="owner" value=(project.owner.username || c.user.username) %]</tt></td>
    </tr>
    <tr>
    <th>Enabled:</th>
    <td>
    [% INCLUDE renderSelection param="enabled" curValue=project.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
    </td>
    </tr>
    </table>
    <div class="form-actions">
    <button type="submit" class="btn btn-primary">
    <i class="icon-ok icon-white"></i>
    [%IF create %]Create[% ELSE %]Apply changes[% END %]
    </button>
    [% IF !create %]
    <button id="delete-project" type="submit" class="btn btn-danger" name="submit" value="delete">
    <i class="icon-trash icon-white"></i>
    Delete this project
    </button>
    <script type="text/javascript">
    $("#delete-project").click(function() {
    return confirm("Are you sure you want to delete this project?");
    });
    </script>
    [% END %]
    </div>
    </form>
    [% END %]
  • replacement in src/root/jobset.tt at line 25
    [4.5542][4.9637:9747](),[4.8025][4.9637:9747](),[4.9637][4.9637:9747]()
    <tt>[% INCLUDE maybeEditString param="$baseName-name" value=input.name extraClass="shortString" %]</tt>
    [4.5542]
    [4.9747]
    <tt>[% INCLUDE maybeEditString param="$baseName-name" value=input.name %]</tt>
  • replacement in src/root/jobset.tt at line 146
    [4.28197][4.28197:28486]()
    <tt>[% INCLUDE maybeEditString param="nixexprpath" value=jobset.nixexprpath extraClass="shortString" %]</tt> in input
    <tt>[% INCLUDE maybeEditString param="nixexprinput" value=jobset.nixexprinput extraClass="shortString" %]</tt>
    [4.28197]
    [4.28486]
    <tt>[% INCLUDE maybeEditString param="nixexprpath" value=jobset.nixexprpath %]</tt> in input
    <tt>[% INCLUDE maybeEditString param="nixexprinput" value=jobset.nixexprinput %]</tt>
  • replacement in src/root/project.tt at line 1
    [4.1667][3.3805:3929]()
    [% WRAPPER layout.tt title=(edit ? (create ? "New Project" : "Editing project $project.name") : "Project $project.name") %]
    [4.1667]
    [4.3183]
    [% WRAPPER layout.tt title="Project $project.name" %]
  • edit in src/root/project.tt at line 3
    [4.3207][4.397:431](),[4.431][4.31371:31402](),[4.31371][4.31371:31402](),[4.31402][3.3930:4033](),[4.534][4.31489:31750](),[3.4033][4.31489:31750](),[4.31489][4.31489:31750](),[4.25997][4.3166:3167](),[4.31750][4.3166:3167](),[4.3166][4.3166:3167](),[4.3167][4.8434:8469](),[4.8469][4.31751:31838](),[4.31880][4.31880:32166](),[4.32166][4.708:736](),[4.26215][4.708:736](),[4.736][4.32167:32314](),[4.32314][4.202:249](),[4.26299][4.202:249](),[4.249][4.32315:32473](),[4.32473][4.1592:1642](),[4.118][4.1592:1642](),[4.1642][4.32474:32673](),[4.32673][4.737:823](),[4.26538][4.737:823](),[4.823][4.1643:1726](),[4.1726][4.912:977](),[4.912][4.912:977](),[4.977][4.1727:1815](),[4.1815][4.1060:1158](),[4.1060][4.1060:1158](),[4.1158][4.1816:1907](),[4.1907][4.1248:1281](),[4.1248][4.1248:1281](),[4.1281][4.1908:1993](),[4.1993][4.1365:1421](),[4.1365][4.1365:1421](),[4.1421][4.32674:32855](),[4.32855][4.1422:1508](),[4.26677][4.1422:1508](),[4.1508][4.250:468](),[4.468][4.8589:8633](),[4.8633][4.507:556](),[4.507][4.507:556](),[4.556][4.8634:8694](),[4.8694][4.598:647](),[4.598][4.598:647](),[4.647][4.8695:8753](),[4.8753][4.0:51](),[4.692][4.0:51](),[4.51][4.8754:8812](),[4.8812][4.792:850](),[4.792][4.792:850](),[4.850][4.8813:9357](),[4.9357][4.965:1028](),[4.965][4.965:1028](),[4.1028][4.9358:9447](),[4.9447][4.1109:1165](),[4.1109][4.1109:1165](),[4.1165][4.32856:33032]()
    <ul class="nav nav-tabs">
    [% IF !edit %]
    <li class="active"><a href="#tabs-project" data-toggle="tab">Overview</a></li>
    [% END %]
    <li><a href="#tabs-settings" data-toggle="tab">Settings</a></li>
    [% IF !edit %]
    <li><a href="#tabs-views" data-toggle="tab">Views</a></li>
    [% END %]
    </ul>
    <div class="tab-content">
    [% IF !edit %]
    <div id="tabs-project" class="tab-pane active">
    [% IF project.jobsets.size > 0 %]
    <p>This project has the following jobsets:</p>
    <table class="tablesorter table table-striped table-condensed">
    <thead>
    <tr>
    <th></th>
    <th>Id</th>
    <th>Description</th>
    <th>Last evaluated</th>
    <th colspan="2">Success</th>
    </tr>
    </thead>
    <tbody>
    [% FOREACH j IN jobsets %]
    [% successrate = 0 %]
    <tr class="clickable [% IF odd %] odd [% END; odd = !odd %]"
    onclick="window.location = '[% c.uri_for('/jobset' project.name j.name) %]'">
    <td>
    [% IF j.get_column('nrscheduled') > 0 %]
    <img src="/static/images/help_16.png" alt="Scheduled" />
    [% ELSIF j.get_column('nrfailed') == 0 %]
    <img src="/static/images/checkmark_16.png" alt="Succeeded" />
    [% ELSIF j.get_column('nrfailed') > 0 && j.get_column('nrsucceeded') > 0 %]
    <img src="/static/images/error_some_16.png" alt="Some Failed" />
    [% ELSE %]
    <img src="/static/images/error_16.png" alt="All Failed" />
    [% END %]
    </td>
    <td>[% INCLUDE renderJobsetName project = project.name jobset = j.name %]</td>
    <td>[% HTML.escape(j.description) %]</td>
    <td>[% INCLUDE renderDateTime timestamp = j.lastcheckedtime %]</td>
    [% IF j.get_column('nrtotal') > 0 %]
    [% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %]
    [% IF j.get_column('nrscheduled') > 0 %]
    [% class = 'label' %]
    [% ELSIF successrate < 25 %]
    [% class = 'label label-important' %]
    [% ELSIF successrate < 75 %]
    [% class = 'label label-warning' %]
    [% ELSIF successrate <= 100 %]
    [% class = 'label label-success' %]
    [% END %]
    [% END %]
    <td>
    <span class="[% class %]">[% successrate FILTER format('%d') %]%</span>
    </td>
    <td>
    [% IF j.get_column('nrsucceeded') > 0 %]
    <span class="label label-success">[% j.get_column('nrsucceeded') %]</span>
    [% END %]
    [% IF j.get_column('nrfailed') > 0 %]
    <span class="label label-important">[% j.get_column('nrfailed') %]</span>
    [% END %]
    [% IF j.get_column('nrscheduled') > 0 %]
    <span class="label label">[% j.get_column('nrscheduled') %]</span>
    [% END %]
    </td>
    </tr>
    [% END %]
    </tbody>
    </table>
    [% ELSE %]
  • replacement in src/root/project.tt at line 4
    [4.33033][4.33033:33098]()
    <p>No jobsets have been defined yet.</p>
    [4.33033]
    [4.33098]
    <ul class="nav nav-tabs">
    <li class="active"><a href="#tabs-project" data-toggle="tab">Jobsets</a></li>
    <li><a href="#tabs-settings" data-toggle="tab">Configuration</a></li>
    <li><a href="#tabs-views" data-toggle="tab">Views</a></li>
    </ul>
  • replacement in src/root/project.tt at line 10
    [4.33099][4.33099:33133]()
    [% END %]
    [4.33099]
    [4.33133]
    <div class="tab-content">
  • edit in src/root/project.tt at line 12
    [4.33134]
    [4.33134]
    <div id="tabs-project" class="tab-pane active">
    [% IF project.jobsets.size > 0 %]
    <p>This project has the following jobsets:</p>
  • replacement in src/root/project.tt at line 16
    [4.33135][4.33135:33458]()
    </div>
    [% END %]
    <div id="tabs-settings" class="tab-pane [% IF edit %]active[% END %]">
    [% IF edit %]
    <form action="[% IF create %][% c.uri_for('/create-project/submit') %][% ELSE %][% c.uri_for('/project' project.name 'submit') %][% END %]" method="post">
    [4.33135]
    [4.33458]
    <table class="tablesorter table table-striped table-condensed">
    <thead>
    <tr>
    <th></th>
    <th>Id</th>
    <th>Description</th>
    <th>Last evaluated</th>
    <th colspan="2">Success</th>
    </tr>
    </thead>
    <tbody>
    [% FOREACH j IN jobsets %]
    [% successrate = 0 %]
    <tr class="clickable [% IF odd %] odd [% END; odd = !odd %]"
    onclick="window.location = '[% c.uri_for('/jobset' project.name j.name) %]'">
    <td>
    [% IF j.get_column('nrscheduled') > 0 %]
    <img src="/static/images/help_16.png" alt="Scheduled" />
    [% ELSIF j.get_column('nrfailed') == 0 %]
    <img src="/static/images/checkmark_16.png" alt="Succeeded" />
    [% ELSIF j.get_column('nrfailed') > 0 && j.get_column('nrsucceeded') > 0 %]
    <img src="/static/images/error_some_16.png" alt="Some Failed" />
    [% ELSE %]
    <img src="/static/images/error_16.png" alt="All Failed" />
  • replacement in src/root/project.tt at line 41
    [4.33485][4.33485:33486](),[4.33524][4.33524:35416]()
    <table class="layoutTable">
    [% IF edit %]
    <tr>
    <th>Identifier:</th>
    <td><tt>[% INCLUDE maybeEditString param="name" value=project.name %]</tt></td>
    </tr>
    [% END %]
    <tr>
    <th>Display name:</th>
    <td>[% INCLUDE maybeEditString param="displayname" value=project.displayname %]</td>
    </tr>
    <tr>
    <th>Description:</th>
    <td>[% INCLUDE maybeEditString param="description" value=project.description %]</td>
    </tr>
    <tr>
    <th>Homepage:</th>
    <td>
    [% IF edit %]
    [% INCLUDE maybeEditString param="homepage" value=project.homepage %]
    [% ELSE %]
    [% IF project.homepage %]
    <a [% HTML.attributes(href => project.homepage) %]>[% HTML.escape(project.homepage) %]</a>
    [% ELSE %]
    <em>(not specified)</em>
    [% END %]
    [% END %]
    </td>
    </tr>
    <tr>
    <th>Owner:</th>
    <td><tt>[% INCLUDE maybeEditString param="owner" value=(project.owner.username || c.user.username) edit=(edit && c.check_user_roles('admin')) %]</tt></td>
    </tr>
    <tr>
    <th>Enabled:</th>
    <td>
    [% INCLUDE renderSelection param="enabled" curValue=project.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
    </td>
    </tr>
    </table>
    [% IF edit %]
    [4.33484]
    [4.35416]
    </td>
    <td>[% INCLUDE renderJobsetName project = project.name jobset = j.name %]</td>
    <td>[% HTML.escape(j.description) %]</td>
    <td>[% INCLUDE renderDateTime timestamp = j.lastcheckedtime %]</td>
    [% IF j.get_column('nrtotal') > 0 %]
    [% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %]
    [% IF j.get_column('nrscheduled') > 0 %]
    [% class = 'label' %]
    [% ELSIF successrate < 25 %]
    [% class = 'label label-important' %]
    [% ELSIF successrate < 75 %]
    [% class = 'label label-warning' %]
    [% ELSIF successrate <= 100 %]
    [% class = 'label label-success' %]
    [% END %]
    [% END %]
    <td><span class="[% class %]">[% successrate FILTER format('%d') %]%</span></td>
    <td>
    [% IF j.get_column('nrsucceeded') > 0 %]
    <span class="label label-success">[% j.get_column('nrsucceeded') %]</span>
    [% END %]
    [% IF j.get_column('nrfailed') > 0 %]
    <span class="label label-important">[% j.get_column('nrfailed') %]</span>
    [% END %]
    [% IF j.get_column('nrscheduled') > 0 %]
    <span class="label label">[% j.get_column('nrscheduled') %]</span>
    [% END %]
    </td>
    </tr>
    [% END %]
    </tbody>
    </table>
  • replacement in src/root/project.tt at line 74
    [4.35417][3.4034:4079](),[3.4079][4.14689:14955](),[4.35439][4.14689:14955](),[4.14689][4.14689:14955](),[4.14955][4.35440:35557](),[4.35557][4.15058:15196](),[4.15058][4.15058:15196](),[4.15196][4.35558:35827](),[4.35827][4.15400:15430](),[4.15400][4.15400:15430](),[4.15430][3.4080:4105]()
    <div class="form-actions">
    <button type="submit" class="btn btn-primary">
    <i class="icon-ok icon-white"></i>
    [%IF create %]Create[% ELSE %]Apply changes[% END %]
    </button>
    [% IF !create %]
    <button id="delete-project" type="submit" class="btn btn-danger" name="submit" value="delete">
    <i class="icon-trash icon-white"></i>
    Delete this project
    </button>
    <script type="text/javascript">
    $("#delete-project").click(function() {
    return confirm("Are you sure you want to delete this project?");
    });
    </script>
    [% END %]
    </div>
    [4.35417]
    [4.35855]
    [% ELSE %]
    <p>No jobsets have been defined yet.</p>
    [% END %]
  • replacement in src/root/project.tt at line 78
    [4.35856][4.15457:15475](),[4.15457][4.15457:15475]()
    </form>
    [4.35856]
    [2.609]
    </div>
  • replacement in src/root/project.tt at line 80
    [2.610][2.610:636]()
    [% END %]
    [2.610]
    [4.3196]
    <div id="tabs-settings" class="tab-pane">
    <table class="layoutTable">
    <tr>
    <th>Display name:</th>
    <td>[% HTML.escape(project.displayname) %]</td>
    </tr>
    <tr>
    <th>Description:</th>
    <td>[% HTML.escape(project.description) %]</td>
    </tr>
    <tr>
    <th>Homepage:</th>
    <td>
    [% IF project.homepage %]
    <a [% HTML.attributes(href => project.homepage) %]>[% HTML.escape(project.homepage) %]</a>
    [% ELSE %]
    <em>(not specified)</em>
    [% END %]
    </td>
    </tr>
    <tr>
    <th>Owner:</th>
    <td><tt>[% HTML.escape(project.owner.username) %]</tt></td>
    </tr>
    <tr>
    <th>Enabled:</th>
    <td>[% project.enabled ? "Yes" : "No" %]</td>
    </tr>
    </table>
    </div>
  • replacement in src/root/project.tt at line 111
    [4.3197][4.35857:35872]()
    </div>
    [4.3197]
    [4.35872]
    <div id="tabs-views" class="tab-pane">
  • replacement in src/root/project.tt at line 113
    [4.35873][4.35873:35951]()
    [% IF !edit %]
    <div id="tabs-views" class="tab-pane">
    [4.35873]
    [4.35951]
    [% IF views.size > 0 %]
  • replacement in src/root/project.tt at line 115
    [4.35992][4.35992:36040]()
    [% IF views.size > 0 %]
    [4.35952]
    [4.36040]
    <p>Project <tt>[% project.name %]</tt> has the following views:</p>
  • replacement in src/root/project.tt at line 117
    [4.36041][4.36041:36133]()
    <p>Project <tt>[% project.name %]</tt> has the following views:</p>
    [4.36041]
    [4.36133]
    <ul>
    [% FOREACH view IN views %]
    <li>
    <a href="[% c.uri_for('/view' project.name view.name) %]"><tt>[% view.name %]</tt></a>
    <a class="btn btn-mini" href="[% c.uri_for('/view' project.name view.name "edit") %]">Edit</a>
    </li>
    [% END %]
    </ul>
  • replacement in src/root/project.tt at line 126
    [4.36134][4.36134:36367](),[4.36367][4.15476:15601](),[4.29686][4.15476:15601](),[4.15601][4.36368:36468]()
    <ul>
    [% FOREACH view IN views %]
    <li>
    <a href="[% c.uri_for('/view' project.name view.name) %]"><tt>[% view.name %]</tt></a>
    <a class="btn btn-mini" href="[% c.uri_for('/view' project.name view.name "edit") %]">Edit</a>
    </li>
    [% END %]
    </ul>
    [4.36134]
    [4.36468]
    [% ELSE %]
  • replacement in src/root/project.tt at line 128
    [4.36469][4.36469:36504]()
    [% ELSE %]
    [4.36469]
    [4.36504]
    <p>Project <tt>[% project.name %]</tt> has no views.</p>
  • replacement in src/root/project.tt at line 130
    [4.36505][4.36505:36586]()
    <p>Project <tt>[% project.name %]</tt> has no views.</p>
    [4.36505]
    [4.36586]
    [% END %]
  • replacement in src/root/project.tt at line 132
    [4.36587][4.36587:36621]()
    [% END %]
    [4.36587]
    [4.36621]
    <p>
    <a class="btn" href="[% c.uri_for('/project' project.name 'create-view') %]"><i class="icon-plus"></i> Create a new view</a>
    </p>
  • replacement in src/root/project.tt at line 136
    [4.36622][4.36622:36727](),[4.36727][4.15686:15789](),[4.15686][4.15686:15789]()
    <p><a class="btn" href="[% c.uri_for('/project' project.name 'create-view') %]">
    <i class="icon-plus"></i> Create a new view
    </a></p>
    [4.36622]
    [4.36728]
    </div>
  • edit in src/root/project.tt at line 138
    [4.36729][4.36729:36770]()
    </div>
    [% END %]