Project

General

Profile

Agile Dwarf project management plugin released

Added by Michael K. over 11 years ago

Hi all,

I'm happy to announce that we've just released Agile Dwarf, a plugin that would be of help to any project manager.
Track progress and budgets with comprehensive run charts, create and edit tasks inline, drag&drop them in a clear kanban-like environment and more.

Give it a try, enjoy and do let me know how it goes.
http://www.agiledwarf.com/

Michael
http://www.iressources.com/


Replies (29)

RE: Agile Dwarf project management plugin released - Added by Jan Niggemann (redmine.org team member) over 11 years ago

This looks really useful, I'll try it sometime next week...
Thank you!

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

Looks like the most convenient and neat Scrum plugin for Redmine.

Thanks a lot! Will work with it extensively in next days.

RE: Agile Dwarf project management plugin released - Added by Razi Baluchi over 11 years ago

Great looking plugin.

Unfortunately, it appears to have issues with postgres when trying to access Tasks or Run Charts:

A ActiveRecord::StatementInvalid occurred in adburndown#show:

PGError: ERROR: syntax error at or near "`" at character 122
: select * from (select old_value as value, journalized_id as issueId, prop_key, DATE created_on from `journals` inner join journal_details on (journals.id = journal_id) inner join issues on (issues.id = journalized_id) where journalized_type = 'Issue' and property = 'attr' and (prop_key = 'estimated_hours' or prop_key = 'done_ratio') and project_id = 26 order by journals.id desc) a group by `issueId`, created_on, prop_key order by created_on desc

A ActiveRecord::StatementInvalid occurred in adtasks#list:

PGError: ERROR: column "issues.tracker_id" must appear in the GROUP BY clause or be used in an aggregate function at character 8
: SELECT issues.*, sum(hours) as spent FROM "issues" left join time_entries ON time_entries.issue_id = issues.id WHERE (issues.project_id = 26 and status_id = 1 and fixed_version_id = '46' and assigned_to_id = 11) GROUP BY issues.id ORDER BY case when issues.ir_position is null then 1 else 0 end ASC, case when issues.ir_position is NULL then issues.id else issues.ir_position end ASC

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Thank you Razi Baluchi, we're looking into it. I'll let you know as soon as we have a fix.

RE: Agile Dwarf project management plugin released - Added by Leonardo Carneiro over 11 years ago

Git cloned today, but i'm running into a internal error when i click in run charts. The log points to a syntax error on file
vendor/plugins/AgileDwarf/app/controllers/adburndown_controller.rb:57

Redmine 1.4.4

RE: Agile Dwarf project management plugin released - Added by Leonardo Carneiro over 11 years ago

ow, sorry, didnt see the post above.

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Thank you for your interest in Agile Dwarf, Leonardo Carneiro. I'll get back to you ASAP on this issue.

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Thank you for your interest in Agile Dwarf, Leonardo Carneiro. I'll get back to you ASAP on this issue.

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

seem to have run into a problem...

When I am trying to add a new task in the Sprints tab nothing seems to happen.
I see that there the POST request seems to be failing:

POST http://192.168.100.6/adtaskinl/create 400 (Bad Request) 

will see if I can get anything from the logs

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Thanks, Vladimir Dzalbo. We'll investigate this and I'll let you know.

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

Found it... I had the tracker Incident (with ID 4) disabled on the project..

Hope it is in TODO list to have it configured? ;)

RE: Agile Dwarf project management plugin released - Added by Vincent van der Locht over 11 years ago

Dear Michael,

Thank you for this plugin.

I've found a few issues:

- On the plugin page on redmine.org/plugins you show that the plugin version is 1.0, but the plugin itself shows 0.2
- I've tested the plugin in a bitnami virtual machine running redmine 2.x in a subdirectory on the server. http://server/redmine/... doesn't work for this plugin.

If possible, I would like to assist in the development of this plugin. Would you be interested in this.

Kind regards,

Vincent van der Locht

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Hi Vincent,

Thank you for your interest. I've fixed the version issue.
It would be great to have a new contributor! Which features would you like to implement?
If you want to fix bugs, by all means do. Just send in your diff, we'll be glad to accept it.

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Vladimir Dzalbo,

Please checkout the latest revision and see if that fixes the problem.

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Leonardo Carneiro,

Are you using PostgreSQL by any chance?

RE: Agile Dwarf project management plugin released - Added by Leonardo Carneiro over 11 years ago

Hi Michael, yes, i'm using postgres 9.1.4 and redmine 1.4.4.

Also, i would like to note that the rake command in the README didn't worked for me.

Command in the README: "rake redmine:plugins:migrate"
Command that really worked: "RAILS_ENV=production rake db:migrate:plugin NAME=AgileDwarf"

I think it may be because of the rails version, but i'm not sure.

rails version: 2.3.14
ruby version: 1.8.7

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

Hi Michael,

Thanks a lot for your effort!

Unfortunately it did not really work out. That's the issue I am having now:

Processing by AdtaskinlController#inplace as HTML
  Parameters: {"estimated_hours"=>"1", "element_id"=>"", "id"=>"847", "project_id"=>"55", "authenticity_token"=>"KEY="}
   (0.1ms)  SELECT MAX(`settings`.`updated_on`) AS max_id FROM `settings`
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('User', 'AnonymousUser') AND `users`.`id` = 4 AND (users.status = 1) LIMIT 1
  Project Load (0.1ms)  SELECT `projects`.* FROM `projects` WHERE `projects`.`id` = 55 LIMIT 1
  EnabledModule Load (0.1ms)  SELECT name FROM `enabled_modules` WHERE `enabled_modules`.`project_id` = 55
Completed 500 Internal Server Error in 10ms

NoMethodError (undefined method `[]' for nil:NilClass):
  plugins/AgileDwarf/app/controllers/adtaskinl_controller.rb:73:in `inplace'
  actionpack (3.2.6) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (3.2.6) lib/abstract_controller/base.rb:167:in `process_action'
  actionpack (3.2.6) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (3.2.6) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
  activesupport (3.2.6) lib/active_support/callbacks.rb:469:in `_run__801128489761467166__process_action__1710448466030218311__callbacks'
  activesupport (3.2.6) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.6) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
  activesupport (3.2.6) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (3.2.6) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (3.2.6) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (3.2.6) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
  activesupport (3.2.6) lib/active_support/notifications.rb:123:in `block in instrument'
  activesupport (3.2.6) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (3.2.6) lib/active_support/notifications.rb:123:in `instrument'
  actionpack (3.2.6) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
  actionpack (3.2.6) lib/action_controller/metal/params_wrapper.rb:206:in `process_action'
  activerecord (3.2.6) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (3.2.6) lib/abstract_controller/base.rb:121:in `process'
  actionpack (3.2.6) lib/abstract_controller/rendering.rb:45:in `process'
  actionpack (3.2.6) lib/action_controller/metal.rb:203:in `dispatch'
  actionpack (3.2.6) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
  actionpack (3.2.6) lib/action_controller/metal.rb:246:in `block in action'
  actionpack (3.2.6) lib/action_dispatch/routing/route_set.rb:73:in `call'
  actionpack (3.2.6) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
  actionpack (3.2.6) lib/action_dispatch/routing/route_set.rb:36:in `call'
  journey (1.0.4) lib/journey/router.rb:68:in `block in call'
  journey (1.0.4) lib/journey/router.rb:56:in `each'
  journey (1.0.4) lib/journey/router.rb:56:in `call'
  actionpack (3.2.6) lib/action_dispatch/routing/route_set.rb:600:in `call'
  rack-openid (1.3.1) lib/rack/openid.rb:98:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
  rack (1.4.1) lib/rack/etag.rb:23:in `call'
  rack (1.4.1) lib/rack/conditionalget.rb:35:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/head.rb:14:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/flash.rb:242:in `call'
  rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'
  rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/cookies.rb:338:in `call'
  activerecord (3.2.6) lib/active_record/query_cache.rb:64:in `call'
  activerecord (3.2.6) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
  activesupport (3.2.6) lib/active_support/callbacks.rb:405:in `_run__4416072411493240599__call__4441487829683152030__callbacks'
  activesupport (3.2.6) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.6) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
  activesupport (3.2.6) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (3.2.6) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.6) lib/rails/rack/logger.rb:26:in `call_app'
  railties (3.2.6) lib/rails/rack/logger.rb:16:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.1) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.1) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.6) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.1) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/static.rb:62:in `call'
  rack-cache (1.2) lib/rack/cache/context.rb:136:in `forward'
  rack-cache (1.2) lib/rack/cache/context.rb:143:in `pass'
  rack-cache (1.2) lib/rack/cache/context.rb:155:in `invalidate'
  rack-cache (1.2) lib/rack/cache/context.rb:71:in `call!'
  rack-cache (1.2) lib/rack/cache/context.rb:51:in `call'
  railties (3.2.6) lib/rails/engine.rb:479:in `call'
  railties (3.2.6) lib/rails/application.rb:220:in `call'
  railties (3.2.6) lib/rails/railtie/configurable.rb:30:in `method_missing'
  passenger (3.0.15) lib/phusion_passenger/rack/request_handler.rb:96:in `process_request'
  passenger (3.0.15) lib/phusion_passenger/abstract_request_handler.rb:516:in `accept_and_process_next_request'
  passenger (3.0.15) lib/phusion_passenger/abstract_request_handler.rb:274:in `main_loop'
  passenger (3.0.15) lib/phusion_passenger/rack/application_spawner.rb:206:in `start_request_handler'
  passenger (3.0.15) lib/phusion_passenger/rack/application_spawner.rb:171:in `block in handle_spawn_application'
  passenger (3.0.15) lib/phusion_passenger/utils.rb:470:in `safe_fork'
  passenger (3.0.15) lib/phusion_passenger/rack/application_spawner.rb:166:in `handle_spawn_application'
  passenger (3.0.15) lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
  passenger (3.0.15) lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
  passenger (3.0.15) lib/phusion_passenger/abstract_server.rb:180:in `start'
  passenger (3.0.15) lib/phusion_passenger/rack/application_spawner.rb:129:in `start'
  passenger (3.0.15) lib/phusion_passenger/spawn_manager.rb:253:in `block (2 levels) in spawn_rack_application'
  passenger (3.0.15) lib/phusion_passenger/abstract_server_collection.rb:132:in `lookup_or_add'
  passenger (3.0.15) lib/phusion_passenger/spawn_manager.rb:246:in `block in spawn_rack_application'
  passenger (3.0.15) lib/phusion_passenger/abstract_server_collection.rb:82:in `block in synchronize'
  <internal:prelude>:10:in `synchronize'
  passenger (3.0.15) lib/phusion_passenger/abstract_server_collection.rb:79:in `synchronize'
  passenger (3.0.15) lib/phusion_passenger/spawn_manager.rb:244:in `spawn_rack_application'
  passenger (3.0.15) lib/phusion_passenger/spawn_manager.rb:137:in `spawn_application'
  passenger (3.0.15) lib/phusion_passenger/spawn_manager.rb:275:in `handle_spawn_application'
  passenger (3.0.15) lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
  passenger (3.0.15) lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
  passenger (3.0.15) helper-scripts/passenger-spawn-server:99:in `<main>'

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

Fixed it in the end so that inplace method of AdtaskinlController looks like this

  def inplace
    # element_id filtered too!
    attribs = params.select{|k,v| k != 'id' && k != 'project_id' && SprintsTasks.column_names.include?(k) }
    attribs = Hash[*attribs.flatten]
    param_id = attribs.flatten[0]

    task = SprintsTasks.find(params[:id], :include => :assigned_to)
    begin
      task.init_journal(User.current)
      result = task.update_attributes(attribs)
    rescue => e
      render :text => e.message.blank? ? e.to_s : e.message, :status => 400
      return
    end

    status = (result ? 200 : 400)
    task.reload

    new_value = param_id == 'assigned_to_id' ? task.assigned_to : task[param_id]
    respond_to do |format|
      format.html { render :text => new_value, :status => status }
    end
  end

Hope that helps ;)

RE: Agile Dwarf project management plugin released - Added by Leonardo Carneiro over 11 years ago

Hi Michael!

I kinda fixed the syntax error that i found in that query in postgresql. When you got time, please, take a look: https://github.com/iRessources/AgileDwarf/issues/9

tks in advance

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Thank you, Leonardo Carneiro.

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

just found another weird problem: cannot update end time for a sprint.

Start time gets updated OK.
End time does not work.. no error, nothing, just does not get updated..

P.S.: Found it after some investigation: the date format is being sent in US standard MM/DD/YYYY, while the server is set up to parse it as DD/MM/YYYY. Any advice on how to fix that? :)

RE: Agile Dwarf project management plugin released - Added by Michael K. over 11 years ago

Yep, thanks, Vladimir Dzalbo, I'll let you know when the fix is available.

RE: Agile Dwarf project management plugin released - Added by Vladimir Dzalbo over 11 years ago

another fix I made yesterday:

in burndown.js had to replace tasks[id] with tasks[id].sprints_tasks in couple of place to get the Chart display correctly

 obj.setOptions = function (d, spent, tasks, changes)
    {
        opt = d;

        if (!spent.length || !changes.length)
            return ;

        // spent series
        var cur = 0;
        for (var i = 0, len = spent.length; i < len; i++)
        {
            var curSpent = spent[i];
            cur += curSpent[1];
            curSpent[1] = Math.ceil(cur);
            curSpent[0] = Date.fromMysql(curSpent[0]);
        }

        // rest series
        var rest = [];
        // correct issues dates
        for (var id in tasks)
        {
            if (!tasks.hasOwnProperty(id))
                continue;
            tasks[id].sprints_tasks.created_on = Date.fromMysql(tasks[id].sprints_tasks.created_on);
        }
        // loop through changes
        for (i = 0, len = changes.length; i < len; )
        {
            // chart date
            var dateTime = Date.fromMysql(changes[i].created_on), changeDate = dateTime;

            // calculate sum of rest times for issues on the end of day with changes (when all changes was been apllied)
            var sum = 0;
            for (id in tasks)
            {
                if (!tasks.hasOwnProperty(id))
                    continue;
                var task = tasks[id].sprints_tasks;
                // delete tasks, that was created after current date
                if (task.created_on > dateTime)
                    delete tasks[id];
                else
                {
                    // rest of work = ((100 - done_ratio) * estimate) / 100
                    sum += ((100 - task.done_ratio) * (task.estimated_hours || 0)) / 100;
                }
            }
            // add new point to series
            rest.push([dateTime, Math.ceil(sum)]);

            // rollback changes in this day
            while (dateTime == changeDate)
            {
                if (changes[i].prop_key == 'done_ratio')
                    tasks[changes[i].issueId].sprints_tasks.done_ratio = changes[i].value;
                else
                    tasks[changes[i].issueId].sprints_tasks.estimated_hours = changes[i].value;
                // next change
                i++;
                if (i >= len)
                    break;
                changeDate = Date.fromMysql(changes[i].created_on);
            }

        }

(1-25/29)