├── .gitignore ├── .no-travis.yml ├── CHANGELOG.rdoc ├── CREDITS.txt ├── Gemfile ├── LICENSE.txt ├── README.md ├── app ├── controllers │ ├── rb_all_projects_controller.rb │ ├── rb_application_controller.rb │ ├── rb_burndown_charts_controller.rb │ ├── rb_calendars_controller.rb │ ├── rb_hooks_render_controller.rb │ ├── rb_impediments_controller.rb │ ├── rb_master_backlogs_controller.rb │ ├── rb_project_settings_controller.rb │ ├── rb_queries_controller.rb │ ├── rb_releases_controller.rb │ ├── rb_releases_multiview_controller.rb │ ├── rb_server_variables_controller.rb │ ├── rb_sprints_controller.rb │ ├── rb_stories_controller.rb │ ├── rb_taskboards_controller.rb │ ├── rb_tasks_controller.rb │ ├── rb_updated_items_controller.rb │ └── rb_wikis_controller.rb ├── helpers │ ├── rb_common_helper.rb │ ├── rb_form_helper.rb │ ├── rb_master_backlogs_helper.rb │ └── rb_server_variables_helper.rb ├── models │ ├── rb_issue_history.rb │ ├── rb_journal.rb │ ├── rb_project_settings.rb │ ├── rb_release.rb │ ├── rb_release_burnchart_day_cache.rb │ ├── rb_release_multiview.rb │ ├── rb_release_multiview_burnchart.rb │ ├── rb_sprint.rb │ ├── rb_sprint_burndown.rb │ ├── rb_stacked_data.rb │ ├── rb_stats.rb │ ├── rb_story.rb │ └── rb_task.rb └── views │ ├── backlogs │ ├── _model_errors.html.erb │ ├── _project_settings.html.erb │ ├── _settings.html.erb │ ├── _validation_errors.html.erb │ ├── not_configured.html.erb │ └── view_issues_sidebar.html.erb │ ├── hooks │ └── _rb_include_scripts.html.erb │ ├── layouts │ └── rb.html.erb │ ├── my │ └── blocks │ │ └── _backlogs_sprints.html.erb │ ├── rb_all_projects │ └── statistics.html.erb │ ├── rb_burndown_charts │ ├── _burndown.html.erb │ ├── print.html.erb │ └── show.html.erb │ ├── rb_impediments │ └── _impediment.html.erb │ ├── rb_master_backlogs │ ├── _backlog.html.erb │ ├── _closedbacklog.html.erb │ ├── _productbacklog.html.erb │ └── show.html.erb │ ├── rb_release_burndown_charts │ └── _burndown.html.erb │ ├── rb_releases │ ├── _form.html.erb │ ├── _release.html.erb │ ├── _release_mbp.html.erb │ ├── _sprint.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb │ ├── rb_releases_multiview │ ├── _burnchart.html.erb │ ├── _form.html.erb │ ├── _release_multiview.html.erb │ ├── _releases.html.erb │ ├── _releases_estimate.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb │ ├── rb_server_variables │ └── show.js.erb │ ├── rb_sprints │ └── _sprint.html.erb │ ├── rb_stories │ ├── _helpers.html.erb │ ├── _story.html.erb │ └── _tooltip.html.erb │ ├── rb_taskboards │ └── show.html.erb │ ├── rb_tasks │ ├── _task.html.erb │ └── index.html.erb │ └── rb_updated_items │ └── show.html.erb ├── assets ├── images │ ├── bg.png │ ├── bouncer.gif │ ├── link.png │ └── tasks.png ├── javascripts │ ├── backlog.js │ ├── backlog_options.js │ ├── board_updater.js │ ├── burndown.js │ ├── common.js │ ├── editable_inplace.js │ ├── impediment.js │ ├── issue.js │ ├── jquery │ │ ├── jquery-1.7.2-ui-1.8.21-ujs-2.0.3.js │ │ ├── jquery.cookie.js │ │ ├── jquery.jqplot │ │ │ ├── MIT-LICENSE.txt │ │ │ ├── README.txt │ │ │ ├── changes.txt │ │ │ ├── copyright.txt │ │ │ ├── docs │ │ │ │ ├── files │ │ │ │ │ ├── MIT-LICENSE-txt.html │ │ │ │ │ ├── changes-txt.html │ │ │ │ │ ├── gpl-2-0-txt.html │ │ │ │ │ ├── images │ │ │ │ │ │ ├── background.jpg │ │ │ │ │ │ ├── basicline.png │ │ │ │ │ │ ├── basiclogaxis.png │ │ │ │ │ │ ├── basiclogoptions.png │ │ │ │ │ │ ├── basicoptions.png │ │ │ │ │ │ ├── dualaxis.png │ │ │ │ │ │ ├── logo.jpg │ │ │ │ │ │ ├── navdocs.png │ │ │ │ │ │ ├── navdocsover.png │ │ │ │ │ │ ├── navdownload.png │ │ │ │ │ │ ├── navdownloadover.png │ │ │ │ │ │ ├── navexamples.png │ │ │ │ │ │ ├── navexamplesover.png │ │ │ │ │ │ ├── navhome.png │ │ │ │ │ │ ├── navhomeover.png │ │ │ │ │ │ ├── new.png │ │ │ │ │ │ ├── sample3.png │ │ │ │ │ │ └── samplesm.png │ │ │ │ │ ├── jqPlotCssStyling-txt.html │ │ │ │ │ ├── jqPlotOptions-txt.html │ │ │ │ │ ├── jqplot-axisLabelRenderer-js.html │ │ │ │ │ ├── jqplot-axisTickRenderer-js.html │ │ │ │ │ ├── jqplot-canvasGridRenderer-js.html │ │ │ │ │ ├── jqplot-core-js.html │ │ │ │ │ ├── jqplot-divTitleRenderer-js.html │ │ │ │ │ ├── jqplot-lineRenderer-js.html │ │ │ │ │ ├── jqplot-linearAxisRenderer-js.html │ │ │ │ │ ├── jqplot-markerRenderer-js.html │ │ │ │ │ ├── jqplot-shadowRenderer-js.html │ │ │ │ │ ├── jqplot-shapeRenderer-js.html │ │ │ │ │ ├── jqplot-themeEngine-js.html │ │ │ │ │ ├── jqplot-toImage-js.html │ │ │ │ │ ├── optionsTutorial-txt.html │ │ │ │ │ ├── plugins │ │ │ │ │ │ ├── jqplot-BezierCurveRenderer-js.html │ │ │ │ │ │ ├── jqplot-barRenderer-js.html │ │ │ │ │ │ ├── jqplot-blockRenderer-js.html │ │ │ │ │ │ ├── jqplot-bubbleRenderer-js.html │ │ │ │ │ │ ├── jqplot-canvasAxisLabelRenderer-js.html │ │ │ │ │ │ ├── jqplot-canvasAxisTickRenderer-js.html │ │ │ │ │ │ ├── jqplot-canvasOverlay-js.html │ │ │ │ │ │ ├── jqplot-categoryAxisRenderer-js.html │ │ │ │ │ │ ├── jqplot-ciParser-js.html │ │ │ │ │ │ ├── jqplot-cursor-js.html │ │ │ │ │ │ ├── jqplot-dateAxisRenderer-js.html │ │ │ │ │ │ ├── jqplot-donutRenderer-js.html │ │ │ │ │ │ ├── jqplot-dragable-js.html │ │ │ │ │ │ ├── jqplot-enhancedLegendRenderer-js.html │ │ │ │ │ │ ├── jqplot-funnelRenderer-js.html │ │ │ │ │ │ ├── jqplot-highlighter-js.html │ │ │ │ │ │ ├── jqplot-logAxisRenderer-js.html │ │ │ │ │ │ ├── jqplot-mekkoAxisRenderer-js.html │ │ │ │ │ │ ├── jqplot-mekkoRenderer-js.html │ │ │ │ │ │ ├── jqplot-meterGaugeRenderer-js.html │ │ │ │ │ │ ├── jqplot-ohlcRenderer-js.html │ │ │ │ │ │ ├── jqplot-pieRenderer-js.html │ │ │ │ │ │ ├── jqplot-pointLabels-js.html │ │ │ │ │ │ ├── jqplot-pyramidAxisRenderer-js.html │ │ │ │ │ │ ├── jqplot-pyramidGridRenderer-js.html │ │ │ │ │ │ ├── jqplot-pyramidRenderer-js.html │ │ │ │ │ │ └── jqplot-trendline-js.html │ │ │ │ │ └── usage-txt.html │ │ │ │ ├── index.html │ │ │ │ ├── index │ │ │ │ │ ├── Classes.html │ │ │ │ │ ├── Files.html │ │ │ │ │ ├── Functions.html │ │ │ │ │ ├── General.html │ │ │ │ │ ├── General2.html │ │ │ │ │ ├── General3.html │ │ │ │ │ ├── General4.html │ │ │ │ │ ├── General5.html │ │ │ │ │ ├── General6.html │ │ │ │ │ ├── General7.html │ │ │ │ │ ├── Hooks.html │ │ │ │ │ ├── Properties.html │ │ │ │ │ ├── Properties2.html │ │ │ │ │ ├── Properties3.html │ │ │ │ │ ├── Properties4.html │ │ │ │ │ ├── Properties5.html │ │ │ │ │ └── Properties6.html │ │ │ │ ├── javascript │ │ │ │ │ ├── main.js │ │ │ │ │ └── searchdata.js │ │ │ │ ├── search │ │ │ │ │ ├── ClassesA.html │ │ │ │ │ ├── ClassesD.html │ │ │ │ │ ├── ClassesG.html │ │ │ │ │ ├── ClassesH.html │ │ │ │ │ ├── ClassesJ.html │ │ │ │ │ ├── ClassesL.html │ │ │ │ │ ├── ClassesS.html │ │ │ │ │ ├── ClassesSymbols.html │ │ │ │ │ ├── ClassesT.html │ │ │ │ │ ├── ClassesV.html │ │ │ │ │ ├── FilesJ.html │ │ │ │ │ ├── FunctionsC.html │ │ │ │ │ ├── FunctionsD.html │ │ │ │ │ ├── FunctionsG.html │ │ │ │ │ ├── FunctionsI.html │ │ │ │ │ ├── FunctionsM.html │ │ │ │ │ ├── FunctionsN.html │ │ │ │ │ ├── FunctionsQ.html │ │ │ │ │ ├── FunctionsR.html │ │ │ │ │ ├── FunctionsS.html │ │ │ │ │ ├── FunctionsZ.html │ │ │ │ │ ├── GeneralA.html │ │ │ │ │ ├── GeneralB.html │ │ │ │ │ ├── GeneralC.html │ │ │ │ │ ├── GeneralD.html │ │ │ │ │ ├── GeneralE.html │ │ │ │ │ ├── GeneralF.html │ │ │ │ │ ├── GeneralG.html │ │ │ │ │ ├── GeneralH.html │ │ │ │ │ ├── GeneralI.html │ │ │ │ │ ├── GeneralJ.html │ │ │ │ │ ├── GeneralL.html │ │ │ │ │ ├── GeneralM.html │ │ │ │ │ ├── GeneralN.html │ │ │ │ │ ├── GeneralO.html │ │ │ │ │ ├── GeneralP.html │ │ │ │ │ ├── GeneralQ.html │ │ │ │ │ ├── GeneralR.html │ │ │ │ │ ├── GeneralS.html │ │ │ │ │ ├── GeneralSymbols.html │ │ │ │ │ ├── GeneralT.html │ │ │ │ │ ├── GeneralU.html │ │ │ │ │ ├── GeneralV.html │ │ │ │ │ ├── GeneralW.html │ │ │ │ │ ├── GeneralX.html │ │ │ │ │ ├── GeneralY.html │ │ │ │ │ ├── GeneralZ.html │ │ │ │ │ ├── HooksA.html │ │ │ │ │ ├── HooksE.html │ │ │ │ │ ├── HooksJ.html │ │ │ │ │ ├── HooksP.html │ │ │ │ │ ├── NoResults.html │ │ │ │ │ ├── PropertiesA.html │ │ │ │ │ ├── PropertiesB.html │ │ │ │ │ ├── PropertiesC.html │ │ │ │ │ ├── PropertiesD.html │ │ │ │ │ ├── PropertiesE.html │ │ │ │ │ ├── PropertiesF.html │ │ │ │ │ ├── PropertiesG.html │ │ │ │ │ ├── PropertiesH.html │ │ │ │ │ ├── PropertiesI.html │ │ │ │ │ ├── PropertiesL.html │ │ │ │ │ ├── PropertiesM.html │ │ │ │ │ ├── PropertiesN.html │ │ │ │ │ ├── PropertiesO.html │ │ │ │ │ ├── PropertiesP.html │ │ │ │ │ ├── PropertiesR.html │ │ │ │ │ ├── PropertiesS.html │ │ │ │ │ ├── PropertiesT.html │ │ │ │ │ ├── PropertiesU.html │ │ │ │ │ ├── PropertiesV.html │ │ │ │ │ ├── PropertiesW.html │ │ │ │ │ ├── PropertiesX.html │ │ │ │ │ ├── PropertiesY.html │ │ │ │ │ └── PropertiesZ.html │ │ │ │ └── styles │ │ │ │ │ ├── 1.css │ │ │ │ │ ├── 2.css │ │ │ │ │ └── main.css │ │ │ ├── examples │ │ │ │ ├── KCPsample4.csv │ │ │ │ ├── ages.json │ │ │ │ ├── ages.json.bak │ │ │ │ ├── ajax-loader.gif │ │ │ │ ├── area.html │ │ │ │ ├── axisLabelTests.html │ │ │ │ ├── axisLabelsRotatedText.html │ │ │ │ ├── axisScalingForceTickAt.html │ │ │ │ ├── bandedLine.html │ │ │ │ ├── bar-charts.html │ │ │ │ ├── barLineAnimated.html │ │ │ │ ├── barTest.html │ │ │ │ ├── bezierCurve.html │ │ │ │ ├── blockPlot.html │ │ │ │ ├── bubble-plots.html │ │ │ │ ├── bubbleChart.html │ │ │ │ ├── candlestick-charts.html │ │ │ │ ├── candlestick.html │ │ │ │ ├── canvas-overlay.html │ │ │ │ ├── colorpicker │ │ │ │ │ ├── README │ │ │ │ │ ├── TODO │ │ │ │ │ ├── images │ │ │ │ │ │ ├── bar-alpha.png │ │ │ │ │ │ ├── bar-opacity.png │ │ │ │ │ │ ├── bar-pointer.png │ │ │ │ │ │ ├── bar.png │ │ │ │ │ │ ├── map-opacity.png │ │ │ │ │ │ ├── map-pointer.png │ │ │ │ │ │ ├── map.png │ │ │ │ │ │ ├── preview-opacity.png │ │ │ │ │ │ └── ui-colorpicker.png │ │ │ │ │ ├── index.html │ │ │ │ │ ├── jquery.colorpicker.css │ │ │ │ │ └── jquery.colorpicker.js │ │ │ │ ├── cursor-highlighter.html │ │ │ │ ├── customHighlighterCursorTrendline.html │ │ │ │ ├── dashboardWidget.html │ │ │ │ ├── dashedLines.html │ │ │ │ ├── data-renderers.html │ │ │ │ ├── date-axes.html │ │ │ │ ├── dateAxisLogAxisZooming.html │ │ │ │ ├── dateAxisRenderer.html │ │ │ │ ├── example.js │ │ │ │ ├── example.min.js │ │ │ │ ├── examples.css │ │ │ │ ├── examples.min.css │ │ │ │ ├── fillBetweenLines.html │ │ │ │ ├── hiddenPlotsInTabs.html │ │ │ │ ├── images │ │ │ │ │ ├── logo.jpg │ │ │ │ │ └── ui-colorpicker.png │ │ │ │ ├── index.html │ │ │ │ ├── jquery-ui │ │ │ │ │ ├── css │ │ │ │ │ │ ├── smoothness │ │ │ │ │ │ │ ├── images │ │ │ │ │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ │ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ │ │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ │ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ │ │ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ │ │ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ │ │ │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ │ │ │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ │ │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ │ │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ │ │ │ │ ├── ui-icons_888888_256x240.png │ │ │ │ │ │ │ │ └── ui-icons_cd0a0a_256x240.png │ │ │ │ │ │ │ ├── jquery-ui.css │ │ │ │ │ │ │ └── jquery-ui.min.css │ │ │ │ │ │ └── ui-lightness │ │ │ │ │ │ │ ├── images │ │ │ │ │ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ │ │ │ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ │ │ │ │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ │ │ │ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ │ │ │ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ │ │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ │ │ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ │ │ │ │ │ ├── ui-bg_highlight-soft_75_ffe45c_1x100.png │ │ │ │ │ │ │ ├── ui-icons_228ef1_256x240.png │ │ │ │ │ │ │ ├── ui-icons_ef8c08_256x240.png │ │ │ │ │ │ │ ├── ui-icons_ffd27a_256x240.png │ │ │ │ │ │ │ └── ui-icons_ffffff_256x240.png │ │ │ │ │ │ │ ├── jquery-ui-1.9pre.css │ │ │ │ │ │ │ ├── jquery-ui-1.9pre.min.css │ │ │ │ │ │ │ ├── jquery-ui.css │ │ │ │ │ │ │ └── jquery-ui.min.css │ │ │ │ │ └── js │ │ │ │ │ │ ├── jquery-ui-1.9pre.min.js │ │ │ │ │ │ ├── jquery-ui.js │ │ │ │ │ │ ├── jquery-ui.min.js │ │ │ │ │ │ ├── jquery.effects.blind.js │ │ │ │ │ │ ├── jquery.effects.blind.min.js │ │ │ │ │ │ ├── jquery.effects.core.js │ │ │ │ │ │ └── jquery.effects.core.min.js │ │ │ │ ├── jquery.print.js │ │ │ │ ├── jquery.printElement.min.js │ │ │ │ ├── jsondata.txt │ │ │ │ ├── kcp.print.js │ │ │ │ ├── kcp_area.html │ │ │ │ ├── kcp_area2.html │ │ │ │ ├── kcp_area2.json │ │ │ │ ├── kcp_cdf.html │ │ │ │ ├── kcp_engel.html │ │ │ │ ├── kcp_lorenz.html │ │ │ │ ├── kcp_pdf.html │ │ │ │ ├── kcp_pyramid.html │ │ │ │ ├── kcp_pyramid2.html │ │ │ │ ├── kcp_pyramid_by_age.html │ │ │ │ ├── kcp_pyramid_by_age.php │ │ │ │ ├── kcp_quintiles.html │ │ │ │ ├── line-charts.html │ │ │ │ ├── mekkoCharts.html │ │ │ │ ├── meterGauge.html │ │ │ │ ├── multipleBarColors.html │ │ │ │ ├── nav.inc │ │ │ │ ├── pie-donut-charts.html │ │ │ │ ├── pieTest.html │ │ │ │ ├── pieTest2.js │ │ │ │ ├── pieTest4.html │ │ │ │ ├── point-labels.html │ │ │ │ ├── quintiles.json │ │ │ │ ├── resizablePlot.html │ │ │ │ ├── resizablePlot.php.orig │ │ │ │ ├── rotated-tick-labels.html │ │ │ │ ├── rotatedTickLabelsZoom.html │ │ │ │ ├── selectorSyntax.html │ │ │ │ ├── smoothedLine.html │ │ │ │ ├── syntaxhighlighter │ │ │ │ │ ├── LGPL-LICENSE │ │ │ │ │ ├── MIT-LICENSE │ │ │ │ │ ├── scripts │ │ │ │ │ │ ├── shAutoloader.js │ │ │ │ │ │ ├── shAutoloader.min.js │ │ │ │ │ │ ├── shBrushJScript.js │ │ │ │ │ │ ├── shBrushJScript.min.js │ │ │ │ │ │ ├── shBrushXml.js │ │ │ │ │ │ ├── shBrushXml.min.js │ │ │ │ │ │ ├── shCore.js │ │ │ │ │ │ └── shCore.min.js │ │ │ │ │ └── styles │ │ │ │ │ │ ├── shCore.css │ │ │ │ │ │ ├── shCore.min.css │ │ │ │ │ │ ├── shCoreDefault.css │ │ │ │ │ │ ├── shCoreDefault.min.css │ │ │ │ │ │ ├── shThemeDefault.css │ │ │ │ │ │ ├── shThemeDefault.min.css │ │ │ │ │ │ ├── shThemejqPlot.css │ │ │ │ │ │ └── shThemejqPlot.min.css │ │ │ │ ├── theming.html │ │ │ │ ├── topbanner.inc │ │ │ │ ├── waterfall.html │ │ │ │ ├── waterfall2.html │ │ │ │ ├── yahooData.js │ │ │ │ ├── yahooData.min.js │ │ │ │ ├── zoom1.html │ │ │ │ ├── zoomOptions.html │ │ │ │ ├── zoomProxy.html │ │ │ │ └── zooming.html │ │ │ ├── excanvas.js │ │ │ ├── excanvas.min.js │ │ │ ├── gpl-2.0.txt │ │ │ ├── jqPlotCssStyling.txt │ │ │ ├── jqPlotOptions.txt │ │ │ ├── jquery.jqplot.css │ │ │ ├── jquery.jqplot.js │ │ │ ├── jquery.jqplot.min.css │ │ │ ├── jquery.jqplot.min.js │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ ├── optionsTutorial.txt │ │ │ ├── plugins │ │ │ │ ├── jqplot.BezierCurveRenderer.js │ │ │ │ ├── jqplot.BezierCurveRenderer.min.js │ │ │ │ ├── jqplot.barRenderer.js │ │ │ │ ├── jqplot.barRenderer.min.js │ │ │ │ ├── jqplot.blockRenderer.js │ │ │ │ ├── jqplot.blockRenderer.min.js │ │ │ │ ├── jqplot.bubbleRenderer.js │ │ │ │ ├── jqplot.bubbleRenderer.min.js │ │ │ │ ├── jqplot.canvasAxisLabelRenderer.js │ │ │ │ ├── jqplot.canvasAxisLabelRenderer.min.js │ │ │ │ ├── jqplot.canvasAxisTickRenderer.js │ │ │ │ ├── jqplot.canvasAxisTickRenderer.min.js │ │ │ │ ├── jqplot.canvasOverlay.js │ │ │ │ ├── jqplot.canvasOverlay.min.js │ │ │ │ ├── jqplot.canvasTextRenderer.js │ │ │ │ ├── jqplot.canvasTextRenderer.min.js │ │ │ │ ├── jqplot.categoryAxisRenderer.js │ │ │ │ ├── jqplot.categoryAxisRenderer.min.js │ │ │ │ ├── jqplot.ciParser.js │ │ │ │ ├── jqplot.ciParser.min.js │ │ │ │ ├── jqplot.cursor.js │ │ │ │ ├── jqplot.cursor.min.js │ │ │ │ ├── jqplot.dateAxisRenderer.js │ │ │ │ ├── jqplot.dateAxisRenderer.min.js │ │ │ │ ├── jqplot.donutRenderer.js │ │ │ │ ├── jqplot.donutRenderer.min.js │ │ │ │ ├── jqplot.dragable.js │ │ │ │ ├── jqplot.dragable.min.js │ │ │ │ ├── jqplot.enhancedLegendRenderer.js │ │ │ │ ├── jqplot.enhancedLegendRenderer.min.js │ │ │ │ ├── jqplot.funnelRenderer.js │ │ │ │ ├── jqplot.funnelRenderer.min.js │ │ │ │ ├── jqplot.highlighter.js │ │ │ │ ├── jqplot.highlighter.min.js │ │ │ │ ├── jqplot.json2.js │ │ │ │ ├── jqplot.json2.min.js │ │ │ │ ├── jqplot.logAxisRenderer.js │ │ │ │ ├── jqplot.logAxisRenderer.min.js │ │ │ │ ├── jqplot.mekkoAxisRenderer.js │ │ │ │ ├── jqplot.mekkoAxisRenderer.min.js │ │ │ │ ├── jqplot.mekkoRenderer.js │ │ │ │ ├── jqplot.mekkoRenderer.min.js │ │ │ │ ├── jqplot.meterGaugeRenderer.js │ │ │ │ ├── jqplot.meterGaugeRenderer.min.js │ │ │ │ ├── jqplot.mobile.js │ │ │ │ ├── jqplot.mobile.min.js │ │ │ │ ├── jqplot.ohlcRenderer.js │ │ │ │ ├── jqplot.ohlcRenderer.min.js │ │ │ │ ├── jqplot.pieRenderer.js │ │ │ │ ├── jqplot.pieRenderer.min.js │ │ │ │ ├── jqplot.pointLabels.js │ │ │ │ ├── jqplot.pointLabels.min.js │ │ │ │ ├── jqplot.pyramidAxisRenderer.js │ │ │ │ ├── jqplot.pyramidAxisRenderer.min.js │ │ │ │ ├── jqplot.pyramidGridRenderer.js │ │ │ │ ├── jqplot.pyramidGridRenderer.min.js │ │ │ │ ├── jqplot.pyramidRenderer.js │ │ │ │ ├── jqplot.pyramidRenderer.min.js │ │ │ │ ├── jqplot.trendline.js │ │ │ │ └── jqplot.trendline.min.js │ │ │ └── usage.txt │ │ ├── jquery.liveFilter.js │ │ ├── jquery.liveFilter.setup.js │ │ ├── jquery.multiselect.filter.js │ │ ├── jquery.multiselect.filter.min.js │ │ ├── jquery.multiselect.js │ │ ├── jquery.multiselect.min.js │ │ ├── jquery.qtip.pack.js │ │ ├── jquery.qtip.setup.js │ │ ├── jquery.verticalfix-min.js │ │ └── jquery.verticalfix.js │ ├── master_backlog.js │ ├── master_backlog_updater.js │ ├── model.js │ ├── release.js │ ├── show_main.js │ ├── sprint.js │ ├── story.js │ ├── task.js │ ├── taskboard.js │ └── taskboard_updater.js └── stylesheets │ ├── global.css │ ├── global_print.css │ ├── images │ ├── ajax.gif │ ├── bouncer.gif │ ├── error.png │ ├── ika_bg.png │ ├── indicator.gif │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ ├── ui-bg_flat_75_ffffff_40x100.png │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_75_dadada_1x400.png │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ ├── ui-bg_glass_95_fef1ec_1x400.png │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_2e83ff_256x240.png │ ├── ui-icons_454545_256x240.png │ ├── ui-icons_888888_256x240.png │ ├── ui-icons_cd0a0a_256x240.png │ └── warning.png │ ├── jquery │ ├── jquery-ui.css │ ├── jquery.jqplot.css │ ├── jquery.jqplot.min.css │ ├── jquery.multiselect.css │ ├── jquery.multiselect.filter.css │ └── jquery.qtip.css │ ├── master_backlog.css │ ├── master_backlog_print.css │ ├── statistics.css │ ├── taskboard.css │ └── taskboard_print.css ├── config ├── database.yml.travis ├── locales │ ├── de.yml │ ├── en-GB.yml │ ├── en.yml │ ├── es.yml │ ├── fr.yml │ ├── it.yml │ ├── ja.yml │ ├── nl.yml │ ├── no.yml │ ├── pl-PL.yml │ ├── pt-BR.yml │ ├── ru.yml │ ├── tr.yml │ └── zh.yml └── routes.rb ├── db └── migrate │ ├── 011_create_stories_tasks_sprints_and_burndown.rb │ ├── 012_migrate_legacy.rb │ ├── 015_order_tasks_using_tree.rb │ ├── 017_change_issue_position_column.rb │ ├── 019_add_release_tables.rb │ ├── 023_null_task_position.rb │ ├── 024_reinstate_remaining.rb │ ├── 025_fractional_points.rb │ ├── 026_add_story_positions.rb │ ├── 027_add_index_on_issues_position.rb │ ├── 029_sum_remaining_hours.rb │ ├── 033_unique_positions.rb │ ├── 036_trust_unique_positions.rb │ ├── 037_add_rb_project_settings.rb │ ├── 038_rb_add_history.rb │ ├── 039_add_show_in_scrum_stats_project_setting.rb │ ├── 040_add_release_id_to_issues.rb │ ├── 041_add_sharing_to_releases.rb │ ├── 042_migrate_releases.rb │ ├── 043_add_releases_planned_velocity.rb │ ├── 044_add_release_relationship_to_issues.rb │ ├── 045_drop_release_burndown_days.rb │ ├── 046_add_releases_indexes.rb │ ├── 047_add_issues_rbcache.rb │ ├── 048_add_issues_release_day_cache.rb │ └── 049_add_release_multiview.rb ├── features ├── .autotest ├── burndown.feature ├── cecilia_burndown.feature ├── common.feature ├── duplicate_story.feature ├── extended_timelog.feature ├── list_with_gaps.feature ├── product_owner.feature ├── release-multiview-burnchart-in-progress.feature ├── release-multiview-burnchart-scope-change.feature ├── release-multiview-burnchart.feature ├── release-multiview-stacked-data.feature ├── release-multiview.feature ├── release3.feature ├── release_burndown.feature ├── release_burndown_complex.feature ├── release_burndown_trendline.feature ├── routes.feature ├── scrum_master.feature ├── settings.feature ├── shared-versions-burndown.feature ├── shared-versions-chief_product_owner.feature ├── shared-versions-chief_product_owner2.feature ├── shared-versions-pblpage.feature ├── shared-versions-positioning.feature ├── shared-versions-scrum_master-dnd.feature ├── shared-versions-team_member-dnd.feature ├── shared-versions.feature ├── sidebar.feature ├── step_definitions │ ├── _given_steps.rb │ ├── _then_steps.rb │ ├── _when_steps.rb │ ├── dragdrop.rb │ ├── helpers.rb │ ├── release_steps.rb │ ├── routing_steps.rb │ ├── stacked_data.rb │ └── web_steps.rb ├── support │ ├── env.rb │ ├── paths.rb │ ├── setup.rb │ └── simplecov_env.rb ├── team_member.feature ├── ui.feature └── updater.feature ├── init.rb ├── lib ├── backlogs_activerecord_mixin.rb ├── backlogs_acts_as_cached_journaled.rb ├── backlogs_custom_field_patch.rb ├── backlogs_hooks.rb ├── backlogs_issue_patch.rb ├── backlogs_issue_query_patch.rb ├── backlogs_issue_status_patch.rb ├── backlogs_issues_controller_patch.rb ├── backlogs_merged_array.rb ├── backlogs_my_controller_patch.rb ├── backlogs_printable_cards.rb ├── backlogs_project_patch.rb ├── backlogs_projects_helper_patch.rb ├── backlogs_setup.rb ├── backlogs_spreadsheet.rb ├── backlogs_time_report_patch.rb ├── backlogs_tracker_patch.rb ├── backlogs_user_patch.rb ├── backlogs_version_patch.rb ├── ci │ ├── README │ ├── __buildscript.sh │ ├── generate.sh │ ├── install-pre.sh │ └── pbuilderrc.tpl ├── color.rb ├── labels │ ├── labels.yaml.default │ ├── story-default.glabels │ └── task-default.glabels ├── linear_regression.rb ├── tasks │ ├── anonymize.rake │ ├── changelog.rb │ ├── cp.rake │ ├── deprecated_tasks.rake │ ├── extract_default_data.rake │ ├── fix_positions.rake │ ├── generate_chart_data.rake │ ├── install.rake │ ├── manage-issues.rb │ ├── position_from_priority.rake │ ├── prepare_fixtures.rake │ ├── prime_stats.rake │ ├── rcov.rake │ ├── rebuild_journal.rake │ ├── sample_project.yaml │ ├── tag.rb │ ├── test.rake │ ├── touch_stories.rake │ ├── translation-manager.rb │ ├── travis-combos.rb │ └── travis.rb └── ttf │ ├── DejaVuSans-Bold.ttf │ ├── DejaVuSans-BoldOblique.ttf │ ├── DejaVuSans-ExtraLight.ttf │ ├── DejaVuSans-Oblique.ttf │ ├── DejaVuSans.ttf │ ├── DejaVuSansCondensed-Bold.ttf │ ├── DejaVuSansCondensed-BoldOblique.ttf │ ├── DejaVuSansCondensed-Oblique.ttf │ ├── DejaVuSansCondensed.ttf │ ├── DejaVuSansMono-Bold.ttf │ ├── DejaVuSansMono-BoldOblique.ttf │ ├── DejaVuSansMono-Oblique.ttf │ ├── DejaVuSansMono.ttf │ ├── DejaVuSerif-Bold.ttf │ ├── DejaVuSerif-BoldItalic.ttf │ ├── DejaVuSerif-Italic.ttf │ ├── DejaVuSerif.ttf │ ├── DejaVuSerifCondensed-Bold.ttf │ ├── DejaVuSerifCondensed-BoldItalic.ttf │ ├── DejaVuSerifCondensed-Italic.ttf │ └── DejaVuSerifCondensed.ttf ├── rbl-test ├── redmine_install.sh ├── screenshots ├── backlogs.png └── release.png ├── spec ├── config.rb ├── controllers │ └── rb_all_projects_controller_spec.rb └── fast_spec_helper.rb └── test.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | # Ignore any accidental remnants from gh-pages branch 3 | _site 4 | _posts 5 | assets/styles 6 | lib/labels/labels.yaml 7 | lib/labels/labels-malformed.yaml 8 | graph.dot 9 | nbproject 10 | *.rc 11 | Gemfile.lock 12 | backlogs.dev 13 | .ruby-version 14 | redmine_backlogs 15 | *~ 16 | \#*\# 17 | -------------------------------------------------------------------------------- /.no-travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | release: 1.0.6 4 | services: 5 | - mysql 6 | - postgresql 7 | rvm: 8 | - 1.9.3 9 | - 2.0.0 10 | env: 11 | - REDMINE_VER=2.2.4 DB=mysql CLUSTER=CLUSTER1 12 | - REDMINE_VER=2.2.4 DB=mysql CLUSTER=CLUSTER2 13 | - REDMINE_VER=2.2.4 DB=postgresql CLUSTER=CLUSTER1 14 | - REDMINE_VER=2.2.4 DB=postgresql CLUSTER=CLUSTER2 15 | - REDMINE_VER=2.3.3 DB=postgresql CLUSTER=CLUSTER1 16 | - REDMINE_VER=2.3.3 DB=postgresql CLUSTER=CLUSTER2 17 | - REDMINE_VER=2.5.1 DB=postgresql CLUSTER=CLUSTER1 18 | - REDMINE_VER=2.5.1 DB=postgresql CLUSTER=CLUSTER2 19 | matrix: 20 | allow_failures: 21 | - rvm: jruby-18mode 22 | - rvm: jruby-19mode 23 | exclude: 24 | - rvm: 2.0.0 25 | env: REDMINE_VER=2.2.4 DB=mysql CLUSTER=CLUSTER1 26 | - rvm: 2.0.0 27 | env: REDMINE_VER=2.2.4 DB=mysql CLUSTER=CLUSTER2 28 | - rvm: 2.0.0 29 | env: REDMINE_VER=2.2.4 DB=postgresql CLUSTER=CLUSTER1 30 | - rvm: 2.0.0 31 | env: REDMINE_VER=2.2.4 DB=postgresql CLUSTER=CLUSTER2 32 | install: echo skip bundle install 33 | before_script: 34 | - sh -c "if [ '$DB' = 'postgresql' ]; then psql -c 'DROP DATABASE IF EXISTS backlogs;' 35 | -U postgres; fi" 36 | - sh -c "if [ '$DB' = 'postgresql' ]; then psql -c 'create database backlogs;' -U 37 | postgres; fi" 38 | - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS backlogs;'; 39 | fi" 40 | script: 41 | - export WORKSPACE=`pwd`/workspace 42 | - export PATH_TO_BACKLOGS=`pwd` 43 | - export PATH_TO_REDMINE=$WORKSPACE/redmine 44 | - mkdir $WORKSPACE 45 | - cp config/database.yml.travis $WORKSPACE/database.yml 46 | - bash -x ./redmine_install.sh -r || exit 1 47 | - bash -x ./redmine_install.sh -i || exit 1 48 | - bash -x ./redmine_install.sh -t || exit 1 49 | - bash -x ./redmine_install.sh -u || exit 1 50 | -------------------------------------------------------------------------------- /CREDITS.txt: -------------------------------------------------------------------------------- 1 | Thanks to the following people for their help: 2 | 3 | * The awesome contributors of Backlogs: https://github.com/backlogs/redmine_backlogs/graphs/contributors 4 | * Emiliano Heyns - Project maintainer 5 | * Mark Maglana (relaxdiego) - Some guy who used to contribute code 6 | * Guy Naor - Project sponsorship 7 | * G2iX - Project sponsorship 8 | * Eric Davis - For the advice on the model patching pattern magic 9 | * Everyone at Redmine.org - For the pure awesomeness that is Redmine :-) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | REDMINE BACKLOGS 2 | ---------------- 3 | 4 | A Redmine plugin for agile teams. For more information, 5 | please visit https://backlogs.github.io/www/ 6 | 7 | PROJECT HEALTH 8 | -------------- 9 | 10 | [![Build Status](https://secure.travis-ci.org/backlogs/redmine_backlogs.png?branch=master)](http://travis-ci.org/backlogs/redmine_backlogs) 11 | [![Code Climate](https://codeclimate.com/github/backlogs/redmine_backlogs.png)](https://codeclimate.com/github/backlogs/redmine_backlogs) 12 | [![Dependency Status](https://gemnasium.com/backlogs/redmine_backlogs.png)](https://gemnasium.com/backlogs/redmine_backlogs) 13 | 14 | 15 | LICENSE 16 | ------- 17 | This plugin is released under the GPL v2 license. See 18 | LICENSE for more information. 19 | 20 | Due to time restraints I can only support the latest release, PLEASE take this into consideration before posting issues. Upgrade first. 21 | 22 | -------------------------------------------------------------------------------- /app/controllers/rb_all_projects_controller.rb: -------------------------------------------------------------------------------- 1 | class RbAllProjectsController < ApplicationController 2 | unloadable 3 | 4 | before_filter :authorize_global 5 | 6 | def statistics 7 | backlogs_projects = RbCommonHelper.find_backlogs_enabled_active_projects 8 | @projects = [] 9 | backlogs_projects.each{|p| 10 | @projects << p if p.visible? && p.rb_project_settings.show_in_scrum_stats 11 | } 12 | @projects.sort! {|a, b| a.scrum_statistics.score <=> b.scrum_statistics.score} 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /app/controllers/rb_application_controller.rb: -------------------------------------------------------------------------------- 1 | # Base class of all controllers in Redmine Backlogs 2 | class RbApplicationController < ApplicationController 3 | unloadable 4 | 5 | before_filter :load_project, :authorize, :check_if_plugin_is_configured 6 | 7 | #provide list of javascript_include_tags which must be rendered before common.js 8 | def rb_jquery_plugins 9 | @rb_jquery_plugins 10 | end 11 | def rb_jquery_plugins=(html) 12 | @rb_jquery_plugins = html 13 | end 14 | 15 | private 16 | 17 | # Loads the project to be used by the authorize filter to 18 | # determine if User.current has permission to invoke the method in question. 19 | def load_project 20 | @project = if params[:sprint_id] 21 | load_sprint 22 | @sprint.project 23 | elsif params[:release_id] && !params[:release_id].empty? 24 | load_release 25 | @release.project 26 | elsif params[:release_multiview_id] && !params[:release_multiview_id].empty? 27 | load_release_multiview 28 | @release_multiview.project 29 | elsif params[:project_id] 30 | Project.find(params[:project_id]) 31 | else 32 | raise "Cannot determine project (#{params.inspect})" 33 | end 34 | end 35 | 36 | def check_if_plugin_is_configured 37 | @settings = Backlogs.settings 38 | if @settings[:story_trackers].blank? || @settings[:task_tracker].blank? 39 | respond_to do |format| 40 | format.html { render :file => "backlogs/not_configured" } 41 | end 42 | end 43 | end 44 | 45 | def load_sprint 46 | @sprint = RbSprint.find(params[:sprint_id]) 47 | end 48 | 49 | def load_release 50 | @release = RbRelease.find(params[:release_id]) 51 | end 52 | 53 | def load_release_multiview 54 | @release_multiview = RbReleaseMultiview.find(params[:release_multiview_id]) 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /app/controllers/rb_burndown_charts_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | 3 | class RbBurndownChartsController < RbApplicationController 4 | unloadable 5 | 6 | def show 7 | respond_to do |format| 8 | format.html 9 | end 10 | end 11 | 12 | def embedded 13 | respond_to do |format| 14 | format.html { render :template => 'rb_burndown_charts/show.html.erb', :layout => false } 15 | end 16 | end 17 | 18 | def print 19 | @width = Backlogs.setting[:burndown_print_width].to_s 20 | @height = Backlogs.setting[:burndown_print_height].to_s 21 | if @width.blank? || @height.blank? 22 | @width = '1300' 23 | @height = '600' 24 | end 25 | respond_to do |format| 26 | format.html { render :layout => false } 27 | end 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /app/controllers/rb_hooks_render_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | 3 | class RbHooksRenderController < RbApplicationController 4 | unloadable 5 | 6 | def view_issues_sidebar 7 | locals = { 8 | :sprints => RbSprint.open_sprints(@project), 9 | :project => @project, 10 | :sprint => @sprint, 11 | :webcal => (request.ssl? ? 'webcals' : 'webcal'), 12 | :key => User.current.api_key 13 | } 14 | 15 | respond_to do |format| 16 | format.html { render :template => 'backlogs/view_issues_sidebar.html.erb', :layout => false, :locals => locals } 17 | end 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /app/controllers/rb_impediments_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | 3 | class RbImpedimentsController < RbApplicationController 4 | unloadable 5 | 6 | def create 7 | @settings = Backlogs.settings 8 | begin 9 | @impediment = RbTask.create_with_relationships(params, User.current.id, @project.id, true) 10 | rescue => e 11 | render :text => e.message.blank? ? e.to_s : e.message, :status => 400 12 | return 13 | end 14 | 15 | result = @impediment.errors.size 16 | status = (result == 0 ? 200 : 400) 17 | @include_meta = true 18 | 19 | respond_to do |format| 20 | format.html { render :partial => "impediment", :object => @impediment, :status => status } 21 | end 22 | end 23 | 24 | def update 25 | @impediment = RbTask.find_by_id(params[:id]) 26 | @settings = Backlogs.settings 27 | begin 28 | result = @impediment.update_with_relationships(params) 29 | rescue => e 30 | render :text => e.message.blank? ? e.to_s : e.message, :status => 400 31 | return 32 | end 33 | status = (result ? 200 : 400) 34 | @include_meta = true 35 | 36 | respond_to do |format| 37 | format.html { render :partial => "impediment", :object => @impediment, :status => status } 38 | end 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /app/controllers/rb_project_settings_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | include ProjectsHelper 3 | 4 | class RbProjectSettingsController < RbApplicationController 5 | unloadable 6 | 7 | def project_settings 8 | enabled = false 9 | enabled_scrum_stats = false 10 | if request.post? and params[:settings] 11 | enabled = true if params[:settings]["show_stories_from_subprojects"]=="enabled" 12 | enabled_scrum_stats = true if params[:settings]["show_in_scrum_stats"]=="enabled" 13 | end 14 | settings = @project.rb_project_settings 15 | settings.show_stories_from_subprojects = enabled 16 | settings.show_in_scrum_stats = enabled_scrum_stats 17 | if settings.save 18 | flash[:notice] = t(:rb_project_settings_updated) 19 | else 20 | flash[:error] = t(:rb_project_settings_update_error) 21 | end 22 | redirect_to :controller => 'projects', :action => 'settings', :id => @project, 23 | :tab => 'backlogs' 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /app/controllers/rb_releases_multiview_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | include RbFormHelper 3 | include ProjectsHelper 4 | 5 | class RbReleasesMultiviewController < RbApplicationController 6 | unloadable 7 | 8 | def index 9 | end 10 | 11 | def show 12 | respond_to do |format| 13 | format.html { render } 14 | end 15 | end 16 | 17 | def new 18 | @release_multiview = RbReleaseMultiview.new(:project => @project) 19 | if request.post? 20 | # Convert id's into numbers and remove blank 21 | params[:release_multiview][:release_ids]=selected_ids(params[:release_multiview][:release_ids]) 22 | @release_multiview.attributes = params[:release_multiview] 23 | 24 | if @release_multiview.save 25 | flash[:notice] = l(:notice_successful_create) 26 | redirect_to :controller => 'rb_releases', :action => 'index', :project_id => @project 27 | end 28 | end 29 | 30 | end 31 | 32 | def edit 33 | if request.post? 34 | # Convert id's into numbers and remove blank 35 | params[:release_multiview][:release_ids]=selected_ids(params[:release_multiview][:release_ids]) 36 | 37 | if @release_multiview.update_attributes(params[:release_multiview]) 38 | flash[:notice] = l(:notice_successful_update) 39 | redirect_to :controller => 'rb_releases_multiview', :action => 'show', :release_multiview_id => @release_multiview 40 | end 41 | end 42 | end 43 | 44 | def update 45 | end 46 | 47 | def destroy 48 | @release_multiview.destroy 49 | redirect_to :controller => 'rb_releases', :action => 'index', :project_id => @project 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /app/controllers/rb_server_variables_controller.rb: -------------------------------------------------------------------------------- 1 | class RbServerVariablesController < RbApplicationController 2 | unloadable 3 | 4 | # for index there's no @project 5 | # (eliminates the need of RbAllProjectsController) 6 | skip_before_filter :load_project, :authorize, :only => [:index] 7 | 8 | def index 9 | @context = params[:context] 10 | respond_to do |format| 11 | format.html { render_404 } 12 | format.js { render :file => 'rb_server_variables/show.js.erb', :layout => false } 13 | end 14 | end 15 | 16 | alias :project :index 17 | alias :sprint :index 18 | end 19 | -------------------------------------------------------------------------------- /app/controllers/rb_tasks_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | 3 | class RbTasksController < RbApplicationController 4 | unloadable 5 | 6 | def create 7 | @settings = Backlogs.settings 8 | @task = nil 9 | begin 10 | @task = RbTask.create_with_relationships(params, User.current.id, @project.id) 11 | rescue => e 12 | render :text => e.message.blank? ? e.to_s : e.message, :status => 400 13 | return 14 | end 15 | 16 | result = @task.errors.size 17 | status = (result == 0 ? 200 : 400) 18 | @include_meta = true 19 | 20 | respond_to do |format| 21 | format.html { render :partial => "task", :object => @task, :status => status } 22 | end 23 | end 24 | 25 | def update 26 | @task = RbTask.find_by_id(params[:id]) 27 | @settings = Backlogs.settings 28 | result = @task.update_with_relationships(params) 29 | status = (result ? 200 : 400) 30 | @include_meta = true 31 | 32 | @task.story.story_follow_task_state if @task.story 33 | 34 | respond_to do |format| 35 | format.html { render :partial => "task", :object => @task, :status => status } 36 | end 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /app/controllers/rb_updated_items_controller.rb: -------------------------------------------------------------------------------- 1 | include RbCommonHelper 2 | 3 | class RbUpdatedItemsController < RbApplicationController 4 | unloadable 5 | 6 | # Returns all models that have changed since params[:since] 7 | # params[:only] limits the types of models that the method 8 | # should return 9 | def show 10 | @settings = Backlogs.settings 11 | only = (params[:only] ? params[:only].split(/, ?/).map{|v| v.to_sym} : [:sprints, :stories, :tasks, :impediments]) 12 | @items = HashWithIndifferentAccess.new 13 | @include_meta = true 14 | @last_update = nil 15 | 16 | latest_updates = [] 17 | if only.include? :stories 18 | @items[:stories] = RbStory.find_all_updated_since(params[:since], @project.id) 19 | if @items[:stories].length > 0 20 | latest_updates << @items[:stories].sort{ |a,b| a.updated_on <=> b.updated_on }.last 21 | end 22 | end 23 | 24 | if only.include? :tasks 25 | @items[:tasks] = RbTask.find_all_updated_since(params[:since], @project.id, false, params[:sprint]) 26 | if @items[:tasks].length > 0 27 | latest_updates << @items[:tasks].sort{ |a,b| a.updated_on <=> b.updated_on }.last 28 | end 29 | end 30 | 31 | if only.include? :impediments 32 | @items[:impediments] = RbTask.find_all_updated_since(params[:since], @project.id, true, params[:sprint]) 33 | if @items[:impediments].length > 0 34 | latest_updates << @items[:impediments].sort{ |a,b| a.updated_on <=> b.updated_on }.last 35 | end 36 | end 37 | 38 | if latest_updates.length > 0 39 | @last_update = latest_updates.sort{ |a,b| a.updated_on <=> b.updated_on }.last.updated_on 40 | end 41 | 42 | respond_to do |format| 43 | format.html { render :layout => false } 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /app/controllers/rb_wikis_controller.rb: -------------------------------------------------------------------------------- 1 | class RbWikisController < RbApplicationController 2 | unloadable 3 | 4 | # NOTE: This method is public (see init.rb). We will let Redmine core's 5 | # WikiController#index tak care of autorization 6 | # NOTE: this redirection causes a page to be created from a template 7 | # as a side-effect of calling @sprint.wiki_page. See rb_sprint model. 8 | def show 9 | #FIXME not authorizing may be a bad idea. We are creating a public page here... ? 10 | #@sprint.wiki_page does actually return wiki_page_title. Redmine titleizes this, so do we, even if it is redundant. 11 | redirect_to :controller => 'wiki', :action => 'show', :project_id => @sprint.project, :id => Wiki.titleize(@sprint.wiki_page) 12 | end 13 | 14 | # NOTE: This method is public (see init.rb). We will let Redmine core's 15 | # WikiController#index tak care of autorization 16 | # NOTE: this redirection causes a page to be created from a template 17 | # as a side-effect of calling @sprint.wiki_page 18 | def edit 19 | redirect_to :controller => 'wiki', :action => 'edit', :project_id => @sprint.project, :id => Wiki.titleize(@sprint.wiki_page) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/helpers/rb_form_helper.rb: -------------------------------------------------------------------------------- 1 | module RbFormHelper 2 | unloadable 3 | 4 | def rb_form_for(*args, &proc) 5 | form_string = form_for(*args, &proc) 6 | if Rails::VERSION::MAJOR < 3 7 | form_string 8 | else 9 | concat(form_string) 10 | end 11 | end 12 | 13 | # Streamline the difference between <%= %> and <% %> 14 | def rb_labelled_fields_for(*args, &proc) 15 | fields_string = labelled_fields_for(*args, &proc) 16 | if Rails::VERSION::MAJOR < 3 17 | fields_string 18 | else 19 | concat(fields_string) 20 | end 21 | end 22 | 23 | # Streamline the difference between <%= %> and <% %> 24 | def rb_labelled_form_for(*args, &proc) 25 | form_string = labelled_form_for(*args, &proc) 26 | if Rails::VERSION::MAJOR < 3 27 | form_string 28 | else 29 | concat(form_string) 30 | end 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /app/helpers/rb_master_backlogs_helper.rb: -------------------------------------------------------------------------------- 1 | module RbMasterBacklogsHelper 2 | unloadable 3 | include Redmine::I18n 4 | 5 | def backlog_html_class(backlog) 6 | is_sprint?(backlog) ? "sprint backlog" : "product backlog" 7 | end 8 | 9 | def backlog_html_id(backlog) 10 | is_sprint?(backlog) ? "sprint_#{backlog.id}" : "product_backlog" 11 | end 12 | 13 | def backlog_id_or_empty(backlog) 14 | is_sprint?(backlog) ? backlog.id : "" 15 | end 16 | 17 | def backlog_menu(is_sprint, items = []) 18 | html = %{ 19 | 34 | } 35 | end 36 | 37 | def date_or_nil(date) 38 | date.blank? ? '' : date.strftime('%Y-%m-%d') 39 | end 40 | 41 | def editable_if_sprint(backlog) 42 | "editable" if is_sprint?(backlog) 43 | end 44 | 45 | def is_sprint?(backlog) 46 | backlog.class.to_s.downcase=='sprint' 47 | end 48 | 49 | def menu_link(label, options = {}) 50 | # options[:class] = "pureCssMenui" 51 | link_to(label, options) 52 | end 53 | 54 | def name_or_default(backlog) 55 | is_sprint?(backlog) ? backlog.name : l(:label_Product_backlog) 56 | end 57 | 58 | def stories(backlog) 59 | backlog[:stories] || backlog.stories 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /app/helpers/rb_server_variables_helper.rb: -------------------------------------------------------------------------------- 1 | module RbServerVariablesHelper 2 | unloadable 3 | 4 | # Calculates workflow transitions matrix. 5 | # Used to render server variables for javascript DnD handling 6 | # 7 | # workflow_transitions(RbStory) 8 | def workflow_transitions(klass) 9 | default_status = IssueStatus.default 10 | default_status = default_status.id.to_s if default_status 11 | roles = User.current.admin ? Role.all : User.current.roles_for_project(@project) 12 | transitions = {:states => {}, :transitions => {} , :default => default_status } 13 | 14 | klass.trackers.each {|tracker_id| 15 | tracker = Tracker.find(tracker_id) 16 | tracker_id = tracker_id.to_s 17 | 18 | transitions[:transitions][tracker_id] = {} 19 | 20 | tracker.issue_statuses.each {|status| 21 | status_id = status.id.to_s 22 | 23 | transitions[:states][status_id] = {:name => status.name, :closed => (status.is_closed? ? l(:label_closed_issues) + ' ' : '')} 24 | 25 | [[false, false], [true, true], [false, true], [true, false]].each{|creator, assignee| 26 | key = "#{creator ? '+' : '-'}c#{assignee ? '+' : '-'}a" 27 | 28 | transitions[:transitions][tracker_id][key] ||= {} 29 | 30 | begin 31 | allowed_statues = status.new_statuses_allowed_to(roles, tracker, creator, assignee) 32 | rescue #Workaround in order to support redmine 1.1.3 33 | allowed_statues = status.new_statuses_allowed_to(roles, tracker) 34 | end 35 | 36 | allowed = allowed_statues.collect{|s| s.id.to_s} 37 | 38 | transitions[:transitions][tracker_id][key][:default] ||= allowed[0] 39 | 40 | allowed.unshift(status_id) 41 | 42 | transitions[:transitions][tracker_id][key][status_id] = allowed.compact.uniq 43 | } 44 | } 45 | } 46 | transitions 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/models/rb_journal.rb: -------------------------------------------------------------------------------- 1 | class RbJournal < ActiveRecord::Base 2 | unloadable 3 | end 4 | -------------------------------------------------------------------------------- /app/models/rb_project_settings.rb: -------------------------------------------------------------------------------- 1 | class RbProjectSettings < ActiveRecord::Base 2 | unloadable 3 | belongs_to :project 4 | end 5 | 6 | -------------------------------------------------------------------------------- /app/models/rb_release_burnchart_day_cache.rb: -------------------------------------------------------------------------------- 1 | # Release burnchart cache per day per story. 2 | # Table layout optimized for quickly summing up release burncharts. 3 | class RbReleaseBurnchartDayCache < ActiveRecord::Base 4 | unloadable 5 | belongs_to :issue 6 | belongs_to :release 7 | 8 | end 9 | -------------------------------------------------------------------------------- /app/models/rb_release_multiview.rb: -------------------------------------------------------------------------------- 1 | class RbReleaseMultiview < ActiveRecord::Base 2 | self.table_name = 'rb_releases_multiview' 3 | 4 | unloadable 5 | 6 | belongs_to :project 7 | 8 | serialize :release_ids 9 | 10 | validates_presence_of :project_id, :name 11 | 12 | include Backlogs::ActiveRecord::Attributes 13 | 14 | def releases 15 | RbRelease.find(:all, 16 | :conditions => {:id => self.release_ids}, 17 | :order => "release_end_date ASC, release_start_date ASC") 18 | end 19 | 20 | def has_burnchart? 21 | releases.inject(false) {|result,release| result |= release.has_burndown?} 22 | end 23 | 24 | def burnchart 25 | return nil unless self.has_burnchart? 26 | @cached_burnchart ||= RbReleaseMultiviewBurnchart.new(self) 27 | return @cached_burnchart 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /app/views/backlogs/_model_errors.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%- model_errors.each do |a, err| %> 3 |
<%= "#{l('field_' + a.to_s)} #{l('error_' + err.to_s)}" %>
4 | <%- end %> 5 |
6 | -------------------------------------------------------------------------------- /app/views/backlogs/_project_settings.html.erb: -------------------------------------------------------------------------------- 1 | <% 2 | # We cannot rely on rb_form_helper being present here 3 | # - in case there is another plugin hooking into ProjectsHelpers - e.g. RemindCRM 4 | # so we duplicate the rb_form_for code here and do not monkeypatch RbFormHelper into ProjectsHelper. 5 | def rb_pr_form_for(*args, &proc) 6 | form_string = form_for(*args, &proc) 7 | if Rails::VERSION::MAJOR < 3 8 | form_string 9 | else 10 | concat(form_string) 11 | end 12 | end 13 | rb_pr_form_for @project, 14 | :as => :rb_project_settings, 15 | :url => { :controller => 'rb_project_settings', 16 | :action => 'project_settings', :project_id => @project }, 17 | :html => {:id => 'backlogs-form', 18 | :method => :post} do |f| %> 19 | 20 | <%= error_messages_for 'rb_project_settings' %> 21 | 22 |
23 | <% if Backlogs.setting[:sharing_enabled] %> 24 |

25 | <%= content_tag(:label, l(:backlogs_show_stories_from_subprojects_in_backlog)) %> 26 | <%= check_box_tag("settings[show_stories_from_subprojects]", 'enabled', 27 | @project.rb_project_settings.show_stories_from_subprojects) %> 28 |

29 | <% end %> 30 |

31 | <%= content_tag(:label, l(:backlogs_show_in_scrum_stats)) %> 32 | <%= check_box_tag("settings[show_in_scrum_stats]", 'enabled', 33 | @project.rb_project_settings.show_in_scrum_stats) %> 34 |

35 |
36 | <%= submit_tag(l(:button_save)) %> 37 | <% end %> 38 | -------------------------------------------------------------------------------- /app/views/backlogs/_validation_errors.html.erb: -------------------------------------------------------------------------------- 1 | <%= validation_errors.length > 1 ? l(:error_intro_plural) : l(:error_intro_singular) %> 2 | 7 | <%= l(:error_outro ) %> 8 | -------------------------------------------------------------------------------- /app/views/backlogs/not_configured.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= l(:label_backlogs_unconfigured, { 3 | :administration => l(:label_administration), 4 | :plugins => l(:label_plugins), 5 | :configure => l(:button_configure) 6 | }) 7 | %> 8 |
9 | -------------------------------------------------------------------------------- /app/views/hooks/_rb_include_scripts.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <%= stylesheet_link_tag 'jquery/jquery.jqplot.min.css', :plugin => 'redmine_backlogs' %> 3 | <%= if (! ((Redmine::VERSION::MAJOR == 2) && (Redmine::VERSION::MINOR >= 1)) || 4 | (Redmine::VERSION::MAJOR > 2) 5 | ) || (controller.is_a? RbApplicationController) 6 | javascript_include_tag 'jquery/jquery-1.7.2-ui-1.8.21-ujs-2.0.3.js', :plugin => 'redmine_backlogs' 7 | end 8 | %> 9 | <%= javascript_include_tag 'jquery/jquery.verticalfix-min.js', :plugin => 'redmine_backlogs' %> 10 | 13 | <%= javascript_include_tag('jquery/jquery.jqplot/jquery.jqplot.js', 14 | 'jquery/jquery.jqplot/plugins/jqplot.highlighter.js', 15 | 'jquery/jquery.jqplot/plugins/jqplot.canvasTextRenderer.min.js', 16 | 'jquery/jquery.jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js', 17 | 'jquery/jquery.jqplot/plugins/jqplot.enhancedLegendRenderer.min.js', 18 | 'jquery/jquery.jqplot/plugins/jqplot.dateAxisRenderer.min.js', 19 | 'jquery/jquery.cookie.js', 20 | :plugin => 'redmine_backlogs') %> 21 | 22 | <%# render the javascript_include_tags which must come before noConflict %> 23 | <%= controller.rb_jquery_plugins if controller.respond_to?('rb_jquery_plugins') %> 24 | <%# load our framework, it initializes the namespace and jquery.noConflict %> 25 | <%= javascript_include_tag 'common.js', :plugin => 'redmine_backlogs' %> 26 | 30 | <%= javascript_include_tag 'burndown.js', :plugin => 'redmine_backlogs' %> 31 | -------------------------------------------------------------------------------- /app/views/rb_burndown_charts/print.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <%= h @sprint.name %> 3 | <%= call_hook :view_layouts_base_html_head %> 4 | 5 | <% if @sprint.has_burndown? %> 6 | <%= render :partial => 'burndown', :locals => {:sprint => @sprint, :mode => :full, :style => "width: #{@width}px; height: #{@height}px" } %> 7 | <% else %> 8 | No burndown data available -- are the sprint start- and end dates set? 9 | <% end %> 10 | 11 | -------------------------------------------------------------------------------- /app/views/rb_burndown_charts/show.html.erb: -------------------------------------------------------------------------------- 1 | <% if @sprint.has_burndown? %> 2 | print 3 | <%= render :partial => 'burndown', :locals => {:sprint => @sprint, :mode => :full, :style => 'width:650px; height: 300px' } %> 4 | 5 |
6 | <%= l(:label_chart_options) %> 7 | 8 | Legend: 9 | <%- ['Off', 'NW', 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W'].each do |legend| %> 10 |  <%= legend %>   11 | <%- end %>
12 | 13 | <% @sprint.burndown.series.sort{|a, b| l("label_#{a}") <=> l("label_#{b}")}.each do |series| %> 14 | <%= l("label_#{series}") %>
15 | <% end %> 16 |
17 | 20 | <% else %> 21 | No burndown data available -- are the sprint start- and end dates set? 22 | <% end %> 23 | -------------------------------------------------------------------------------- /app/views/rb_master_backlogs/_backlog.html.erb: -------------------------------------------------------------------------------- 1 | <% 2 | # Add special class on sprints shared system wide. Used for enabling DnD. 3 | shared_system = '' 4 | shared_system = 'shared-system-wide' if backlog[:sprint] && backlog[:sprint].sharing=='system' 5 | %> 6 | <% cls = '' unless defined?(cls) %> 7 |
8 |
9 | <%- if backlog[:sprint] %> 10 | <%= render :partial => "rb_sprints/sprint", :object => backlog[:sprint], :locals => {:cls => 'model sprint'} %> 11 | <%- elsif backlog[:release] %> 12 | <%= render :partial => "rb_releases/release_mbp", :object => backlog[:release], :as => :release %> 13 | <%- else %> 14 | <%= render :partial => "productbacklog" %> 15 | <%- end %> 16 |
17 | 20 |
21 | -------------------------------------------------------------------------------- /app/views/rb_master_backlogs/_closedbacklog.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render :partial => "rb_sprints/sprint", :object => closedbacklog[:sprint], :locals => {:cls => 'sprint'} %> 4 |
5 | 8 |
9 | -------------------------------------------------------------------------------- /app/views/rb_master_backlogs/_productbacklog.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
<%=l(:label_product_backlog).titleize %>
5 |
6 |
7 | 8 |
9 | 14 |
15 | 16 |
17 | <%- if User.current.allowed_to?(:manage_versions, @project) %> 18 | <%= link_to l(:label_close_completed_sprints), {:controller => 'rb_sprints', :action => 'close_completed', :project_id => @project}, :class => 'close_sprint', :method => :put %> 19 | <%- end %> 20 |
21 |
22 | 23 |
24 | -------------------------------------------------------------------------------- /app/views/rb_releases/_form.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 | <% rb_labelled_fields_for :release, @release do |f| %> 4 |

5 | <%= f.text_field :name, :required => true %> 6 |

7 |

8 | <%= f.text_area :description, :cols => 60, :rows => 10, :class => 'wiki-edit' %> 9 |

10 |

11 | <%= f.select :status, RbRelease::RELEASE_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %> 12 |

13 | 14 |

15 | <%= f.text_field :release_start_date, :required => true %> 16 | <%= calendar_for('release_release_start_date') %> 17 |

18 |

19 | <%= f.text_field :release_end_date, :required => true %> 20 | <%= calendar_for('release_release_end_date') %> 21 |

22 |

23 | <%= f.text_field :planned_velocity %> 24 |

25 |

26 | <%= f.select :sharing, 27 | @release.allowed_sharings.collect {|v| [ 28 | format_release_sharing(v), 29 | v]} %> 30 |

31 | <% end %> 32 |
33 | -------------------------------------------------------------------------------- /app/views/rb_releases/_release.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= release_link_or_empty(release) %>

3 |

<%= l(:field_release_start_date) %>: <%= release.release_start_date %>

4 |

<%= l(:field_release_end_date) %>: <%= release.release_end_date %>

5 |
6 |
7 | <%= render :partial => "backlogs/model_errors", :object => release.errors unless release.errors.empty? %> 8 |
9 |
10 | -------------------------------------------------------------------------------- /app/views/rb_releases/_release_mbp.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
<%= release_link_or_empty(release) %>
4 |
<%= id_or_empty(release) %>
5 |
6 | 7 |
8 |
9 |
<%= h release.name %>
10 |
11 |
12 | 13 |
14 | 19 |
20 | 21 |
22 |
<%= release.release_start_date || l(:label_no_start) %>
23 |
<%= release.release_end_date || l(:label_no_end) %>
24 |
25 | <%= render :partial => "backlogs/model_errors", :object => release.errors unless release.errors.empty? %> 26 |
27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /app/views/rb_releases/_sprint.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% if version %> 3 |

<%= tag 'a', :name => version.name %><%= link_to_version version %>

4 | <% if version.completed? || version.closed? %> 5 |

<%= format_date(version.effective_date) %>

6 | <% elsif version.effective_date %> 7 |

<%= due_date_distance_in_words(version.effective_date) %> (<%= format_date(version.effective_date) %>)

8 | <% end %> 9 | 10 |

<%=h version.description %>

11 | <% if version.custom_field_values.any? %> 12 | 19 | <% end %> 20 | <% end %> 21 | <%= form_tag({}) do -%> 22 | <% issues.sort!{|a,b|a.position <=> b.position} 23 | sum_points = 0.0 24 | %> 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | <% issues.each do |issue| 34 | klass=issue.closed? ? 'closed':'open' %> 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <% 43 | sum_points = sum_points + issue.story_points.to_f if issue.story_points 44 | end %> 45 | 46 |
#TrackerSubjectStory Points
<%= check_box_tag 'ids[]', issue.id, false, :id => nil %><%= link_to issue.id, {:controller => 'issues', :action => 'show', :id => issue.id} %><%= h tracker_name_or_empty(issue) %><%= issue.subject %><%= story_points_or_empty(issue) %>
<%= sum_points %>
47 | <% end %> 48 |
49 | <%= context_menu issues_context_menu_path %> 50 | -------------------------------------------------------------------------------- /app/views/rb_releases/edit.html.erb: -------------------------------------------------------------------------------- 1 |

<%=l(:label_release)%>

2 | 3 | <% rb_labelled_form_for :release, @release, 4 | :url => {:controller => 'rb_releases', :action => 'edit', :release_id => @release}, 5 | :html => { :method => :post } do |f| %> 6 | <%= error_messages_for 'release' %> 7 | <%= render :partial => 'rb_releases/form', :locals => { :f => f } %> 8 | <%= submit_tag l(:button_save) %> 9 | <% end %> 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/views/rb_releases/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= link_to_if_authorized l(:label_release_new), 3 | {:controller => 'rb_releases', :action => 'new', :project_id => @project}, 4 | :class => 'icon icon-add' %> 5 | <%= link_to_if_authorized l(:label_release_multiview_new), 6 | {:controller => 'rb_releases_multiview', :action => 'new', :project_id => @project}, 7 | :class => 'icon icon-add' %> 8 |
9 | 10 |

<%=l(:label_release_planning)%>

11 | 12 | <% if @releases_open.empty? && @releases_closed.empty? %>

<%= l(:label_no_data) %>

<% end %> 13 | 14 | <% @releases_open.each do |release| %> 15 | <%= render :partial => 'rb_releases/release', :object => release %> 16 | <% end %> 17 | 18 |

<%=l(:label_release_multiview)%>

19 | <% @releases_multiview.each do |multiview| %> 20 | <%= render :partial => 'rb_releases_multiview/release_multiview', :object => multiview %> 21 | <% end %> 22 | 23 |

<%=l(:label_closed_releases)%>

24 | <% @releases_closed.each do |release| %> 25 | <%= render :partial => 'rb_releases/release', :object => release %> 26 | <% end %> 27 | 28 | <% content_for :sidebar do %> 29 |

<%= l(:label_release_plural) %>

30 | <% if @releases_open.empty? %> 31 | no releases 32 | <% elsif @releases_open.size == 1 %> 33 | one release 34 | <% else %> 35 | <%= @releases_open.size %> releases 36 | <% end %> 37 | <% end %> 38 | 39 | <% html_title(l(:label_release_plural)) -%> 40 | -------------------------------------------------------------------------------- /app/views/rb_releases/new.html.erb: -------------------------------------------------------------------------------- 1 |

<%=l(:label_release_new)%>

2 | 3 | <% rb_labelled_form_for @release, :url => url_for(:controller=> 'rb_releases', :action => 'new', :project_id => @project) do |f| %> 4 | <%= error_messages_for 'release' %> 5 | <%= render :partial => 'rb_releases/form', :locals => { :f => f } %> 6 | <%= submit_tag l(:button_create) %> 7 | <% end %> 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/_burnchart.html.erb: -------------------------------------------------------------------------------- 1 |
Generating chart...
2 | 3 | 14 | 15 | 53 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/_form.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 | <% rb_labelled_fields_for :release_multiview, @release_multiview do |f| %> 4 |

5 | <%= f.text_field :name, :required => true %> 6 |

7 |

8 | <%= f.text_area :description, :cols => 60, :rows => 10, :class => 'wiki-edit' %> 9 |

10 |

11 | <%= f.select :release_ids, release_options_for_select(@project.shared_releases, @release_multiview.releases),{}, :multiple => true, :size => 10 %> 12 |

13 | <% end %> 14 |
15 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/_release_multiview.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= release_multiview_link_or_empty(release_multiview) %>

3 |
4 |
5 | <%= render :partial => "backlogs/model_errors", :object => release_multiview.errors unless release_multiview.errors.empty? %> 6 |
7 |
8 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/_releases.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <% releases.each do |r| 8 | klass=r.closed? ? 'closed':'open' %> 9 | 10 | 11 | 12 | 13 | 14 | <% end %> 15 |
Release<%= l(:field_release_start_date) %><%= l(:field_release_end_date) %>
<%= release_link_or_empty(r) %><%= r.release_start_date %><%= r.release_end_date %>
16 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/_releases_estimate.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <% releases.each do |r| 9 | klass=r[:release].closed? ? 'closed':'open' %> 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% end %> 17 |
Release<%= l(:field_release_start_date) %><%= l(:field_release_end_date) %>Estimated end date
<%= release_link_or_empty(r[:release]) %><%= r[:release].release_start_date %><%= r[:release].release_end_date %><%= r[:trend_end_date] %>
18 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/edit.html.erb: -------------------------------------------------------------------------------- 1 |

<%=l(:label_release_multiview)%>

2 | 3 | <% rb_labelled_form_for :release_multiview, @release_multiview, 4 | :url => {:controller => 'rb_releases_multiview', :action => 'edit', :release_multiview_id => @release_multiview}, 5 | :html => { :method => :post } do |f| %> 6 | <%= error_messages_for 'release_multiview' %> 7 | <%= render :partial => 'rb_releases_multiview/form', :locals => { :f => f } %> 8 | <%= submit_tag l(:button_save) %> 9 | <% end %> 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= link_to_if_authorized l(:label_release_new), 3 | {:controller => 'rb_releases', :action => 'new', :project_id => @project}, 4 | :class => 'icon icon-add' %> 5 | <%= link_to_if_authorized l(:label_releases_multi_view_new), 6 | {:controller => 'rb_releases_multi_view', :action => 'new', :project_id => @project}, 7 | :class => 'icon icon-add' %> 8 |
9 | 10 |

<%=l(:label_release_planning)%>

11 | 12 | <% if @releases_open.empty? && @releases_closed.empty? %>

<%= l(:label_no_data) %>

<% end %> 13 | 14 | <% @releases_open.each do |release| %> 15 | <%= render :partial => 'rb_releases/release', :object => release %> 16 | <% end %> 17 | 18 |

<%=l(:label_closed_releases)%>

19 | <% @releases_closed.each do |release| %> 20 | <%= render :partial => 'rb_releases/release', :object => release %> 21 | <% end %> 22 | 23 | <% content_for :sidebar do %> 24 |

<%= l(:label_release_plural) %>

25 | <% if @releases_open.empty? %> 26 | no releases 27 | <% elsif @releases_open.size == 1 %> 28 | one release 29 | <% else %> 30 | <%= @releases_open.size %> releases 31 | <% end %> 32 | <% end %> 33 | 34 | <% html_title(l(:label_release_plural)) -%> 35 | -------------------------------------------------------------------------------- /app/views/rb_releases_multiview/new.html.erb: -------------------------------------------------------------------------------- 1 |

<%=l(:label_release_multiview_new)%>

2 | 3 | <% rb_labelled_form_for @release_multiview, :url => url_for(:controller=>'rb_releases_multiview', :action => 'new', :project_id => @project) do |f| %> 4 | <%= error_messages_for 'release_multiview' %> 5 | <%= render :partial => 'rb_releases_multiview/form', :locals => { :f => f } %> 6 | <%= submit_tag l(:button_create) %> 7 | <% end %> 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/views/rb_sprints/_sprint.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
<%= sprint_link_or_empty(sprint) %>
4 |
<%= id_or_empty(sprint) %>
5 |
6 | 7 |
8 |
9 |
<%= h sprint.name %>
10 |
11 |
12 | 13 |
14 | 19 |
20 | 21 |
22 |
<%= sprint.sprint_start_date || l(:label_no_start) %>
23 |
<%= sprint.effective_date || l(:label_no_end) %>
24 |
<%= h sprint.description %>
25 |
26 | <%= render :partial => "backlogs/model_errors", :object => sprint.errors unless sprint.errors.empty? %> 27 |
28 |
29 |
30 | 31 |
32 | -------------------------------------------------------------------------------- /app/views/rb_stories/_helpers.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | <%- unless Backlogs.setting[:story_points].blank? -%> 9 | 14 | <%- end -%> 15 | 16 | 25 | 26 | 29 | 30 |
31 | <%= render :partial => 'rb_stories/story', :object => RbStory.new %> 32 |
33 | -------------------------------------------------------------------------------- /app/views/rb_stories/_tooltip.html.erb: -------------------------------------------------------------------------------- 1 | <%= I18n.t :field_subject %>: <%=h tooltip.subject %>
2 | <%= I18n.t :field_tracker_id %>: <%=h tooltip.tracker %>
3 | <%= I18n.t :story_status %>: <%=h status_label_or_default(tooltip) %>
4 | <%= I18n.t :field_category %>: <%=h tooltip.category %>
5 | <%= I18n.t :story_points %>: <%=h story_points_or_empty(tooltip) %>
6 | <%= I18n.t :story_estimation_hours %>: <%=h tooltip.estimated_hours %>
7 | <%= I18n.t :story_spent_time %>: <%= tooltip.total_spent_hours.round(2) %>
8 | <%= I18n.t :story_remaining_hours %>: <%=h remaining_hours_or_empty(tooltip) %>
9 | <%= I18n.t :field_assigned_to %>: <%=h assignee_name_or_empty(tooltip) %>
10 | <%= I18n.t :field_project %>: <%=h project_name_or_empty(tooltip) %>
11 | <%= I18n.t :field_release %>: <%=h release_or_empty(tooltip) %>
12 |
<%= textilizable tooltip, :description, :attachments => tooltip.attachments%>
13 | 14 | <%=h custom_fields_or_empty(tooltip) %> 15 | -------------------------------------------------------------------------------- /app/views/rb_tasks/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
<%= date_string_with_milliseconds( (@last_updated.blank? ? Time.parse(params[:after]) : @last_updated.updated_on), 0.001 ) %>
3 | <%= render :partial => "task", :collection => @tasks, :locals => { :include_meta => @include_meta } %> 4 | <%- if @impediments %> 5 | <%= render :partial => "impediment", :collection => @impediments, :locals => { :include_meta => @include_meta }%> 6 | <%- end %> 7 |
8 | -------------------------------------------------------------------------------- /app/views/rb_updated_items/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
<%= date_string_with_milliseconds(@last_update, 0.001) %>
3 |
4 | <%= render :partial => "rb_stories/story", :collection => @items[:stories], 5 | :locals => { :render_higher_item_id => true } %> 6 |
7 |
8 | <%= render :partial => "rb_tasks/task", :collection => @items[:tasks] %> 9 |
10 |
11 | <%= render :partial => "rb_impediments/impediment", :collection => @items[:impediments] %> 12 |
13 |
14 | -------------------------------------------------------------------------------- /assets/images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/images/bg.png -------------------------------------------------------------------------------- /assets/images/bouncer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/images/bouncer.gif -------------------------------------------------------------------------------- /assets/images/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/images/link.png -------------------------------------------------------------------------------- /assets/images/tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/images/tasks.png -------------------------------------------------------------------------------- /assets/javascripts/impediment.js: -------------------------------------------------------------------------------- 1 | /************************************** 2 | IMPEDIMENT 3 | ***************************************/ 4 | 5 | RB.Impediment = RB.Object.create(RB.Task, { 6 | 7 | initialize: function(el){ 8 | var j; // This ensures that we use a local 'j' variable, not a global one. 9 | 10 | this.$ = j = RB.$(el); 11 | this.el = el; 12 | 13 | j.addClass("impediment"); // If node is based on #task_template, it doesn't have the impediment class yet 14 | 15 | // Associate this object with the element for later retrieval 16 | j.data('this', this); 17 | 18 | if (RB.permissions.update_impediments) { 19 | j.delegate('.editable', 'click', this.handleClick); 20 | } 21 | }, 22 | 23 | // Override saveDirectives of RB.Task 24 | saveDirectives: function(){ 25 | var url; 26 | var j = this.$; 27 | var nxt = this.$.next(); 28 | var statusID = j.parents('td').first().attr('id').split("_")[1]; 29 | 30 | var data = j.find('.editor').serialize() + 31 | "&is_impediment=true" + 32 | "&fixed_version_id=" + RB.constants['sprint_id'] + 33 | "&status_id=" + statusID + 34 | "&next=" + (nxt.length==1 ? nxt.data('this').getID() : '') + 35 | (this.isNew() ? "" : "&id=" + j.children('.id').text()); 36 | 37 | if( this.isNew() ){ 38 | url = RB.urlFor('create_impediment'); 39 | } else { 40 | url = RB.urlFor('update_impediment', { id: this.getID() }); 41 | data += "&_method=put"; 42 | } 43 | 44 | return { 45 | url: url, 46 | data: data 47 | }; 48 | } 49 | 50 | }); 51 | -------------------------------------------------------------------------------- /assets/javascripts/issue.js: -------------------------------------------------------------------------------- 1 | /************************************** 2 | ISSUE 3 | ***************************************/ 4 | RB.Issue = RB.Object.create(RB.Model, { 5 | 6 | beforeSaveDragResult: function(){ 7 | // Do nothing 8 | }, 9 | 10 | getType: function(){ 11 | return "Issue"; 12 | }, 13 | 14 | saveDragResult: function(){ 15 | this.beforeSaveDragResult(); 16 | if(!this.$.hasClass('editing')) this.saveEdits(); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.3.0 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function ($, document, undefined) { 9 | 10 | var pluses = /\+/g; 11 | 12 | function raw(s) { 13 | return s; 14 | } 15 | 16 | function decoded(s) { 17 | return decodeURIComponent(s.replace(pluses, ' ')); 18 | } 19 | 20 | var config = $.cookie = function (key, value, options) { 21 | 22 | // write 23 | if (value !== undefined) { 24 | options = $.extend({}, config.defaults, options); 25 | 26 | if (value === null) { 27 | options.expires = -1; 28 | } 29 | 30 | if (typeof options.expires === 'number') { 31 | var days = options.expires, t = options.expires = new Date(); 32 | t.setDate(t.getDate() + days); 33 | } 34 | 35 | value = config.json ? JSON.stringify(value) : String(value); 36 | 37 | return (document.cookie = [ 38 | encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value), 39 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 40 | options.path ? '; path=' + options.path : '', 41 | options.domain ? '; domain=' + options.domain : '', 42 | options.secure ? '; secure' : '' 43 | ].join('')); 44 | } 45 | 46 | // read 47 | var decode = config.raw ? raw : decoded; 48 | var cookies = document.cookie.split('; '); 49 | for (var i = 0, l = cookies.length; i < l; i++) { 50 | var parts = cookies[i].split('='); 51 | if (decode(parts.shift()) === key) { 52 | var cookie = decode(parts.join('=')); 53 | return config.json ? JSON.parse(cookie) : cookie; 54 | } 55 | } 56 | 57 | return null; 58 | }; 59 | 60 | config.defaults = {}; 61 | 62 | $.removeCookie = function (key, options) { 63 | if ($.cookie(key) !== null) { 64 | $.cookie(key, null, options); 65 | return true; 66 | } 67 | return false; 68 | }; 69 | 70 | })(jQuery, document); 71 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Title: MIT License 2 | 3 | Copyright (c) 2009-2011 Chris Leonello 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/background.jpg -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/basicline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/basicline.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/basiclogaxis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/basiclogaxis.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/basiclogoptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/basiclogoptions.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/basicoptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/basicoptions.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/dualaxis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/dualaxis.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/logo.jpg -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdocs.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdocsover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdocsover.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdownload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdownload.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdownloadover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navdownloadover.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navexamples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navexamples.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navexamplesover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navexamplesover.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navhome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navhome.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/navhomeover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/navhomeover.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/new.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/sample3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/sample3.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/files/images/samplesm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/docs/files/images/samplesm.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesA.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesG.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesH.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesJ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesS.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesT.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/ClassesV.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/FunctionsC.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
copy, $.jqplot.ThemeEngine
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/FunctionsI.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
init, jqPlot
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/FunctionsN.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
newTheme, $.jqplot.ThemeEngine
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/FunctionsQ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
quickInit, jqPlot
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/GeneralQ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
quickInit, jqPlot
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/HooksA.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
addLegendRowHooks, $.jqplot.$.jqplot
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/HooksJ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/NoResults.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/search/PropertiesZ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Loading...
zoom, $.jqplot.Cursor
Searching...
No Matches
-------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/docs/styles/main.css: -------------------------------------------------------------------------------- 1 | @import URL("1.css"); 2 | @import URL("2.css"); 3 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/ajax-loader.gif -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/TODO: -------------------------------------------------------------------------------- 1 | Make simple blog page + demo 2 | 3 | Post to... 4 | http://wiki.jqueryui.com/w/page/12137750/ColorPicker 5 | - screenshot 6 | - link(s) 7 | - check specs/requirements and add/fix them 8 | 9 | Colorwheel 10 | Triangle/wheel 11 | Related-colors swatching 12 | Configurable swatch layout 13 | container-width/height, swatch-width/height 14 | Autoscaling (table?) -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar-alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar-alpha.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar-opacity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar-opacity.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar-pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar-pointer.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/bar.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/map-opacity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/map-opacity.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/map-pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/map-pointer.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/map.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/preview-opacity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/preview-opacity.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/ui-colorpicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/colorpicker/images/ui-colorpicker.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/examples.min.css: -------------------------------------------------------------------------------- 1 | body{margin:0;padding:0;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;}div.logo{position:relative;height:94px;padding:0;margin-bottom:30px;top:0;background-image:url('./images/logo.jpg');background-repeat:no-repeat;background-color:#292929;}div.nav{position:relative;top:70px;text-align:right;}a.nav span{font-size:11px;position:relative;bottom:2px;}a.nav:visited{text-decoration:none;border:0;color:#aaa;}a.nav,a.nav:link{border:0;text-decoration:none;font-family:Tahoma,"Helvetica Neue","Trebuchet MS",Verdana,Arial,sans-serif;font-size:16px;color:#aaa;margin-right:11px;}a.nav:hover{text-decoration:none;border:0;color:#E0771C;}a.nav:active{text-decoration:none;border:0;color:#E0771C;}div.example-content{margin:30px 50px;}div.example-nav{margin-bottom:30px;}pre.code-block{background:#D8F4DC;border:1px solid #c8c8c8;padding-top:1em;padding-left:3em;padding-bottom:1em;margin-top:1em;margin-bottom:3em;}pre.code{border:1px solid #c8c8c8;padding-top:1em;padding-left:3em;padding-bottom:1em;margin-top:1em;margin-bottom:4em;}div.include{margin-bottom:2em;}p{margin:2em 0;}.jqplot-image-button{margin-bottom:15px;margin-top:15px;}div.jqplot-image-container{position:relative;z-index:11;margin:auto;display:none;background-color:#fff;border:1px solid #999;display:inline-block;margin-top:25px;}div.jqplot-image-container-header{font-size:1.0em;font-weight:bold;padding:5px 15px;background-color:#eee;}div.jqplot-image-container-content{padding:15px;background-color:#fff;}a.jqplot-image-container-close{float:right;}div.example-plot{width:500px;height:300px;}.jqplot-table-legend-label{white-space:nowrap;}div.syntaxhighlighter{margin-top:4em!important;margin-bottom:3em!important;} -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/images/logo.jpg -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/images/ui-colorpicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/images/ui-colorpicker.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jquery-ui/js/jquery.effects.blind.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI Effects Blind 1.9pre 3 | * 4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * http://jquery.org/license 7 | * 8 | * http://docs.jquery.com/UI/Effects/Blind 9 | * 10 | * Depends: 11 | * jquery.effects.core.js 12 | */ 13 | (function(b){var n=/up|down|vertical/,o=/up|left|vertical|horizontal/;b.effects.effect.blind=function(g,p){var a=b(this),i=["position","top","bottom","left","right","height","width"],l=b.effects.setMode(a,g.mode||"hide"),e=g.direction||"up",f=n.test(e),h=f?"height":"width",m=f?"top":"left";e=o.test(e);var j={},k=l==="show",c,d;a.parent().is(".ui-effects-wrapper")?b.effects.save(a.parent(),i):b.effects.save(a,i);a.show();d=parseInt(a.css("top"),10);c=b.effects.createWrapper(a).css({overflow:"hidden"}); 14 | d=f?c[h]()+d:c[h]();j[h]=k?d:0;if(!e){a.css(f?"bottom":"right",0).css(f?"top":"left","").css({position:"absolute"});j[m]=k?0:d}if(k){c.css(h,0);e||c.css(m,d)}c.animate(j,{duration:g.duration,easing:g.easing,queue:false,complete:function(){l==="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);p()}})}})(jQuery); 15 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/jsondata.txt: -------------------------------------------------------------------------------- 1 | [[1, 3, 2, 4, 6, 9]] -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/kcp_area2.json: -------------------------------------------------------------------------------- 1 | {"rural": [0.9176, 0.9296, 0.927, 0.9251, 0.9241, 0.9225, 0.9197, 0.9164, 0.9131, 0.9098, 0.9064, 0.9028, 0.8991, 0.8957, 0.8925, 0.8896, 0.8869, 0.8844, 0.882, 0.8797, 0.8776, 0.8755, 0.8735, 0.8715, 0.8696, 0.8677, 0.8658, 0.8637, 0.8616, 0.8594, 0.8572, 0.8548, 0.8524, 0.8499, 0.8473, 0.8446, 0.8418, 0.8389, 0.8359, 0.8328, 0.8295, 0.8262, 0.8227, 0.8191, 0.8155, 0.8119, 0.8083, 0.8048, 0.8013, 0.7979, 0.7945, 0.7912, 0.7879, 0.7846, 0.7813, 0.778, 0.7747, 0.7714, 0.768, 0.7647, 0.7612, 0.7577, 0.7538, 0.7496, 0.7449, 0.7398, 0.7342, 0.7279, 0.721, 0.7137, 0.7059, 0.6977, 0.6889, 0.6797, 0.6698, 0.6593, 0.6482, 0.6367, 0.6247, 0.6121, 0.5989, 0.5852, 0.571, 0.5561, 0.5402, 0.5232, 0.505, 0.4855, 0.4643, 0.4414, 0.4166, 0.3893, 0.3577, 0.3204, 0.2764, 0.2272, 0.1774, 0.1231, 0.0855, 0.0849], 2 | "urban": [0.0824, 0.0704, 0.073, 0.0749, 0.0759, 0.0775, 0.0803, 0.0836, 0.0869, 0.0902, 0.0936, 0.0972, 0.1009, 0.1043, 0.1075, 0.1104, 0.1131, 0.1156, 0.118, 0.1203, 0.1224, 0.1245, 0.1265, 0.1285, 0.1304, 0.1323, 0.1342, 0.1363, 0.1384, 0.1406, 0.1428, 0.1452, 0.1476, 0.1501, 0.1527, 0.1554, 0.1582, 0.1611, 0.1641, 0.1672, 0.1705, 0.1738, 0.1773, 0.1809, 0.1845, 0.1881, 0.1917, 0.1952, 0.1987, 0.2021, 0.2055, 0.2088, 0.2121, 0.2154, 0.2187, 0.222, 0.2253, 0.2286, 0.232, 0.2353, 0.2388, 0.2423, 0.2462, 0.2504, 0.2551, 0.2602, 0.2658, 0.2721, 0.279, 0.2863, 0.2941, 0.3023, 0.3111, 0.3203, 0.3302, 0.3407, 0.3518, 0.3633, 0.3753, 0.3879, 0.4011, 0.4148, 0.429, 0.4439, 0.4598, 0.4768, 0.495, 0.5145, 0.5357, 0.5586, 0.5834, 0.6107, 0.6423, 0.6796, 0.7236, 0.7728, 0.8226, 0.8769, 0.9145, 0.9151]} -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/nav.inc: -------------------------------------------------------------------------------- 1 |
2 | Previous Examples Next'; 38 | 39 | ?> 40 |
41 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/syntaxhighlighter/MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003, 2004 Jim Weirich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/syntaxhighlighter/scripts/shAutoloader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(2(){1 h=5;h.I=2(){2 n(c,a){4(1 d=0;d35?String.fromCharCode(a+29):a.toString(36))};if(!"".replace(/^/,String)){while(j--){i[g(j)]=f[j]||g(j)}f=[function(a){return i[a]}];g=function(){return"\\w+"};j=1}while(j--){if(f[j]){h=h.replace(new RegExp("\\b"+g(j)+"\\b","g"),f[j])}}return h}('(2(){1 h=5;h.I=2(){2 n(c,a){4(1 d=0;d[:\\w-\\.]+)","xg").exec(i),c=[];if(f.attributes!=null){var e,h=new XRegExp("(? [\\w:\\-\\.]+)\\s*=\\s*(? \".*?\"|'.*?'|\\w+)","xg");while((e=h.exec(i))!=null){c.push(new g(e.name,f.index+e.index,"color1"));c.push(new g(e.value,f.index+e.index+e[0].indexOf(e.value),"string"))}}if(d!=null){c.push(new g(d.name,f.index+d[0].indexOf(d.name),"keyword"))}return c}this.regexList=[{regex:new XRegExp("(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)","gm"),css:"color2"},{regex:SyntaxHighlighter.regexLib.xmlComments,css:"comments"},{regex:new XRegExp("(<|<)[\\s\\/\\?]*(\\w+)(?.*?)[\\s\\/\\?]*(>|>)","sg"),func:b}]}a.prototype=new SyntaxHighlighter.Highlighter();a.aliases=["xml","xhtml","xslt","html"];SyntaxHighlighter.brushes.Xml=a;typeof(exports)!="undefined"?exports.Brush=a:null})(); -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.jqplot/examples/topbanner.inc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.liveFilter.js: -------------------------------------------------------------------------------- 1 | /***********************************************************/ 2 | /* LiveFilter Plugin */ 3 | /* Version: 1.2 */ 4 | /* Mike Merritt */ 5 | /* Updated: Apr 15th, 2010 */ 6 | /***********************************************************/ 7 | 8 | (function($){ 9 | $.fn.liveFilter = function (aType) { 10 | 11 | // Determine what we are going to be filtering. 12 | var filterTarget = $(this); 13 | var child; 14 | if ($(this).is('ul')) { 15 | child = 'li'; 16 | } else if ($(this).is('ol')) { 17 | child = 'li'; 18 | } else if ($(this).is('table')) { 19 | child = 'tbody tr'; 20 | } 21 | 22 | // Declare variables 23 | var hide; 24 | var show; 25 | var filter; 26 | 27 | var getPlaceholder = function() { 28 | 29 | } 30 | 31 | 32 | // Input element event 33 | $('input.filter').keyup(function() { 34 | 35 | // Grab the filter value 36 | filter = $(this).val(); 37 | 38 | // Grab the ones we need to hide and the ones we need to show 39 | hide = $(filterTarget).find(child + ':not(:Contains("' + filter + '"))'); 40 | show = $(filterTarget).find(child + ':Contains("' + filter + '")') 41 | 42 | // Animate the items we are hiding and showing 43 | if ( aType == 'basic' ) { 44 | hide.hide(); 45 | show.show(); 46 | } else if ( aType == 'slide' ) { 47 | hide.slideUp(500); 48 | show.slideDown(500); 49 | } else if ( aType == 'fade' ) { 50 | hide.fadeOut(400); 51 | show.fadeIn(400); 52 | } 53 | 54 | }); 55 | 56 | // Custom expression for case insensitive contains() 57 | $.expr[':'].Contains = function(a,i,m){ 58 | return $(a).text().toLowerCase().indexOf(m[3].toLowerCase())>=0; 59 | }; 60 | 61 | } 62 | 63 | })(jQuery); 64 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.liveFilter.setup.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | $('ul.stories').liveFilter('basic'); 3 | }); 4 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.qtip.setup.js: -------------------------------------------------------------------------------- 1 | $.qtipMakeOptions = function(container, ajax) { 2 | var options = { 3 | content: { 4 | text: container.children('div.tooltip_text') 5 | }, 6 | position: { 7 | my: 'top left', 8 | target: 'mouse', 9 | viewport: RB.$(window), // Keep it on-screen at all times if possible 10 | adjust: { 11 | x: 10, y: 10 12 | } 13 | }, 14 | hide: { 15 | fixed: true // Helps to prevent the tooltip from hiding ocassionally when tracking! 16 | } 17 | }; 18 | if (ajax) { 19 | var id = container.children('.id .v').text(); 20 | options['content'] = { 21 | text: '
Loading...
', 22 | ajax: { 23 | url: RB.urlFor('show_tooltip', {id: id}), 24 | type: 'GET', 25 | data: { project_id: RB.constants.project_id }, //to satisfy before_filter and authorize 26 | once: true 27 | } 28 | }; 29 | } 30 | return options; 31 | } 32 | 33 | $(function($) { 34 | RB.util.initToolTip(); 35 | }); 36 | -------------------------------------------------------------------------------- /assets/javascripts/jquery/jquery.verticalfix-min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.verticalfix.js 3 | * Copyright (c) 2013 redmine backlogs 4 | * 5 | * based on jquery.scrollfollow.js Copyright (c) 2008 Net Perspective (http://kitchen.net-perspective.com/) 6 | * original author R.A. Ray 7 | * Licensed under the MIT License (http://www.opensource.org/licenses/mit-license.php) 8 | * 9 | * @author Patrick Atamaniuk 10 | * 11 | * @projectDescription jQuery plugin for vertically anchor an element as the user scrolls the page. 12 | * 13 | * @version 1.0.0 14 | * 15 | * @requires jquery.js (tested with 1.7) 16 | * 17 | * @param delay int - Time between the scroll and the beginning of the fixup in milliseconds 18 | * default: 0 19 | */(function(a){a.verticalFix=function(b,c){function d(){var c=parseInt(a(document).scrollTop());b.initialOffsetTop>=c?(b.css("position","absolute"),b.css("top",b.initialTop),b.css("left",0)):(b.css("position","fixed"),b.css("top",0),b.css({left:b.containerLeft-a(document).scrollLeft()}))}b=a(b),b.cont=b.parent(),b.initialOffsetTop=parseInt(b.offset().top),b.initialTop=parseInt(b.css("top"))||0,b.containerLeft=b.cont.position().left||0,a(window).scroll(function(){a.fn.verticalFix.interval=setTimeout(function(){d()},c.delay)}),a(window).resize(function(){a.fn.verticalFix.interval=setTimeout(function(){d()},c.delay)}),d()},a.fn.verticalFix=function(b){return b=b||{},b.delay=b.delay||0,this.each(function(){new a.verticalFix(this,b)}),this}})(jQuery); -------------------------------------------------------------------------------- /assets/javascripts/master_backlog.js: -------------------------------------------------------------------------------- 1 | // Initialize the backlogs after DOM is loaded 2 | RB.$(function() { 3 | // Initialize each backlog 4 | RB.BacklogOptionsInstance = RB.Factory.initialize(RB.BacklogOptions, this); 5 | RB.Factory.initialize(RB.BacklogMultilineBtn, RB.$('#multiline')); 6 | RB.$('.backlog').each(function(index){ 7 | RB.Factory.initialize(RB.Backlog, this); 8 | }); 9 | // RB.$("#project_info").bind('click', function(){ RB.$("#velocity").dialog({ modal: true, title: "Project Info"}); }); 10 | RB.BacklogsUpdater.start(); 11 | 12 | // Workaround for IE7 13 | if(RB.$.browser.msie && RB.$.browser.version <= 7){ 14 | var z = 2000; 15 | RB.$('.backlog, .header').each(function(){ 16 | RB.$(this).css('z-index', z); 17 | z--; 18 | }); 19 | } 20 | 21 | // hold down alt when clicking an issue id to open it in the current tab 22 | RB.$('#backlogs_container').delegate('li.story > .id a', 'click', function(e) { 23 | if (e.shiftKey) { 24 | location.href = this.href; 25 | return false; 26 | } 27 | }); 28 | 29 | // show closed sprints 30 | RB.$('#show_completed_sprints').click(function(e) { 31 | e.preventDefault(); 32 | RB.$('#closed_sprint_backlogs_container'). 33 | html('Loading...'). 34 | show(). 35 | load(RB.routes.closed_sprints, function(){ //success callback 36 | var csbc = RB.$('#closed_sprint_backlogs_container'); 37 | if (!RB.$.trim(csbc.html())) csbc.html(RB.constants.locale._('No data to show')); 38 | else RB.util.initToolTip(); //refreshToolTip requires a model scope. 39 | }); 40 | RB.$('#show_completed_sprints').hide(); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /assets/javascripts/release.js: -------------------------------------------------------------------------------- 1 | /*************************************** 2 | RELEASE 3 | ***************************************/ 4 | 5 | RB.Release = RB.Object.create(RB.Sprint, { 6 | update_permission: 'update_releases', 7 | create_url: 'create_release', 8 | update_url: 'update_release', 9 | 10 | getType: function(){ 11 | return "Release"; 12 | }, 13 | 14 | editorDisplayed: function(editor){ 15 | var name = editor.find('.name.editor'); 16 | name.width(Math.max(300, parseInt(name.attr('_rb_width'), 10))); 17 | var d = new Date(); 18 | var now, start, end; 19 | start = editor.find('.release_start_date.editor'); 20 | if (start.val()=='no start') { 21 | now = RB.$.datepicker.formatDate('yy-mm-dd', new Date()); 22 | start.val(now); 23 | } 24 | end = editor.find('.end_date.editor'); 25 | if (end.val()=='no end') { 26 | now = new Date(); 27 | now.setDate(now.getDate() + 14); 28 | now = RB.$.datepicker.formatDate('yy-mm-dd', now); 29 | end.val(now); 30 | } 31 | } 32 | }); 33 | -------------------------------------------------------------------------------- /assets/javascripts/taskboard_updater.js: -------------------------------------------------------------------------------- 1 | RB.TaskboardUpdater = RB.Object.create(RB.BoardUpdater, { 2 | 3 | processAllItems: function(data){ 4 | var self = this; 5 | 6 | // Process tasks 7 | var items = RB.$(data).find('.task'); 8 | items.each(function(i, v){ 9 | try { 10 | self.processItem(v, false); 11 | } catch(e) {} 12 | }); 13 | 14 | // Process impediments 15 | items = RB.$(data).find('.impediment'); 16 | items.each(function(i, v){ 17 | try { 18 | self.processItem(v, true); 19 | } catch(e) {} 20 | }); 21 | }, 22 | 23 | processItem: function(html, isImpediment){ 24 | var update = RB.Factory.initialize(isImpediment ? RB.Impediment : RB.Task, html); 25 | var target; 26 | var oldCellID = ''; 27 | var newCell; 28 | var idPrefix = '#issue_'; 29 | 30 | if(RB.$(idPrefix + update.getID()).length===0){ 31 | target = update; // Create a new item 32 | } else { 33 | target = RB.$(idPrefix + update.getID()).data('this'); // Re-use existing item 34 | target.refresh(update); 35 | oldCellID = target.$.parents('td').first().attr('id'); 36 | } 37 | 38 | // Find the correct cell for the item 39 | newCell = isImpediment ? RB.$('#impcell_' + target.$.find('.meta .status_id').text()) : RB.$('#' + target.$.find('.meta .story_id').text() + '_' + target.$.find('.meta .status_id').text()); 40 | 41 | // Prepend to the cell if it's not already there 42 | if(oldCellID != newCell.attr('id')){ 43 | newCell.prepend(target.$); 44 | } 45 | 46 | //update tooltip 47 | RB.util.refreshToolTip(target); 48 | 49 | target.$.effect("highlight", { easing: 'easeInExpo' }, 4000); 50 | }, 51 | 52 | start: function(){ 53 | this.params = 'only=tasks,impediments&sprint='+RB.constants.sprint_id; 54 | this.initialize(); 55 | } 56 | 57 | }); 58 | -------------------------------------------------------------------------------- /assets/stylesheets/global_print.css: -------------------------------------------------------------------------------- 1 | #toolbar .links{ 2 | display:none !important; 3 | } 4 | .add_new { 5 | display: none; 6 | } 7 | .breadcrumbs select { 8 | display: none; 9 | } -------------------------------------------------------------------------------- /assets/stylesheets/images/ajax.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ajax.gif -------------------------------------------------------------------------------- /assets/stylesheets/images/bouncer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/bouncer.gif -------------------------------------------------------------------------------- /assets/stylesheets/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/error.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ika_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ika_bg.png -------------------------------------------------------------------------------- /assets/stylesheets/images/indicator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/indicator.gif -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /assets/stylesheets/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /assets/stylesheets/images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/images/warning.png -------------------------------------------------------------------------------- /assets/stylesheets/jquery/jquery.multiselect.css: -------------------------------------------------------------------------------- 1 | .ui-multiselect { padding:2px 0 2px 4px; text-align:left } 2 | .ui-multiselect span.ui-icon { float:right } 3 | .ui-multiselect-single .ui-multiselect-checkboxes input { position:absolute !important; top: auto !important; left:-9999px; } 4 | .ui-multiselect-single .ui-multiselect-checkboxes label { padding:5px !important } 5 | 6 | .ui-multiselect-header { margin-bottom:3px; padding:3px 0 3px 4px } 7 | .ui-multiselect-header ul { font-size:0.9em } 8 | .ui-multiselect-header ul li { float:left; padding:0 10px 0 0 } 9 | .ui-multiselect-header a { text-decoration:none } 10 | .ui-multiselect-header a:hover { text-decoration:underline } 11 | .ui-multiselect-header span.ui-icon { float:left } 12 | .ui-multiselect-header li.ui-multiselect-close { float:right; text-align:right; padding-right:0 } 13 | 14 | .ui-multiselect-menu { display:none; padding:3px; position:absolute; z-index:10000; text-align: left } 15 | .ui-multiselect-checkboxes { position:relative /* fixes bug in IE6/7 */; overflow-y:scroll } 16 | .ui-multiselect-checkboxes label { cursor:default; display:block; border:1px solid transparent; padding:3px 1px } 17 | .ui-multiselect-checkboxes label input { position:relative; top:1px } 18 | .ui-multiselect-checkboxes li { clear:both; font-size:0.9em; padding-right:3px } 19 | .ui-multiselect-checkboxes li.ui-multiselect-optgroup-label { text-align:center; font-weight:bold; border-bottom:1px solid } 20 | .ui-multiselect-checkboxes li.ui-multiselect-optgroup-label a { display:block; padding:3px; margin:1px 0; text-decoration:none } 21 | 22 | /* remove label borders in IE6 because IE6 does not support transparency */ 23 | * html .ui-multiselect-checkboxes label { border:none } 24 | -------------------------------------------------------------------------------- /assets/stylesheets/jquery/jquery.multiselect.filter.css: -------------------------------------------------------------------------------- 1 | .ui-multiselect-hasfilter ul { position:relative; top:2px } 2 | .ui-multiselect-filter { float:left; margin-right:10px; font-size:11px } 3 | .ui-multiselect-filter input { width:100px; font-size:10px; margin-left:5px; height:15px; padding:2px; border:1px solid #292929; -webkit-appearance:textfield; -webkit-box-sizing:content-box; } 4 | -------------------------------------------------------------------------------- /assets/stylesheets/master_backlog_print.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/master_backlog_print.css -------------------------------------------------------------------------------- /assets/stylesheets/statistics.css: -------------------------------------------------------------------------------- 1 | .score { text-align: center; width: 1.5em; font-size: large; display: inline-block; } 2 | .score_0 { background-color: #FF0000; } 3 | .score_1 { background-color: #FF5300; } 4 | .score_2 { background-color: #FF8100; } 5 | .score_3 { background-color: #FFA100; } 6 | .score_4 { background-color: #FFBB00; } 7 | .score_5 { background-color: #FFD300; } 8 | .score_6 { background-color: #FFEC00; } 9 | .score_7 { background-color: #E9FB00; } 10 | .score_8 { background-color: #B1F100; } 11 | .score_9 { background-color: #74E600; } 12 | .score_10 { background-color: #00CC00; } 13 | -------------------------------------------------------------------------------- /assets/stylesheets/taskboard_print.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/assets/stylesheets/taskboard_print.css -------------------------------------------------------------------------------- /config/database.yml.travis: -------------------------------------------------------------------------------- 1 | sqlite: &sqlite 2 | adapter: sqlite3 3 | database: db/backlogs.sqlite3 4 | 5 | mysql: &mysql 6 | adapter: <%= ENV['TRAVIS_RUBY_VERSION'] == '1.8.7' ? 'mysql' : 'mysql2' %> 7 | username: root 8 | password: 9 | database: backlogs 10 | 11 | postgresql: &postgresql 12 | adapter: postgresql 13 | username: postgres 14 | password: 15 | database: backlogs 16 | min_messages: ERROR 17 | 18 | defaults: &defaults 19 | pool: 5 20 | timeout: 5000 21 | <<: *<%= ENV['DB'] || "unspecified" %> 22 | 23 | development: 24 | <<: *defaults 25 | 26 | test: 27 | <<: *defaults 28 | 29 | production: 30 | <<: *defaults 31 | -------------------------------------------------------------------------------- /db/migrate/011_create_stories_tasks_sprints_and_burndown.rb: -------------------------------------------------------------------------------- 1 | class CreateStoriesTasksSprintsAndBurndown < ActiveRecord::Migration 2 | def self.up 3 | add_column :issues, :position, :integer 4 | add_column :issues, :story_points, :integer 5 | add_column :issues, :remaining_hours, :float 6 | 7 | add_column :versions, :sprint_start_date, :date, :null => true 8 | 9 | create_table :burndown_days do |t| 10 | t.column :points_committed, :integer, :null => false, :default => 0 11 | t.column :points_accepted, :integer, :null => false, :default => 0 12 | t.column :points_resolved, :integer, :null => false, :default => 0 13 | t.column :remaining_hours, :float, :null => false, :default => 0 14 | 15 | t.column :version_id, :integer, :null => false 16 | t.timestamps 17 | end 18 | 19 | add_index :burndown_days, :version_id 20 | 21 | # RM core started needing this... I'm not agreeing, but I need to 22 | # get the migration working 23 | execute "update issues set start_date = NULL where due_date < start_date" 24 | end 25 | 26 | def self.down 27 | remove_column :issues, :position 28 | remove_column :issues, :story_points 29 | remove_column :issues, :remaining_hours 30 | 31 | remove_column :versions, :sprint_start_date 32 | 33 | remove_index :burndown_days, :version_id 34 | drop_table :burndown_days 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /db/migrate/015_order_tasks_using_tree.rb: -------------------------------------------------------------------------------- 1 | class OrderTasksUsingTree < ActiveRecord::Migration 2 | def self.up 3 | unless ActiveRecord::Base.connection.table_exists?('rb_issue_history') 4 | create_table :rb_issue_history do |t| 5 | t.column :issue_id, :integer, :default => 0, :null => false 6 | t.text :history 7 | end 8 | add_index :rb_issue_history, :issue_id, :unique => true 9 | end 10 | 11 | unless ActiveRecord::Base.connection.table_exists?('rb_sprint_burndown') 12 | create_table :rb_sprint_burndown do |t| 13 | t.column :version_id, :integer, :default => 0, :null => false 14 | t.text :stories 15 | t.text :burndown 16 | t.timestamps 17 | end 18 | add_index :rb_sprint_burndown, :version_id, :unique => true 19 | end 20 | 21 | last_task = {} 22 | if RbTask.tracker 23 | ActiveRecord::Base.transaction do 24 | RbTask.find(:all, :conditions => ["tracker_id = ?", RbTask.tracker], :order => "project_id ASC, parent_id ASC, position ASC").each do |t| 25 | begin 26 | t.move_after last_task[t.parent_id] if last_task[t.parent_id] 27 | rescue 28 | # nested tasks break this migrations. Task order not that 29 | # big a deal, proceed 30 | end 31 | 32 | last_task[t.parent_id] = t.id 33 | end 34 | end 35 | end 36 | end 37 | 38 | def self.down 39 | puts "Reverting irreversible migration" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /db/migrate/017_change_issue_position_column.rb: -------------------------------------------------------------------------------- 1 | class ChangeIssuePositionColumn < ActiveRecord::Migration 2 | def self.up 3 | change_column :issues, :position, :integer, :null => true, :default => nil 4 | end 5 | 6 | def self.down 7 | puts "Can't disable null positions" 8 | # change_column :issues, :position, :integer, :null => false 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/019_add_release_tables.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseTables < ActiveRecord::Migration 2 | def self.up 3 | create_table :releases do |t| 4 | t.column :name, :string, :null => false 5 | t.column :release_start_date, :date, :null => false 6 | t.column :release_end_date, :date, :null => false 7 | t.column :initial_story_points, :integer, :null => true 8 | t.column :project_id, :integer, :null => false 9 | t.timestamps 10 | end 11 | 12 | create_table :release_burndown_days do |t| 13 | t.column :release_id, :integer, :null => false 14 | t.column :day, :date, :null => false 15 | t.column :remaining_story_points, :integer, :null => false 16 | t.timestamps 17 | end 18 | end 19 | 20 | def self.down 21 | drop_table :releases 22 | if ActiveRecord::Base.connection.table_exists?('release_burndown_days') 23 | drop_table :release_burndown_days 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /db/migrate/023_null_task_position.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | 3 | class NullTaskPosition < ActiveRecord::Migration 4 | def self.up 5 | if RbTask.tracker 6 | execute "update issues set position = null where tracker_id = #{RbTask.tracker}" 7 | end 8 | 9 | if RbTask.tracker && RbStory.trackers.size > 0 10 | create_table :backlogs_tmp_set_task_tracker do |t| 11 | t.column :story_root_id, :integer, :null => false 12 | t.column :story_lft, :integer, :null => false 13 | t.column :story_rgt, :integer, :null => false 14 | end 15 | 16 | execute "insert into backlogs_tmp_set_task_tracker (story_root_id, story_lft, story_rgt) 17 | select root_id, lft, rgt from issues where tracker_id in (#{RbStory.trackers(:type=>:string)})" 18 | 19 | execute "update issues set tracker_id = #{RbTask.tracker} 20 | where exists (select 1 from backlogs_tmp_set_task_tracker where root_id = story_root_id and lft > story_lft and rgt < story_rgt)" 21 | 22 | drop_table :backlogs_tmp_set_task_tracker 23 | end 24 | end 25 | 26 | def self.down 27 | puts "Reverting irreversible migration" 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /db/migrate/025_fractional_points.rb: -------------------------------------------------------------------------------- 1 | class FractionalPoints < ActiveRecord::Migration 2 | def self.up 3 | add_column :issues, :fractional_story_points, :float 4 | execute "update issues set fractional_story_points = story_points" 5 | remove_column :issues, :story_points 6 | 7 | add_column :issues, :story_points, :float 8 | execute "update issues set story_points = fractional_story_points" 9 | remove_column :issues, :fractional_story_points 10 | end 11 | 12 | def self.down 13 | puts "Reverting irreversible migration" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/026_add_story_positions.rb: -------------------------------------------------------------------------------- 1 | class AddStoryPositions < ActiveRecord::Migration 2 | def self.up 3 | # Rails doesn't support temp tables, mysql doesn't support update 4 | # from same-table subselect 5 | 6 | unless RbStory.trackers.size == 0 7 | max = 0 8 | execute("select max(position) from issues").each{|row| max = row[0]} 9 | 10 | execute "update issues 11 | set position = #{max} + id 12 | where position is null and tracker_id in (#{RbStory.trackers(:type=>:string)})" 13 | end 14 | end 15 | 16 | def self.down 17 | puts "Reverting irreversible migration" 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/027_add_index_on_issues_position.rb: -------------------------------------------------------------------------------- 1 | class AddIndexOnIssuesPosition < ActiveRecord::Migration 2 | def self.up 3 | add_index :issues, :position 4 | end 5 | 6 | def self.down 7 | remove_index :issues, :position 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/029_sum_remaining_hours.rb: -------------------------------------------------------------------------------- 1 | class SumRemainingHours < ActiveRecord::Migration 2 | def self.up 3 | unless RbStory.trackers == [] 4 | create_table :backlogs_tmp_story_remaining_hours do |t| 5 | t.column :tmp_id, :integer, :null => false 6 | t.column :tmp_root_id, :integer, :null => false 7 | t.column :tmp_lft, :integer, :null => false 8 | t.column :tmp_rgt, :integer, :null => false 9 | t.column :tmp_remaining_hours, :float, :null => false 10 | end 11 | 12 | 13 | # non-leaf stories 14 | execute "insert into backlogs_tmp_story_remaining_hours (tmp_id, tmp_root_id, tmp_lft, tmp_rgt, tmp_remaining_hours) 15 | select id, root_id, lft, rgt, 0 16 | from issues 17 | where tracker_id in (#{RbStory.trackers(:type=>:string)}) and lft <> (rgt - 1)" 18 | 19 | # tasks below these stories 20 | execute "insert into backlogs_tmp_story_remaining_hours (tmp_id, tmp_root_id, tmp_lft, tmp_rgt, tmp_remaining_hours) 21 | select issues.id, root_id, lft, rgt, coalesce(remaining_hours, 0) 22 | from backlogs_tmp_story_remaining_hours 23 | join issues on tmp_root_id = root_id and lft > tmp_lft and rgt < tmp_rgt" 24 | 25 | # update non-leaf-tasks below non-leaf stories and set their remaining_hours to the sum of their leaf-tasks 26 | execute "update issues 27 | set remaining_hours = ( 28 | select sum(tmp_remaining_hours) 29 | from backlogs_tmp_story_remaining_hours 30 | where root_id = tmp_root_id and lft < tmp_lft and rgt > tmp_rgt and tmp_lft = (tmp_rgt - 1) 31 | ) 32 | where lft <> (rgt - 1) and id in (select tmp_id from backlogs_tmp_story_remaining_hours)" 33 | 34 | drop_table :backlogs_tmp_story_remaining_hours 35 | end 36 | end 37 | 38 | def self.down 39 | #pass 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /db/migrate/033_unique_positions.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | 3 | class UniquePositions < ActiveRecord::Migration 4 | def self.up 5 | unless ActiveRecord::Base.connection.table_exists?('rb_issue_history') 6 | create_table :rb_issue_history do |t| 7 | t.column :issue_id, :integer, :default => 0, :null => false 8 | t.text :history 9 | end 10 | add_index :rb_issue_history, :issue_id, :unique => true 11 | end 12 | 13 | unless ActiveRecord::Base.connection.table_exists?('rb_sprint_burndown') 14 | create_table :rb_sprint_burndown do |t| 15 | t.column :version_id, :integer, :default => 0, :null => false 16 | t.text :stories 17 | t.text :burndown 18 | t.timestamps 19 | end 20 | add_index :rb_sprint_burndown, :version_id, :unique => true 21 | end 22 | 23 | RbStory.transaction do 24 | ids = RbStory.connection.select_values('select id from issues order by position') 25 | ids.each_with_index{|id, i| 26 | RbStory.connection.execute("update issues set position = #{i * RbStory.list_spacing} where id = #{id}") 27 | } 28 | end 29 | 30 | change_column :issues, :position, :integer, :null => false 31 | 32 | # Needed until MySQL undoes the retardation that is http://bugs.mysql.com/bug.php?id=5573 33 | add_column :issues, :position_lock, :integer, :null=>false, :default => 0 34 | add_index :issues, [:position, :position_lock], :unique => true 35 | end 36 | 37 | def self.down 38 | remove_index :issues, [:position, :position_lock] 39 | remove_column :issues, :position_lock 40 | change_column :issues, :position, :integer, :null => true 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /db/migrate/036_trust_unique_positions.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | 3 | class TrustUniquePositions < ActiveRecord::Migration 4 | def self.up 5 | # Needed until MySQL undoes the retardation that is http://bugs.mysql.com/bug.php?id=5573 6 | remove_index :issues, [:position, :position_lock] 7 | remove_column :issues, :position_lock 8 | end 9 | 10 | def self.down 11 | add_column :issues, :position_lock, :integer 12 | add_index :issues, [:position, :position_lock] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/037_add_rb_project_settings.rb: -------------------------------------------------------------------------------- 1 | class AddRbProjectSettings < ActiveRecord::Migration 2 | def self.up 3 | create_table :rb_project_settings do |t| 4 | t.references :project 5 | t.boolean :show_stories_from_subprojects, :default => true, :null => false 6 | end 7 | end 8 | 9 | def self.down 10 | drop_table :rb_project_settings 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /db/migrate/038_rb_add_history.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | require 'yaml' 3 | 4 | class RbAddHistory < ActiveRecord::Migration 5 | def self.up 6 | #drop_table :rb_journals if ActiveRecord::Base.connection.table_exists?('rb_journals') 7 | 8 | unless ActiveRecord::Base.connection.table_exists?('rb_issue_history') 9 | create_table :rb_issue_history do |t| 10 | t.column :issue_id, :integer, :default => 0, :null => false 11 | t.text :history 12 | end 13 | add_index :rb_issue_history, :issue_id, :unique => true 14 | end 15 | 16 | unless ActiveRecord::Base.connection.table_exists?('rb_sprint_burndown') 17 | create_table :rb_sprint_burndown do |t| 18 | t.column :version_id, :integer, :default => 0, :null => false 19 | t.text :stories 20 | t.text :burndown 21 | t.timestamps 22 | end 23 | add_index :rb_sprint_burndown, :version_id, :unique => true 24 | end 25 | 26 | #migration 40 wants to add release-issue relation. issue_history tracks this, so the relation needs to be there before a history migration is performed 27 | unless ActiveRecord::Base.connection.column_exists?(:issues, :release_id) 28 | add_column :issues, :release_id, :integer 29 | end 30 | 31 | if ENV['rbl_migration_ignore_historic_history'] =~ /^yes$/i 32 | puts "You have chosen to ignore the existing history and to start anew. Fine by me, but it will take a while for the charts to become meaningful. DO NOT POST ISSUES ABOUT THE CHARTS BEING WRONG until you have at least 5 sprints of data since this installation." 33 | else 34 | puts "Rebuilding history..." 35 | RbIssueHistory.rebuild 36 | puts "Rebuild done" 37 | end 38 | end 39 | 40 | def self.down 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /db/migrate/039_add_show_in_scrum_stats_project_setting.rb: -------------------------------------------------------------------------------- 1 | class AddShowInScrumStatsProjectSetting < ActiveRecord::Migration 2 | def self.up 3 | add_column :rb_project_settings, :show_in_scrum_stats, :boolean, {:default => true, :null => false} 4 | end 5 | 6 | def self.down 7 | remove_column :rb_project_settings, :show_in_scrum_stats 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /db/migrate/040_add_release_id_to_issues.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseIdToIssues < ActiveRecord::Migration 2 | def self.up 3 | unless ActiveRecord::Base.connection.column_exists?(:issues, :release_id) 4 | add_column :issues, :release_id, :integer 5 | end 6 | end 7 | 8 | def self.down 9 | remove_column :issues, :release_id 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/041_add_sharing_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddSharingToReleases < ActiveRecord::Migration 2 | def self.up 3 | add_column :releases, :sharing, :string, :default => 'none', :null => false 4 | add_index :releases, :sharing 5 | end 6 | 7 | def self.down 8 | remove_column :releases, :sharing 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/042_migrate_releases.rb: -------------------------------------------------------------------------------- 1 | class MigrateReleases < ActiveRecord::Migration 2 | def self.up 3 | add_column :releases, :status, :string, :null => false, :default => 'open' 4 | add_column :releases, :description, :text 5 | 6 | puts "Migrating implicit releases..." 7 | RbRelease.integrate_implicit_stories 8 | puts "Migration of implicit releases done." 9 | end 10 | 11 | def self.down 12 | remove_columns :releases, :status 13 | remove_columns :releases, :description 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/043_add_releases_planned_velocity.rb: -------------------------------------------------------------------------------- 1 | class AddReleasesPlannedVelocity < ActiveRecord::Migration 2 | def self.up 3 | add_column :releases, :planned_velocity, :float 4 | end 5 | 6 | def self.down 7 | remove_columns :releases, :planned_velocity 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/044_add_release_relationship_to_issues.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseRelationshipToIssues < ActiveRecord::Migration 2 | def self.up 3 | add_column :issues, :release_relationship, :string, :default => 'auto', :null => false 4 | end 5 | 6 | def self.down 7 | remove_column :issues, :release_relationship 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/045_drop_release_burndown_days.rb: -------------------------------------------------------------------------------- 1 | class DropReleaseBurndownDays < ActiveRecord::Migration 2 | def self.up 3 | if ActiveRecord::Base.connection.table_exists?('release_burndown_days') 4 | drop_table :release_burndown_days 5 | end 6 | remove_column :releases, :initial_story_points 7 | end 8 | 9 | def self.down 10 | create_table :release_burndown_days do |t| 11 | t.column :release_id, :integer, :null => false 12 | t.column :day, :date, :null => false 13 | t.column :remaining_story_points, :integer, :null => false 14 | t.timestamps 15 | end 16 | add_column :releases, :initial_story_points, :integer, :null => true 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /db/migrate/046_add_releases_indexes.rb: -------------------------------------------------------------------------------- 1 | class AddReleasesIndexes < ActiveRecord::Migration 2 | def self.up 3 | add_index :issues, :release_id 4 | add_index :issues, :release_relationship 5 | add_index :releases, :project_id 6 | add_index :releases, :status 7 | add_index :releases, :release_start_date 8 | add_index :releases, :release_end_date 9 | end 10 | 11 | def self.down 12 | remove_index :issues, :column => :release_id 13 | remove_index :issues, :column => :release_relationship 14 | remove_index :releases, :column => :project_id 15 | remove_index :releases, :column => :status 16 | remove_index :releases, :column => :release_start_date 17 | remove_index :releases, :column => :release_end_date 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /db/migrate/047_add_issues_rbcache.rb: -------------------------------------------------------------------------------- 1 | class AddIssuesRbcache < ActiveRecord::Migration 2 | def self.up 3 | create_table :rb_release_burndown_caches do |t| 4 | t.column :issue_id, :integer, :null => false 5 | t.column :value, :text 6 | end 7 | add_index :rb_release_burndown_caches, :issue_id 8 | end 9 | 10 | def self.down 11 | drop_table :rb_release_burndown_caches 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/048_add_issues_release_day_cache.rb: -------------------------------------------------------------------------------- 1 | require "./plugins/redmine_backlogs/db/migrate/047_add_issues_rbcache.rb" 2 | 3 | class AddIssuesReleaseDayCache < ActiveRecord::Migration 4 | def self.up 5 | create_table :rb_release_burnchart_day_caches, :id => false do |t| 6 | t.column :issue_id, :integer, :null => false 7 | t.column :release_id, :integer, :null => false 8 | t.column :day, :date, :null => false 9 | t.column :total_points, :float, :default => 0, :null => false 10 | t.column :added_points, :float, :default => 0, :null => false 11 | t.column :closed_points, :float, :default => 0, :null => false 12 | end 13 | add_index :rb_release_burnchart_day_caches, :issue_id 14 | add_index :rb_release_burnchart_day_caches, :release_id 15 | add_index :rb_release_burnchart_day_caches, :day 16 | 17 | AddIssuesRbcache.new.down 18 | end 19 | 20 | def self.down 21 | remove_index :rb_release_burnchart_day_caches, :column => :issue_id 22 | remove_index :rb_release_burnchart_day_caches, :column => :release_id 23 | remove_index :rb_release_burnchart_day_caches, :column => :day 24 | drop_table :rb_release_burnchart_day_caches 25 | AddIssuesRbcache.new.up 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /db/migrate/049_add_release_multiview.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseMultiview < ActiveRecord::Migration 2 | def self.up 3 | create_table :rb_releases_multiview do |t| 4 | t.column :name, :string, :null => false 5 | t.text :description 6 | t.belongs_to :project 7 | t.text :release_ids 8 | end 9 | end 10 | 11 | def self.down 12 | drop_table :rb_releases_multiview 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /features/.autotest: -------------------------------------------------------------------------------- 1 | if RUBY_PLATFORM.downcase.include?("darwin") 2 | require "autotest/growl" 3 | require 'autotest/fsevent' 4 | end 5 | require 'redgreen/autotest' 6 | 7 | Autotest.add_hook :initialize do |at| 8 | %w{.git .DS_Store test assets}.each { |exception| at.add_exception(exception) } 9 | at.remove_exception 'vendor/plugins' 10 | at.find_directories << 'vendor/plugins/redmine_backlogs' 11 | at.libs << 'vendor/plugins/redmine_backlogs/features' 12 | at.libs << 'vendor/plugins/redmine_backlogs/lib' 13 | false 14 | end 15 | 16 | Autotest.add_hook :all_good do |at| 17 | system "rake redmine:backlogs:rcov" 18 | false 19 | end -------------------------------------------------------------------------------- /features/common.feature: -------------------------------------------------------------------------------- 1 | Feature: Common 2 | As a user 3 | I want to do stuff 4 | So that I can do my job 5 | 6 | Background: 7 | Given the ecookbook project has the backlogs plugin enabled 8 | And no versions or issues exist 9 | And I am a team member of the project 10 | And sharing is not enabled 11 | 12 | Scenario: View the product backlog 13 | Given I am viewing the master backlog 14 | When I request the server_variables resource 15 | Then the request should complete successfully 16 | 17 | Scenario: View the product backlog 18 | Given I am viewing the master backlog 19 | And sharing is enabled 20 | When I request the server_variables resource 21 | Then the request should complete successfully 22 | 23 | Scenario: View the product backlog without any stories 24 | Given there are no stories in the project 25 | When I view the master backlog 26 | Then the request should complete successfully 27 | -------------------------------------------------------------------------------- /features/duplicate_story.feature: -------------------------------------------------------------------------------- 1 | Feature: Duplicate story 2 | As a member 3 | I want be able to duplicate a story 4 | So that I can split a story or continue work in another sprint 5 | 6 | Background: 7 | Given the ecookbook project has the backlogs plugin enabled 8 | And I am a scrum master of the project 9 | And I have deleted all existing issues 10 | And I have defined the following sprints: 11 | | name | sprint_start_date | effective_date | 12 | | Sprint 001 | 2010-01-01 | 2010-01-31 | 13 | | Sprint 002 | 2010-02-01 | 2010-02-28 | 14 | | Sprint 003 | 2010-03-01 | 2010-03-31 | 15 | | Sprint 004 | 2010-04-01 | 2010-04-30 | 16 | And I have defined the following stories in the following sprints: 17 | | subject | sprint | 18 | | Story 1 | Sprint 001 | 19 | And I have defined the following tasks: 20 | | subject | story | 21 | | Task 1 | Story 1 | 22 | | Task 2 | Story 1 | 23 | 24 | Scenario: Duplicate story without tasks 25 | Given I am duplicating Story 1 to Story 1A for Sprint 002 26 | And I choose to copy none tasks 27 | When I click copy 28 | Then the request should complete successfully 29 | And sprint Sprint 002 should contain Story 1A 30 | 31 | #using javascript to disable redmine2.1 copy_subtasks button 32 | @javascript 33 | Scenario: Duplicate story with tasks 34 | Given I am duplicating Story 1 to Story 1B for Sprint 003 35 | And I choose to copy open tasks 36 | When I click copy 37 | Then the request should complete successfully 38 | And sprint Sprint 003 should contain Story 1B 39 | And the story named Story 1B should have a task named Task 1 40 | And the story named Story 1B should have a task named Task 2 41 | 42 | # Scenario: Duplicate story with some tasks closed 43 | 44 | -------------------------------------------------------------------------------- /features/extended_timelog.feature: -------------------------------------------------------------------------------- 1 | Feature: Extended timelog 2 | As a member 3 | I want to update spent time and remaining hours easily 4 | So that I can update everyone on the status of the project 5 | 6 | Background: 7 | Given the ecookbook project has the backlogs plugin enabled 8 | And timelog from taskboard has been enabled 9 | And I am a team member of the project and allowed to update remaining hours 10 | And I have deleted all existing issues 11 | And I have defined the following sprints: 12 | | name | sprint_start_date | effective_date | 13 | | Sprint 001 | 2010-01-01 | 2010-01-31 | 14 | And I have defined the following stories in the following sprints: 15 | | subject | sprint | 16 | | Story 1 | Sprint 001 | 17 | And I have defined the following tasks: 18 | | subject | story | 19 | | Task 1 | Story 1 | 20 | 21 | Scenario: Log time and set remaining hours from "Log time"-view 22 | Given I am logging time for task Task 1 23 | And I set the hours spent to 2 24 | And I set the remaining_hours to 5 25 | When I click save 26 | Then the request should complete successfully 27 | And task Task 1 should have remaining_hours set to 5 28 | And task Task 1 should have a total time spent of 2 hours 29 | 30 | Scenario: Log time from "Log Time"-view without selecting task 31 | Given I am viewing log time for the ecookbook project 32 | And I set the hours spent to 2 33 | When I click save 34 | Then the request should complete successfully 35 | -------------------------------------------------------------------------------- /features/step_definitions/routing_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I (post|put|get) the "(.+)" page$/ do |method,url| 2 | @url = url 3 | @request = { method => url } 4 | @method = method 5 | end 6 | When /^I (post|put|get) the "(.+)" page with params:$/ do |method,url,params| 7 | @url = url 8 | @request = { method => url } 9 | @method = method 10 | 11 | @params = params.transpose.hashes[0] 12 | end 13 | When /^I (post|put|get) the "(.+)" page using format "(.+)"$/ do |method,url, format| 14 | @url = url 15 | @request = { method => url } 16 | @method = method 17 | 18 | @format = format 19 | end 20 | 21 | Then /^application should route me to:$/ do |controller| 22 | if Rails::VERSION::MAJOR >= 3 23 | @routes = Rails.application.routes # workaround for assert_recognizes bug 24 | end 25 | controller = controller.transpose 26 | # convert headers to symbols 27 | controller.map_headers! { |header| header.to_sym } 28 | controller_with_params = controller.hashes[0] 29 | @request.should route_to controller_with_params 30 | controller_with_params[:format] = @format if @format 31 | controller_with_params.merge!(@params) if @params 32 | url = url_for(controller_with_params) 33 | if @method == 'put' 34 | put url, controller_with_params 35 | else 36 | post url, controller_with_params 37 | end 38 | end 39 | 40 | -------------------------------------------------------------------------------- /features/step_definitions/stacked_data.rb: -------------------------------------------------------------------------------- 1 | Given(/^I initialize RbStackedData with closed date (.*)$/) do |date| 2 | date = Time.zone.parse(date).to_date 3 | @stacked_data = RbStackedData.new(date) 4 | end 5 | 6 | Given(/^I add the following series "(.*)":$/) do |id,table| 7 | tmp_days = [] 8 | tmp_total_points = [] 9 | tmp_closed_points = [] 10 | table.hashes.each do |entry| 11 | tmp_days << Time.zone.parse(entry[:days]).to_date 12 | tmp_total_points << entry[:total_points].to_i 13 | tmp_closed_points << entry[:closed_points].to_i 14 | end 15 | series = {:days => tmp_days, :total_points => tmp_total_points, :closed_points => tmp_closed_points} 16 | @stacked_data.add(series,id,true) 17 | end 18 | 19 | Given(/^I finish RbStackedData$/) do 20 | @stacked_data.finalize(true) 21 | end 22 | 23 | 24 | Then(/^series (\d+) should be:$/) do |series_number, table| 25 | idx = series_number.to_i 26 | expected_days = [] 27 | expected_total = [] 28 | table.hashes.each do |entry| 29 | expected_days << Time.zone.parse(entry[:days]).to_date 30 | expected_total << entry[:total_points].to_i 31 | end 32 | puts @stacked_data[idx].inspect 33 | @stacked_data[idx][:days].should == expected_days 34 | @stacked_data[idx][:total_points].should == expected_total 35 | end 36 | 37 | Then(/^closed series should be:$/) do |table| 38 | expected_days = [] 39 | expected_closed = [] 40 | table.hashes.each do |entry| 41 | expected_days << Time.zone.parse(entry[:days]).to_date 42 | expected_closed << entry[:closed_points].to_i 43 | end 44 | puts @stacked_data.closed_data.inspect 45 | @stacked_data.closed_data[:days].should == expected_days 46 | @stacked_data.closed_data[:closed_points].should == expected_closed 47 | end 48 | 49 | Then(/^series "(.*)" trend end date should be (.*)$/) do |id,date| 50 | date = Time.zone.parse(date).to_date 51 | @stacked_data.total_estimates[id][:end_date_estimate].should === date 52 | end 53 | -------------------------------------------------------------------------------- /features/support/paths.rb: -------------------------------------------------------------------------------- 1 | module NavigationHelpers 2 | # Maps a name to a path. Used by the 3 | # 4 | # When /^I go to (.+)$/ do |page_name| 5 | # 6 | # step definition in web_steps.rb 7 | # 8 | def path_to(page_name) 9 | case page_name 10 | 11 | when /the home\s?page/ 12 | '/' 13 | 14 | when /project (.*) page/ 15 | url_for(:controller => :projects, :action => :show, :id => Project.find($1).id, :only_path => true) 16 | # Add more mappings here. 17 | # Here is an example that pulls values out of the Regexp: 18 | # 19 | # when /^(.*)'s profile page$/i 20 | # user_profile_path(User.find_by_login($1)) 21 | 22 | else 23 | begin 24 | page_name =~ /the (.*) page/ 25 | path_components = $1.split(/\s+/) 26 | self.send(path_components.push('path').join('_').to_sym) 27 | rescue Object => e 28 | raise "Can't find mapping from \"#{page_name}\" to a path.\n" + 29 | "Now, go and add a mapping in #{__FILE__}" 30 | end 31 | end 32 | end 33 | end 34 | 35 | World(NavigationHelpers) 36 | -------------------------------------------------------------------------------- /features/support/setup.rb: -------------------------------------------------------------------------------- 1 | # Sets up the Rails environment for Cucumber 2 | ENV["RAILS_ENV"] = "test" 3 | require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') 4 | require 'cucumber/rails/world' 5 | Cucumber::Rails::World.use_transactional_fixtures = true 6 | 7 | if Rails::VERSION::MAJOR >= 3 8 | require 'rspec/rails/matchers' 9 | World(RSpec::Rails::Matchers::RoutingMatchers) 10 | end 11 | 12 | #Seed the DB 13 | def seed_the_database 14 | if Rails::VERSION::MAJOR < 3 15 | fixtures = Fixtures 16 | else 17 | fixtures = ActiveRecord::Fixtures 18 | end 19 | seed_the_database_with(fixtures) 20 | end 21 | 22 | def seed_the_database_with(fixtures) 23 | fixtures.reset_cache 24 | fixtures_folder = File.join(Rails.root, 'test', 'fixtures') 25 | fixtures_files = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') } 26 | fixtures.create_fixtures(fixtures_folder, fixtures_files) 27 | end 28 | 29 | seed_the_database 30 | 31 | if Cucumber::Rails.const_defined?(:Database) 32 | # only for recent cucumber-rails 33 | # do not clean the database between @javascript scenarios 34 | Cucumber::Rails::Database.javascript_strategy = :transaction 35 | else 36 | DatabaseCleaner.strategy = nil 37 | Before do 38 | seed_the_database 39 | end 40 | end 41 | 42 | # use headless webkit to test javascript ui 43 | require 'capybara/poltergeist' 44 | Capybara.javascript_driver = :poltergeist 45 | Capybara.register_driver :poltergeist do |app| 46 | Capybara::Poltergeist::Driver.new(app, :inspector => true) 47 | end 48 | #give travis some time for ajax requests to complete 49 | Capybara.default_wait_time = 15 50 | 51 | if Rails::VERSION::MAJOR >= 3 52 | require 'rake' 53 | require 'rails/tasks' 54 | Rake::Task["tmp:create"].invoke 55 | end 56 | 57 | -------------------------------------------------------------------------------- /features/support/simplecov_env.rb: -------------------------------------------------------------------------------- 1 | if RUBY_VERSION >= "1.9" 2 | require 'simplecov' 3 | SimpleCov.start 'rails' do 4 | add_group('Backlogs', 'redmine_backlogs') 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /features/ui.feature: -------------------------------------------------------------------------------- 1 | Feature: User interface 2 | As a user 3 | I want to use Backlogs via AJAX interface 4 | So that I can use it without reloading a page 5 | 6 | Background: 7 | Given the ecookbook project has the backlogs plugin enabled 8 | And I am logged out 9 | #And I am a team member of the project 10 | And I am a scrum master of the project 11 | And I have deleted all existing issues 12 | And I have defined the following sprints: 13 | | name | sprint_start_date | effective_date | 14 | | Sprint 001 | 2010-01-01 | 2010-01-31 | 15 | 16 | @javascript 17 | Scenario: Backlogs page 18 | Given I am viewing the master backlog 19 | 20 | @javascript 21 | Scenario: Taskboard page 22 | Given I am viewing the taskboard for Sprint 001 23 | 24 | -------------------------------------------------------------------------------- /lib/backlogs_acts_as_cached_journaled.rb: -------------------------------------------------------------------------------- 1 | module ActiveRecord; module Acts; end; end 2 | module ActiveRecord::Acts::ActsAsRbCachedJournaled 3 | 4 | def self.included(base) 5 | base.extend(ClassMethods) 6 | end 7 | 8 | module ClassMethods 9 | def acts_as_rb_cached_journaled(add_entry, dependants) 10 | after_save do |o| 11 | deps = dependants.nil? [] : self.send(dependants) 12 | ([self] + deps).each{|o| o.send(add_entry) } 13 | end 14 | end 15 | end 16 | end 17 | 18 | ActiveRecord::Base.send(:include, ActiveRecord::Acts::ActsAsRbCachedJournaled 19 | -------------------------------------------------------------------------------- /lib/backlogs_custom_field_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'custom_field' 2 | 3 | module Backlogs 4 | module CustomFieldPatch 5 | def self.included(base) # :nodoc: 6 | base.extend(ClassMethods) 7 | base.send(:include, InstanceMethods) 8 | base.class_eval do 9 | class << self 10 | alias_method_chain :customized_class, :sti 11 | end 12 | end 13 | end 14 | 15 | module ClassMethods 16 | def customized_class_with_sti 17 | (self.respond_to?(:rb_sti_class) ? self.rb_sti_class : self).customized_class_without_sti 18 | end 19 | end 20 | 21 | module InstanceMethods 22 | end 23 | end 24 | end 25 | 26 | CustomField.send(:include, Backlogs::CustomFieldPatch) unless CustomField.included_modules.include? Backlogs::CustomFieldPatch 27 | -------------------------------------------------------------------------------- /lib/backlogs_issue_status_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'user' 2 | 3 | module Backlogs 4 | module IssueStatusPatch 5 | def self.included(base) # :nodoc: 6 | base.extend(ClassMethods) 7 | base.send(:include, InstanceMethods) 8 | end 9 | 10 | module ClassMethods 11 | end 12 | 13 | module InstanceMethods 14 | def backlog 15 | return :success if is_closed? && (default_done_ratio.nil? || default_done_ratio == 100) 16 | return :failure if is_closed? 17 | return :new if is_default? || default_done_ratio == 0 18 | return :in_progress 19 | end 20 | 21 | def backlog_is?(states) 22 | states = [states] unless states.is_a?(Array) 23 | raise "Not a valid state set #{states.inspect}" unless (states - [:success, :failure, :new, :in_progress]) == [] 24 | return states.include?(backlog) 25 | end 26 | end 27 | end 28 | end 29 | 30 | IssueStatus.send(:include, Backlogs::IssueStatusPatch) unless IssueStatus.included_modules.include? Backlogs::IssueStatusPatch 31 | -------------------------------------------------------------------------------- /lib/backlogs_my_controller_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'my_controller' 2 | 3 | module Backlogs 4 | module MyControllerPatch 5 | def self.included(base) # :nodoc: 6 | base.extend(ClassMethods) 7 | base.send(:include, InstanceMethods) 8 | 9 | base.class_eval do 10 | unloadable # Send unloadable so it will not be unloaded in development 11 | after_filter :save_backlogs_preferences, :only => [:account] 12 | end 13 | end 14 | 15 | module ClassMethods 16 | end 17 | 18 | module InstanceMethods 19 | def save_backlogs_preferences 20 | if request.post? && flash[:notice] == l(:notice_account_updated) 21 | color = (params[:backlogs] ? params[:backlogs][:task_color] : '').to_s 22 | if color == '' || color.match(/^#[A-Fa-f0-9]{6}$/) 23 | User.current.backlogs_preference[:task_color] = color 24 | else 25 | flash[:notice] = "Invalid task color code #{color}" 26 | end 27 | end 28 | end 29 | end 30 | end 31 | end 32 | 33 | MyController.send(:include, Backlogs::MyControllerPatch) unless MyController.included_modules.include? Backlogs::MyControllerPatch 34 | -------------------------------------------------------------------------------- /lib/backlogs_projects_helper_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'projects_helper' 2 | 3 | module Backlogs 4 | module ProjectsHelperPatch 5 | 6 | def self.included(base) 7 | base.send(:include, InstanceMethods) 8 | base.class_eval do 9 | unloadable 10 | alias_method_chain :project_settings_tabs, :backlogs 11 | end 12 | end 13 | 14 | module InstanceMethods 15 | 16 | def project_settings_tabs_with_backlogs 17 | tabs = project_settings_tabs_without_backlogs 18 | tabs << {:name => 'backlogs', 19 | :action => :manage_project_backlogs, 20 | :partial => 'backlogs/project_settings', 21 | :label => :label_backlogs 22 | } if @project.module_enabled?('backlogs') and 23 | User.current.allowed_to?(:configure_backlogs, nil, :global=>true) 24 | return tabs 25 | end 26 | 27 | end 28 | 29 | end 30 | end 31 | 32 | ProjectsHelper.send(:include, Backlogs::ProjectsHelperPatch) unless ProjectsHelper.included_modules.include? Backlogs::ProjectsHelperPatch 33 | 34 | -------------------------------------------------------------------------------- /lib/backlogs_time_report_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'redmine/helpers/time_report' 2 | 3 | module Backlogs 4 | module TimeReportPatch 5 | def self.included(base) 6 | base.send(:include, InstanceMethods) 7 | 8 | base.class_eval do 9 | alias_method_chain :load_available_criteria, :releases 10 | end 11 | end 12 | 13 | module InstanceMethods 14 | def load_available_criteria_with_releases 15 | load_available_criteria_without_releases 16 | @available_criteria["release"] = 17 | { :sql => "COALESCE((select release_id from #{Issue.table_name} where id=parent_issue.parent_id), #{Issue.table_name}.release_id)", 18 | :joins => "left outer join #{Issue.table_name} parent_issue on parent_issue.id = #{TimeEntry.table_name}.issue_id", 19 | :klass => RbRelease, 20 | :label => :field_release 21 | } 22 | @available_criteria 23 | end 24 | end 25 | 26 | end 27 | end 28 | 29 | Redmine::Helpers::TimeReport.send(:include,Backlogs::TimeReportPatch) unless Redmine::Helpers::TimeReport.included_modules.include? Backlogs::TimeReportPatch 30 | -------------------------------------------------------------------------------- /lib/backlogs_tracker_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'user' 2 | 3 | module Backlogs 4 | module TrackerPatch 5 | def self.included(base) # :nodoc: 6 | base.extend(ClassMethods) 7 | base.send(:include, InstanceMethods) 8 | end 9 | 10 | module ClassMethods 11 | end 12 | 13 | module InstanceMethods 14 | def backlog? 15 | return (issue_statuses.collect{|s| s.backlog}.compact.uniq.size == 4) 16 | end 17 | 18 | def status_for_done_ratio(r) 19 | return (issue_statuses.select{|s| !s.default_done_ratio.nil? && s.default_done_ratio < r && !s.is_closed?}.sort{|a, b| b.default_done_ratio <=> a.default_done_ratio} + [nil])[0] 20 | end 21 | end 22 | end 23 | end 24 | 25 | Tracker.send(:include, Backlogs::TrackerPatch) unless Tracker.included_modules.include? Backlogs::TrackerPatch 26 | -------------------------------------------------------------------------------- /lib/backlogs_version_patch.rb: -------------------------------------------------------------------------------- 1 | require_dependency 'version' 2 | 3 | module Backlogs 4 | module VersionPatch 5 | def self.included(base) # :nodoc: 6 | base.extend(ClassMethods) 7 | base.send(:include, InstanceMethods) 8 | 9 | base.class_eval do 10 | unloadable 11 | 12 | has_one :sprint_burndown, :class_name => RbSprintBurndown, :dependent => :destroy 13 | 14 | after_save :clear_burndown 15 | 16 | include Backlogs::ActiveRecord::Attributes 17 | end 18 | end 19 | 20 | module ClassMethods 21 | end 22 | 23 | module InstanceMethods 24 | def clear_burndown 25 | self.burndown.touch! 26 | end 27 | 28 | # load on demand 29 | def burndown 30 | self.sprint_burndown = self.create_sprint_burndown(:version_id => self.id) unless self.new_record? || self.sprint_burndown 31 | return self.sprint_burndown 32 | end 33 | 34 | def days 35 | #return Day objects. Version stores start and effective date without timezone. These are used to filter history entries and thus the zone of these days are those of the history dates 36 | return nil unless self.sprint_start_date && self.effective_date 37 | (self.sprint_start_date - 1 .. self.effective_date).to_a.select{|d| Backlogs.setting[:include_sat_and_sun] || ![0,6].include?(d.wday)} 38 | end 39 | def has_burndown? 40 | return (self.days || []).size != 0 41 | end 42 | 43 | end 44 | end 45 | end 46 | 47 | Version.send(:include, Backlogs::VersionPatch) unless Version.included_modules.include? Backlogs::VersionPatch 48 | -------------------------------------------------------------------------------- /lib/ci/README: -------------------------------------------------------------------------------- 1 | Poor mans backlogs integration tester for ubuntu precise 64bit 2 | 3 | Basic host preparation: 4 | 1. execute install-pre.sh to install environmental basics and the test environment template on the host system 5 | 6 | Setup: 7 | 2. run generate.sh to generate tests from travis matrix. 8 | 9 | Testing: 10 | 3. edit generated-tests.sh to suite the needs and run it with 'sudo bash generated-tests.sh'. It will fork of all tests in parallel, so better have ram and cpus. To stop the tests, wait an hour or reboot the host. 11 | When the test session is running, type -a " to get a list of session windows to choose from. 12 | 13 | Watch the logfiles and put the system load on youtube :-) 14 | -------------------------------------------------------------------------------- /lib/ci/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Evaluate .travis.yml matrix and generate a script which would run the tests. 4 | # That generated-tests.sh then has to be run as root manually. 5 | # It will run all tests in parallel, probably maxing out the system. It runs in a screen session. 6 | 7 | BINDMOUNTDIR=`realpath $PWD/../..` 8 | BUILDER="pbuilder --execute __buildscript.sh" 9 | RUBY_SCRIPT=$(cat <<__END 10 | data = YAML::load(STDIN.read) 11 | exclude = data['matrix']['exclude'] 12 | data['rvm'].each{|rvm| 13 | data['env'].each{|env| 14 | do_exclude = false 15 | exclude.each{|x| 16 | do_exclude = true if x['rvm'] == rvm && x['env'] == env 17 | } 18 | unless do_exclude 19 | session="#{rvm}.#{env.sub(' ','_').sub('=','_')}" 20 | puts "echo '(env BINDMOUNTDIR=${BINDMOUNTDIR} RVM=#{rvm} #{env} ${BUILDER} && echo '\\\\''OK'\\\\'' || echo '\\\\''FAILED'\\\\'') 2>&1 | tee \"log.\$\$.#{session}\"; read a' > \"run.#{session}\"" 21 | puts "chmod 700 \"run.#{session}\"" 22 | puts "screen -S backlogci -X screen \"./run.#{session}\"" 23 | end 24 | } 25 | } 26 | __END 27 | ) 28 | 29 | cat <<_END > generated-tests.sh 30 | #!/bin/bash 31 | screen -dmS backlogci 32 | screen -S backlogci -X screen top 33 | _END 34 | cat ../../.travis.yml |ruby -ryaml -e "$RUBY_SCRIPT" >> generated-tests.sh 35 | echo "screen -RS backlogci -p 1" >> generated-tests.sh 36 | chmod 700 generated-tests.sh 37 | 38 | echo "Now run generated-tests.sh as root." 39 | -------------------------------------------------------------------------------- /lib/ci/install-pre.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo apt-get install pbuilder debootstrap devscripts realpath screen 3 | 4 | if [ ! -f phantomjs-1.8.1-linux-x86_64.tar.bz2 ]; then 5 | curl http://phantomjs.googlecode.com/files/phantomjs-1.8.1-linux-x86_64.tar.bz2 >phantomjs-1.8.1-linux-x86_64.tar.bz2 6 | fi 7 | 8 | BINDMOUNTDIR=`realpath $PWD/../..` 9 | cat pbuilderrc.tpl | sed -e "s=__BINDMOUNTDIR__=${BINDMOUNTDIR}=g" > ${HOME}/.pbuilderrc 10 | if [ ! -f $HOME/backlogs_ci/backlogs_ci-base.tgz ]; then 11 | echo "Creating pbuilder environment. Need to get root, sorry..." 12 | sudo pbuilder --create 13 | fi 14 | 15 | 16 | -------------------------------------------------------------------------------- /lib/ci/pbuilderrc.tpl: -------------------------------------------------------------------------------- 1 | # build user id must not exist on the host system 2 | BUILDUSERID=1234 3 | # where most stuff takes place 4 | BASE=$HOME/backlogs_ci 5 | NAME=backlogs_ci 6 | 7 | BUILDUSERNAME=backlogs 8 | BASETGZ="$BASE/$NAME-base.tgz" 9 | BUILDRESULT="$BASE/$NAME/result/" 10 | BUILDPLACE="$BASE/build/" 11 | APTCACHE="$BASE/$NAME/aptcache/" 12 | APTCACHEHARDLINK=no 13 | OTHERMIRROR="deb http://de.archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse" 14 | COMPONENTS="main restricted universe multiverse" 15 | EXTRAPACKAGES="less curl wget git-core autoconf bison build-essential git-core imagemagick libcurl4-openssl-dev libssl-dev libxml2-dev libxslt1-dev libyaml-dev openssl zlib1g zlib1g-dev libmagickwand4 libmagickwand-dev libgraphicsmagick1-dev libmysqlclient-dev libpq-dev libsqlite3-dev mysql-server postgresql" 16 | BINDMOUNTS="__BINDMOUNTDIR__" 17 | -------------------------------------------------------------------------------- /lib/labels/story-default.glabels: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/labels/story-default.glabels -------------------------------------------------------------------------------- /lib/labels/task-default.glabels: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/labels/task-default.glabels -------------------------------------------------------------------------------- /lib/linear_regression.rb: -------------------------------------------------------------------------------- 1 | 2 | module Backlogs 3 | # Creates a linear fit of a set of days and data 4 | class LinearRegression 5 | attr_reader :slope # points/day 6 | attr_reader :intercept # estimated starting point from first day 7 | attr_reader :days 8 | 9 | # @param days array of dates in dataset 10 | # param data array of values 11 | def initialize(days, data) 12 | @days = days 13 | @data = data 14 | 15 | days_number = @days.collect{|d| (d - days.first).to_i } 16 | count = days_number.size.to_f 17 | if count > 1 18 | # Least mean square (x=days_number, y=data) 19 | avg_x = days_number.sum / count 20 | avg_y = data.sum / count 21 | avg_xy = days_number.each.with_index.inject(0){|sum,(d,i)| 22 | sum + (d * data[i]) } / count 23 | avg_xx = days_number.inject(0){|sum,d| sum + (d * d) } / count 24 | 25 | @slope = (avg_xy - (avg_x * avg_y)) / (avg_xx - (avg_x**2)) 26 | @intercept = (avg_xx*avg_y - (avg_x*avg_xy)) / (avg_xx - (avg_x**2)) 27 | else 28 | @slope = 0 29 | @intercept = data[0] 30 | end 31 | end 32 | 33 | # Calculate date of linear fit crossing other line 34 | # Only return if lines are crossing in the future 35 | def crossing_date(other) 36 | trend_cross_days = (predict_value(@days.last) - other.predict_value(@days.last)) / 37 | (other.slope - @slope) 38 | return @days.last + trend_cross_days unless trend_cross_days.infinite? or trend_cross_days <= 0 39 | end 40 | 41 | # Return trendline in form of two points 42 | def predict_line(date) 43 | return [[@days.first,@intercept],[date, predict_value(date)]] 44 | end 45 | 46 | # Return predicted value for a given date. 47 | def predict_value(date) 48 | days_between = (date - @days.first).to_i 49 | return days_between * @slope + @intercept 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/tasks/changelog.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'open-uri' 5 | require 'json' 6 | 7 | last_version = nil 8 | changelog = File.open('CHANGELOG.rdoc').each{|line| 9 | m = line.match(/^== .* (v[0-9]+\.[0-9]+\.[0-9]+)$/) 10 | if m 11 | last_version = m[1] 12 | break 13 | end 14 | } 15 | 16 | puts "== #{Date.today.strftime('%Y-%m-%d')} v???\n\n" 17 | gitlog = `git --no-pager log -50 --date=short --format="%ad %s"` 18 | gitlog.split("\n").each{|line| 19 | line = line.strip 20 | 21 | m = line.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2} (v[0-9]+\.[0-9]+\.[0-9]+)/) 22 | break if m && m[1] == last_version 23 | 24 | if m 25 | puts "\n== #{line}\n\n" 26 | else 27 | issues = line.scan(/#[0-9]+/) 28 | issues.each{|issueno| 29 | begin 30 | issue = open("https://api.github.com/repos/backlogs/redmine_backlogs/issues/#{issueno.gsub(/^#/, '')}").read 31 | issue = JSON.parse(issue) 32 | line.gsub!(/#{issueno}/, "\"#{issue['title']}\"") 33 | rescue OpenURI::HTTPError 34 | #Skip if detected issue id is not from the github repository 35 | end 36 | } 37 | puts "* #{line.gsub(/^[0-9]{4}-[0-9]{2}-[0-9]{2}/, '').strip}" 38 | end 39 | } 40 | 41 | puts "\n" 42 | 43 | puts File.open('CHANGELOG.rdoc').read 44 | -------------------------------------------------------------------------------- /lib/tasks/cp.rake: -------------------------------------------------------------------------------- 1 | desc 'CP Test' 2 | 3 | namespace :redmine do 4 | namespace :backlogs do 5 | task :cp => :environment do 6 | RbIssueHistory.rebuild 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/tasks/deprecated_tasks.rake: -------------------------------------------------------------------------------- 1 | rule /^redmine:backlogs_plugin/ do |t| 2 | task_name = t.name.split(':backlogs_plugin:').last 3 | notice = "NOTICE: redmine:backlogs_plugin:#{task_name} is DEPRECATED. Use redmine:backlogs:#{task_name} instead." 4 | puts "*".ljust(notice.length, "*") 5 | puts notice 6 | puts "*".ljust(notice.length, "*") 7 | Rake::Task["redmine:backlogs:#{task_name}"].invoke 8 | end -------------------------------------------------------------------------------- /lib/tasks/extract_default_data.rake: -------------------------------------------------------------------------------- 1 | desc 'Create YAML files in features/fixtures' 2 | 3 | namespace :redmine do 4 | namespace :backlogs do 5 | task :extract_fixtures => :environment do 6 | ENV["RAILS_ENV"] ||= "development" 7 | sql = "SELECT * FROM %s" 8 | skip_tables = ['schema_migrations'] 9 | 10 | ActiveRecord::Base.establish_connection 11 | 12 | (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name| 13 | i = "000" 14 | File.open("#{RAILS_ROOT}/vendor/plugins/redmine_backlogs/features/fixtures/#{table_name}.yml", 'w') do |file| 15 | data = ActiveRecord::Base.connection.select_all(sql % table_name) 16 | puts data 17 | file.write data.inject({}) { |hash, record| 18 | hash["#{table_name}_#{i.succ!}"] = record 19 | hash 20 | }.to_yaml 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/tasks/fix_positions.rake: -------------------------------------------------------------------------------- 1 | namespace :redmine do 2 | namespace :backlogs do 3 | desc "Remove duplicate positions in the issues table" 4 | task :fix_positions => :environment do 5 | unless Backlogs.migrated? 6 | puts "Please run plugin migrations first" 7 | else 8 | RbStory.connection.execute("drop table if exists _backlogs_tmp_position") 9 | 10 | RbStory.transaction do 11 | ids = RbStory.connection.select_values('select id from issues order by position') 12 | ids.each_with_index{|id, i| 13 | RbStory.connection.execute("update issues set position = #{i * RbStory.list_spacing} where id = #{id}") 14 | } 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/tasks/generate_chart_data.rake: -------------------------------------------------------------------------------- 1 | desc 'Generate chart data for all backlogs' 2 | 3 | namespace :redmine do 4 | namespace :backlogs do 5 | task :generate_chart_data => :environment do 6 | RbSprint.generate_burndown(!ENV['all']) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/tasks/position_from_priority.rake: -------------------------------------------------------------------------------- 1 | namespace :redmine do 2 | namespace :backlogs do 3 | desc "Remove duplicate positions in the issues table" 4 | task :position_from_priority => :environment do 5 | unless Backlogs.migrated? 6 | puts "Please run plugin migrations first" 7 | else 8 | RbStory.transaction do 9 | ids = RbStory.connection.select_values('select issues.id 10 | from issues 11 | join enumerations on issues.priority_id = enumerations.id 12 | order by enumerations.position desc') 13 | ids.each_with_index{|id, i| 14 | RbStory.connection.execute("update issues set position = #{i * RbStory.list_spacing} where id = #{id}") 15 | } 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/tasks/prepare_fixtures.rake: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'yaml' 3 | 4 | namespace :redmine do 5 | namespace :backlogs do 6 | desc "Prepare fixtures for testing" 7 | task :prepare_fixtures => :environment do 8 | root = case Rails::VERSION::MAJOR 9 | when 2 then RAILS_ROOT.to_s 10 | when 3 then Rails.root.to_s 11 | else nil 12 | end 13 | 14 | issues = File.join(root, 'test/fixtures/issues.yml') 15 | data = YAML::load(open(issues)) 16 | data.keys.each_with_index{|k, i| data[k]['position'] = i } 17 | File.open(issues, 'w') {|f| f.write(data.to_yaml) } 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/tasks/prime_stats.rake: -------------------------------------------------------------------------------- 1 | namespace :redmine do 2 | namespace :backlogs do 3 | desc "Prime the statistics cache" 4 | task :prime_stats => :environment do 5 | projects = RbCommonHelper.find_backlogs_enabled_active_projects 6 | projects.each{|project| 7 | puts project.name 8 | project.scrum_statistics(:force) 9 | } 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/tasks/rcov.rake: -------------------------------------------------------------------------------- 1 | begin 2 | if RUBY_VERSION >= '1.9' 3 | raise LoadError 4 | end 5 | 6 | require 'cucumber/rake/task' #I have to add this 7 | 8 | namespace :redmine do 9 | namespace :backlogs do 10 | 11 | desc "Generate RCov report for Redmine Backlogs" 12 | task :rcov => ["rcov:all"] 13 | 14 | namespace :rcov do 15 | Cucumber::Rake::Task.new(:cucumber) do |t| 16 | t.cucumber_opts = " --no-color" 17 | t.rcov = true 18 | t.rcov_opts = %w{ --rails --text-report --include-file vendor\/plugins\/redmine_backlogs --exclude config\/,features\/.+\/,^app\/,^lib\/,osx\/objc,gems\/ } 19 | t.rcov_opts << %[-o "coverage"] 20 | end 21 | 22 | task :all do |t| 23 | rm "coverage.data" if File.exist?("coverage.data") 24 | Rake::Task["redmine:backlogs:rcov:cucumber"].invoke 25 | end 26 | end 27 | end 28 | end 29 | rescue LoadError 30 | #pass 31 | end 32 | -------------------------------------------------------------------------------- /lib/tasks/rebuild_journal.rake: -------------------------------------------------------------------------------- 1 | namespace :redmine do 2 | namespace :backlogs do 3 | desc "Rebuild unified journal" 4 | task :rebuild_journal => :environment do 5 | RbIssueHistory.rebuild 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/tasks/test.rake: -------------------------------------------------------------------------------- 1 | desc 'Test' 2 | 3 | require 'pp' 4 | require 'date' 5 | 6 | begin 7 | require 'timecop' # redmine pre-loads all tasks 8 | rescue LoadError 9 | end 10 | 11 | 12 | namespace :redmine do 13 | namespace :backlogs do 14 | task :test => :environment do 15 | RbStory.all(:conditions => ['fixed_version_id = 89']).each{|story| 16 | next unless story.is_story? 17 | puts story.id 18 | puts story.history.history.inspect 19 | } 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/tasks/touch_stories.rake: -------------------------------------------------------------------------------- 1 | # 2 | # load all stories and just save them again 3 | # in order to trigger _before_save hook. This way, remaining_hours get 4 | # recalculated for each story. This fixes probably weird behavior of 5 | # the current day of the burndown graph after upgrading an existing old database 6 | # 7 | namespace :redmine do 8 | namespace :backlogs do 9 | desc "Touch all stories so they rebuild the remaining yours from their leaves" 10 | task :touch_stories => :environment do 11 | RbStory.where(['tracker_id in (?)', RbStory.trackers]).each{|story| 12 | puts "Touch #{story.id}" 13 | story.save! 14 | } 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/tasks/travis-combos.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'yaml' 4 | require 'pp' 5 | 6 | travis = YAML::load_file('.travis.yml') 7 | 8 | af = (travis['rvm'].collect{|rvm| {'rvm' => rvm}} + travis['env'].collect{|env| {'env' => env}}) - travis['matrix']['allow_failures'] 9 | pp af 10 | 11 | possibilities = [] 12 | travis['rvm'].each{|rvm| 13 | travis['env'].each{|env| 14 | possibilities << {'rvm' => rvm, 'env' => env} 15 | } 16 | } 17 | 18 | exc = possibilities - travis['matrix']['exclude'] 19 | pp exc 20 | 21 | #language: ruby 22 | #rvm: 23 | # - 1.8.7 24 | # - 1.9.3 25 | # - jruby-18mode 26 | # - jruby-19mode 27 | #env: 28 | # - REDMINE_VER=1 29 | # - REDMINE_VER=203 30 | # - REDMINE_VER=204 31 | # - REDMINE_VER=21 32 | # - REDMINE_VER=m 33 | # - REDMINE_VER=cp 34 | #matrix: 35 | # allow_failures: 36 | # - rvm: jruby-18mode 37 | # - rvm: 1.8.7 38 | # - env: REDMINE_VER=1 39 | # - env: REDMINE_VER=m 40 | # - env: REDMINE_VER=cp 41 | # exclude: 42 | # - rvm: jruby-18mode 43 | # env: REDMINE_VER=203 44 | # - rvm: jruby-18mode 45 | # env: REDMINE_VER=204 46 | # - rvm: jruby-18mode 47 | # env: REDMINE_VER=21 48 | # - rvm: 1.8.7 49 | # env: REDMINE_VER=cp 50 | # - rvm: jruby-18mode 51 | # env: REDMINE_VER=cp 52 | # 53 | #install: "echo skip bundle install" 54 | # 55 | #script: 56 | # - export WORKSPACE=`pwd`/workspace 57 | # - export PATH_TO_BACKLOGS=`pwd` 58 | # - export PATH_TO_REDMINE=$WORKSPACE/redmine 59 | # - mkdir $WORKSPACE 60 | # - cp config/database.yml.travis $WORKSPACE/database.yml 61 | # - bash -x ./redmine20_install.sh -r 62 | # - bash -x ./redmine20_install.sh -i 63 | # - bash -x ./redmine20_install.sh -t 64 | # - bash -x ./redmine20_install.sh -u 65 | # 66 | -------------------------------------------------------------------------------- /lib/tasks/travis.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'yaml' 4 | require 'pp' 5 | 6 | travis = YAML::load_file('.travis.yml') 7 | 8 | vers = ARGV 9 | #travis['env'].each{|env| 10 | # vers << env.split[0] 11 | #} 12 | travis['env'] = [] 13 | 14 | vers.each{|ver| 15 | Dir['features/*.feature'].collect{|feature| File.basename(feature, File.extname(feature))}.sort.each{|feature| 16 | travis['env'] << "REDMINE_VER=#{ver} FEATURE=#{feature} RAILS_ENV=test" 17 | } 18 | } 19 | 20 | File.open('.travis.yml', 'w'){|f| f.write(travis.to_yaml)} 21 | 22 | -------------------------------------------------------------------------------- /lib/ttf/DejaVuSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSans-Bold.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSans-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSans-BoldOblique.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSans-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSans-ExtraLight.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSans-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSans-Oblique.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSans.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansCondensed-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansCondensed-Bold.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansCondensed-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansCondensed-BoldOblique.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansCondensed-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansCondensed-Oblique.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansCondensed.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansCondensed.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansMono-Bold.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansMono-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansMono-BoldOblique.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansMono-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansMono-Oblique.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerif-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerif-Bold.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerif-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerif-BoldItalic.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerif-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerif-Italic.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerif.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerif.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerifCondensed-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerifCondensed-Bold.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerifCondensed-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerifCondensed-BoldItalic.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerifCondensed-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerifCondensed-Italic.ttf -------------------------------------------------------------------------------- /lib/ttf/DejaVuSerifCondensed.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/lib/ttf/DejaVuSerifCondensed.ttf -------------------------------------------------------------------------------- /screenshots/backlogs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/screenshots/backlogs.png -------------------------------------------------------------------------------- /screenshots/release.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backlogs/redmine_backlogs/2b6011e1a027f8e6bc33043a1a580a6f434117c7/screenshots/release.png -------------------------------------------------------------------------------- /spec/config.rb: -------------------------------------------------------------------------------- 1 | if RUBY_VERSION >= "1.9" 2 | require 'simplecov' 3 | SimpleCov.start 'rails' do 4 | add_group('Backlogs', 'redmine_backlogs') 5 | end 6 | end 7 | 8 | -------------------------------------------------------------------------------- /spec/controllers/rb_all_projects_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'fast_spec_helper' 2 | 3 | class ScrumStatistics 4 | def initialize(score) 5 | @score = score 6 | end 7 | def score 8 | @score 9 | end 10 | end 11 | class Project 12 | STATUS_ACTIVE = 1 13 | def initialize(score) 14 | @stats = ScrumStatistics.new(score) 15 | end 16 | def scrum_statistics 17 | @stats 18 | end 19 | end 20 | module RbCommonHelper 21 | end 22 | class ApplicationController 23 | def self.before_filter(*args) 24 | end 25 | end 26 | class Object 27 | def unloadable 28 | end 29 | end 30 | 31 | require 'rb_all_projects_controller' 32 | 33 | describe RbAllProjectsController, "#statistics" do 34 | it "returns enabled active projects sorted by the scrum statistics score" do 35 | # Set up 36 | project1 = Project.new(1) 37 | project2 = Project.new(2) 38 | project3 = Project.new(3) 39 | unsorted_projects = [ project3, project1, project2 ] 40 | 41 | # Exercise && Verify 42 | RbCommonHelper.should_receive(:find_backlogs_enabled_active_projects).and_return(unsorted_projects) 43 | sorted_projects = [ project1, project2, project3 ] 44 | RbAllProjectsController.new.statistics.should eq(sorted_projects) 45 | 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /spec/fast_spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'config' 2 | 3 | plugin_path = 'plugins/redmine_backlogs' 4 | $:.push File.expand_path("#{plugin_path}/app/helpers") 5 | $:.push File.expand_path("#{plugin_path}/app/models") 6 | $:.push File.expand_path("#{plugin_path}/app/controllers") 7 | $:.push File.expand_path("#{plugin_path}/lib") 8 | 9 | -------------------------------------------------------------------------------- /test.rb: -------------------------------------------------------------------------------- 1 | #!/home/hnse/.rvm/gems/ruby-1.9.3-p194@redmine/bin/rails runner 2 | require 'pp' 3 | 4 | s = RbSprint.find(:first, :conditions => 'not (sprint_start_date is null and effective_date is null)') 5 | t = RbTask.find(:first, :conditions => ['tracker_id = ? and fixed_version_id = ?', RbTask.tracker, s.id]) 6 | b = t.burndown 7 | 8 | pp b 9 | --------------------------------------------------------------------------------