card-mod-edit 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/set/all/bridge.rb +64 -0
- data/set/all/bridge/bridge.haml +8 -0
- data/set/all/bridge/bridge_pills.rb +47 -0
- data/set/all/bridge/follow_section.rb +37 -0
- data/set/all/bridge/related_section.rb +34 -0
- data/set/all/bridge/tab_views.rb +41 -0
- data/set/all/bridge/tab_visibility.rb +53 -0
- data/set/all/edit_content.rb +60 -0
- data/set/all/edit_inline.rb +56 -0
- data/set/all/edit_name.rb +58 -0
- data/set/all/edit_type.rb +101 -0
- data/set/all/editing.rb +91 -0
- data/set/all/editor.rb +56 -0
- data/set/all/form.rb +245 -0
- data/set/all/form_buttons.rb +64 -0
- data/set/all/form_elements.rb +71 -0
- data/set/all/formgroup.rb +37 -0
- data/set/all/new.rb +188 -0
- data/set/all/overlay_guide.haml +7 -0
- data/set/all/overlay_guide.rb +9 -0
- data/set/all/template_nest.rb +42 -0
- data/set/type/list.rb +15 -0
- data/set/type/plain_text.rb +13 -0
- data/set/type/pointer.rb +11 -0
- metadata +71 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
format :html do
|
2
|
+
view :edit_type, cache: :never, perms: :update do
|
3
|
+
frame do
|
4
|
+
_render_edit_type_form
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
view :edit_type_form, cache: :never, perms: :update, wrap: :slot do
|
9
|
+
card_form :update, success: edit_type_success do
|
10
|
+
[type_formgroup, render_new_buttons]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def edit_type_success
|
15
|
+
{ view: :core }
|
16
|
+
end
|
17
|
+
|
18
|
+
view :edit_type_row do
|
19
|
+
return _render_bridge_type_formgroup if voo.visible?(:type_form) { false }
|
20
|
+
|
21
|
+
edit_row_fixed_width "Type", link_to_card(card.type), :bridge_type_formgroup
|
22
|
+
end
|
23
|
+
|
24
|
+
view :bridge_type_formgroup, unknown: true, wrap: :slot do
|
25
|
+
type_formgroup href: path(mark: card.id,
|
26
|
+
view: :edit_form,
|
27
|
+
assign: true,
|
28
|
+
slot: { show: :type_form }),
|
29
|
+
class: "live-type-field slotter",
|
30
|
+
'data-remote': true,
|
31
|
+
'data-slot-selector': ".card-slot.edit_form-view"
|
32
|
+
end
|
33
|
+
|
34
|
+
view :type_formgroup do
|
35
|
+
type_formgroup
|
36
|
+
end
|
37
|
+
|
38
|
+
def type_formgroup args={}
|
39
|
+
add_class args, "type-field"
|
40
|
+
wrap_type_formgroup do
|
41
|
+
type_field args
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def wrap_type_formgroup
|
46
|
+
formgroup "Type", input: "type", class: "type-formgroup", help: false do
|
47
|
+
output [yield, hidden_field_tag(:assign, true)]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def type_field args={}
|
52
|
+
typelist = Auth.createable_types
|
53
|
+
current_type = type_field_current_value args, typelist
|
54
|
+
template.select_tag "card[type]", type_field_options(current_type),
|
55
|
+
args.merge("data-select2-id": "#{unique_id}-#{Time.now.to_i}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def type_field_options current_type
|
59
|
+
types = grouped_types(current_type)
|
60
|
+
|
61
|
+
if types.size == 1
|
62
|
+
options_for_select types.flatten[1], current_type
|
63
|
+
else
|
64
|
+
grouped_options_for_select types, current_type
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def grouped_types current_type
|
69
|
+
groups = Hash.new { |h, k| h[k] = [] }
|
70
|
+
allowed = ::Set.new Auth.createable_types
|
71
|
+
allowed << current_type if current_type
|
72
|
+
|
73
|
+
visible_cardtype_groups.each_pair do |name, items|
|
74
|
+
if name == "Custom"
|
75
|
+
Auth.createable_types.each do |type|
|
76
|
+
groups["Custom"] << type unless ::Card::Set::Self::Cardtype::GROUP_MAP[type]
|
77
|
+
end
|
78
|
+
else
|
79
|
+
items.each do |i|
|
80
|
+
groups[name] << i if allowed.include?(i)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
groups
|
85
|
+
end
|
86
|
+
|
87
|
+
def visible_cardtype_groups
|
88
|
+
::Card::Set::Self::Cardtype::GROUP
|
89
|
+
end
|
90
|
+
|
91
|
+
def type_field_current_value args, typelist
|
92
|
+
return if args.delete :no_current_type
|
93
|
+
|
94
|
+
if !card.new_card? && !typelist.include?(card.type_name)
|
95
|
+
# current type should be an option on existing cards,
|
96
|
+
# regardless of create perms
|
97
|
+
typelist.push(card.type_name).sort!
|
98
|
+
end
|
99
|
+
card.type_name_or_default
|
100
|
+
end
|
101
|
+
end
|
data/set/all/editing.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
format :html do
|
2
|
+
###---( TOP_LEVEL (used by menu) NEW / EDIT VIEWS )
|
3
|
+
view :bridge, perms: :update, unknown: true, cache: :never, wrap: :bridge do
|
4
|
+
with_nest_mode :edit do
|
5
|
+
add_name_context
|
6
|
+
voo.show :help
|
7
|
+
wrap true, breadcrumb_data("Editing", "edit") do
|
8
|
+
bridge_parts
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
view :cardboard, :bridge
|
14
|
+
|
15
|
+
def bridge_parts
|
16
|
+
voo.show! :edit_type_row
|
17
|
+
|
18
|
+
[
|
19
|
+
frame_help,
|
20
|
+
_render_edit_name_row(home_view: :edit_name_row),
|
21
|
+
# home_view is necessary for cancel to work correctly.
|
22
|
+
# it seems a little strange to have to think about home_view here,
|
23
|
+
# but the issue is that something currently has to happen prior to the
|
24
|
+
# render to get voo.slot_options to have the write home view in
|
25
|
+
# the slot wrap. I think this would probably best be handled as an
|
26
|
+
# option to #wrap that triggers a new heir voo
|
27
|
+
_render_edit_form
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def edit_success
|
32
|
+
# for override
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit_view_hidden
|
36
|
+
# for override
|
37
|
+
end
|
38
|
+
|
39
|
+
view :edit_buttons do
|
40
|
+
button_formgroup do
|
41
|
+
wrap_with "div", class: "d-flex" do
|
42
|
+
[standard_submit_button, edit_cancel_button, delete_button]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: add undo functionality
|
48
|
+
view :just_deleted, unknown: true do
|
49
|
+
wrap { "#{render_title} deleted" }
|
50
|
+
end
|
51
|
+
|
52
|
+
view :edit_rules, cache: :never, unknown: true do
|
53
|
+
nest current_set_card, view: :bridge_rules_tab
|
54
|
+
end
|
55
|
+
|
56
|
+
view :edit_structure, cache: :never do
|
57
|
+
return unless card.structure
|
58
|
+
|
59
|
+
nest card.structure_rule_card, view: :edit
|
60
|
+
# FIXME: this stuff:
|
61
|
+
# slot: {
|
62
|
+
# cancel_slot_selector: ".card-slot.related-view",
|
63
|
+
# cancel_path: card.format.path(view: :edit), hide: :edit_toolbar,
|
64
|
+
# hidden: { success: { view: :open, "slot[subframe]" => true } }
|
65
|
+
# }
|
66
|
+
# }
|
67
|
+
end
|
68
|
+
|
69
|
+
view :edit_nests, cache: :never do
|
70
|
+
frame do
|
71
|
+
with_nest_mode :edit do
|
72
|
+
multi_card_edit
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# FIXME: - view can recurse. temporarily turned off
|
78
|
+
#
|
79
|
+
# view :edit_nest_rules, cache: :never do
|
80
|
+
# return ""#
|
81
|
+
# view = args[:rule_view] || :field_related_rules
|
82
|
+
# frame do
|
83
|
+
# # with_nest_mode :edit do
|
84
|
+
# nested_fields.map do |name, _options|
|
85
|
+
# nest Card.fetch(name.to_name.trait(:self)),
|
86
|
+
# view: :titled, title: name, rule_view: view,
|
87
|
+
# hide: :set_label, show: :rule_navbar
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
# end
|
91
|
+
end
|
data/set/all/editor.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
Self::InputOptions.add_to_basket :options, "text area"
|
3
|
+
Self::InputOptions.add_to_basket :options, "text field"
|
4
|
+
|
5
|
+
format :html do
|
6
|
+
def input_type
|
7
|
+
voo.input_type.present? ? voo.input_type : input_type_from_rule
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_type_from_rule
|
11
|
+
card.rule(:input_type)&.gsub(/[\[\]]/, "")&.tr(" ", "_")
|
12
|
+
end
|
13
|
+
|
14
|
+
def input_method input_type
|
15
|
+
"#{input_type}_input"
|
16
|
+
end
|
17
|
+
|
18
|
+
# core view of card is input
|
19
|
+
def input_defined_by_card
|
20
|
+
with_card input_type do |input_card|
|
21
|
+
nest input_card, view: :core
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# move somewhere more accessible?
|
26
|
+
def with_card mark
|
27
|
+
return nil unless (card = Card[mark])
|
28
|
+
|
29
|
+
yield card
|
30
|
+
rescue Card::Error::CodenameNotFound
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
view :input, unknown: true do
|
35
|
+
try(input_method(input_type)) ||
|
36
|
+
input_defined_by_card ||
|
37
|
+
send(input_method(default_input_type))
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_input_type
|
41
|
+
:rich_text
|
42
|
+
end
|
43
|
+
|
44
|
+
def rich_text_input
|
45
|
+
send "#{Cardio.config.rich_text_editor || :text_area}_editor_input"
|
46
|
+
end
|
47
|
+
|
48
|
+
def text_area_input
|
49
|
+
text_area :content, rows: 5, class: "d0-card-content",
|
50
|
+
"data-card-type-code" => card.type_code
|
51
|
+
end
|
52
|
+
|
53
|
+
def text_field_input
|
54
|
+
text_field :content, class: classy("d0-card-content")
|
55
|
+
end
|
56
|
+
end
|
data/set/all/form.rb
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
format :html do
|
2
|
+
# FIELDSET VIEWS
|
3
|
+
|
4
|
+
# sometimes multiple card formgroups, sometimes just one
|
5
|
+
view :content_formgroups, cache: :never do
|
6
|
+
wrap_with :fieldset, edit_slot, class: classy("card-editor", "editor")
|
7
|
+
end
|
8
|
+
|
9
|
+
view :name_formgroup do
|
10
|
+
formgroup "Name", input: "name", help: false do
|
11
|
+
raw name_field
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# single card content formgroup, labeled with "Content"
|
16
|
+
view :content_formgroup, unknown: true, cache: :never do
|
17
|
+
wrap_content_formgroup { content_field }
|
18
|
+
end
|
19
|
+
|
20
|
+
view :edit_in_form, cache: :never, perms: :update, unknown: true do
|
21
|
+
reset_form
|
22
|
+
@in_multi_card_editor = true
|
23
|
+
edit_slot
|
24
|
+
end
|
25
|
+
|
26
|
+
view :conflict_tracker, cache: :never, unknown: true do
|
27
|
+
return unless card&.real?
|
28
|
+
|
29
|
+
card.last_action_id_before_edit = card.last_action_id
|
30
|
+
hidden_field :last_action_id_before_edit, class: "current_revision_id"
|
31
|
+
end
|
32
|
+
|
33
|
+
def wrap_content_formgroup
|
34
|
+
formgroup("Content", input: :content, help: false,
|
35
|
+
class: classy("card-editor")) { yield }
|
36
|
+
end
|
37
|
+
|
38
|
+
def button_formgroup
|
39
|
+
wrap_with :div, class: classy("form-group") do
|
40
|
+
wrap_with :div, yield
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def name_field
|
45
|
+
# value needed because otherwise gets wrong value if there are updates
|
46
|
+
text_field :name, value: card.name, autocomplete: "off"
|
47
|
+
end
|
48
|
+
|
49
|
+
def content_field
|
50
|
+
with_nest_mode :normal do
|
51
|
+
# by changing nest mode to normal, we ensure that editors (eg image
|
52
|
+
# previews) can render core views.
|
53
|
+
output [_render_conflict_tracker, _render_input]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# SAMPLE editor view for override
|
58
|
+
# view :input do
|
59
|
+
# text_area :content, rows: 5, class: "d0-card-content"
|
60
|
+
# end
|
61
|
+
|
62
|
+
def edit_slot
|
63
|
+
case
|
64
|
+
when inline_nests_editor? then _render_core
|
65
|
+
when multi_card_editor? then multi_card_edit(true)
|
66
|
+
when in_multi_card_editor? then editor_in_multi_card
|
67
|
+
else single_card_edit_field
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# test: render nests within a normal rendering of the card's content?
|
72
|
+
# (as opposed to a standardized form)
|
73
|
+
def inline_nests_editor?
|
74
|
+
voo.input_type == :inline_nests
|
75
|
+
end
|
76
|
+
|
77
|
+
# test: are we opening a new multi-card form?
|
78
|
+
def multi_card_editor?
|
79
|
+
voo.structure || voo.edit_structure || # structure configured in voo
|
80
|
+
card.structure || # structure in card rule
|
81
|
+
edit_fields? # list of fields in card rule
|
82
|
+
end
|
83
|
+
|
84
|
+
# override and return true to optimize
|
85
|
+
def edit_fields?
|
86
|
+
edit_fields.present?
|
87
|
+
end
|
88
|
+
|
89
|
+
# test: are we already within a multi-card form?
|
90
|
+
def in_multi_card_editor?
|
91
|
+
@in_multi_card_editor.present?
|
92
|
+
end
|
93
|
+
|
94
|
+
def single_card_edit_field
|
95
|
+
if voo.show?(:type_formgroup) || voo.show?(:name_formgroup)
|
96
|
+
_render_content_formgroup # use formgroup for consistency
|
97
|
+
else
|
98
|
+
editor_wrap(:content) { content_field }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def editor_in_multi_card
|
103
|
+
add_junction_class
|
104
|
+
formgroup render_title,
|
105
|
+
input: "content", help: true, class: classy("card-editor") do
|
106
|
+
[content_field, (form.hidden_field(:type_id) if card.new_card?)]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def multi_card_edit fields_only=false
|
111
|
+
field_configs = edit_field_configs fields_only
|
112
|
+
return structure_link if field_configs.empty?
|
113
|
+
|
114
|
+
field_configs.map do |name, options|
|
115
|
+
nest name, options || {}
|
116
|
+
end.join "\n"
|
117
|
+
end
|
118
|
+
|
119
|
+
def structure_link
|
120
|
+
# LOCALIZE
|
121
|
+
structured = link_to_card card.structure_rule_card, "structured"
|
122
|
+
"<label>Content</label>"\
|
123
|
+
"<p><em>Uneditable; content is #{structured} without nests</em></p>"
|
124
|
+
end
|
125
|
+
|
126
|
+
# @param [Hash|Array] fields either an array with field names and/or field
|
127
|
+
# cards or a hash with the fields as keys and a hash with nest options as
|
128
|
+
# values
|
129
|
+
def process_edit_fields fields
|
130
|
+
fields.map do |field, opts|
|
131
|
+
field_nest field, opts
|
132
|
+
end.join "\n"
|
133
|
+
end
|
134
|
+
###
|
135
|
+
|
136
|
+
# If you use subfield cards to render a form for a new card
|
137
|
+
# then the subfield cards should be created on the new card not the existing
|
138
|
+
# card that build the form
|
139
|
+
|
140
|
+
def form
|
141
|
+
@form ||= inherit(:form) || new_form
|
142
|
+
end
|
143
|
+
|
144
|
+
def new_form
|
145
|
+
@form_root = true unless parent&.form_root
|
146
|
+
instantiate_builder(form_prefix, card, {})
|
147
|
+
end
|
148
|
+
|
149
|
+
def reset_form
|
150
|
+
@form = new_form
|
151
|
+
end
|
152
|
+
|
153
|
+
def form_prefix
|
154
|
+
case
|
155
|
+
when explicit_form_prefix then explicit_form_prefix # configured
|
156
|
+
when simple_form? then "card" # simple form
|
157
|
+
when parent.card.name == card.name then parent.form_prefix # card nests self
|
158
|
+
else edit_in_form_prefix
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def simple_form?
|
163
|
+
form_root? || !form_root || !parent
|
164
|
+
end
|
165
|
+
|
166
|
+
def edit_in_form_prefix
|
167
|
+
"#{parent.form_prefix}[subcards][#{card.name.from form_context.card.name}]"
|
168
|
+
end
|
169
|
+
|
170
|
+
def explicit_form_prefix
|
171
|
+
inherit :explicit_form_prefix
|
172
|
+
end
|
173
|
+
|
174
|
+
def form_context
|
175
|
+
form_root? || !form_root ? self : parent
|
176
|
+
end
|
177
|
+
|
178
|
+
def form_root?
|
179
|
+
@form_root == true
|
180
|
+
end
|
181
|
+
|
182
|
+
def form_root
|
183
|
+
return self if @form_root
|
184
|
+
|
185
|
+
parent ? parent.form_root : nil
|
186
|
+
end
|
187
|
+
|
188
|
+
def card_form action, opts={}
|
189
|
+
@form_root = true
|
190
|
+
hidden = hidden_form_tags action, opts
|
191
|
+
form_for card, card_form_opts(action, opts) do |cform|
|
192
|
+
@form = cform
|
193
|
+
hidden + output(yield(cform))
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def hidden_form_tags _action, opts
|
198
|
+
success = opts.delete :success
|
199
|
+
success_tags success
|
200
|
+
end
|
201
|
+
|
202
|
+
# @param action [Symbol] :create or :update
|
203
|
+
# @param opts [Hash] html options
|
204
|
+
# @option opts [Boolean] :redirect (false) if true form is no "slotter"
|
205
|
+
def card_form_opts action, opts={}
|
206
|
+
url, action = card_form_url_and_action action
|
207
|
+
html_opts = card_form_html_opts action, opts
|
208
|
+
form_opts = { url: url, html: html_opts }
|
209
|
+
form_opts[:remote] = true unless html_opts.delete(:redirect)
|
210
|
+
form_opts
|
211
|
+
end
|
212
|
+
|
213
|
+
def card_form_html_opts action, opts={}
|
214
|
+
add_class opts, "card-form"
|
215
|
+
add_class opts, "slotter" unless opts[:redirect] || opts[:no_slotter]
|
216
|
+
add_class opts, "autosave" if action == :update
|
217
|
+
opts
|
218
|
+
end
|
219
|
+
|
220
|
+
def card_form_url_and_action action
|
221
|
+
case action
|
222
|
+
when Symbol then [path(action: action), action]
|
223
|
+
when Hash then [path(action), action[:action]]
|
224
|
+
# for when non-action path args are required
|
225
|
+
else
|
226
|
+
raise Card::Error, "unsupported #card_form_url action: #{action}"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def editor_wrap type=nil
|
231
|
+
html_class = "editor"
|
232
|
+
html_class << " #{type}-editor" if type
|
233
|
+
wrap_with :div, class: html_class do
|
234
|
+
yield
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# FIELD VIEWS
|
239
|
+
|
240
|
+
def add_junction_class
|
241
|
+
return unless card.name.junction?
|
242
|
+
|
243
|
+
class_up "card-editor", "RIGHT-#{card.name.tag_name.safe_key}"
|
244
|
+
end
|
245
|
+
end
|