Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@
# See COPYRIGHT and LICENSE files for more details.
#++

module CustomActions
class TableComponent < ::TableComponent
columns :name, :description, :sort
module Automations
class IndexComponent < ::TableComponent
columns :name, :triggers, :conditions, :actions, :sort

def headers
[
["name", { caption: CustomAction.human_attribute_name(:name) }],
["description", { caption: CustomAction.human_attribute_name(:description) }],
["name", { caption: Automation.human_attribute_name(:name) }],
["triggers", { caption: I18n.t("automations.triggers.name") }],
["conditions", { caption: I18n.t("automations.conditions") }],
["actions", { caption: I18n.t("automations.actions.name") }],
["sort", { caption: I18n.t(:label_sort) }]
]
end
Expand All @@ -45,10 +47,10 @@ def sortable?
end

def inline_create_link
link_to new_custom_action_path,
aria: { label: t("custom_actions.new") },
link_to new_automation_path,
aria: { label: t("automations.new") },
class: "wp-inline-create--add-link",
title: t("custom_actions.new") do
title: t("automations.new") do
helpers.op_icon("icon icon-add")
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,30 @@
# See COPYRIGHT and LICENSE files for more details.
#++

module CustomActions
module Automations
class RowComponent < ::RowComponent
def action
def automation
row
end

def name
link_to action.name, edit_custom_action_path(action)
link_to automation.name, edit_automation_path(automation)
end

delegate :description, to: :action
def triggers
automation.triggers.map(&:human_name).join(", ")
end

def conditions
automation.conditions.map(&:human_name).join(", ")
end

def actions
automation.actions.map(&:human_name).join(", ")
end

def sort
helpers.reorder_links("custom_action", { action: "update", id: action }, method: :put)
helpers.reorder_links("automation", { action: "update", id: automation }, method: :put)
end

def button_links
Expand All @@ -54,15 +64,15 @@ def button_links
def edit_link
link_to(
helpers.op_icon("icon icon-edit"),
helpers.edit_custom_action_path(action),
helpers.edit_automation_path(automation),
title: t(:button_edit)
)
end

def delete_link
link_to(
helpers.op_icon("icon icon-delete"),
helpers.custom_action_path(action),
helpers.automation_path(automation),
data: {
turbo_method: :delete,
turbo_confirm: I18n.t(:text_are_you_sure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,23 @@

require "model_contract"

# Contract for create (c) and update (u)
module CustomActions
module Automations
class CuContract < ::ModelContract
def self.model
CustomAction
end

def initialize(model, user = nil)
super
Automation
end

attribute :name
attribute :description

attribute :actions do
if model.actions.empty?
errors.add :actions, :empty
end
model.actions.each do |action|
action.validate(errors)
end
live_actions = model.actions.reject(&:marked_for_destruction?)
errors.add(:actions, :empty) if live_actions.empty?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 I18n::MissingTranslationData in Automations#update

Showing /home/dev/openproject/app/views/automations/edit.html.erb where line #45 raised:

Translation missing. Options considered were:
- en.activerecord.attributes.automation.actions
- en.attributes.actions
- en.activerecord.models.actions

live_actions.each { |action| action.validate(errors) }
end

attribute :conditions do
model.conditions.each do |condition|
condition.validate(errors)
end
model.conditions.each { |condition| condition.validate(errors) }
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,31 @@
# See COPYRIGHT and LICENSE files for more details.
#++

module CustomActions
module Automations
class ExecuteContract < BaseContract
property :lock_version
property :work_package_id

validates :work_package_id, presence: true
validate :work_package_visible
validate :custom_action_conditions_fulfilled
validate :automation_conditions_fulfilled

private

def work_package_visible
return unless model.work_package_id

unless WorkPackage.visible(user).where(id: model.work_package_id).exists?
errors.add(:work_package_id, :does_not_exist)
end
errors.add(:work_package_id, :does_not_exist) unless WorkPackage.visible(user).exists?(id: model.work_package_id)
end

def custom_action_conditions_fulfilled
def automation_conditions_fulfilled
return unless model.work_package_id
return unless options[:custom_action]
return unless options[:automation]

work_package = WorkPackage.visible(user).find_by(id: model.work_package_id)
return unless work_package

unless options[:custom_action].conditions_fulfilled?(work_package, user)
errors.add(:base, :error_unauthorized)
end
errors.add(:base, :error_unauthorized) unless options[:automation].conditions_fulfilled?(work_package, user)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -28,75 +28,72 @@
# See COPYRIGHT and LICENSE files for more details.
#++

class CustomActionsController < ApplicationController
class AutomationsController < ApplicationController
before_action :require_admin

guard_enterprise_feature(:custom_actions, only: %i[new create edit update]) do
redirect_to action: :index
end

before_action :find_custom_action, only: %i(edit update destroy)
before_action :pad_params, only: %i(create update)
before_action :find_automation, only: %i[edit update destroy]
before_action :pad_params, only: %i[create update]

layout "admin"

def index
@custom_actions = CustomAction.order_by_position
@automations = Automation.order_by_position.includes(:triggers)
end

def new
@custom_action = CustomAction.new
@automation = Automation.new
@automation.triggers.build(type: "Automations::Triggers::Manual")
end

def edit; end

def create
CustomActions::CreateService
Automations::CreateService
.new(user: current_user)
.call(attributes: permitted_params.custom_action.to_h,
.call(attributes: permitted_params.automation.to_h,
&index_or_render(:new))
end

def update
CustomActions::UpdateService
.new(action: @custom_action, user: current_user)
.call(attributes: permitted_params.custom_action.to_h,
Automations::UpdateService
.new(action: @automation, user: current_user)
.call(attributes: permitted_params.automation.to_h,
&index_or_render(:edit))
end

def destroy
@custom_action.destroy
@automation.destroy!

redirect_to custom_actions_path, status: :see_other
redirect_to automations_path, status: :see_other
end

private

def find_custom_action
@custom_action = CustomAction.find(params[:id])
def find_automation
@automation = Automation.find(params.expect(:id))
end

def index_or_render(render_action)
->(call) {
call.on_success do
redirect_to custom_actions_path, status: :see_other
redirect_to automations_path, status: :see_other
end

call.on_failure do
@custom_action = call.result
@automation = call.result
render action: render_action, status: :unprocessable_entity
end
}
end

# If no action/condition is set in the view, the
# actions/conditions already existing on a custom action should be removed.
# But because it is not feasible to have an empty and hidden hash object in a form
# we have to pad the params here.
def pad_params
return if !params[:custom_action] || params[:custom_action][:move_to]
return if !params[:automation] || params[:automation][:move_to]

params[:custom_action][:conditions] ||= {}
params[:custom_action][:actions] ||= {}
params[:automation][:conditions] ||= {}
params[:automation][:actions] ||= {}
end
end
Loading
Loading