Commits vergleichen
18 Commits
main
...
templates_
Autor | SHA1 | Datum | |
---|---|---|---|
|
72faab283d | ||
|
098c16cd47 | ||
|
a904d14e70 | ||
|
5e0ffd49db | ||
|
07f7e285ec | ||
|
310a3b0328 | ||
|
28094ab17b | ||
|
f9f67c09e8 | ||
|
ce705d32da | ||
|
b37bd54bcc | ||
|
5213c3e6cd | ||
|
c70b815226 | ||
|
4b559fb74e | ||
|
442f096940 | ||
|
343f594f18 | ||
|
b0f7fbf298 | ||
|
856bd11e2a | ||
|
1db9793d3e |
11 geänderte Dateien mit 220 neuen und 108 gelöschten Zeilen
|
@ -61,6 +61,22 @@ const step = {
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* unit: custom_wizard:templates_and_builder
|
||||
* type: step
|
||||
* number: 2
|
||||
* title: Add the attribute to the wizard schema
|
||||
* description: Custom Wizard templates are modeled and serialized in the
|
||||
* client via the Wizard Schema. In some cases, when adding a new
|
||||
* attribute, you just need to add it to the schema for the
|
||||
* attribute to be loaded from, and sent back to, the server.
|
||||
* However, if you are adding a new type-specific field attribute,
|
||||
* currently you only need to add it to the field type schema on
|
||||
* the server. The field schema on the server is loaded into the
|
||||
* empty ``types`` object below.
|
||||
* refernces: plugins/discourse-custom-wizard/discourse/lib/wizard-json
|
||||
* plugins/discourse-custom-wizard/discourse/models/custom-wizard
|
||||
*/
|
||||
const field = {
|
||||
basic: {
|
||||
id: null,
|
||||
|
|
|
@ -99,6 +99,22 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{!--
|
||||
/* learning_step
|
||||
* unit: custom_wizard:templates_and_builder
|
||||
* type: step
|
||||
* number: 1
|
||||
* title: Add the attribute to the template
|
||||
* description: First, add a new setting block to allow the site admin to
|
||||
* administer how the attribute will work. Here we can see the
|
||||
* controls for the Character Counter field attribute. Note
|
||||
* the attribute is only available for text type fields (see
|
||||
* isTextType conditional above this block). Note the
|
||||
* consistent use of the ``setting``, ``setting-label`` and
|
||||
* ``setting-value`` HTML structure throughout this component,
|
||||
* and other Custom Wizard admin components.
|
||||
*/
|
||||
--}}
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n "admin.wizard.field.char_counter"}}</label>
|
||||
|
|
|
@ -17,6 +17,17 @@ export default {
|
|||
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
||||
const toMarkdown = requirejs("discourse/lib/to-markdown").default;
|
||||
|
||||
/*
|
||||
* unit: custom_wizard:templates_and_builder
|
||||
* type: step
|
||||
* number: 8
|
||||
* title: Handle the attribute in the wizard client
|
||||
* description: We can now handle our new attribute in the wizard client.
|
||||
* For our "highlighted" attribute, we would add a
|
||||
* classNameBinding in the wizard-field component which
|
||||
* we've imported from the discourse/discourse wizard and are
|
||||
* extending here.
|
||||
*/
|
||||
FieldComponent.reopen({
|
||||
classNameBindings: ["field.id"],
|
||||
|
||||
|
|
|
@ -82,40 +82,15 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
|||
:theme_id,
|
||||
permitted: mapped_params,
|
||||
steps: [
|
||||
:id,
|
||||
:index,
|
||||
:title,
|
||||
:key,
|
||||
:banner,
|
||||
:raw_description,
|
||||
:required_data_message,
|
||||
:force_final,
|
||||
required_data: mapped_params,
|
||||
permitted_params: mapped_params,
|
||||
condition: mapped_params,
|
||||
*CustomWizard::Step.type_attributes(:permitted),
|
||||
CustomWizard::Step.type_attributes(:mapped).map do |attribute|
|
||||
[attribute, mapped_params]
|
||||
end.to_h,
|
||||
fields: [
|
||||
:id,
|
||||
:index,
|
||||
:label,
|
||||
:image,
|
||||
:description,
|
||||
:required,
|
||||
:key,
|
||||
:type,
|
||||
:min_length,
|
||||
:max_length,
|
||||
:char_counter,
|
||||
:file_types,
|
||||
:format,
|
||||
:limit,
|
||||
:property,
|
||||
:preview_template,
|
||||
:placeholder,
|
||||
prefill: mapped_params,
|
||||
content: mapped_params,
|
||||
condition: mapped_params,
|
||||
index: mapped_params,
|
||||
validations: {},
|
||||
*CustomWizard::Field.type_attributes(:permitted),
|
||||
CustomWizard::Field.type_attributes(:mapped).map do |attribute|
|
||||
[attribute, mapped_params]
|
||||
end.to_h
|
||||
]
|
||||
],
|
||||
actions: [
|
||||
|
|
|
@ -78,6 +78,14 @@ class CustomWizard::Builder
|
|||
@wizard
|
||||
end
|
||||
|
||||
##
|
||||
# type: step
|
||||
# number: 7
|
||||
# title: Add it to the builder
|
||||
# description: When our template is built into a wizard, we need our new
|
||||
# attribute to be built here in the builder so it's ready to
|
||||
# be sent to the wizard client.
|
||||
##
|
||||
def append_field(step, step_template, field_template, build_opts)
|
||||
params = {
|
||||
id: field_template['id'],
|
||||
|
|
|
@ -3,51 +3,94 @@
|
|||
class CustomWizard::Field
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
attr_reader :raw,
|
||||
:id,
|
||||
:type,
|
||||
:required,
|
||||
:value,
|
||||
:label,
|
||||
:description,
|
||||
:image,
|
||||
:key,
|
||||
:validations,
|
||||
:min_length,
|
||||
:max_length,
|
||||
:char_counter,
|
||||
:file_types,
|
||||
:format,
|
||||
:limit,
|
||||
:property,
|
||||
:content,
|
||||
:preview_template,
|
||||
:placeholder
|
||||
##
|
||||
# type: step
|
||||
# number: 3
|
||||
# title: Add the field name to attribute map
|
||||
# description: The attribute map serves as a global registry for field attributes. Set the
|
||||
# key as the attribute name and value as an array of properties. Use the properties according to
|
||||
# your usecase. Here's a list and description of each of the properties.
|
||||
# ```
|
||||
# accessible: The attribute is set as a CustomWizard::Field attr_accessor
|
||||
# serializable: The attribute is serialized to the client
|
||||
# permitted: The attribute is permitted in the admin controller
|
||||
# mapped: The attribute is mapped and permitted (see above)
|
||||
# excluded: The attribute is not initialized in the constructor
|
||||
# ```
|
||||
##
|
||||
|
||||
attr_accessor :index,
|
||||
:step
|
||||
def self.attribute_map
|
||||
{
|
||||
raw: [],
|
||||
id: [:serializable, :permitted],
|
||||
index: [:accessible, :serializable, :permitted, :mapped],
|
||||
type: [:serializable, :permitted],
|
||||
step: [:accessible],
|
||||
required: [:serializable, :permitted],
|
||||
value: [:serializable],
|
||||
description: [:serializable, :permitted],
|
||||
image: [:serializable, :permitted],
|
||||
key: [:permitted],
|
||||
validations: [:serializable],
|
||||
min_length: [:permitted],
|
||||
max_length: [:serializable, :permitted],
|
||||
char_counter: [:serializable, :permitted],
|
||||
file_types: [:serializable, :permitted],
|
||||
format: [:serializable, :permitted],
|
||||
limit: [:serializable, :permitted],
|
||||
property: [:serializable, :permitted],
|
||||
# label is excluded so that it isn't initialized and the value
|
||||
# returned by `label` method is used for serialization
|
||||
label: [:excluded, :serializable, :permitted],
|
||||
content: [:serializable, :permitted, :mapped],
|
||||
prefill: [:permitted, :mapped],
|
||||
condition: [:permitted, :mapped],
|
||||
preview_template: [:serializable, :permitted, :mapped],
|
||||
placeholder: [:serializable, :permitted, :mapped],
|
||||
}
|
||||
end
|
||||
|
||||
def self.all_attributes
|
||||
attribute_map.keys
|
||||
end
|
||||
|
||||
def self.included_attributes
|
||||
all_attributes - excluded_attributes
|
||||
end
|
||||
|
||||
def self.type_attributes(type)
|
||||
attribute_map.map { |attribute, props| props.include?(type.to_sym) ? attribute : nil }.compact
|
||||
end
|
||||
|
||||
def self.accessible_attributes
|
||||
type_attributes(:accessible)
|
||||
end
|
||||
|
||||
def self.excluded_attributes
|
||||
type_attributes(:excluded)
|
||||
end
|
||||
|
||||
def self.readonly_attributes
|
||||
included_attributes - accessible_attributes
|
||||
end
|
||||
|
||||
def self.serializable_attributes
|
||||
type_attributes(:serializable)
|
||||
end
|
||||
|
||||
attr_reader *readonly_attributes
|
||||
attr_accessor *accessible_attributes
|
||||
|
||||
def initialize(attrs)
|
||||
attrs.each do |k, v|
|
||||
if self.singleton_class.included_attributes.include?(k.to_sym)
|
||||
instance_variable_set("@#{k}", v)
|
||||
end
|
||||
end
|
||||
|
||||
@raw = attrs || {}
|
||||
@id = attrs[:id]
|
||||
@index = attrs[:index]
|
||||
@type = attrs[:type]
|
||||
@required = !!attrs[:required]
|
||||
@value = attrs[:value] || default_value
|
||||
@description = attrs[:description]
|
||||
@image = attrs[:image]
|
||||
@key = attrs[:key]
|
||||
@validations = attrs[:validations]
|
||||
@min_length = attrs[:min_length]
|
||||
@max_length = attrs[:max_length]
|
||||
@char_counter = attrs[:char_counter]
|
||||
@file_types = attrs[:file_types]
|
||||
@format = attrs[:format]
|
||||
@limit = attrs[:limit]
|
||||
@property = attrs[:property]
|
||||
@content = attrs[:content]
|
||||
@preview_template = attrs[:preview_template]
|
||||
@placeholder = attrs[:placeholder]
|
||||
end
|
||||
|
||||
def label
|
||||
|
|
|
@ -3,25 +3,61 @@
|
|||
class CustomWizard::Step
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
attr_reader :id,
|
||||
:updater
|
||||
def self.attribute_map
|
||||
{
|
||||
id: [:serializable, :permitted],
|
||||
updater: [],
|
||||
index: [:accessible, :serializable, :permitted],
|
||||
title: [:accessible, :serializable, :permitted],
|
||||
description: [:accessible, :serializable],
|
||||
key: [:accessible, :permitted],
|
||||
permitted: [:accessible, :serializable],
|
||||
permitted_message: [:accessible, :serializable],
|
||||
fields: [:accessible],
|
||||
next: [:accessible, :serializable],
|
||||
previous: [:accessible, :serializable],
|
||||
banner: [:accessible, :serializable, :permitted],
|
||||
disabled: [:accessible],
|
||||
description_vars: [:accessible],
|
||||
last_step: [:accessible],
|
||||
force_final: [:accessible],
|
||||
conditional_final_step: [:accessible],
|
||||
wizard: [:accessible],
|
||||
raw_description: [:permitted],
|
||||
required_data_message: [:permitted],
|
||||
required_data: [:permitted, :mapped],
|
||||
permitted_params: [:permitted, :mapped],
|
||||
condition: [:permitted, :mapped],
|
||||
final: [:serializable]
|
||||
}
|
||||
end
|
||||
|
||||
attr_accessor :index,
|
||||
:title,
|
||||
:description,
|
||||
:key,
|
||||
:permitted,
|
||||
:permitted_message,
|
||||
:fields,
|
||||
:next,
|
||||
:previous,
|
||||
:banner,
|
||||
:disabled,
|
||||
:description_vars,
|
||||
:last_step,
|
||||
:force_final,
|
||||
:conditional_final_step,
|
||||
:wizard
|
||||
def self.type_attributes(type)
|
||||
attribute_map.map { |attribute, props| props.include?(type.to_sym) ? attribute : nil }.compact
|
||||
end
|
||||
|
||||
def self.all_attributes
|
||||
attribute_map.keys
|
||||
end
|
||||
|
||||
def self.accessible_attributes
|
||||
type_attributes(:accessible)
|
||||
end
|
||||
|
||||
def self.included_attributes
|
||||
all_attributes - excluded_attributes
|
||||
end
|
||||
|
||||
def self.readonly_attributes
|
||||
included_attributes - accessible_attributes
|
||||
end
|
||||
|
||||
def self.excluded_attributes
|
||||
type_attributes(:excluded)
|
||||
end
|
||||
|
||||
attr_reader *readonly_attributes
|
||||
attr_accessor *accessible_attributes
|
||||
|
||||
def initialize(id)
|
||||
@id = id
|
||||
|
|
|
@ -8,6 +8,15 @@ class CustomWizard::TemplateValidator
|
|||
@opts = opts
|
||||
end
|
||||
|
||||
##
|
||||
# type: step
|
||||
# number: 5
|
||||
# title: Add a template validation (optional)
|
||||
# description: If our new attribute requires validation of a value entered
|
||||
# during administration of a wizard that should be handled here.
|
||||
# Template validators are run before the template is saved to
|
||||
# the database.
|
||||
##
|
||||
def perform
|
||||
data = @data
|
||||
|
||||
|
|
|
@ -6,6 +6,14 @@ require_dependency 'wizard/builder'
|
|||
|
||||
UserHistory.actions[:custom_wizard_step] = 1000
|
||||
|
||||
##
|
||||
# type: step
|
||||
# number: 6
|
||||
# title: Add the parameter to the wizard model
|
||||
# description: The template is loaded into the wizard model when it is built,
|
||||
# our attribute has to be present, for it to build properly...
|
||||
##
|
||||
|
||||
class CustomWizard::Wizard
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
# url: https://github.com/paviliondev/discourse-custom-wizard
|
||||
# contact emails: angus@thepavilion.io
|
||||
|
||||
## learning_unit
|
||||
# unit: custom_wizard:templates_and_builder
|
||||
# type: introduction
|
||||
# title: Adding a new wizard field attribute.
|
||||
# description: In this unit, we'll learn about creating, editing, validating
|
||||
# and building wizard templates by adding a new field attribute.
|
||||
##
|
||||
gem 'liquid', '5.0.1', require: true
|
||||
register_asset 'stylesheets/common/wizard-admin.scss'
|
||||
register_asset 'stylesheets/common/wizard-mapper.scss'
|
||||
|
|
|
@ -2,24 +2,7 @@
|
|||
|
||||
class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||
|
||||
attributes :id,
|
||||
:index,
|
||||
:type,
|
||||
:required,
|
||||
:value,
|
||||
:label,
|
||||
:placeholder,
|
||||
:description,
|
||||
:image,
|
||||
:file_types,
|
||||
:format,
|
||||
:limit,
|
||||
:property,
|
||||
:content,
|
||||
:validations,
|
||||
:max_length,
|
||||
:char_counter,
|
||||
:preview_template
|
||||
attributes *CustomWizard::Field.serializable_attributes
|
||||
|
||||
def id
|
||||
object.id
|
||||
|
|
Laden …
In neuem Issue referenzieren