Merge branch 'wiki'

Conflicts:
	app/views/layouts/_project_menu.html.haml
This commit is contained in:
Dmitriy Zaporozhets 2012-02-21 20:32:43 +02:00
commit ce8eba8913
22 changed files with 294 additions and 17 deletions

View file

@ -72,4 +72,6 @@ $hover: #FDF5D9;
@import "highlight.css.scss"; @import "highlight.css.scss";
@import "highlight.black.css.scss"; @import "highlight.black.css.scss";
@import "wiki.scss";

View file

@ -221,3 +221,7 @@ input.git_clone_url {
width:270px; width:270px;
background:#fff !important; background:#fff !important;
} }
.span12 hr{
margin-top: 2px;
}

View file

@ -0,0 +1,5 @@
p.time {
color: #999;
font-size: 90%;
margin: 30px 3px 3px 2px;
}

View file

@ -0,0 +1,68 @@
class WikisController < ApplicationController
before_filter :project
before_filter :add_project_abilities
before_filter :authorize_read_wiki!
before_filter :authorize_write_wiki!, :except => [:show, :destroy]
before_filter :authorize_admin_wiki!, :only => :destroy
layout "project"
def show
if params[:old_page_id]
@wiki = @project.wikis.find(params[:old_page_id])
else
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
end
respond_to do |format|
if @wiki
format.html
else
@wiki = @project.wikis.new(:slug => params[:id])
format.html { render "edit" }
end
end
end
def edit
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
@wiki = Wiki.regenerate_from @wiki
end
def create
@wiki = @project.wikis.new(params[:wiki])
@wiki.user = current_user
respond_to do |format|
if @wiki.save
format.html { redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
def history
@wikis = @project.wikis.where(:slug => params[:id]).order("created_at")
end
def destroy
@wikis = @project.wikis.where(:slug => params[:id]).delete_all
respond_to do |format|
format.html { redirect_to project_wiki_path(@project, :index), notice: "Page was successfully deleted" }
end
end
protected
def authorize_read_wiki!
can?(current_user, :read_wiki, @project)
end
def authorize_write_wiki!
can?(current_user, :write_wiki, @project)
end
def authorize_admin_wiki!
can?(current_user, :admin_wiki, @project)
end
end

View file

@ -0,0 +1,5 @@
module WikisHelper
def markdown_to_html(text)
RDiscount.new(text).to_html.html_safe
end
end

View file

@ -5,6 +5,7 @@ class Ability
when "Issue" then issue_abilities(object, subject) when "Issue" then issue_abilities(object, subject)
when "Note" then note_abilities(object, subject) when "Note" then note_abilities(object, subject)
when "Snippet" then snippet_abilities(object, subject) when "Snippet" then snippet_abilities(object, subject)
when "Wiki" then wiki_abilities(object, subject)
else [] else []
end end
end end
@ -14,35 +15,40 @@ class Ability
rules << [ rules << [
:read_project, :read_project,
:read_wiki,
:read_issue, :read_issue,
:read_snippet, :read_snippet,
:read_team_member, :read_team_member,
:read_merge_request, :read_merge_request,
:read_note :read_note,
] if project.allow_read_for?(user)
rules << [
:write_project, :write_project,
:write_issue, :write_issue,
:write_snippet, :write_snippet,
:write_merge_request, :write_merge_request,
:write_note :write_note
] if project.allow_write_for?(user) ] if project.guest_access_for?(user)
rules << [
:download_code,
] if project.report_access_for?(user)
rules << [
:write_wiki
] if project.dev_access_for?(user)
rules << [ rules << [
:modify_issue, :modify_issue,
:modify_snippet, :modify_snippet,
:modify_wiki,
:admin_project, :admin_project,
:admin_issue, :admin_issue,
:admin_snippet, :admin_snippet,
:admin_team_member, :admin_team_member,
:admin_merge_request, :admin_merge_request,
:admin_note :admin_note,
] if project.allow_admin_for?(user) :admin_wiki
] if project.master_access_for?(user)
rules << [
:download_code,
] if project.allow_pull_for?(user)
rules.flatten rules.flatten
end end

View file

@ -12,6 +12,7 @@ class Project < ActiveRecord::Base
has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key" has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key"
has_many :web_hooks, :dependent => :destroy has_many :web_hooks, :dependent => :destroy
has_many :protected_branches, :dependent => :destroy has_many :protected_branches, :dependent => :destroy
has_many :wikis, :dependent => :destroy
acts_as_taggable acts_as_taggable
@ -232,16 +233,20 @@ class Project < ActiveRecord::Base
!users_projects.where(:user_id => user.id).empty? !users_projects.where(:user_id => user.id).empty?
end end
def allow_write_for?(user) def guest_access_for?(user)
!users_projects.where(:user_id => user.id).empty? !users_projects.where(:user_id => user.id).empty?
end end
def allow_admin_for?(user) def report_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [UsersProject::MASTER]).empty? || owner_id == user.id !users_projects.where(:user_id => user.id, :project_access => [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end end
def allow_pull_for?(user) def dev_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty? !users_projects.where(:user_id => user.id, :project_access => [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
def master_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [UsersProject::MASTER]).empty? || owner_id == user.id
end end
def root_ref def root_ref

33
app/models/wiki.rb Normal file
View file

@ -0,0 +1,33 @@
class Wiki < ActiveRecord::Base
belongs_to :project
belongs_to :user
validates :content, :title, :user_id, :presence => true
validates :title, :length => 1..250
before_update :set_slug
def to_param
slug
end
protected
def set_slug
self.slug = self.title.parameterize
end
class << self
def regenerate_from wiki
regenerated_field = [:slug, :content, :title]
new_wiki = Wiki.new
regenerated_field.each do |field|
new_wiki.send("#{field}=", wiki.send(field))
end
new_wiki
end
end
end

View file

@ -12,7 +12,6 @@
= link_to project_issues_filter_path(@project), :class => (controller.controller_name == "issues") ? "current" : nil do = link_to project_issues_filter_path(@project), :class => (controller.controller_name == "issues") ? "current" : nil do
Issues Issues
%span.count= @project.issues.opened.count %span.count= @project.issues.opened.count
- if @project.merge_requests_enabled - if @project.merge_requests_enabled
= link_to project_merge_requests_path(@project), :class => (controller.controller_name == "merge_requests") ? "current" : nil do = link_to project_merge_requests_path(@project), :class => (controller.controller_name == "merge_requests") ? "current" : nil do
Merge Requests Merge Requests
@ -21,3 +20,7 @@
- if @project.wall_enabled - if @project.wall_enabled
= link_to wall_project_path(@project), :class => current_page?(:controller => "projects", :action => "wall", :id => @project) ? "current" : nil do = link_to wall_project_path(@project), :class => current_page?(:controller => "projects", :action => "wall", :id => @project) ? "current" : nil do
Wall Wall
- if @project.wiki_enabled
= link_to project_wiki_path(@project, :index), :class => (controller.controller_name == "wikis") ? "current" : nil do
Wiki

View file

@ -42,6 +42,10 @@
= f.label :wall_enabled, "Wall" = f.label :wall_enabled, "Wall"
.input= f.check_box :wall_enabled .input= f.check_box :wall_enabled
.clearfix
= f.label :wiki_enabled, "Wiki"
.input= f.check_box :wiki_enabled
.clearfix .clearfix
= f.label :description = f.label :description
.input= f.text_area :description, :placeholder => "project description", :class => "xlarge", :rows => 4 .input= f.text_area :description, :placeholder => "project description", :class => "xlarge", :rows => 4

View file

@ -0,0 +1,18 @@
= form_for [@project, @wiki] do |f|
-if @wiki.errors.any?
#error_explanation
%h2= "#{pluralize(@wiki.errors.count, "error")} prohibited this wiki from being saved:"
%ul
- @wiki.errors.full_messages.each do |msg|
%li= msg
.clearfix
= f.label :title
.input= f.text_field :title, :class => :xxlarge
= f.hidden_field :slug
.clearfix
= f.label :content
.input= f.text_area :content, :class => :xxlarge
.actions
= f.submit 'Save', :class => "primary btn"
= link_to "Cancel", project_wiki_path(@project, :index), :class => "btn"

View file

@ -0,0 +1,3 @@
%h1 Editing page
= render 'form'

View file

@ -0,0 +1,19 @@
%h2 Versions
%table
%thead
%tr
%th #
%th last edit
%th created by
%tbody
- @wikis.each_with_index do |wiki_page, i|
%tr
%td= i + 1
%td
= link_to wiki_page.created_at.to_s(:short), project_wiki_path(@project, wiki_page, :old_page_id => wiki_page.id)
(
= time_ago_in_words(wiki_page.created_at)
ago
)
%td= wiki_page.user.name

View file

@ -0,0 +1,15 @@
%h3
= @wiki.title
= link_to edit_project_wiki_path(@project, @wiki), :class => "right btn small" do
Edit
- if can? current_user, :write_wiki, @project
= link_to history_project_wiki_path(@project, @wiki), :class => "right btn small" do
History
%hr
= markdown_to_html @wiki.content
%p.time Last edited by #{@wiki.user.name}, in #{time_ago_in_words @wiki.created_at}
- if can? current_user, :write_wiki, @project
= link_to project_wiki_path(@project, @wiki), :confirm => "Are you sure you want to delete this page?", :method => :delete do
Delete this page

View file

@ -1,5 +1,6 @@
Gitlab::Application.routes.draw do Gitlab::Application.routes.draw do
# Optionally, enable Resque here # Optionally, enable Resque here
require 'resque/server' require 'resque/server'
mount Resque::Server.new, at: '/info/resque' mount Resque::Server.new, at: '/info/resque'
@ -55,6 +56,12 @@ Gitlab::Application.routes.draw do
get "files" get "files"
end end
resources :wikis, :only => [:show, :edit, :destroy, :create] do
member do
get "history"
end
end
resource :repository do resource :repository do
member do member do
get "branches" get "branches"

View file

@ -0,0 +1,11 @@
class CreateWikis < ActiveRecord::Migration
def change
create_table :wikis do |t|
t.string :title
t.text :content
t.integer :project_id
t.timestamps
end
end
end

View file

@ -0,0 +1,6 @@
class AddSlugToWiki < ActiveRecord::Migration
def change
add_column :wikis, :slug, :string
end
end

View file

@ -0,0 +1,6 @@
class AddWikiEnabledToProject < ActiveRecord::Migration
def change
add_column :projects, :wiki_enabled, :boolean, :default => true, :null => false
end
end

View file

@ -0,0 +1,6 @@
class AddUserToWiki < ActiveRecord::Migration
def change
add_column :wikis, :user_id, :integer
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120216085842) do ActiveRecord::Schema.define(:version => 20120219193300) do
create_table "issues", :force => true do |t| create_table "issues", :force => true do |t|
t.string "title" t.string "title"
@ -80,6 +80,7 @@ ActiveRecord::Schema.define(:version => 20120216085842) do
t.boolean "issues_enabled", :default => true, :null => false t.boolean "issues_enabled", :default => true, :null => false
t.boolean "wall_enabled", :default => true, :null => false t.boolean "wall_enabled", :default => true, :null => false
t.boolean "merge_requests_enabled", :default => true, :null => false t.boolean "merge_requests_enabled", :default => true, :null => false
t.boolean "wiki_enabled", :default => true, :null => false
end end
create_table "protected_branches", :force => true do |t| create_table "protected_branches", :force => true do |t|
@ -158,4 +159,14 @@ ActiveRecord::Schema.define(:version => 20120216085842) do
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "wikis", :force => true do |t|
t.string "title"
t.text "content"
t.integer "project_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "slug"
t.integer "user_id"
end
end end

View file

@ -59,3 +59,8 @@ end
Factory.add(:web_hook, WebHook) do |obj| Factory.add(:web_hook, WebHook) do |obj|
obj.url = Faker::Internet.url obj.url = Faker::Internet.url
end end
Factory.add(:wikis, WebHook) do |obj|
obj.title = Faker::Lorem.sentence
obj.content = Faker::Lorem.sentence
end

View file

@ -0,0 +1,35 @@
require 'spec_helper'
describe "Wiki" do
let(:project) { Factory :project }
before do
login_as :user
project.add_access(@user, :read, :write)
end
describe "Add pages" do
before do
visit project_wiki_path(project, :index)
end
it "should see form" do
page.should have_content("Editing page")
end
it "should see added page" do
fill_in "Title", :with => 'Test title'
fill_in "Content", :with => '[link test](test)'
click_on "Save"
page.should have_content("Test title")
page.should have_content("link test")
click_link "link test"
page.should have_content("Editing page")
end
end
end