card-mod-edit 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ format :html do
2
+ def standard_submit_button
3
+ output [standard_save_button, standard_save_and_close_button]
4
+ end
5
+
6
+ def standard_save_button opts={}
7
+ return if voo&.hide?(:save_button)
8
+ add_class opts, "submit-button btn-sm mr-3 _update-history-pills"
9
+ opts[:text] ||= "Save"
10
+ opts["data-cy"] = "save"
11
+ submit_button opts
12
+ end
13
+
14
+ # @param opts [Hash]
15
+ # @option close [:modal, :overlay]
16
+ #
17
+ def standard_save_and_close_button opts={}
18
+ close = opts.delete(:close) || :modal
19
+ text = opts[:text] || "Save and Close"
20
+ add_class opts, "submit-button btn-sm mr-3 _close-on-success"
21
+ add_class opts, "_update-origin" unless opts[:no_origin_update]
22
+ opts.reverse_merge! text: text, "data-cy": "submit-#{close}"
23
+
24
+ submit_button opts
25
+ end
26
+
27
+ def standard_cancel_button args={}
28
+ args.reverse_merge! class: "cancel-button ml-4", href: path, "data-cy": "cancel"
29
+ cancel_button args
30
+ end
31
+
32
+ def modal_cancel_button
33
+ modal_close_button "Cancel", situation: "secondary", class: "btn-sm cancel-button"
34
+ end
35
+
36
+ def edit_cancel_button
37
+ modal_cancel_button
38
+ end
39
+
40
+ def new_cancel_button
41
+ voo.show?(:cancel_button) && modal_cancel_button
42
+ end
43
+
44
+ def delete_button opts={}
45
+ link_to "Delete", delete_button_opts(opts)
46
+ end
47
+
48
+ def delete_button_opts opts={}
49
+ add_class opts, "slotter btn btn-outline-danger ml-auto btn-sm"
50
+ opts["data-confirm"] = delete_confirm opts
51
+ opts[:path] = { action: :delete }
52
+ opts[:path][:success] = delete_success(opts) unless opts.delete(:no_success)
53
+ opts[:remote] = true
54
+ opts
55
+ end
56
+
57
+ def delete_confirm opts
58
+ opts.delete(:confirm) || "Are you sure you want to delete #{safe_name}?"
59
+ end
60
+
61
+ def delete_success opts
62
+ opts.delete(:success) || (main? ? "REDIRECT: *previous" : { view: :just_deleted })
63
+ end
64
+ end
@@ -0,0 +1,71 @@
1
+ format :html do
2
+ def success_tags opts
3
+ return "" unless opts.present?
4
+
5
+ hidden_tags success: opts
6
+ end
7
+
8
+ # convert hash into a collection of hidden tags
9
+ def hidden_tags hash, base=nil
10
+ hash ||= {}
11
+ hash.inject("") do |result, (key, val)|
12
+ new_base = base ? "#{base}[#{key}]" : key
13
+ result + process_hidden_value(val, new_base)
14
+ end
15
+ end
16
+
17
+ def process_hidden_value val, base
18
+ case val
19
+ when Hash
20
+ hidden_tags val, base
21
+ when Array
22
+ base += "[]"
23
+ val.map do |v|
24
+ hidden_field_tag base, v
25
+ end.join
26
+ else
27
+ hidden_field_tag base, val
28
+ end
29
+ end
30
+
31
+ FIELD_HELPERS =
32
+ %w[
33
+ hidden_field color_field date_field datetime_field datetime_local_field
34
+ email_field month_field number_field password_field phone_field
35
+ range_field search_field telephone_field text_area text_field time_field
36
+ url_field week_field file_field label check_box radio_button
37
+ ].freeze
38
+
39
+ FIELD_HELPERS.each do |method_name|
40
+ define_method(method_name) do |*args|
41
+ form.send(method_name, *args)
42
+ end
43
+ end
44
+
45
+ def submit_button args={}
46
+ text = args.delete(:text) || "Submit"
47
+ args.reverse_merge! situation: "primary", data: {}
48
+ args[:data][:disable_with] ||= args.delete(:disable_with) || "Submitting"
49
+ button_tag text, args
50
+ end
51
+
52
+ # redirect to *previous if no :href is given
53
+ def cancel_button args={}
54
+ return unless voo.show? :cancel_button
55
+ text = args.delete(:text) || "Cancel"
56
+ add_class args, "btn btn-#{args.delete(:situation) || 'secondary'}"
57
+ add_class args, cancel_strategy(args[:redirect], args[:href])
58
+ args[:href] ||= path_to_previous
59
+ args["data-remote"] = true
60
+ link_to text, args
61
+ end
62
+
63
+ def cancel_strategy redirect, href
64
+ redirect = href.blank? if redirect.nil?
65
+ redirect ? "redirecter" : "slotter"
66
+ end
67
+
68
+ def path_to_previous
69
+ path mark: "*previous"
70
+ end
71
+ end
@@ -0,0 +1,37 @@
1
+ format :html do
2
+ # a formgroup has a label, an input and help text
3
+ def formgroup title, opts={}, &block
4
+ wrap_with :div, formgroup_div_args(opts[:class]) do
5
+ formgroup_body title, opts, &block
6
+ end
7
+ end
8
+
9
+ def formgroup_body title, opts, &block
10
+ label = formgroup_label opts[:input], title
11
+ editor_body = editor_wrap opts[:input], &block
12
+ help_text = formgroup_help_text opts[:help]
13
+ "#{label}<div>#{help_text} #{editor_body}</div>"
14
+ end
15
+
16
+ def formgroup_label input, title
17
+ return if voo&.hide?(:title) || title.blank?
18
+
19
+ label_type = input || :content
20
+ form.label label_type, title
21
+ end
22
+
23
+ def formgroup_div_args html_class
24
+ div_args = { class: ["form-group", html_class].compact.join(" ") }
25
+ div_args[:card_id] = card.id if card.real?
26
+ div_args[:card_name] = h card.name if card.name.present?
27
+ div_args
28
+ end
29
+
30
+ def formgroup_help_text text=nil
31
+ return "" if text == false
32
+
33
+ class_up "help-text", "help-block"
34
+ voo.help = text if voo && text.to_s != "true"
35
+ _render_help
36
+ end
37
+ end
@@ -0,0 +1,188 @@
1
+ format :html do
2
+ view :new, perms: :create, unknown: true, cache: :never do
3
+ new_view_frame_and_form new_form_opts
4
+ end
5
+
6
+ view :new_content_form, wrap: :slot, unknown: true, cache: :never do
7
+ with_nest_mode :edit do
8
+ create_form
9
+ end
10
+ end
11
+
12
+ view :new_in_modal, perms: :create, unknown: true, cache: :never,
13
+ wrap: { modal: { footer: "", size: :edit_modal_size,
14
+ title: :new_in_modal_title,
15
+ menu: :new_modal_menu } } do
16
+ _render_new_content_form
17
+ end
18
+
19
+ def create_form
20
+ form_opts = new_in_modal_form_opts.reverse_merge(success: new_in_modal_success)
21
+ buttons = form_opts.delete(:buttons) || _render_new_buttons
22
+
23
+ voo.title ||= new_view_title if new_name_prompt?
24
+ voo.show :help
25
+ card_form(:create, form_opts) do
26
+ create_form_with_alert_guide buttons
27
+ end
28
+ end
29
+
30
+ def new_modal_size
31
+ :large
32
+ end
33
+
34
+ def new_modal_menu
35
+ wrap_with_modal_menu do
36
+ [close_modal_window, render_bridge_link]
37
+ end
38
+ end
39
+
40
+ def new_view_frame_and_form form_opts={}
41
+ buttons = form_opts.delete(:buttons) || _render_new_buttons
42
+ form_opts = form_opts.reverse_merge(success: new_success)
43
+
44
+ with_nest_mode :edit do
45
+ voo.title ||= new_view_title if new_name_prompt?
46
+ voo.show :help
47
+ frame_and_form :create, form_opts do
48
+ create_form_with_alert_guide buttons
49
+ end
50
+ end
51
+ end
52
+
53
+ def create_form_with_alert_guide buttons
54
+ wrap_with :div, class: "d-flex justify-content-between" do
55
+ [(wrap_with(:div, class: "w-100") do
56
+ [
57
+ new_view_hidden,
58
+ new_view_name,
59
+ new_view_type,
60
+ _render_content_formgroups,
61
+ buttons
62
+ ]
63
+ end),
64
+ (alert_guide if voo.show?(:guide))]
65
+ end
66
+ end
67
+
68
+ def new_view_hidden; end
69
+
70
+ def new_in_modal_form_opts
71
+ { "data-slot-selector": "modal-origin", "data-slot-error-selector": ".card-slot",
72
+ buttons: _render_new_in_modal_buttons }
73
+ end
74
+
75
+ def new_form_opts
76
+ { "main-success" => "REDIRECT" }
77
+ end
78
+
79
+ def new_view_title
80
+ output(
81
+ "New",
82
+ (card.type_name unless card.type_id == Card.default_type_id)
83
+ )
84
+ end
85
+
86
+ def new_in_modal_title
87
+ new_name_prompt? ? new_view_title : render_title
88
+ end
89
+
90
+ def new_success
91
+ card.rule(:thanks) || "_self"
92
+ end
93
+
94
+ def new_in_modal_success; end
95
+
96
+ # NAME HANDLING
97
+
98
+ def new_view_name
99
+ if new_name_prompt?
100
+ new_name_formgroup
101
+ elsif !autoname?
102
+ hidden_field_tag "card[name]", card.name
103
+ end
104
+ end
105
+
106
+ def new_name_formgroup
107
+ output _render_name_formgroup,
108
+ hidden_field_tag("name_prompt", true)
109
+ end
110
+
111
+ def new_name_prompt?
112
+ voo.visible? :name_formgroup do
113
+ needs_name? || params[:name_prompt]
114
+ end
115
+ end
116
+
117
+ def autoname?
118
+ @autoname.nil? ? (@autoname = card.rule_card :autoname).present? : @autoname
119
+ end
120
+
121
+ def needs_name?
122
+ card.name.blank? && !autoname?
123
+ end
124
+
125
+ # TYPE HANDLING
126
+
127
+ def new_view_type
128
+ if new_type_prompt?
129
+ _render_new_type_formgroup
130
+ else
131
+ hidden_field_tag "card[type_id]", card.type_id
132
+ end
133
+ end
134
+
135
+ def new_type_prompt?
136
+ voo.visible? :new_type_formgroup do
137
+ !new_type_preset? && new_type_prompt_context? && new_type_permitted?
138
+ end
139
+ end
140
+
141
+ def new_type_preset?
142
+ params[:type] || voo.type
143
+ end
144
+
145
+ def new_type_prompt_context?
146
+ main? || card.simple? || card.is_template?
147
+ end
148
+
149
+ def new_type_permitted?
150
+ Card.new(type_id: card.type_id).ok? :create
151
+ end
152
+
153
+ view :new_type_formgroup do
154
+ wrap_type_formgroup do
155
+ type_field class: "type-field live-type-field",
156
+ href: path(view: :new),
157
+ "data-remote" => true
158
+ end
159
+ end
160
+
161
+ view :new_buttons do
162
+ button_formgroup do
163
+ [standard_create_button, standard_cancel_button(cancel_button_new_args)]
164
+ end
165
+ end
166
+
167
+ view :new_in_modal_buttons do
168
+ button_formgroup do
169
+ wrap_with "div", class: "d-flex" do
170
+ [standard_save_and_close_button(text: "Submit"), modal_cancel_button]
171
+ end
172
+ end
173
+ end
174
+
175
+ # path to redirect to after canceling a new form
176
+ def cancel_button_new_args
177
+ href = case
178
+ when main? then path_to_previous
179
+ when voo&.home_view then path(view: voo.home_view)
180
+ else path(view: :unknown)
181
+ end
182
+ { href: href }
183
+ end
184
+
185
+ def standard_create_button
186
+ submit_button class: "submit-button create-submit-button"
187
+ end
188
+ end
@@ -0,0 +1,7 @@
1
+ %div
2
+ .d-flex.ml-2
3
+ .ml-auto
4
+ = link_to fa_icon(:close), path: "#", "data-dismiss": "overlay", class: "text-dark p-1 ml-1"
5
+
6
+ = guide
7
+
@@ -0,0 +1,9 @@
1
+ format :html do
2
+ view :overlay_guide,
3
+ cache: :never, unknown: true, template: :haml,
4
+ wrap: { slot: { class: "_overlay d0-card-overlay card nodblclick" } } do
5
+ # TODO: use a common template for this and the nest editor
6
+ # (the common thing is that they both are an overlay of the bridge sidebar)
7
+ # and maybe make it look more like the overlay on the left with the same close icon
8
+ end
9
+ end
@@ -0,0 +1,42 @@
1
+ format do
2
+ view :template_nest, cache: :never, unknown: true do
3
+ return "" unless voo.nest_name
4
+
5
+ if voo.nest_name.to_name.field_only?
6
+ with_nest_mode :normal do
7
+ nest template_link_set_name, view: :template_link
8
+ end
9
+ else
10
+ "{{#{voo.nest_syntax}}}"
11
+ end
12
+ end
13
+
14
+ def template_link_set_name
15
+ name = voo.nest_name.to_name
16
+ if name.absolute?
17
+ name.trait_name :self
18
+ else
19
+ template_link_set_name_for_relative_name name
20
+ end
21
+ end
22
+
23
+ def template_link_set_name_for_relative_name name
24
+ name = name.stripped.gsub(/^\+/, "")
25
+
26
+ if (type = on_type_set)
27
+ [type, name].to_name.trait_name :type_plus_right
28
+ else
29
+ name.to_name.trait_name :right
30
+ end
31
+ end
32
+
33
+ def on_type_set
34
+ return unless
35
+ (tmpl_set_name = parent.card.name.trunk_name) &&
36
+ (tmpl_set_class_name = tmpl_set_name.tag_name) &&
37
+ (tmpl_set_class_card = Card[tmpl_set_class_name]) &&
38
+ (tmpl_set_class_card.codename == :type)
39
+
40
+ tmpl_set_name.left_name
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ def input_type_content_options
2
+ ["multiselect", "checkbox", "autocompleted list", "filtered list"]
3
+ end
4
+
5
+ def show_content_options?
6
+ true
7
+ end
8
+
9
+ def show_input_type?
10
+ true
11
+ end
12
+
13
+ def field_settings
14
+ %i[default help input_type content_options content_option_view]
15
+ end
@@ -0,0 +1,13 @@
1
+ format :html do
2
+ def input_type_content_options
3
+ ["text area", "text field", "ace editor"]
4
+ end
5
+ end
6
+
7
+ def field_settings
8
+ %i[default help input_type]
9
+ end
10
+
11
+ def show_input_type?
12
+ true
13
+ end