mirror of
https://github.com/discourse/discourse.git
synced 2024-12-16 11:37:06 +08:00
247 lines
5.5 KiB
Ruby
247 lines
5.5 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module DiscourseAutomation
|
||
|
class Field < ActiveRecord::Base
|
||
|
self.table_name = "discourse_automation_fields"
|
||
|
|
||
|
belongs_to :automation, class_name: "DiscourseAutomation::Automation"
|
||
|
|
||
|
around_save :on_update_callback
|
||
|
|
||
|
def on_update_callback
|
||
|
previous_fields = automation.serialized_fields
|
||
|
|
||
|
automation.reset!
|
||
|
|
||
|
yield
|
||
|
|
||
|
automation&.triggerable&.on_update&.call(
|
||
|
automation,
|
||
|
automation.serialized_fields,
|
||
|
previous_fields,
|
||
|
)
|
||
|
end
|
||
|
|
||
|
validate :required_field
|
||
|
def required_field
|
||
|
if template && template[:required] && metadata && metadata["value"].blank?
|
||
|
raise_required_field(name, target, targetable)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
validate :validator
|
||
|
def validator
|
||
|
if template && template[:validator]
|
||
|
error = template[:validator].call(metadata["value"])
|
||
|
errors.add(:base, error) if error
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def targetable
|
||
|
target == "trigger" ? automation.triggerable : automation.scriptable
|
||
|
end
|
||
|
|
||
|
def template
|
||
|
targetable&.fields&.find do |tf|
|
||
|
targetable.id == target && tf[:name].to_s == name && tf[:component].to_s == component
|
||
|
end
|
||
|
end
|
||
|
|
||
|
validate :metadata_schema
|
||
|
def metadata_schema
|
||
|
if !(targetable.components.include?(component.to_sym))
|
||
|
errors.add(
|
||
|
:base,
|
||
|
I18n.t(
|
||
|
"discourse_automation.models.fields.invalid_field",
|
||
|
component: component,
|
||
|
target: target,
|
||
|
target_name: targetable.name,
|
||
|
),
|
||
|
)
|
||
|
else
|
||
|
schema = SCHEMAS[component]
|
||
|
if !schema ||
|
||
|
!JSONSchemer.schema({ "type" => "object", "properties" => schema }).valid?(metadata)
|
||
|
errors.add(
|
||
|
:base,
|
||
|
I18n.t(
|
||
|
"discourse_automation.models.fields.invalid_metadata",
|
||
|
component: component,
|
||
|
field: name,
|
||
|
),
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
SCHEMAS = {
|
||
|
"key-value" => {
|
||
|
"type" => "array",
|
||
|
"uniqueItems" => true,
|
||
|
"items" => {
|
||
|
"type" => "object",
|
||
|
"title" => "group",
|
||
|
"properties" => {
|
||
|
"key" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
"value" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"choices" => {
|
||
|
"value" => {
|
||
|
"type" => %w[string integer null],
|
||
|
},
|
||
|
},
|
||
|
"tags" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"trust-levels" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "integer" }],
|
||
|
},
|
||
|
},
|
||
|
"categories" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"category" => {
|
||
|
"value" => {
|
||
|
"type" => %w[string integer null],
|
||
|
},
|
||
|
},
|
||
|
"category_notification_level" => {
|
||
|
"value" => {
|
||
|
"type" => "integer",
|
||
|
},
|
||
|
},
|
||
|
"custom_field" => {
|
||
|
"value" => {
|
||
|
"type" => "integer",
|
||
|
},
|
||
|
},
|
||
|
"custom_fields" => {
|
||
|
"value" => {
|
||
|
"type" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"user" => {
|
||
|
"value" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
},
|
||
|
"user_profile" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"users" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"text" => {
|
||
|
"value" => {
|
||
|
"type" => %w[string integer null],
|
||
|
},
|
||
|
},
|
||
|
"post" => {
|
||
|
"value" => {
|
||
|
"type" => %w[string integer null],
|
||
|
},
|
||
|
},
|
||
|
"message" => {
|
||
|
"value" => {
|
||
|
"type" => %w[string integer null],
|
||
|
},
|
||
|
},
|
||
|
"boolean" => {
|
||
|
"value" => {
|
||
|
"type" => ["boolean"],
|
||
|
},
|
||
|
},
|
||
|
"text_list" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"date_time" => {
|
||
|
"value" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
},
|
||
|
"group" => {
|
||
|
"value" => {
|
||
|
"type" => "integer",
|
||
|
},
|
||
|
},
|
||
|
"email_group_user" => {
|
||
|
"value" => {
|
||
|
"type" => "array",
|
||
|
"items" => [{ type: "string" }],
|
||
|
},
|
||
|
},
|
||
|
"pms" => {
|
||
|
type: "array",
|
||
|
items: [
|
||
|
{
|
||
|
type: "object",
|
||
|
properties: {
|
||
|
"raw" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
"title" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
"delay" => {
|
||
|
"type" => "integer",
|
||
|
},
|
||
|
"prefers_encrypt" => {
|
||
|
"type" => "boolean",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
"period" => {
|
||
|
"type" => "object",
|
||
|
"properties" => {
|
||
|
"interval" => {
|
||
|
"type" => "integer",
|
||
|
},
|
||
|
"frequency" => {
|
||
|
"type" => "string",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
private
|
||
|
|
||
|
def raise_required_field(name, target, targetable)
|
||
|
errors.add(
|
||
|
:base,
|
||
|
I18n.t(
|
||
|
"discourse_automation.models.fields.required_field",
|
||
|
name: name,
|
||
|
target: target,
|
||
|
target_name: targetable.name,
|
||
|
),
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
end
|