diff --git a/app/assets/javascripts/application/posts.js b/app/assets/javascripts/application/posts.js new file mode 100644 index 00000000..71d26223 --- /dev/null +++ b/app/assets/javascripts/application/posts.js @@ -0,0 +1,54 @@ +function removePost(group_id, membership_id, post_type_id, post_id) { + const button = document.getElementById(`post-action-button-${membership_id}-${post_type_id}`) + button.disabled = true + fetch(`/groups/${group_id}/memberships/${membership_id}/posts/${post_id}.json`, + { + headers: { + 'X-CSRF-TOKEN': getCsrfToken(), + }, + method: 'DELETE', + credentials: 'same-origin', + }) + .then(response => { + if (response.status === 200) { + button.onclick = () => addPost(group_id, membership_id, post_type_id) + + button.classList.remove("uk-button-danger") + button.classList.add("uk-button-success") + + const buttonTexts = button.innerText.split('(') + buttonTexts[1] = "(Hozzáad)" + button.innerText = buttonTexts.join('') + button.disabled = false + } + }) +} + +function addPost(group_id, membership_id, post_type_id) { + const button = document.getElementById(`post-action-button-${membership_id}-${post_type_id}`) + button.disabled = true + fetch(`/groups/${group_id}/memberships/${membership_id}/posts.json`, { + headers: { + 'X-CSRF-TOKEN': getCsrfToken(), + 'Content-Type': 'application/json' + }, + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({post_type_id: post_type_id}) + }).then(response => { + if (response.status === 200) { + response.json().then(data => { + button.onclick = () => removePost(group_id, membership_id, post_type_id, data.post_id) + + button.classList.remove("uk-button-success") + button.classList.add("uk-button-danger") + + const buttonTexts = button.innerText.split('(') + buttonTexts[1] = "(Elvesz)" + button.innerText = buttonTexts.join('') + + button.disabled = false + }); + } + }) +} diff --git a/app/assets/stylesheets/posts.css b/app/assets/stylesheets/posts.css new file mode 100644 index 00000000..6c74e849 --- /dev/null +++ b/app/assets/stylesheets/posts.css @@ -0,0 +1,33 @@ + +.wrapper { + position: relative; + overflow: auto; + border: 1px solid lightgray; + white-space: nowrap; +} + +.sticky-col { + position: -webkit-sticky; + position: sticky; + background-color: white; +} + +.first-col { + width: 120px; + min-width: 120px; + max-width: 120px; + left: 0px; + white-space: normal; +} + +td, thead { + background-color: white; +} + +tr:hover > td { + background-color: #99baca; +} + +tr:hover > .first-col { + background-color: #99baca; +} diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index a702df1e..5f55c833 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -5,6 +5,19 @@ def index @membership = Membership.find(params[:membership_id]) end + def group_posts + @group = Group.includes(:post_types, :memberships).find(params[:group_id]) + authorize @group, :manage_posts? + + @post_type_ids = @group.post_types.map(&:id) + .reject { |post_type_id| post_type_id.eql? PostType::LEADER_POST_ID } + @group_post_types = @group.post_types.reduce({}) do |hash, post_type| + hash.merge({ post_type.id => post_type }) + end + @memberships = @group.memberships.active.includes(:posts, :user) + .sort { |a, b| hu_compare(a.user.full_name, b.user.full_name) } + end + def create group = Group.find(params[:group_id]) membership = Membership.find(params[:membership_id]) @@ -12,17 +25,29 @@ def create authorize Post.new(membership: membership, post_type_id: post_type_id) new_post = CreatePost.call(group, membership, post_type_id) - return redirect_to group_path(group) if new_post.leader? + respond_to do |format| + format.html do + return redirect_to group_path(group) if new_post.leader? - redirect_back fallback_location: group_path(group) + redirect_back fallback_location: group_path(group) + end + format.json { render json: { post_id: new_post.id } } + end end def destroy post_id = params[:id] group_url = group_path(params[:group_id]) authorize Post.find(post_id) - return redirect_back fallback_location: group_url if DestroyPost.call(post_id) - redirect_back fallback_location: group_url, alert: t(:no_leader_error) + destroyed = DestroyPost.call(post_id) + respond_to do |format| + format.html do + return redirect_back fallback_location: group_url if destroyed + + redirect_back fallback_location: group_url, alert: t(:no_leader_error) + end + format.json { return render plain: 'ok', status: :ok } + end end end diff --git a/app/decorators/membership_view_model_decorator.rb b/app/decorators/membership_view_model_decorator.rb index 8f796629..aac13095 100644 --- a/app/decorators/membership_view_model_decorator.rb +++ b/app/decorators/membership_view_model_decorator.rb @@ -57,6 +57,12 @@ def evaluation_button 'uk-button-success') end + def all_posts_button + return unless policy(current_group).manage_posts? + + styled_link_to('Posztok kezelése', group_posts_path(current_group), 'uk-button-success') + end + def all_members_count membership_view_model.group.memberships.count end diff --git a/app/views/groups/show.html.erb b/app/views/groups/show.html.erb index 54475db2..d852673c 100644 --- a/app/views/groups/show.html.erb +++ b/app/views/groups/show.html.erb @@ -18,6 +18,7 @@ <%= @viewmodel.join_group_button %> <%= @viewmodel.withdraw_membership_button %> <%= @viewmodel.evaluation_button %> + <%= @viewmodel.all_posts_button %> diff --git a/app/views/posts/group_posts.html.erb b/app/views/posts/group_posts.html.erb new file mode 100644 index 00000000..c905fe19 --- /dev/null +++ b/app/views/posts/group_posts.html.erb @@ -0,0 +1,44 @@ +<%= stylesheet_link_tag params[:controller] %> + +<%= button_to "Vissza", group_path(@group.id), method: :get, + class: "uk-button uk-button-primary uk-button-large uk-margin-bottom" %> + +
+
+ + + + + <% @post_type_ids.each do |id| %> + + <% end %> + + + + <% @memberships.each do |membership| %> + + + <% @post_type_ids.each do |post_type_id| %> + <% post = membership.posts.to_a.find { |post| post.post_type_id == post_type_id } %> + <% post_type = @group_post_types[post_type_id] %> + + + <% end %> + +
<%= @group_post_types[id].name %>
+ <%= link_to membership.user.full_name, profile_path(membership.user.screen_name), target: :blank, rel: "noreferrer" %> + + <% if post.present? %> + <%= button_tag "#{post_type.name} (Elvesz)", class: "uk-button uk-button-danger uk-width-1-1 uk-align-center", + id: "post-action-button-#{membership.id}-#{post_type_id}", onclick: "removePost(#{@group.id}, #{membership.id},#{post_type_id}, #{post.id})" %> + <% else %> + <%= button_tag "#{post_type.name} (Hozzáad)", class: "uk-button uk-button-success uk-width-1-1 uk-align-center", + id: "post-action-button-#{membership.id}-#{post_type_id}", onclick: "addPost(#{@group.id}, #{membership.id},#{post_type_id})" %> + <% end %> + <% end %> +
+
+
+ +<%= button_to "Vissza", group_path(@group.id), method: :get, + class: "uk-button uk-button-primary uk-button-large uk-margin-top" %> diff --git a/config/routes.rb b/config/routes.rb index e58356de..d1daba0b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,6 +47,7 @@ resources :posts, only: [:index, :create, :destroy] end + get '/group_posts', to: "posts#group_posts", as: :posts resources :post_types, only: [:index, :create, :destroy] get '/evaluations/current', to: 'evaluations#current' diff --git a/spec/requests/posts_controller_spec_spec.rb b/spec/requests/posts_controller_spec_spec.rb new file mode 100644 index 00000000..9e8d6beb --- /dev/null +++ b/spec/requests/posts_controller_spec_spec.rb @@ -0,0 +1,20 @@ +describe PostsController do + + describe '#all_posts' do + before(:each) do + login_as(user) + end + let(:user) { group.leader.user } + + context 'when the group exists' do + let(:group) { create(:group) } + + it 'is ok' do + get "/groups/#{group.id}/group_posts" + + expect(response).to have_http_status :ok + expect(response).to render_template :group_posts + end + end + end +end