Guest User

Untitled

a guest
Apr 12th, 2018
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.21 KB | None | 0 0
  1. #!/bin/sh
  2. ## Build Agility
  3. rm -fr agility
  4. hobo agility
  5. cd agility
  6.  
  7. # add db:seeds rake task
  8. cat <<__PATCH |patch -p1
  9.  
  10. patch rails for db:seeds
  11.  
  12. diff --git a/lib/tasks/database.rake b/lib/tasks/database.rake
  13. new file mode 100644
  14. index 0000000..c8114f0
  15. --- /dev/null
  16. +++ b/lib/tasks/database.rake
  17. @@ -0,0 +1,15 @@
  18. +# until rails 3.0, we grab this task from the edge...
  19. +namespace :db do
  20. + desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
  21. + task :reset => [ 'db:drop', 'db:setup' ]
  22. +
  23. + desc 'Create the database, load the schema, and initialize with the seed data'
  24. + task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
  25. +
  26. + desc 'Load the seed data from db/seeds.rb'
  27. + task :seed => :environment do
  28. + seed_file = File.join(Rails.root, 'db', 'seeds.rb')
  29. + load(seed_file) if File.exist?(seed_file)
  30. + end
  31. +end
  32. +
  33. __PATCH
  34.  
  35. # add cucumber and rspec
  36. ./script/generate rspec -q
  37. ./script/generate cucumber -q
  38.  
  39. # Generate the app, models and resources
  40. ./script/generate hobo_model_resource project name:string
  41. ./script/generate hobo_model_resource story title:string body:text status:string
  42. ./script/generate hobo_model_resource task description:string
  43. ./script/generate hobo_model task_assignment
  44.  
  45. # Associations
  46. cat <<__PATCH |patch -p1
  47.  
  48. * The Models associations
  49.  
  50. diff --git a/app/models/project.rb b/app/models/project.rb
  51. index 7dc4ebc..a6f4e3b 100644
  52. --- a/app/models/project.rb
  53. +++ b/app/models/project.rb
  54. @@ -7,6 +7,7 @@ class Project < ActiveRecord::Base
  55. timestamps
  56. end
  57.  
  58. + has_many :stories, :dependent => :destroy
  59.  
  60. # --- Permissions --- #
  61.  
  62. diff --git a/app/models/story.rb b/app/models/story.rb
  63. index 7f2e550..1d3b609 100644
  64. --- a/app/models/story.rb
  65. +++ b/app/models/story.rb
  66. @@ -9,6 +9,9 @@ class Story < ActiveRecord::Base
  67. timestamps
  68. end
  69.  
  70. + belongs_to :project
  71. +
  72. + has_many :tasks, :dependent => :destroy
  73.  
  74. # --- Permissions --- #
  75.  
  76. diff --git a/app/models/task.rb b/app/models/task.rb
  77. index 23479ba..f79516b 100644
  78. --- a/app/models/task.rb
  79. +++ b/app/models/task.rb
  80. @@ -7,6 +7,10 @@ class Task < ActiveRecord::Base
  81. timestamps
  82. end
  83.  
  84. + belongs_to :story
  85. +
  86. + has_many :task_assignments, :dependent => :destroy
  87. + has_many :users, :through => :task_assignments
  88.  
  89. # --- Permissions --- #
  90.  
  91. diff --git a/app/models/task_assignment.rb b/app/models/task_assignment.rb
  92. index 486f72f..b420c68 100644
  93. --- a/app/models/task_assignment.rb
  94. +++ b/app/models/task_assignment.rb
  95. @@ -6,6 +6,8 @@ class TaskAssignment < ActiveRecord::Base
  96. timestamps
  97. end
  98.  
  99. + belongs_to :user
  100. + belongs_to :task
  101.  
  102. # --- Permissions --- #
  103.  
  104. diff --git a/app/models/user.rb b/app/models/user.rb
  105. index 21366ba..8ab0d4b 100644
  106. --- a/app/models/user.rb
  107. +++ b/app/models/user.rb
  108. @@ -9,6 +9,9 @@ class User < ActiveRecord::Base
  109. timestamps
  110. end
  111.  
  112. + has_many :task_assignments, :dependent => :destroy
  113. + has_many :tasks, :through => :task_assignments
  114. +
  115. # This gives admin rights to the first sign-up.
  116. # Just remove it if you don't want that
  117. before_create { |user| user.administrator = true if RAILS_ENV != "test" && count == 0 }
  118. __PATCH
  119.  
  120. # Run the Hobo Migrator
  121. ./script/generate hobo_migration initial_models --default-name --migrate
  122.  
  123. # Removing Actions / Permissions
  124. cat <<__PATCH |patch -p1
  125.  
  126. * The Models actions and permissions
  127.  
  128. diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb
  129. index f0dd368..a54eec1 100644
  130. --- a/app/controllers/stories_controller.rb
  131. +++ b/app/controllers/stories_controller.rb
  132. @@ -2,6 +2,8 @@ class StoriesController < ApplicationController
  133.  
  134. hobo_model_controller
  135.  
  136. - auto_actions :all
  137. + auto_actions :all, :except => :index
  138. +
  139. + auto_actions_for :project, [:new, :create]
  140.  
  141. end
  142. diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb
  143. index f5a4f00..7423c3b 100644
  144. --- a/app/controllers/tasks_controller.rb
  145. +++ b/app/controllers/tasks_controller.rb
  146. @@ -2,6 +2,8 @@ class TasksController < ApplicationController
  147.  
  148. hobo_model_controller
  149.  
  150. - auto_actions :all
  151. + auto_actions :write_only, :edit
  152. +
  153. + auto_actions_for :story, :create
  154.  
  155. end
  156. diff --git a/app/models/story.rb b/app/models/story.rb
  157. index 1d3b609..aaae40a 100644
  158. --- a/app/models/story.rb
  159. +++ b/app/models/story.rb
  160. @@ -20,7 +20,7 @@ class Story < ActiveRecord::Base
  161. end
  162.  
  163. def update_permitted?
  164. - acting_user.administrator?
  165. + acting_user.signed_up? && !project_changed?
  166. end
  167.  
  168. def destroy_permitted?
  169. diff --git a/app/models/task.rb b/app/models/task.rb
  170. index f79516b..8fad2b5 100644
  171. --- a/app/models/task.rb
  172. +++ b/app/models/task.rb
  173. @@ -10,7 +10,7 @@ class Task < ActiveRecord::Base
  174. belongs_to :story
  175.  
  176. has_many :task_assignments, :dependent => :destroy
  177. - has_many :users, :through => :task_assignments
  178. + has_many :users, :through => :task_assignments, :accessible => true
  179.  
  180. # --- Permissions --- #
  181.  
  182. @@ -19,7 +19,7 @@ class Task < ActiveRecord::Base
  183. end
  184.  
  185. def update_permitted?
  186. - acting_user.administrator?
  187. + acting_user.signed_up? && !story_changed?
  188. end
  189.  
  190. def destroy_permitted?
  191. __PATCH
  192.  
  193. # Customising views
  194. cat <<__PATCH |patch -p1
  195.  
  196. * Dryml intro
  197.  
  198. diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
  199. index 210b07d..a14339c 100644
  200. --- a/app/controllers/projects_controller.rb
  201. +++ b/app/controllers/projects_controller.rb
  202. @@ -4,4 +4,11 @@ class ProjectsController < ApplicationController
  203.  
  204. auto_actions :all
  205.  
  206. + def show
  207. + @project = find_instance
  208. + @stories =
  209. + @project.stories.apply_scopes(:search => [params[:search], :title],
  210. + :order_by => parse_sort_param(:title, :status))
  211. + end
  212. +
  213. end
  214. diff --git a/app/views/projects/show.dryml b/app/views/projects/show.dryml
  215. new file mode 100644
  216. index 0000000..2e8a3a2
  217. --- /dev/null
  218. +++ b/app/views/projects/show.dryml
  219. @@ -0,0 +1,7 @@
  220. +<show-page>
  221. + <collection: replace>
  222. + <table-plus with="&@stories" fields="this, tasks.count, status">
  223. + <empty-message:>No stories match your criteria</empty-message:>
  224. + </table-plus>
  225. + </collection:>
  226. +</show-page>
  227. diff --git a/app/views/taglibs/application.dryml b/app/views/taglibs/application.dryml
  228. index 92c7ebe..c9548da 100644
  229. --- a/app/views/taglibs/application.dryml
  230. +++ b/app/views/taglibs/application.dryml
  231. @@ -8,4 +8,12 @@
  232.  
  233. <def tag="app-name">Agility</def>
  234.  
  235. -
  236. +<extend tag="card" for="Task">
  237. + <old-card merge>
  238. + <append-body:>
  239. + <div class="users">
  240. + Assigned users: <repeat:users join=", "><a/></repeat><else>None</else>
  241. + </div>
  242. + </append-body:>
  243. + </old-card>
  244. +</extend>
  245. diff --git a/app/views/users/show.dryml b/app/views/users/show.dryml
  246. new file mode 100644
  247. index 0000000..a2e5c01
  248. --- /dev/null
  249. +++ b/app/views/users/show.dryml
  250. @@ -0,0 +1,9 @@
  251. +<show-page>
  252. + <content-body:>
  253. + <h3><Your/> Assigned Tasks</h3>
  254. + <repeat with="&@user.tasks.group_by(&:story)">
  255. + <h4>Story: <a with="&this_key"/></h4>
  256. + <collection/>
  257. + </repeat>
  258. + </content-body:>
  259. +</show-page>
  260. __PATCH
  261.  
  262. # Add User Activation
  263. cat <<__PATCH |patch -p1
  264.  
  265. * User Activation
  266.  
  267. diff --git a/app/models/user.rb b/app/models/user.rb
  268. index 8ab0d4b..db88be2 100644
  269. --- a/app/models/user.rb
  270. +++ b/app/models/user.rb
  271. @@ -20,12 +20,16 @@ class User < ActiveRecord::Base
  272. # --- Signup lifecycle --- #
  273.  
  274. lifecycle do
  275. -
  276. - state :active, :default => true
  277. + state :inactive, :default => true
  278. + state :active
  279.  
  280. create :signup, :available_to => "Guest",
  281. :params => [:name, :email_address, :password, :password_confirmation],
  282. - :become => :active
  283. + :become => :inactive, :new_key => true do
  284. + UserMailer.deliver_activation(self, lifecycle.key)
  285. + end
  286. +
  287. + transition :activate, { :inactive => :active }, :available_to => :key_holder
  288.  
  289. transition :request_password_reset, { :active => :active }, :new_key => true do
  290. UserMailer.deliver_forgot_password(self, lifecycle.key)
  291. diff --git a/app/models/user_mailer.rb b/app/models/user_mailer.rb
  292. index 76eb31c..a1bd10c 100644
  293. --- a/app/models/user_mailer.rb
  294. +++ b/app/models/user_mailer.rb
  295. @@ -11,4 +11,15 @@ class UserMailer < ActionMailer::Base
  296. @headers = {}
  297. end
  298.  
  299. + def activation(user, key)
  300. + host = Hobo::Controller.request_host
  301. + app_name = Hobo::Controller.app_name || host
  302. + @subject = "#{app_name} -- activate"
  303. + @body = { :user => user, :key => key, :host => host, :app_name => app_name }
  304. + @recipients = user.email_address
  305. + @from = "no-reply@#{host}"
  306. + @sent_on = Time.now
  307. + @headers = {}
  308. + end
  309. +
  310. end
  311. diff --git a/app/views/user_mailer/activation.erb b/app/views/user_mailer/activation.erb
  312. new file mode 100644
  313. index 0000000..d8f0b56
  314. --- /dev/null
  315. +++ b/app/views/user_mailer/activation.erb
  316. @@ -0,0 +1,9 @@
  317. +<%= @user %>,
  318. +
  319. +To activate your account for <%= @app_name %>, click on this link:
  320. +
  321. + <%= user_activate_url :host => @host, :id => @user, :key => @key %>
  322. +
  323. +Thank you,
  324. +
  325. +The <%= @app_name %> team.
  326. diff --git a/config/initializers/mailer.rb b/config/initializers/mailer.rb
  327. new file mode 100644
  328. index 0000000..82dbdeb
  329. --- /dev/null
  330. +++ b/config/initializers/mailer.rb
  331. @@ -0,0 +1,9 @@
  332. +ActionMailer::Base.delivery_method = :smtp
  333. +ActionMailer::Base.smtp_settings = {
  334. +# :address => "smtp.example.com",
  335. +# :port => 25,
  336. +# :domain => "example.com",
  337. +# :authentication => :login,
  338. +# :user_name => "username",
  339. +# :password => "password",
  340. +}
  341. __PATCH
  342.  
  343. # Run the Hobo Migrator
  344. ./script/generate hobo_migration user_activation --default-name --migrate
  345.  
  346. # Odds and ends
  347. # Generate StoryStatus resource
  348. ./script/generate hobo_model_resource story_status name:string
  349.  
  350. # Story Status association/action/permission
  351. cat <<__PATCH |patch -p1
  352.  
  353. * Story Status seed/associations/actions/permissions
  354.  
  355. diff --git a/app/controllers/story_statuses_controller.rb b/app/controllers/story_statuses_controller.rb
  356. index 53a3817..318bad5 100644
  357. --- a/app/controllers/story_statuses_controller.rb
  358. +++ b/app/controllers/story_statuses_controller.rb
  359. @@ -2,6 +2,6 @@ class StoryStatusesController < ApplicationController
  360.  
  361. hobo_model_controller
  362.  
  363. - auto_actions :all
  364. + auto_actions :write_only, :new, :index
  365.  
  366. end
  367. diff --git a/app/models/story.rb b/app/models/story.rb
  368. index aaae40a..e497310 100644
  369. --- a/app/models/story.rb
  370. +++ b/app/models/story.rb
  371. @@ -5,11 +5,11 @@ class Story < ActiveRecord::Base
  372. fields do
  373. title :string
  374. body :text
  375. - status :string
  376. timestamps
  377. end
  378.  
  379. belongs_to :project
  380. + belongs_to :status, :class_name => "StoryStatus"
  381.  
  382. has_many :tasks, :dependent => :destroy
  383.  
  384. @@ -31,4 +31,9 @@ class Story < ActiveRecord::Base
  385. true
  386. end
  387.  
  388. + # force 'new' status at create.
  389. + def before_create
  390. + self.status = @default_status ||= StoryStatus.find_by_name( 'new' )
  391. + end
  392. +
  393. end
  394. diff --git a/app/views/stories/show.dryml b/app/views/stories/show.dryml
  395. new file mode 100644
  396. index 0000000..122a7a2
  397. --- /dev/null
  398. +++ b/app/views/stories/show.dryml
  399. @@ -0,0 +1,3 @@
  400. +<show-page>
  401. + <field-list: tag="editor"/>
  402. +</show-page>
  403. diff --git a/db/seeds.rb b/db/seeds.rb
  404. new file mode 100644
  405. index 0000000..ac68552
  406. --- /dev/null
  407. +++ b/db/seeds.rb
  408. @@ -0,0 +1,3 @@
  409. +# Story Status
  410. +statuses = %w(new accepted discussion implementation user_testing deployed rejected)
  411. +statuses.each { |status| StoryStatus.create :name => status }
  412. __PATCH
  413.  
  414. # Run the Hobo Migrator
  415. ./script/generate hobo_migration story_status_model --default-name --force-drop --migrate
  416. # Use the new (Rails 3.0) rake task to seed the storystatus table
  417. rake -s db:seed
  418.  
  419. # Filtering stories by status
  420. cat <<__PATCH |patch -p1
  421.  
  422. * Story Status filter on Project
  423.  
  424. diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
  425. index a14339c..3a75081 100644
  426. --- a/app/controllers/projects_controller.rb
  427. +++ b/app/controllers/projects_controller.rb
  428. @@ -8,6 +8,7 @@ class ProjectsController < ApplicationController
  429. @project = find_instance
  430. @stories =
  431. @project.stories.apply_scopes(:search => [params[:search], :title],
  432. + :status_is => params[:status],
  433. :order_by => parse_sort_param(:title, :status))
  434. end
  435.  
  436. diff --git a/app/views/projects/show.dryml b/app/views/projects/show.dryml
  437. index 2e8a3a2..ccf08e2 100644
  438. --- a/app/views/projects/show.dryml
  439. +++ b/app/views/projects/show.dryml
  440. @@ -1,6 +1,11 @@
  441. <show-page>
  442. <collection: replace>
  443. <table-plus with="&@stories" fields="this, tasks.count, status">
  444. + <prepend-header:>
  445. + <div class="filter">
  446. + Display by status: <filter-menu param-name="status" options="&StoryStatus.all"/>
  447. + </div>
  448. + </prepend-header:>
  449. <empty-message:>No stories match your criteria</empty-message:>
  450. </table-plus>
  451. </collection:>
  452. diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css
  453. index e69de29..9fc31c9 100644
  454. --- a/public/stylesheets/application.css
  455. +++ b/public/stylesheets/application.css
  456. @@ -0,0 +1,2 @@
  457. +.show-page.project .filter {float: left;}
  458. +.show-page.project .filter form, .show-page.project .filter form div {display: inline;}
  459. __PATCH
  460.  
  461.  
  462. # Add Acts as List plugin
  463. ./script/plugin install acts_as_list
  464. cat <<__PATCH |patch -p1
  465.  
  466. * Acting as list
  467.  
  468. diff --git a/app/models/story.rb b/app/models/story.rb
  469. index e497310..93c31bd 100644
  470. --- a/app/models/story.rb
  471. +++ b/app/models/story.rb
  472. @@ -11,7 +11,7 @@ class Story < ActiveRecord::Base
  473. belongs_to :project
  474. belongs_to :status, :class_name => "StoryStatus"
  475.  
  476. - has_many :tasks, :dependent => :destroy
  477. + has_many :tasks, :dependent => :destroy, :order => :position
  478.  
  479. # --- Permissions --- #
  480.  
  481. diff --git a/app/models/task.rb b/app/models/task.rb
  482. index 8fad2b5..6c14685 100644
  483. --- a/app/models/task.rb
  484. +++ b/app/models/task.rb
  485. @@ -9,6 +9,9 @@ class Task < ActiveRecord::Base
  486.  
  487. belongs_to :story
  488.  
  489. + acts_as_list :scope => :story
  490. + attr_protected :position
  491. +
  492. has_many :task_assignments, :dependent => :destroy
  493. has_many :users, :through => :task_assignments, :accessible => true
  494.  
  495. diff --git a/app/views/tasks/edit.dryml b/app/views/tasks/edit.dryml
  496. new file mode 100644
  497. index 0000000..fdee2fe
  498. --- /dev/null
  499. +++ b/app/views/tasks/edit.dryml
  500. @@ -0,0 +1,5 @@
  501. +<edit-page>
  502. + <form:>
  503. + <cancel: with="&this.story"/>
  504. + </form:>
  505. +</edit-page>
  506. __PATCH
  507.  
  508. # Run the Hobo Migrator
  509. ./script/generate hobo_migration acts_as_list --default-name --migrate
  510.  
  511. # Markdown / Textile formatting of stories
  512. cat <<__PATCH |patch -p1
  513.  
  514. * Markdown
  515.  
  516. diff --git a/app/models/story.rb b/app/models/story.rb
  517. index 93c31bd..39651df 100644
  518. --- a/app/models/story.rb
  519. +++ b/app/models/story.rb
  520. @@ -4,7 +4,7 @@ class Story < ActiveRecord::Base
  521.  
  522. fields do
  523. title :string
  524. - body :text
  525. + body :markdown
  526. timestamps
  527. end
  528.  
  529. diff --git a/config/environment.rb b/config/environment.rb
  530. index f95dfb7..2b0ea3a 100644
  531. --- a/config/environment.rb
  532. +++ b/config/environment.rb
  533. @@ -9,6 +9,8 @@ require File.join(File.dirname(__FILE__), 'boot')
  534. Rails::Initializer.run do |config|
  535. config.gem 'hobo'
  536.  
  537. + config.gem 'bluecloth'
  538. +
  539. # Settings in config/environments/* take precedence over those specified here.
  540. # Application configuration should go into files in config/initializers
  541. # -- all .rb files in that directory are automatically loaded.
  542. __PATCH
  543. rake -s gems:install
  544.  
  545. # touch up front page.
  546. cat <<__PATCH |patch -p1
  547.  
  548. * User front page
  549.  
  550. diff --git a/app/views/front/index.dryml b/app/views/front/index.dryml
  551. index ef5c3a5..670c62e 100644
  552. --- a/app/views/front/index.dryml
  553. +++ b/app/views/front/index.dryml
  554. @@ -13,7 +13,9 @@
  555. </section>
  556. </header>
  557.  
  558. - <section class="content-body">
  559. + <section class="content-body" if="&logged_in?">
  560. + <h3>Your Projects</h3>
  561. + <collection:projects with="&current_user"><card without-creator-link/></collection>
  562. </section>
  563. </content:>
  564.  
  565. __PATCH
  566.  
  567. # Project ownership
  568. cat <<__PATCH |patch -p1
  569.  
  570. * Project Ownership - association/permission
  571.  
  572. diff --git a/app/models/project.rb b/app/models/project.rb
  573. index a6f4e3b..f3a877a 100644
  574. --- a/app/models/project.rb
  575. +++ b/app/models/project.rb
  576. @@ -9,18 +9,20 @@ class Project < ActiveRecord::Base
  577.  
  578. has_many :stories, :dependent => :destroy
  579.  
  580. + belongs_to :owner, :class_name => "User", :creator => true
  581. +
  582. # --- Permissions --- #
  583.  
  584. def create_permitted?
  585. - acting_user.administrator?
  586. + owner_is? acting_user
  587. end
  588.  
  589. def update_permitted?
  590. - acting_user.administrator?
  591. + acting_user.administrator? || (owner_is?(acting_user) && !owner_changed?)
  592. end
  593.  
  594. def destroy_permitted?
  595. - acting_user.administrator?
  596. + acting_user.administrator? || owner_is?(acting_user)
  597. end
  598.  
  599. def view_permitted?(field)
  600. diff --git a/app/models/user.rb b/app/models/user.rb
  601. index db88be2..e85cef0 100644
  602. --- a/app/models/user.rb
  603. +++ b/app/models/user.rb
  604. @@ -11,6 +11,7 @@ class User < ActiveRecord::Base
  605.  
  606. has_many :task_assignments, :dependent => :destroy
  607. has_many :tasks, :through => :task_assignments
  608. + has_many :projects, :class_name => "Project", :foreign_key => "owner_id"
  609.  
  610. # This gives admin rights to the first sign-up.
  611. # Just remove it if you don't want that
  612. __PATCH
  613.  
  614. # Project Ownership - migration
  615. ./script/generate hobo_migration project_ownership --default-name --migrate
  616.  
  617. # Granting read access to others
  618. ./script/generate hobo_model_resource project_membership
  619.  
  620. # Project Membership - association/action
  621. cat <<__PATCH |patch -p1
  622.  
  623. * Project Membership - association/action
  624.  
  625. diff --git a/app/controllers/project_memberships_controller.rb b/app/controllers/project_memberships_controller.rb
  626. index aa14a80..4e32ec5 100644
  627. --- a/app/controllers/project_memberships_controller.rb
  628. +++ b/app/controllers/project_memberships_controller.rb
  629. @@ -2,6 +2,6 @@ class ProjectMembershipsController < ApplicationController
  630.  
  631. hobo_model_controller
  632.  
  633. - auto_actions :all
  634. + auto_actions :write_only
  635.  
  636. end
  637. diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb
  638. index b0a4acb..f5e6703 100644
  639. --- a/app/models/project_membership.rb
  640. +++ b/app/models/project_membership.rb
  641. @@ -6,6 +6,8 @@ class ProjectMembership < ActiveRecord::Base
  642. timestamps
  643. end
  644.  
  645. + belongs_to :project
  646. + belongs_to :user
  647.  
  648. # --- Permissions --- #
  649.  
  650. __PATCH
  651.  
  652. # Project Membership migration
  653. ./script/generate hobo_migration project_memberships --default-name --migrate
  654.  
  655. # Project Membership associations/actions/permissions
  656. cat <<__PATCH |patch -p1
  657.  
  658. * Project Membership associations/actions/permissions
  659.  
  660. diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
  661. index 3a75081..caa8d5a 100644
  662. --- a/app/controllers/projects_controller.rb
  663. +++ b/app/controllers/projects_controller.rb
  664. @@ -2,7 +2,9 @@ class ProjectsController < ApplicationController
  665.  
  666. hobo_model_controller
  667.  
  668. - auto_actions :all
  669. + auto_actions :show, :edit, :update, :destroy
  670. +
  671. + auto_actions_for :owner, [:new, :create]
  672.  
  673. def show
  674. @project = find_instance
  675. diff --git a/app/models/project.rb b/app/models/project.rb
  676. index f3a877a..be59f11 100644
  677. --- a/app/models/project.rb
  678. +++ b/app/models/project.rb
  679. @@ -8,6 +8,8 @@ class Project < ActiveRecord::Base
  680. end
  681.  
  682. has_many :stories, :dependent => :destroy
  683. + has_many :memberships, :class_name => "ProjectMembership", :dependent => :destroy
  684. + has_many :members, :through => :memberships, :source => :user
  685.  
  686. belongs_to :owner, :class_name => "User", :creator => true
  687.  
  688. @@ -26,7 +28,7 @@ class Project < ActiveRecord::Base
  689. end
  690.  
  691. def view_permitted?(field)
  692. - true
  693. + acting_user.administrator? || acting_user == owner || acting_user.in?(members)
  694. end
  695.  
  696. end
  697. diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb
  698. index f5e6703..b7cc12e 100644
  699. --- a/app/models/project_membership.rb
  700. +++ b/app/models/project_membership.rb
  701. @@ -12,15 +12,15 @@ class ProjectMembership < ActiveRecord::Base
  702. # --- Permissions --- #
  703.  
  704. def create_permitted?
  705. - acting_user.administrator?
  706. + acting_user.administrator? || project.owner_is?(acting_user)
  707. end
  708.  
  709. def update_permitted?
  710. - acting_user.administrator?
  711. + acting_user.administrator? || project.owner_is?(acting_user)
  712. end
  713.  
  714. def destroy_permitted?
  715. - acting_user.administrator?
  716. + acting_user.administrator? || project.owner_is?(acting_user)
  717. end
  718.  
  719. def view_permitted?(field)
  720. diff --git a/app/models/story.rb b/app/models/story.rb
  721. index 39651df..f08e141 100644
  722. --- a/app/models/story.rb
  723. +++ b/app/models/story.rb
  724. @@ -28,7 +28,7 @@ class Story < ActiveRecord::Base
  725. end
  726.  
  727. def view_permitted?(field)
  728. - true
  729. + project.viewable_by?(acting_user)
  730. end
  731.  
  732. # force 'new' status at create.
  733. diff --git a/app/models/task.rb b/app/models/task.rb
  734. index 6c14685..a1053d2 100644
  735. --- a/app/models/task.rb
  736. +++ b/app/models/task.rb
  737. @@ -30,7 +30,7 @@ class Task < ActiveRecord::Base
  738. end
  739.  
  740. def view_permitted?(field)
  741. - true
  742. + story.viewable_by?(acting_user)
  743. end
  744.  
  745. end
  746. diff --git a/app/models/user.rb b/app/models/user.rb
  747. index e85cef0..8b9ef5a 100644
  748. --- a/app/models/user.rb
  749. +++ b/app/models/user.rb
  750. @@ -12,6 +12,8 @@ class User < ActiveRecord::Base
  751. has_many :task_assignments, :dependent => :destroy
  752. has_many :tasks, :through => :task_assignments
  753. has_many :projects, :class_name => "Project", :foreign_key => "owner_id"
  754. + has_many :project_memberships, :dependent => :destroy
  755. + has_many :joined_projects, :through => :project_memberships, :source => :project
  756.  
  757. # This gives admin rights to the first sign-up.
  758. # Just remove it if you don't want that
  759. __PATCH
  760.  
  761. # Project Contributor associations/actions/permissions
  762. cat <<__PATCH |patch -p1
  763.  
  764. * Project Contributor associations/actions/permissions
  765.  
  766. diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
  767. index caa8d5a..4f11ceb 100644
  768. --- a/app/controllers/projects_controller.rb
  769. +++ b/app/controllers/projects_controller.rb
  770. @@ -6,6 +6,11 @@ class ProjectsController < ApplicationController
  771.  
  772. auto_actions_for :owner, [:new, :create]
  773.  
  774. + autocomplete :new_member_name do
  775. + project = find_instance
  776. + hobo_completions :name, User.without_project(project).is_not(project.owner)
  777. + end
  778. +
  779. def show
  780. @project = find_instance
  781. @stories =
  782. diff --git a/app/models/project.rb b/app/models/project.rb
  783. index be59f11..bfc7c8e 100644
  784. --- a/app/models/project.rb
  785. +++ b/app/models/project.rb
  786. @@ -13,6 +13,14 @@ class Project < ActiveRecord::Base
  787.  
  788. belongs_to :owner, :class_name => "User", :creator => true
  789.  
  790. + has_many :contributor_memberships, :class_name => "ProjectMembership", :scope => :contributor
  791. + has_many :contributors, :through => :contributor_memberships, :source => :user
  792. +
  793. + # permission helper
  794. + def accepts_changes_from?(user)
  795. + user.administrator? || user == owner || user.in?(contributors)
  796. + end
  797. +
  798. # --- Permissions --- #
  799.  
  800. def create_permitted?
  801. @@ -20,7 +28,7 @@ class Project < ActiveRecord::Base
  802. end
  803.  
  804. def update_permitted?
  805. - acting_user.administrator? || (owner_is?(acting_user) && !owner_changed?)
  806. + accepts_changes_from?(acting_user) && !owner_changed?
  807. end
  808.  
  809. def destroy_permitted?
  810. diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb
  811. index b7cc12e..33c2285 100644
  812. --- a/app/models/project_membership.rb
  813. +++ b/app/models/project_membership.rb
  814. @@ -3,6 +3,7 @@ class ProjectMembership < ActiveRecord::Base
  815. hobo_model # Don't put anything above this
  816.  
  817. fields do
  818. + contributor :boolean, :default => false
  819. timestamps
  820. end
  821.  
  822. diff --git a/app/models/story.rb b/app/models/story.rb
  823. index f08e141..2846d76 100644
  824. --- a/app/models/story.rb
  825. +++ b/app/models/story.rb
  826. @@ -16,15 +16,15 @@ class Story < ActiveRecord::Base
  827. # --- Permissions --- #
  828.  
  829. def create_permitted?
  830. - acting_user.administrator?
  831. + project.creatable_by?(acting_user)
  832. end
  833.  
  834. def update_permitted?
  835. - acting_user.signed_up? && !project_changed?
  836. + project.updatable_by?(acting_user)
  837. end
  838.  
  839. def destroy_permitted?
  840. - acting_user.administrator?
  841. + project.destroyable_by?(acting_user)
  842. end
  843.  
  844. def view_permitted?(field)
  845. diff --git a/app/models/task.rb b/app/models/task.rb
  846. index a1053d2..0c058dd 100644
  847. --- a/app/models/task.rb
  848. +++ b/app/models/task.rb
  849. @@ -18,15 +18,15 @@ class Task < ActiveRecord::Base
  850. # --- Permissions --- #
  851.  
  852. def create_permitted?
  853. - acting_user.administrator?
  854. + story.creatable_by?(acting_user)
  855. end
  856.  
  857. def update_permitted?
  858. - acting_user.signed_up? && !story_changed?
  859. + story.updatable_by?(acting_user)
  860. end
  861.  
  862. def destroy_permitted?
  863. - acting_user.administrator?
  864. + story.destroyable_by?(acting_user)
  865. end
  866.  
  867. def view_permitted?(field)
  868. diff --git a/app/models/task_assignment.rb b/app/models/task_assignment.rb
  869. index b420c68..8f11a46 100644
  870. --- a/app/models/task_assignment.rb
  871. +++ b/app/models/task_assignment.rb
  872. @@ -12,19 +12,19 @@ class TaskAssignment < ActiveRecord::Base
  873. # --- Permissions --- #
  874.  
  875. def create_permitted?
  876. - acting_user.administrator?
  877. + task.creatable_by?(acting_user)
  878. end
  879.  
  880. def update_permitted?
  881. - acting_user.administrator?
  882. + task.updatable_by?(acting_user)
  883. end
  884.  
  885. def destroy_permitted?
  886. - acting_user.administrator?
  887. + task.destroyable_by?(acting_user)
  888. end
  889.  
  890. def view_permitted?(field)
  891. - true
  892. + task.viewable_by?(acting_user)
  893. end
  894.  
  895. end
  896. diff --git a/app/viewhints/project_hints.rb b/app/viewhints/project_hints.rb
  897. index c0c7e8c..21a1a45 100644
  898. --- a/app/viewhints/project_hints.rb
  899. +++ b/app/viewhints/project_hints.rb
  900. @@ -1,4 +1,3 @@
  901. class ProjectHints < Hobo::ViewHints
  902. -
  903. -
  904. + children :stories, :memberships
  905. end
  906. __PATCH
  907.  
  908. # Project Contributor migration
  909. ./script/generate hobo_migration project_contributorships --default-name --migrate
  910.  
  911. # Project Contributor view layer
  912. cat <<__PATCH |patch -p1
  913.  
  914. * Project Contributor view layer
  915.  
  916. diff --git a/app/views/front/index.dryml b/app/views/front/index.dryml
  917. index 670c62e..a7ff9bc 100644
  918. --- a/app/views/front/index.dryml
  919. +++ b/app/views/front/index.dryml
  920. @@ -13,9 +13,14 @@
  921. </section>
  922. </header>
  923.  
  924. - <section class="content-body" if="&logged_in?">
  925. + <section with="&current_user" class="content-body" if="&logged_in?">
  926. <h3>Your Projects</h3>
  927. - <collection:projects with="&current_user"><card without-creator-link/></collection>
  928. + <collection:projects><card without-creator-link/></collection>
  929. +
  930. + <a:projects action="new">New Project</a>
  931. +
  932. + <h3>Projects you have joined</h3>
  933. + <collection:joined-projects><card without-creator-link/></collection>
  934. </section>
  935. </content:>
  936.  
  937. diff --git a/app/views/projects/show.dryml b/app/views/projects/show.dryml
  938. index ccf08e2..8c11a0b 100644
  939. --- a/app/views/projects/show.dryml
  940. +++ b/app/views/projects/show.dryml
  941. @@ -9,4 +9,19 @@
  942. <empty-message:>No stories match your criteria</empty-message:>
  943. </table-plus>
  944. </collection:>
  945. +
  946. + <aside:>
  947. + <h2>Project Members</h2>
  948. + <collection:memberships part="members">
  949. + <card><heading:><a:user/></heading:></card>
  950. + </collection>
  951. +
  952. + <form:memberships.new update="members" reset-form refocus-form>
  953. + <div>
  954. + Add a member:
  955. + <name-one:user complete-target="&@project" completer="new_member_name"/>
  956. + </div>
  957. + </form>
  958. + </aside:>
  959. +
  960. </show-page>
  961. diff --git a/app/views/taglibs/application.dryml b/app/views/taglibs/application.dryml
  962. index c9548da..c4c2888 100644
  963. --- a/app/views/taglibs/application.dryml
  964. +++ b/app/views/taglibs/application.dryml
  965. @@ -17,3 +17,13 @@
  966. </append-body:>
  967. </old-card>
  968. </extend>
  969. +
  970. +<extend tag="card" for="ProjectMembership">
  971. + <old-card merge>
  972. + <body:>
  973. + <span>Contributor?</span>
  974. + <editor:contributor/>
  975. + </body:>
  976. + </old-card>
  977. +</extend>
  978. +
  979. __PATCH
Add Comment
Please, Sign In to add comment