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,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a7bdfc901290eeb41d413810325770cbb1a84550f5904ac31f040199bb6ea867
4
+ data.tar.gz: 2bc78ed7d0e52c36cb1780cdf094d42923c5cc8acaffcfd860895b09cdad6e42
5
+ SHA512:
6
+ metadata.gz: 837208fbdc76eabc11fc0994c0f6287266479d4e157ec7468eb6333bd628b897c11413a829c35d2bd44b68ce08f06365c9b63f38f717d9ae6695713c927d85cb
7
+ data.tar.gz: 1fd91ea28bfbdc343dbf7f240b102e32e6d0249531ed212643d07b9f2bfbce262d553c55bc278dd23f98a4f5475a5697c30bb48de67e18924f72815b4fde06e7
@@ -0,0 +1,64 @@
1
+ format :html do
2
+ BRIDGE_TABS = { "Account" => :account_tab,
3
+ "Guide" => :guide_tab,
4
+ "Engage" => :engage_tab,
5
+ "History" => :history_tab,
6
+ "Related" => :related_tab,
7
+ "Rules" => :rules_tab }.freeze
8
+
9
+ wrapper :bridge do
10
+ class_up "modal-dialog", "no-gaps"
11
+ voo.hide! :modal_footer
12
+ wrap_with_modal size: :full, title: bridge_breadcrumbs do
13
+ haml :bridge
14
+ end
15
+ end
16
+
17
+ def bridge_tabs
18
+ wrap do
19
+ tabs(visible_bridge_tabs, bridge_tab, load: :lazy) { _render bridge_tab }
20
+ end
21
+ end
22
+
23
+ def bridge_tab
24
+ @bridge_tab ||= bridge_param :tab
25
+ end
26
+
27
+ def bridge_param key
28
+ params.dig(:bridge, key)&.to_sym || try("default_bridge_#{key}")
29
+ end
30
+
31
+ def bridge_breadcrumbs
32
+ <<-HTML.strip_heredoc
33
+ <nav aria-label="breadcrumb">
34
+ <ol class="breadcrumb _bridge-breadcrumb">
35
+ <li class="breadcrumb-item">#{card.name}</li>
36
+ <li class="breadcrumb-item active">Edit</li>
37
+ </ol>
38
+ </nav>
39
+ HTML
40
+ end
41
+
42
+ def bridge_link_opts opts={}
43
+ opts[:"data-slot-selector"] = bridge_slot_selector
44
+ opts[:remote] = true
45
+ add_class opts, "slotter"
46
+ opts.bury :path, :layout, :overlay
47
+ opts[:path][:view] ||= :content
48
+ opts
49
+ end
50
+
51
+ def bridge_slot_selector
52
+ ".bridge-main > .overlay-container > .card-slot._bottomlay-slot," \
53
+ ".bridge-main > ._overlay-container-placeholder > .card-slot"
54
+ end
55
+
56
+ def default_bridge_tab
57
+ show_guide_tab? ? :guide_tab : :engage_tab
58
+ end
59
+
60
+ def breadcrumb_data title, html_class=nil
61
+ html_class ||= title.underscore
62
+ { "data-breadcrumb": title, "data-breadcrumb-class": html_class }
63
+ end
64
+ end
@@ -0,0 +1,8 @@
1
+ .bridge.container-fluid
2
+ .row
3
+ .col-8.bridge-main
4
+ ._overlay-container-placeholder
5
+ = interior
6
+ .col-4.bridge-sidebar.nodblclick
7
+ ._overlay-container-placeholder
8
+ = bridge_tabs
@@ -0,0 +1,47 @@
1
+ format :html do
2
+ BRIDGE_PILL_UL_CLASSES =
3
+ "nav nav-pills _auto-single-select bridge-pills flex-column".freeze
4
+
5
+ BRIDGE_PILL_LI_CLASSES = "nav-item".freeze
6
+
7
+ def bridge_pills items
8
+ list_tag class: BRIDGE_PILL_UL_CLASSES, items: { class: BRIDGE_PILL_LI_CLASSES } do
9
+ items
10
+ end
11
+ end
12
+
13
+ def bridge_pill_items data, breadcrumb
14
+ data.map do |text, field, extra_opts|
15
+ opts = bridge_pill_item_opts breadcrumb, extra_opts, text
16
+ mark = opts.delete(:mark) == :absolute ? field : [card, field]
17
+ link_to_card mark, text, opts
18
+ end
19
+ end
20
+
21
+ def bridge_pill_item_opts breadcrumb, extra_opts, text
22
+ opts = bridge_link_opts.merge("data-toggle": "pill")
23
+ opts.merge! breadcrumb_data(breadcrumb)
24
+
25
+ if extra_opts
26
+ classes = extra_opts.delete :class
27
+ add_class opts, classes if classes
28
+ opts.deep_merge! extra_opts
29
+ end
30
+ opts["data-cy"] = "#{text.to_name.key}-pill"
31
+ add_class opts, "nav-link"
32
+ opts
33
+ end
34
+
35
+ def bridge_pill_sections tab_name
36
+ wrap_with :ul, class: BRIDGE_PILL_UL_CLASSES do
37
+ yield.map { |args| bridge_pill_section(tab_name, *args) }
38
+ end
39
+ end
40
+
41
+ def bridge_pill_section tab_name, title, items
42
+ wrap_with(:h6, title, class: "ml-1 mt-3") +
43
+ wrap_each_with(:li, class: BRIDGE_PILL_LI_CLASSES) do
44
+ bridge_pill_items(items, tab_name)
45
+ end.html_safe
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ format :html do
2
+ def follow_section
3
+ return unless show_follow?
4
+
5
+ wrap_with :div, class: "mb-3" do
6
+ [follow_button_group, followers_bridge_link, follow_overview_button]
7
+ end
8
+ end
9
+
10
+ def follow_button_group
11
+ wrap_with :div, class: "btn-group btn-group-sm follow-btn-group" do
12
+ [follow_button, follow_advanced]
13
+ end
14
+ end
15
+
16
+ def follow_overview_button
17
+ link_to_card [Auth.current, :follow], "all followed cards",
18
+ bridge_link_opts(class: "btn btn-sm btn-secondary",
19
+ "data-cy": "follow-overview")
20
+ end
21
+
22
+ def follow_advanced
23
+ opts = bridge_link_opts(class: "btn btn-sm btn-primary",
24
+ path: { view: :overlay_rule },
25
+ "data-cy": "follow-advanced")
26
+ opts[:path].delete :layout
27
+ link_to_card card.follow_rule_card(Auth.current.name, new: {}),
28
+ icon_tag("more_horiz"), opts
29
+ end
30
+
31
+ def followers_bridge_link
32
+ cnt = card.followers_count
33
+ link_to_card card.name.field(:followers), "#{cnt} follower#{'s' unless cnt == 1}",
34
+ bridge_link_opts(class: "btn btn-sm ml-2 btn-secondary slotter",
35
+ remote: true, "data-cy": "followers")
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ format :html do
2
+ RELATED_ITEMS =
3
+ {
4
+ "by name" => [["children", :children],
5
+ ["mates", :mates]],
6
+ # FIXME: optimize,
7
+ "by content" => [["links out", :links_to],
8
+ ["links in", :linked_to_by],
9
+ ["nests", :nests],
10
+ ["nested by", :nested_by],
11
+ ["references out", :refers_to],
12
+ ["references in", :referred_to_by]]
13
+ # ["by edit", [["creator", :creator],
14
+ # ["editors", :editors],
15
+ # ["last edited", :last_edited]]]
16
+ }.freeze
17
+
18
+ def related_by_name_items
19
+ pills = []
20
+ if card.name.junction?
21
+ pills += card.name.ancestors.map { |a| [a, a, { mark: :absolute }] }
22
+ end
23
+ pills += RELATED_ITEMS["by name"]
24
+ pills
25
+ end
26
+
27
+ def related_by_content_items
28
+ RELATED_ITEMS["by content"]
29
+ end
30
+
31
+ def related_by_type_items
32
+ [["#{card.type} cards", [card.type, :type, :by_name], mark: :absolute]]
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ format :html do
2
+ view :engage_tab, wrap: { div: { class: "m-3 mt-4 _engage-tab" } }, cache: :never do
3
+ [render_follow_section, discussion_section].compact
4
+ end
5
+
6
+ view :history_tab, wrap: :slot do
7
+ class_up "d0-card-body", "history-slot"
8
+ voo.hide :act_legend
9
+ acts_bridge_layout card.history_acts
10
+ end
11
+
12
+ view :related_tab do
13
+ bridge_pill_sections "Related" do
14
+ %w[name content type].map do |section_name|
15
+ ["by #{section_name}", send("related_by_#{section_name}_items")]
16
+ end
17
+ end
18
+ end
19
+
20
+ view :rules_tab, unknown: true do
21
+ class_up "card-slot", "flex-column"
22
+ wrap do
23
+ nest current_set_card, view: :bridge_rules_tab
24
+ end
25
+ end
26
+
27
+ view :follow_section, wrap: :slot, cache: :never do
28
+ follow_section
29
+ end
30
+
31
+ view :guide_tab, unknown: true do
32
+ render_guide
33
+ end
34
+
35
+ def discussion_section
36
+ return unless show_discussion?
37
+
38
+ field_nest(:discussion, view: :titled, title: "Discussion", show: :comment_box,
39
+ hide: [:menu])
40
+ end
41
+ end
@@ -0,0 +1,53 @@
1
+ format :html do
2
+ def visible_bridge_tabs
3
+ BRIDGE_TABS.select do |_title, view|
4
+ send "show_#{view}?"
5
+ end
6
+ end
7
+
8
+ private
9
+
10
+ def show_engage_tab?
11
+ return unless card.real?
12
+
13
+ show_follow? || show_discussion?
14
+ end
15
+
16
+ def show_account_tab?
17
+ false
18
+ end
19
+
20
+ def show_history_tab?
21
+ card.real?
22
+ end
23
+
24
+ def show_related_tab?
25
+ card.real?
26
+ end
27
+
28
+ def show_rules_tab?
29
+ true
30
+ end
31
+
32
+ def show_guide_tab?
33
+ guide.present?
34
+ end
35
+
36
+ def show_discussion?
37
+ d_card = discussion_card
38
+ return unless d_card
39
+
40
+ permission_task = d_card.new_card? ? :update : :read
41
+ d_card.ok? permission_task
42
+ end
43
+
44
+ def discussion_card?
45
+ card.junction? && card.name.tag_name.key == :discussion.cardname.key
46
+ end
47
+
48
+ def discussion_card
49
+ return if card.new_card? || discussion_card?
50
+
51
+ card.fetch :discussion, skip_modules: true, new: {}
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+ format :html do
2
+ view :edit_form, wrap: :slot do
3
+ voo.show :edit_type_row
4
+ with_nest_mode :edit do
5
+ edit_form
6
+ end
7
+ end
8
+
9
+ def edit_form
10
+ voo.hide :edit_type_row
11
+ form_opts = edit_form_opts.reverse_merge success: edit_success
12
+ card_form(:update, form_opts) do
13
+ [
14
+ edit_view_hidden,
15
+ _render_edit_type_row(home_view: :edit_type_row),
16
+ # home_view is necessary for cancel to work correctly.
17
+ # it seems a little strange to have to think about home_view here,
18
+ # but the issue is that something currently has to happen prior to the
19
+ # render to get voo.slot_options to have the write home view in
20
+ # the slot wrap. Id think this would probably best be handled as an
21
+ # option to #wrap that triggers a new heir voo
22
+ _render_content_formgroups,
23
+ _render_edit_buttons
24
+ ]
25
+ end
26
+ end
27
+
28
+ view :edit, perms: :update, unknown: true, cache: :never,
29
+ wrap: { modal: { footer: "",
30
+ size: :edit_modal_size,
31
+ title: :render_title,
32
+ menu: :edit_modal_menu } } do
33
+ add_name_context
34
+ with_nest_mode :edit do
35
+ voo.show :help
36
+ voo.hide :save_button
37
+ wrap true do
38
+ [
39
+ frame_help,
40
+ _render_edit_form
41
+ ]
42
+ end
43
+ end
44
+ end
45
+
46
+ def edit_modal_size
47
+ :large
48
+ end
49
+
50
+ def edit_modal_menu
51
+ wrap_with_modal_menu do
52
+ [close_modal_window, render_bridge_link]
53
+ end
54
+ end
55
+
56
+ def edit_form_opts
57
+ # for override
58
+ { "data-slot-selector": "modal-origin", "data-slot-error-selector": ".card-slot" }
59
+ end
60
+ end
@@ -0,0 +1,56 @@
1
+ format :html do
2
+ view :edit_inline, perms: :update, unknown: true, cache: :never, wrap: :slot do
3
+ voo.hide :name_formgroup, :type_formgroup
4
+ with_nest_mode :edit do
5
+ card_form :update, success: edit_success do
6
+ [
7
+ edit_view_hidden,
8
+ _render_content_formgroups,
9
+ _render_edit_inline_buttons
10
+ ]
11
+ end
12
+ end
13
+ end
14
+
15
+ view :edit_name_row do
16
+ edit_row_fixed_width "Name", card.name, :name_form
17
+ end
18
+
19
+ view :edit_inline_buttons do
20
+ button_formgroup do
21
+ wrap_with "div", class: "d-flex" do
22
+ [standard_save_button, cancel_in_place_button, delete_button]
23
+ end
24
+ end
25
+ end
26
+
27
+ # TODO: better styling for this so that is reusable
28
+ # At the moment it is used for the name and type field in the bridge
29
+ # (with fixed 50px width for the title column) and
30
+ # for password and email for accounts (with fixed 75px width for the title column)
31
+ # The view is very similar to labeled but with fixed edit link on the right
32
+ # and a fixed width for the labels so that the content column is aligned
33
+ # There is also the problem that label and content are not vertically aligned
34
+ view :edit_row do
35
+ edit_row_fixed_width render_title, render_core, :edit_inline, 75
36
+ end
37
+
38
+ def edit_row_fixed_width title, content, edit_view, width=50
39
+ class_up "card-slot", "d-flex"
40
+ wrap do
41
+ ["<label class='w-#{width}px'>#{title}</label>",
42
+ content,
43
+ edit_inline_link(edit_view, align: :right)]
44
+ end
45
+ end
46
+
47
+ def edit_inline_link view=:edit_inline, align: :left
48
+ align = align == :left ? "ml-2" : "ml-auto"
49
+ link_to_view view, menu_icon, class: "#{align} edit-link", "data-cy": "edit-link"
50
+ end
51
+
52
+ def cancel_in_place_button args={}
53
+ args.reverse_merge! class: "cancel-button btn-sm", href: path
54
+ cancel_button args
55
+ end
56
+ end
@@ -0,0 +1,58 @@
1
+ format :html do
2
+ # note: depends on js with selector ".edit_name-view .card-form"
3
+ view :edit_name, perms: :update do
4
+ frame { name_form }
5
+ end
6
+
7
+ # note: depends on js with selector ".name_form-view .card-form"
8
+ view :name_form, perms: :update, wrap: :slot, cache: :never do
9
+ name_form :edit_name_row
10
+ end
11
+
12
+ def name_form success_view=nil
13
+ card_form({ action: :update, id: card.id },
14
+ # "main-success" => "REDIRECT",
15
+ "data-update-origin": "true",
16
+ success: edit_name_success(success_view)) do
17
+ [hidden_edit_name_fields,
18
+ _render_name_formgroup,
19
+ rename_confirmation_alert,
20
+ edit_name_buttons]
21
+ end
22
+ end
23
+
24
+ def edit_name_success view=nil
25
+ success = { id: "_self" }
26
+ success[:view] = view if view
27
+ success
28
+ end
29
+
30
+ def hidden_edit_name_fields
31
+ hidden_tags old_name: card.name, card: { update_referers: false }
32
+ end
33
+
34
+ def edit_name_buttons
35
+ button_formgroup do
36
+ [rename_and_update_button, rename_button, standard_cancel_button]
37
+ end
38
+ end
39
+
40
+ # LOCALIZE
41
+ def rename_and_update_button
42
+ submit_button text: "Rename and Update", disable_with: "Renaming",
43
+ class: "renamer-updater"
44
+ end
45
+
46
+ def rename_button
47
+ button_tag "Rename", data: { disable_with: "Renaming" }, class: "renamer"
48
+ end
49
+
50
+ # LOCALIZE
51
+ def rename_confirmation_alert
52
+ msg = "<h5>Are you sure you want to rename <em>#{safe_name}</em>?</h5>"
53
+ msg << %(<h6>This may change names referred to by other cards.</h6>)
54
+ msg << %(<p>You may choose to <em>update or ignore</em> the referers.</p>)
55
+ msg << hidden_field_tag(:referers, 1)
56
+ alert("warning", false, false, class: "hidden-alert") { msg }
57
+ end
58
+ end