Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow unpermitted tags to be added to messages, threads #63

Merged
merged 5 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/components/common/removable_tag_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<% if @tag.visible %>
<div class="flex justify-center items-center relative gap-1 px-2 py-1 rounded-md bg-gray-50 border border-gray-300">
<p class=" text-sm text-left text-gray-600"><%= @tag.name %></p>
<% if @object_tag.deletable %>
<%= button_to url_for(@object_tag), method: :delete, form: { data: { turbo_confirm: "Naozaj odstrániť štítok #{@tag.name} zo správy?" } } do %>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class=" w-3.5 h-3.5 relative" preserveAspectRatio="xMidYMid meet">
<path d="M3.5 3.5L10.5 10.5M3.5 10.5L10.5 3.5L3.5 10.5Z" stroke="#6B7280" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<% end %>
<% end %>
</div>
<% end %>
8 changes: 8 additions & 0 deletions app/components/common/removable_tag_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Common
class RemovableTagComponent < ViewComponent::Base
def initialize(object_tag)
@object_tag = object_tag
@tag = @object_tag.tag
end
end
end
3 changes: 1 addition & 2 deletions app/components/common/tag_selector_component.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
module Common
class TagSelectorComponent < ViewComponent::Base
def initialize(object, available_tags)
def initialize(object)
@object = object
@available_tags = available_tags
end
end
end
4 changes: 2 additions & 2 deletions app/components/common/tag_selector_popup_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
<% @tags.each do |tag|%>
<div class="flex justify-center items-center gap-1.5 px-2 py-1 rounded-md bg-blue-50 border border-blue-300 hover:cursor-pointer">
<% if @object.class.name == 'MessageThread' %>
<%= form_with model: [MessageThreadsTag.new(message_thread: @object, tag: tag)], class: "contents" do |form| %>
<%= form_with model: [MessageThreadsTag.new(message_thread: @object, tag: tag)], data: { turbo_frame: '_top' }, class: "contents" do |form| %>
<%= form.hidden_field :message_thread_id %>
<%= form.hidden_field :tag_id %>
<%= form.submit "#{tag.name}" ,class:"text-sm text-left text-blue-600 hover:cursor-pointer" %>
<% end %>
<% else %>
<%= form_with model: [MessagesTag.new(message: @object, tag: tag)], class: "contents" do |form| %>
<%= form_with model: [MessagesTag.new(message: @object, tag: tag)], data: { turbo_frame: '_top' }, class: "contents" do |form| %>
<%= form.hidden_field :message_id %>
<%= form.hidden_field :tag_id %>
<%= form.submit "#{tag.name}", class:"text-sm text-left text-blue-600 hover:cursor-pointer" %>
Expand Down
21 changes: 6 additions & 15 deletions app/components/message_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<div class="flex flex-col justify-stretch items-stretch">
<%= render MessageThreadHeaderComponent.new(@message.thread, @available_tags) %>
<%= render MessageThreadHeaderComponent.new(@message.thread, @thread_tags_with_deletable_flag) %>
<div class="flex flex-col justify-stretch items-stretch gap-2 p-4">
<% if @notice %>
<% @notice.each do |type, msg| %>
<div class="bg-blue-100 border-t border-b border-blue-500 text-blue-700 px-4 py-3 w-full" role="alert">
<p class="font-bold"><%= @notice %></p>
<p class="font-bold"><%= msg %></p>
</div>
<% end %>
<div class="flex flex-col justify-stretch items-stretch rounded-md bg-white border border-gray-200">
Expand All @@ -19,19 +19,10 @@
<p class=" text-base font-semibold text-left text-gray-900"><%= @message.recipient_name || 'Neznámy' %></p>
</div>
<div class="flex justify-stretch items-start gap-2 pt-1">
<% @message.tags.each do |tag| %>
<% if tag.visible %>
<div class="flex justify-center items-center relative gap-1 px-2 py-1 rounded-md bg-gray-50 border border-gray-300">
<p class=" text-sm text-left text-gray-600"><%= tag.name %></p>
<%= button_to messages_tag_path(MessagesTag.find_by(message_id: @message.id, tag_id: tag.id)), method: :delete, form: { data: { turbo_confirm: "Naozaj odstrániť štítok #{tag.name} zo správy?" } } do %>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class=" w-3.5 h-3.5 relative" preserveAspectRatio="xMidYMid meet">
<path d="M3.5 3.5L10.5 10.5M3.5 10.5L10.5 3.5L3.5 10.5Z" stroke="#6B7280" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<% end %>
</div>
<% end %>
<% @message_tags_with_deletable_flag.each do |message_tag| %>
<%= render Common::RemovableTagComponent.new(message_tag) %>
<% end %>
<%= render Common::TagSelectorComponent.new(@message, @available_tags) %>
<%= render Common::TagSelectorComponent.new(@message) %>
</div>
</div>
<div class="flex flex-col justify-strech items-start flex-grow gap-1">
Expand Down
5 changes: 3 additions & 2 deletions app/components/message_component.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
class MessageComponent < ViewComponent::Base
renders_many :attachments

def initialize(message:, notice:, available_tags:)
def initialize(message:, notice:, message_tags_with_deletable_flag:, thread_tags_with_deletable_flag:)
@message = message
@notice = notice
@available_tags = available_tags
@message_tags_with_deletable_flag = message_tags_with_deletable_flag
@thread_tags_with_deletable_flag = thread_tags_with_deletable_flag
end
end
15 changes: 3 additions & 12 deletions app/components/message_thread_header_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,10 @@
<div class="flex justify-start items-center relative gap-4">
<%= render MessageThreadRenameComponent.new(message_thread: @message_thread) %>
<div class="flex justify-start items-start gap-2">
<% @message_thread.tags.each do |tag|%>
<% if tag.visible %>
<div class="flex justify-start items-start gap-1 px-2 py-1 rounded-md bg-gray-50 border border-gray-300">
<p class="text-sm text-left text-gray-600"><%= tag.name %></p>
<%= button_to message_threads_tag_path(@message_thread.message_threads_tags.find_by(tag_id: tag.id)), method: :delete, form: { data: { turbo_confirm: "Naozaj odstrániť štítok #{tag.name} z vlákna?" } } do %>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class=" w-3.5 h-3.5 relative" preserveAspectRatio="xMidYMid meet">
<path d="M3.5 3.5L10.5 10.5M3.5 10.5L10.5 3.5L3.5 10.5Z" stroke="#6B7280" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<% end %>
</div>
<% end %>
<% @thread_tags_with_deletable_flag.each do |thread_tag|%>
<%= render Common::RemovableTagComponent.new(thread_tag) %>
<% end %>
<%= render Common::TagSelectorComponent.new(@message_thread, @available_tags) %>
<%= render Common::TagSelectorComponent.new(@message_thread) %>
</div>
</div>
<div class="todo flex flex-col justify-start items-end gap-1">
Expand Down
4 changes: 2 additions & 2 deletions app/components/message_thread_header_component.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class MessageThreadHeaderComponent < ViewComponent::Base
def initialize(message_thread, available_tags)
def initialize(message_thread, thread_tags_with_deletable_flag)
@message_thread = message_thread
@available_tags = available_tags
@thread_tags_with_deletable_flag = thread_tags_with_deletable_flag
end
end
31 changes: 31 additions & 0 deletions app/controllers/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,37 @@ def authorize_delivery_notification
def set_message
@message = policy_scope(Message).find(params[:id])
@menu = SidebarMenu.new(controller_name, action_name, { message: @message })
@notice = flash
set_message_tags_with_deletable_flag
set_thread_tags_with_deletable_flag
end

def set_message_tags_with_deletable_flag
@message_tags_with_deletable_flag =
@message
.messages_tags
.includes(:tag)
.select("messages_tags.*, #{deletable_subquery('tags.id = messages_tags.tag_id').to_sql} as deletable")
.order("tags.name")
end

def set_thread_tags_with_deletable_flag
@thread_tags_with_deletable_flag =
@message
.thread
.message_threads_tags
.includes(:tag)
.select("message_threads_tags.*, #{deletable_subquery('tags.id = message_threads_tags.tag_id').to_sql} as deletable")
.order('tags.name')
end

def deletable_subquery(where_clause)
Tag
.joins(:groups, { groups: :group_memberships })
.where('group_memberships.user_id = ?', Current.user.id)
.where(where_clause)
.arel
.exists
end

def permit_reply_params
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/messages_tags_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class MessagesTagsController < ApplicationController
before_action :set_messages_tag, only: %i[ destroy ]
before_action :set_messages_tag, only: %i[destroy]

def create
@messages_tag = MessagesTag.new(messages_tag_params)
authorize @messages_tag

if @messages_tag.save
redirect_back fallback_location:"/", notice: "Tag was successfully added"
redirect_back fallback_location: "/", notice: "Tag was successfully added"
else
render :new, status: :unprocessable_entity
end
Expand All @@ -15,7 +15,7 @@ def create
def destroy
authorize @messages_tag
@messages_tag.destroy
redirect_back fallback_location:"/", notice: "Tag was successfully removed"
redirect_back fallback_location: '/', notice: 'Tag was successfully removed'
end

private
Expand Down
5 changes: 1 addition & 4 deletions app/controllers/tags_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ def get_available
authorize [Tag]
set_object
@tenant = Current.tenant
@tags =
@tenant.tags.where.not(id: @object.tags.ids).where(visible: true)
.where(id: TagGroup.select(:tag_id).joins(:group, :tag, group: :users).where(group: { tenant_id: @tenant.id }, tag: { tenant_id: @tenant.id }, users: { id: Current.user.id }))
respond_to { |format| format.html }
@tags = @tenant.tags.where.not(id: @object.tags.ids).where(visible: true)
end

private
Expand Down
5 changes: 3 additions & 2 deletions app/models/govbox/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ def self.create_message_with_thread!(govbox_message)
delivered_at: govbox_message.delivered_at
)

self.create_message_tag(message, govbox_message)

message.save!

self.create_message_tag(message, govbox_message)

message
end

Expand Down
1 change: 1 addition & 0 deletions app/models/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

class Message < ApplicationRecord
has_and_belongs_to_many :tags
has_many :messages_tags, dependent: :destroy
belongs_to :thread, class_name: 'MessageThread', foreign_key: :message_thread_id
belongs_to :author, class_name: 'User', foreign_key: :author_id, optional: true
has_many :objects, class_name: 'MessageObject', dependent: :destroy
Expand Down
30 changes: 8 additions & 22 deletions app/policies/messages_tag_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,24 @@ def resolve
if @user.site_admin?
scope.all
else
# TODO: toto zrejme nestaci, potrebujeme obmedzit aj na konkretneho usera a jeho boxy
scope.includes(:message, :tag).where(message: {tenant_id: Current.tenant.id}, tag: {tenant_id: Current.tenant.id})
scope.joins(:message, :tag).where(message: Pundit.policy_scope(user, Message), tag: Pundit.policy_scope(user, Tag))
end
end
end

def index
true
end

def show?
true
end

def create?
true
end

def new?
create?
end
return false unless Pundit.policy_scope(user, Message).find_by(id: @messages_tag.message_id)
return false unless @messages_tag.tag.tenant == Current.tenant

def update?
true
end

def edit?
update?
end

def destroy?
return false unless @messages_tag
return false unless Pundit.policy_scope(user, Message).find_by(id: @messages_tag.message_id)
return false unless Pundit.policy_scope(user, Tag).find_by(id: @messages_tag.tag_id)
return false unless @messages_tag.tag.tenant == Current.tenant

true
end
end

2 changes: 1 addition & 1 deletion app/views/messages/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= render TW::FlashComponent.new(flash: flash) %>
<%= render MessageComponent.new(message: @message, notice: @notice, available_tags: @available_tags) do |component| %>
<%= render MessageComponent.new(message: @message, notice: @notice, message_tags_with_deletable_flag: @message_tags_with_deletable_flag, thread_tags_with_deletable_flag: @thread_tags_with_deletable_flag) do |component| %>
<% @message.objects.each do |message_object| %>
<% component.with_attachment do %>
<% render MessageAttachmentComponent.new(message_attachment: message_object) %>
Expand Down