Skip to content

Instantly share code, notes, and snippets.

@TMorgan99
Created June 29, 2009 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TMorgan99/137873 to your computer and use it in GitHub Desktop.
Save TMorgan99/137873 to your computer and use it in GitHub Desktop.
#!/bin/sh
## Build Agility
rm -fr agility
hobo agility
cd agility
# add db:seeds rake task
cat <<__PATCH |patch -p1
patch rails for db:seeds
diff --git a/lib/tasks/database.rake b/lib/tasks/database.rake
new file mode 100644
index 0000000..c8114f0
--- /dev/null
+++ b/lib/tasks/database.rake
@@ -0,0 +1,15 @@
+# until rails 3.0, we grab this task from the edge...
+namespace :db do
+ desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
+ task :reset => [ 'db:drop', 'db:setup' ]
+
+ desc 'Create the database, load the schema, and initialize with the seed data'
+ task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
+
+ desc 'Load the seed data from db/seeds.rb'
+ task :seed => :environment do
+ seed_file = File.join(Rails.root, 'db', 'seeds.rb')
+ load(seed_file) if File.exist?(seed_file)
+ end
+end
+
__PATCH
# add cucumber and rspec
./script/generate rspec -q
./script/generate cucumber -q
# Generate the app, models and resources
./script/generate hobo_model_resource project name:string
./script/generate hobo_model_resource story title:string body:text status:string
./script/generate hobo_model_resource task description:string
./script/generate hobo_model task_assignment
# Associations
cat <<__PATCH |patch -p1
* The Models associations
diff --git a/app/models/project.rb b/app/models/project.rb
index 7dc4ebc..a6f4e3b 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -7,6 +7,7 @@ class Project < ActiveRecord::Base
timestamps
end
+ has_many :stories, :dependent => :destroy
# --- Permissions --- #
diff --git a/app/models/story.rb b/app/models/story.rb
index 7f2e550..1d3b609 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -9,6 +9,9 @@ class Story < ActiveRecord::Base
timestamps
end
+ belongs_to :project
+
+ has_many :tasks, :dependent => :destroy
# --- Permissions --- #
diff --git a/app/models/task.rb b/app/models/task.rb
index 23479ba..f79516b 100644
--- a/app/models/task.rb
+++ b/app/models/task.rb
@@ -7,6 +7,10 @@ class Task < ActiveRecord::Base
timestamps
end
+ belongs_to :story
+
+ has_many :task_assignments, :dependent => :destroy
+ has_many :users, :through => :task_assignments
# --- Permissions --- #
diff --git a/app/models/task_assignment.rb b/app/models/task_assignment.rb
index 486f72f..b420c68 100644
--- a/app/models/task_assignment.rb
+++ b/app/models/task_assignment.rb
@@ -6,6 +6,8 @@ class TaskAssignment < ActiveRecord::Base
timestamps
end
+ belongs_to :user
+ belongs_to :task
# --- Permissions --- #
diff --git a/app/models/user.rb b/app/models/user.rb
index 21366ba..8ab0d4b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -9,6 +9,9 @@ class User < ActiveRecord::Base
timestamps
end
+ has_many :task_assignments, :dependent => :destroy
+ has_many :tasks, :through => :task_assignments
+
# This gives admin rights to the first sign-up.
# Just remove it if you don't want that
before_create { |user| user.administrator = true if RAILS_ENV != "test" && count == 0 }
__PATCH
# Run the Hobo Migrator
./script/generate hobo_migration initial_models --default-name --migrate
# Removing Actions / Permissions
cat <<__PATCH |patch -p1
* The Models actions and permissions
diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb
index f0dd368..a54eec1 100644
--- a/app/controllers/stories_controller.rb
+++ b/app/controllers/stories_controller.rb
@@ -2,6 +2,8 @@ class StoriesController < ApplicationController
hobo_model_controller
- auto_actions :all
+ auto_actions :all, :except => :index
+
+ auto_actions_for :project, [:new, :create]
end
diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb
index f5a4f00..7423c3b 100644
--- a/app/controllers/tasks_controller.rb
+++ b/app/controllers/tasks_controller.rb
@@ -2,6 +2,8 @@ class TasksController < ApplicationController
hobo_model_controller
- auto_actions :all
+ auto_actions :write_only, :edit
+
+ auto_actions_for :story, :create
end
diff --git a/app/models/story.rb b/app/models/story.rb
index 1d3b609..aaae40a 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -20,7 +20,7 @@ class Story < ActiveRecord::Base
end
def update_permitted?
- acting_user.administrator?
+ acting_user.signed_up? && !project_changed?
end
def destroy_permitted?
diff --git a/app/models/task.rb b/app/models/task.rb
index f79516b..8fad2b5 100644
--- a/app/models/task.rb
+++ b/app/models/task.rb
@@ -10,7 +10,7 @@ class Task < ActiveRecord::Base
belongs_to :story
has_many :task_assignments, :dependent => :destroy
- has_many :users, :through => :task_assignments
+ has_many :users, :through => :task_assignments, :accessible => true
# --- Permissions --- #
@@ -19,7 +19,7 @@ class Task < ActiveRecord::Base
end
def update_permitted?
- acting_user.administrator?
+ acting_user.signed_up? && !story_changed?
end
def destroy_permitted?
__PATCH
# Customising views
cat <<__PATCH |patch -p1
* Dryml intro
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 210b07d..a14339c 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -4,4 +4,11 @@ class ProjectsController < ApplicationController
auto_actions :all
+ def show
+ @project = find_instance
+ @stories =
+ @project.stories.apply_scopes(:search => [params[:search], :title],
+ :order_by => parse_sort_param(:title, :status))
+ end
+
end
diff --git a/app/views/projects/show.dryml b/app/views/projects/show.dryml
new file mode 100644
index 0000000..2e8a3a2
--- /dev/null
+++ b/app/views/projects/show.dryml
@@ -0,0 +1,7 @@
+<show-page>
+ <collection: replace>
+ <table-plus with="&@stories" fields="this, tasks.count, status">
+ <empty-message:>No stories match your criteria</empty-message:>
+ </table-plus>
+ </collection:>
+</show-page>
diff --git a/app/views/taglibs/application.dryml b/app/views/taglibs/application.dryml
index 92c7ebe..c9548da 100644
--- a/app/views/taglibs/application.dryml
+++ b/app/views/taglibs/application.dryml
@@ -8,4 +8,12 @@
<def tag="app-name">Agility</def>
-
+<extend tag="card" for="Task">
+ <old-card merge>
+ <append-body:>
+ <div class="users">
+ Assigned users: <repeat:users join=", "><a/></repeat><else>None</else>
+ </div>
+ </append-body:>
+ </old-card>
+</extend>
diff --git a/app/views/users/show.dryml b/app/views/users/show.dryml
new file mode 100644
index 0000000..a2e5c01
--- /dev/null
+++ b/app/views/users/show.dryml
@@ -0,0 +1,9 @@
+<show-page>
+ <content-body:>
+ <h3><Your/> Assigned Tasks</h3>
+ <repeat with="&@user.tasks.group_by(&:story)">
+ <h4>Story: <a with="&this_key"/></h4>
+ <collection/>
+ </repeat>
+ </content-body:>
+</show-page>
__PATCH
# Add User Activation
cat <<__PATCH |patch -p1
* User Activation
diff --git a/app/models/user.rb b/app/models/user.rb
index 8ab0d4b..db88be2 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -20,12 +20,16 @@ class User < ActiveRecord::Base
# --- Signup lifecycle --- #
lifecycle do
-
- state :active, :default => true
+ state :inactive, :default => true
+ state :active
create :signup, :available_to => "Guest",
:params => [:name, :email_address, :password, :password_confirmation],
- :become => :active
+ :become => :inactive, :new_key => true do
+ UserMailer.deliver_activation(self, lifecycle.key)
+ end
+
+ transition :activate, { :inactive => :active }, :available_to => :key_holder
transition :request_password_reset, { :active => :active }, :new_key => true do
UserMailer.deliver_forgot_password(self, lifecycle.key)
diff --git a/app/models/user_mailer.rb b/app/models/user_mailer.rb
index 76eb31c..a1bd10c 100644
--- a/app/models/user_mailer.rb
+++ b/app/models/user_mailer.rb
@@ -11,4 +11,15 @@ class UserMailer < ActionMailer::Base
@headers = {}
end
+ def activation(user, key)
+ host = Hobo::Controller.request_host
+ app_name = Hobo::Controller.app_name || host
+ @subject = "#{app_name} -- activate"
+ @body = { :user => user, :key => key, :host => host, :app_name => app_name }
+ @recipients = user.email_address
+ @from = "no-reply@#{host}"
+ @sent_on = Time.now
+ @headers = {}
+ end
+
end
diff --git a/app/views/user_mailer/activation.erb b/app/views/user_mailer/activation.erb
new file mode 100644
index 0000000..d8f0b56
--- /dev/null
+++ b/app/views/user_mailer/activation.erb
@@ -0,0 +1,9 @@
+<%= @user %>,
+
+To activate your account for <%= @app_name %>, click on this link:
+
+ <%= user_activate_url :host => @host, :id => @user, :key => @key %>
+
+Thank you,
+
+The <%= @app_name %> team.
diff --git a/config/initializers/mailer.rb b/config/initializers/mailer.rb
new file mode 100644
index 0000000..82dbdeb
--- /dev/null
+++ b/config/initializers/mailer.rb
@@ -0,0 +1,9 @@
+ActionMailer::Base.delivery_method = :smtp
+ActionMailer::Base.smtp_settings = {
+# :address => "smtp.example.com",
+# :port => 25,
+# :domain => "example.com",
+# :authentication => :login,
+# :user_name => "username",
+# :password => "password",
+}
__PATCH
# Run the Hobo Migrator
./script/generate hobo_migration user_activation --default-name --migrate
# Odds and ends
# Generate StoryStatus resource
./script/generate hobo_model_resource story_status name:string
# Story Status association/action/permission
cat <<__PATCH |patch -p1
* Story Status seed/associations/actions/permissions
diff --git a/app/controllers/story_statuses_controller.rb b/app/controllers/story_statuses_controller.rb
index 53a3817..318bad5 100644
--- a/app/controllers/story_statuses_controller.rb
+++ b/app/controllers/story_statuses_controller.rb
@@ -2,6 +2,6 @@ class StoryStatusesController < ApplicationController
hobo_model_controller
- auto_actions :all
+ auto_actions :write_only, :new, :index
end
diff --git a/app/models/story.rb b/app/models/story.rb
index aaae40a..e497310 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -5,11 +5,11 @@ class Story < ActiveRecord::Base
fields do
title :string
body :text
- status :string
timestamps
end
belongs_to :project
+ belongs_to :status, :class_name => "StoryStatus"
has_many :tasks, :dependent => :destroy
@@ -31,4 +31,9 @@ class Story < ActiveRecord::Base
true
end
+ # force 'new' status at create.
+ def before_create
+ self.status = @default_status ||= StoryStatus.find_by_name( 'new' )
+ end
+
end
diff --git a/app/views/stories/show.dryml b/app/views/stories/show.dryml
new file mode 100644
index 0000000..122a7a2
--- /dev/null
+++ b/app/views/stories/show.dryml
@@ -0,0 +1,3 @@
+<show-page>
+ <field-list: tag="editor"/>
+</show-page>
diff --git a/db/seeds.rb b/db/seeds.rb
new file mode 100644
index 0000000..ac68552
--- /dev/null
+++ b/db/seeds.rb
@@ -0,0 +1,3 @@
+# Story Status
+statuses = %w(new accepted discussion implementation user_testing deployed rejected)
+statuses.each { |status| StoryStatus.create :name => status }
__PATCH
# Run the Hobo Migrator
./script/generate hobo_migration story_status_model --default-name --force-drop --migrate
# Use the new (Rails 3.0) rake task to seed the storystatus table
rake -s db:seed
# Filtering stories by status
cat <<__PATCH |patch -p1
* Story Status filter on Project
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a14339c..3a75081 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -8,6 +8,7 @@ class ProjectsController < ApplicationController
@project = find_instance
@stories =
@project.stories.apply_scopes(:search => [params[:search], :title],
+ :status_is => params[:status],
:order_by => parse_sort_param(:title, :status))
end
diff --git a/app/views/projects/show.dryml b/app/views/projects/show.dryml
index 2e8a3a2..ccf08e2 100644
--- a/app/views/projects/show.dryml
+++ b/app/views/projects/show.dryml
@@ -1,6 +1,11 @@
<show-page>
<collection: replace>
<table-plus with="&@stories" fields="this, tasks.count, status">
+ <prepend-header:>
+ <div class="filter">
+ Display by status: <filter-menu param-name="status" options="&StoryStatus.all"/>
+ </div>
+ </prepend-header:>
<empty-message:>No stories match your criteria</empty-message:>
</table-plus>
</collection:>
diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css
index e69de29..9fc31c9 100644
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -0,0 +1,2 @@
+.show-page.project .filter {float: left;}
+.show-page.project .filter form, .show-page.project .filter form div {display: inline;}
__PATCH
# Add Acts as List plugin
./script/plugin install acts_as_list
cat <<__PATCH |patch -p1
* Acting as list
diff --git a/app/models/story.rb b/app/models/story.rb
index e497310..93c31bd 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -11,7 +11,7 @@ class Story < ActiveRecord::Base
belongs_to :project
belongs_to :status, :class_name => "StoryStatus"
- has_many :tasks, :dependent => :destroy
+ has_many :tasks, :dependent => :destroy, :order => :position
# --- Permissions --- #
diff --git a/app/models/task.rb b/app/models/task.rb
index 8fad2b5..6c14685 100644
--- a/app/models/task.rb
+++ b/app/models/task.rb
@@ -9,6 +9,9 @@ class Task < ActiveRecord::Base
belongs_to :story
+ acts_as_list :scope => :story
+ attr_protected :position
+
has_many :task_assignments, :dependent => :destroy
has_many :users, :through => :task_assignments, :accessible => true
diff --git a/app/views/tasks/edit.dryml b/app/views/tasks/edit.dryml
new file mode 100644
index 0000000..fdee2fe
--- /dev/null
+++ b/app/views/tasks/edit.dryml
@@ -0,0 +1,5 @@
+<edit-page>
+ <form:>
+ <cancel: with="&this.story"/>
+ </form:>
+</edit-page>
__PATCH
# Run the Hobo Migrator
./script/generate hobo_migration acts_as_list --default-name --migrate
# Markdown / Textile formatting of stories
cat <<__PATCH |patch -p1
* Markdown
diff --git a/app/models/story.rb b/app/models/story.rb
index 93c31bd..39651df 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -4,7 +4,7 @@ class Story < ActiveRecord::Base
fields do
title :string
- body :text
+ body :markdown
timestamps
end
diff --git a/config/environment.rb b/config/environment.rb
index f95dfb7..2b0ea3a 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -9,6 +9,8 @@ require File.join(File.dirname(__FILE__), 'boot')
Rails::Initializer.run do |config|
config.gem 'hobo'
+ config.gem 'bluecloth'
+
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
__PATCH
rake -s gems:install
# touch up front page.
cat <<__PATCH |patch -p1
* User front page
diff --git a/app/views/front/index.dryml b/app/views/front/index.dryml
index ef5c3a5..670c62e 100644
--- a/app/views/front/index.dryml
+++ b/app/views/front/index.dryml
@@ -13,7 +13,9 @@
</section>
</header>
- <section class="content-body">
+ <section class="content-body" if="&logged_in?">
+ <h3>Your Projects</h3>
+ <collection:projects with="&current_user"><card without-creator-link/></collection>
</section>
</content:>
__PATCH
# Project ownership
cat <<__PATCH |patch -p1
* Project Ownership - association/permission
diff --git a/app/models/project.rb b/app/models/project.rb
index a6f4e3b..f3a877a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -9,18 +9,20 @@ class Project < ActiveRecord::Base
has_many :stories, :dependent => :destroy
+ belongs_to :owner, :class_name => "User", :creator => true
+
# --- Permissions --- #
def create_permitted?
- acting_user.administrator?
+ owner_is? acting_user
end
def update_permitted?
- acting_user.administrator?
+ acting_user.administrator? || (owner_is?(acting_user) && !owner_changed?)
end
def destroy_permitted?
- acting_user.administrator?
+ acting_user.administrator? || owner_is?(acting_user)
end
def view_permitted?(field)
diff --git a/app/models/user.rb b/app/models/user.rb
index db88be2..e85cef0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -11,6 +11,7 @@ class User < ActiveRecord::Base
has_many :task_assignments, :dependent => :destroy
has_many :tasks, :through => :task_assignments
+ has_many :projects, :class_name => "Project", :foreign_key => "owner_id"
# This gives admin rights to the first sign-up.
# Just remove it if you don't want that
__PATCH
# Project Ownership - migration
./script/generate hobo_migration project_ownership --default-name --migrate
# Granting read access to others
./script/generate hobo_model_resource project_membership
# Project Membership - association/action
cat <<__PATCH |patch -p1
* Project Membership - association/action
diff --git a/app/controllers/project_memberships_controller.rb b/app/controllers/project_memberships_controller.rb
index aa14a80..4e32ec5 100644
--- a/app/controllers/project_memberships_controller.rb
+++ b/app/controllers/project_memberships_controller.rb
@@ -2,6 +2,6 @@ class ProjectMembershipsController < ApplicationController
hobo_model_controller
- auto_actions :all
+ auto_actions :write_only
end
diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb
index b0a4acb..f5e6703 100644
--- a/app/models/project_membership.rb
+++ b/app/models/project_membership.rb
@@ -6,6 +6,8 @@ class ProjectMembership < ActiveRecord::Base
timestamps
end
+ belongs_to :project
+ belongs_to :user
# --- Permissions --- #
__PATCH
# Project Membership migration
./script/generate hobo_migration project_memberships --default-name --migrate
# Project Membership associations/actions/permissions
cat <<__PATCH |patch -p1
* Project Membership associations/actions/permissions
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 3a75081..caa8d5a 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -2,7 +2,9 @@ class ProjectsController < ApplicationController
hobo_model_controller
- auto_actions :all
+ auto_actions :show, :edit, :update, :destroy
+
+ auto_actions_for :owner, [:new, :create]
def show
@project = find_instance
diff --git a/app/models/project.rb b/app/models/project.rb
index f3a877a..be59f11 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -8,6 +8,8 @@ class Project < ActiveRecord::Base
end
has_many :stories, :dependent => :destroy
+ has_many :memberships, :class_name => "ProjectMembership", :dependent => :destroy
+ has_many :members, :through => :memberships, :source => :user
belongs_to :owner, :class_name => "User", :creator => true
@@ -26,7 +28,7 @@ class Project < ActiveRecord::Base
end
def view_permitted?(field)
- true
+ acting_user.administrator? || acting_user == owner || acting_user.in?(members)
end
end
diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb
index f5e6703..b7cc12e 100644
--- a/app/models/project_membership.rb
+++ b/app/models/project_membership.rb
@@ -12,15 +12,15 @@ class ProjectMembership < ActiveRecord::Base
# --- Permissions --- #
def create_permitted?
- acting_user.administrator?
+ acting_user.administrator? || project.owner_is?(acting_user)
end
def update_permitted?
- acting_user.administrator?
+ acting_user.administrator? || project.owner_is?(acting_user)
end
def destroy_permitted?
- acting_user.administrator?
+ acting_user.administrator? || project.owner_is?(acting_user)
end
def view_permitted?(field)
diff --git a/app/models/story.rb b/app/models/story.rb
index 39651df..f08e141 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -28,7 +28,7 @@ class Story < ActiveRecord::Base
end
def view_permitted?(field)
- true
+ project.viewable_by?(acting_user)
end
# force 'new' status at create.
diff --git a/app/models/task.rb b/app/models/task.rb
index 6c14685..a1053d2 100644
--- a/app/models/task.rb
+++ b/app/models/task.rb
@@ -30,7 +30,7 @@ class Task < ActiveRecord::Base
end
def view_permitted?(field)
- true
+ story.viewable_by?(acting_user)
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index e85cef0..8b9ef5a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,8 @@ class User < ActiveRecord::Base
has_many :task_assignments, :dependent => :destroy
has_many :tasks, :through => :task_assignments
has_many :projects, :class_name => "Project", :foreign_key => "owner_id"
+ has_many :project_memberships, :dependent => :destroy
+ has_many :joined_projects, :through => :project_memberships, :source => :project
# This gives admin rights to the first sign-up.
# Just remove it if you don't want that
__PATCH
# Project Contributor associations/actions/permissions
cat <<__PATCH |patch -p1
* Project Contributor associations/actions/permissions
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index caa8d5a..4f11ceb 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -6,6 +6,11 @@ class ProjectsController < ApplicationController
auto_actions_for :owner, [:new, :create]
+ autocomplete :new_member_name do
+ project = find_instance
+ hobo_completions :name, User.without_project(project).is_not(project.owner)
+ end
+
def show
@project = find_instance
@stories =
diff --git a/app/models/project.rb b/app/models/project.rb
index be59f11..bfc7c8e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -13,6 +13,14 @@ class Project < ActiveRecord::Base
belongs_to :owner, :class_name => "User", :creator => true
+ has_many :contributor_memberships, :class_name => "ProjectMembership", :scope => :contributor
+ has_many :contributors, :through => :contributor_memberships, :source => :user
+
+ # permission helper
+ def accepts_changes_from?(user)
+ user.administrator? || user == owner || user.in?(contributors)
+ end
+
# --- Permissions --- #
def create_permitted?
@@ -20,7 +28,7 @@ class Project < ActiveRecord::Base
end
def update_permitted?
- acting_user.administrator? || (owner_is?(acting_user) && !owner_changed?)
+ accepts_changes_from?(acting_user) && !owner_changed?
end
def destroy_permitted?
diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb
index b7cc12e..33c2285 100644
--- a/app/models/project_membership.rb
+++ b/app/models/project_membership.rb
@@ -3,6 +3,7 @@ class ProjectMembership < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
+ contributor :boolean, :default => false
timestamps
end
diff --git a/app/models/story.rb b/app/models/story.rb
index f08e141..2846d76 100644
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -16,15 +16,15 @@ class Story < ActiveRecord::Base
# --- Permissions --- #
def create_permitted?
- acting_user.administrator?
+ project.creatable_by?(acting_user)
end
def update_permitted?
- acting_user.signed_up? && !project_changed?
+ project.updatable_by?(acting_user)
end
def destroy_permitted?
- acting_user.administrator?
+ project.destroyable_by?(acting_user)
end
def view_permitted?(field)
diff --git a/app/models/task.rb b/app/models/task.rb
index a1053d2..0c058dd 100644
--- a/app/models/task.rb
+++ b/app/models/task.rb
@@ -18,15 +18,15 @@ class Task < ActiveRecord::Base
# --- Permissions --- #
def create_permitted?
- acting_user.administrator?
+ story.creatable_by?(acting_user)
end
def update_permitted?
- acting_user.signed_up? && !story_changed?
+ story.updatable_by?(acting_user)
end
def destroy_permitted?
- acting_user.administrator?
+ story.destroyable_by?(acting_user)
end
def view_permitted?(field)
diff --git a/app/models/task_assignment.rb b/app/models/task_assignment.rb
index b420c68..8f11a46 100644
--- a/app/models/task_assignment.rb
+++ b/app/models/task_assignment.rb
@@ -12,19 +12,19 @@ class TaskAssignment < ActiveRecord::Base
# --- Permissions --- #
def create_permitted?
- acting_user.administrator?
+ task.creatable_by?(acting_user)
end
def update_permitted?
- acting_user.administrator?
+ task.updatable_by?(acting_user)
end
def destroy_permitted?
- acting_user.administrator?
+ task.destroyable_by?(acting_user)
end
def view_permitted?(field)
- true
+ task.viewable_by?(acting_user)
end
end
diff --git a/app/viewhints/project_hints.rb b/app/viewhints/project_hints.rb
index c0c7e8c..21a1a45 100644
--- a/app/viewhints/project_hints.rb
+++ b/app/viewhints/project_hints.rb
@@ -1,4 +1,3 @@
class ProjectHints < Hobo::ViewHints
-
-
+ children :stories, :memberships
end
__PATCH
# Project Contributor migration
./script/generate hobo_migration project_contributorships --default-name --migrate
# Project Contributor view layer
cat <<__PATCH |patch -p1
* Project Contributor view layer
diff --git a/app/views/front/index.dryml b/app/views/front/index.dryml
index 670c62e..a7ff9bc 100644
--- a/app/views/front/index.dryml
+++ b/app/views/front/index.dryml
@@ -13,9 +13,14 @@
</section>
</header>
- <section class="content-body" if="&logged_in?">
+ <section with="&current_user" class="content-body" if="&logged_in?">
<h3>Your Projects</h3>
- <collection:projects with="&current_user"><card without-creator-link/></collection>
+ <collection:projects><card without-creator-link/></collection>
+
+ <a:projects action="new">New Project</a>
+
+ <h3>Projects you have joined</h3>
+ <collection:joined-projects><card without-creator-link/></collection>
</section>
</content:>
diff --git a/app/views/projects/show.dryml b/app/views/projects/show.dryml
index ccf08e2..8c11a0b 100644
--- a/app/views/projects/show.dryml
+++ b/app/views/projects/show.dryml
@@ -9,4 +9,19 @@
<empty-message:>No stories match your criteria</empty-message:>
</table-plus>
</collection:>
+
+ <aside:>
+ <h2>Project Members</h2>
+ <collection:memberships part="members">
+ <card><heading:><a:user/></heading:></card>
+ </collection>
+
+ <form:memberships.new update="members" reset-form refocus-form>
+ <div>
+ Add a member:
+ <name-one:user complete-target="&@project" completer="new_member_name"/>
+ </div>
+ </form>
+ </aside:>
+
</show-page>
diff --git a/app/views/taglibs/application.dryml b/app/views/taglibs/application.dryml
index c9548da..c4c2888 100644
--- a/app/views/taglibs/application.dryml
+++ b/app/views/taglibs/application.dryml
@@ -17,3 +17,13 @@
</append-body:>
</old-card>
</extend>
+
+<extend tag="card" for="ProjectMembership">
+ <old-card merge>
+ <body:>
+ <span>Contributor?</span>
+ <editor:contributor/>
+ </body:>
+ </old-card>
+</extend>
+
__PATCH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment