card-mod-list 0.11.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a0d458cf092c0f324ec963f3bbee7e8c72d0c418aa19703fdc6d76d9f501e8e6
4
+ data.tar.gz: ec7e3011dccbbc15a1be9ca841625cf61c83bfbbb6653e4f9688d3de0869aa41
5
+ SHA512:
6
+ metadata.gz: 63e316144f8954ca5df190117baefaad4b8e5183e0fd47753f0dfdaba30749df52e97d8d1868690f101994617c9b8815f4f7d1ad431496eee464da323f91822e
7
+ data.tar.gz: d55af462a1c12e8890f36584a387e23db5787dd7024a298eee4448db755d1cbf23e6199ac55e6c5e10a39fb8df9c100827ccbc7ba8592537e36de9da777ed452
@@ -0,0 +1,9 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ class AddPointerCards < Cardio::Migration
4
+ def up
5
+ ensure_card name: "script: pointer config",
6
+ type_id: Card::CoffeeScriptID,
7
+ codename: "script_pointer_config"
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ include_set Abstract::Paging
2
+ include_set Abstract::Items
3
+
4
+ def diff_args
5
+ { diff_format: :pointer }
6
+ end
7
+
8
+ def count
9
+ item_strings.size
10
+ end
@@ -0,0 +1,71 @@
1
+ event :add_and_drop_items, :prepare_to_validate, on: :save do
2
+ adds = Env.params["add_item"]
3
+ drops = Env.params["drop_item"]
4
+ Array.wrap(adds).each { |i| add_item i } if adds
5
+ Array.wrap(drops).each { |i| drop_item i } if drops
6
+ end
7
+
8
+ event :insert_item_event, :prepare_to_validate, on: :save, when: :item_to_insert do
9
+ index = Env.params["item_index"] || 0
10
+ insert_item index.to_i, item_to_insert
11
+ end
12
+
13
+ def item_to_insert
14
+ Env.params["insert_item"]
15
+ end
16
+
17
+ # If a card's type and content are updated in the same action, the new module
18
+ # will override the old module's events and functions. But this event is only
19
+ # on pointers -- other type cards do not have this event,
20
+ # Therefore if something is changed from a pointer and its content is changed
21
+ # in the same action, this event will be run and will treat the content like
22
+ # it' still pointer content. The "when" clause helps with that (but is a hack)
23
+ event :standardize_items, :prepare_to_validate,
24
+ on: :save, changed: :content, when: :still_pointer? do
25
+ items_to_content item_strings
26
+ end
27
+
28
+ def still_pointer?
29
+ type_id == PointerID
30
+ # Card.new(type_id: type_id).is_a? Abstract::Pointer
31
+ end
32
+
33
+ def changed_item_names
34
+ dropped_item_names + added_item_names
35
+ end
36
+
37
+ def dropped_item_names
38
+ return item_names if trash
39
+ return [] unless (old_content = db_content_before_act)
40
+
41
+ old_items = item_names content: old_content
42
+ old_items - item_names
43
+ end
44
+
45
+ def added_item_names
46
+ return [] if trash
47
+ return item_names unless (old_content = db_content_before_act)
48
+
49
+ old_items = item_names content: old_content
50
+ item_names - old_items
51
+ end
52
+
53
+ # TODO: refactor. many of the above could be written more elegantly with improved
54
+ # handling of :content in item_names. If content is nil here, we would expect an
55
+ # empty set of cards, but in fact we get items based on self.content.
56
+
57
+ def changed_item_cards
58
+ dropped_item_cards + added_item_cards
59
+ end
60
+
61
+ def dropped_item_cards
62
+ return [] unless db_content_before_act
63
+
64
+ all_item_cards item_names: dropped_item_names
65
+ end
66
+
67
+ def added_item_cards
68
+ return item_cards unless db_content_before_act
69
+
70
+ all_item_cards item_names: added_item_names
71
+ end
@@ -0,0 +1,123 @@
1
+ format :html do
2
+ view :core, cache: :never do
3
+ standard_pointer_core
4
+ end
5
+
6
+ view :item_cores, cache: :never do
7
+ card.known_item_cards.map do |item|
8
+ nest item, view: :core
9
+ end.join "\n"
10
+ end
11
+
12
+ def standard_pointer_core
13
+ with_paging do |paging_args|
14
+ wrap_with :div, standard_pointer_items(paging_args), class: "pointer-list"
15
+ end
16
+ end
17
+
18
+ def standard_pointer_items paging_args
19
+ pointer_items(paging_args.extract!(:limit, :offset)).join(voo.separator || "\n")
20
+ end
21
+
22
+ view :one_line_content do
23
+ item_view = implicit_item_view
24
+ item_view = item_view == "name" ? "name" : "link"
25
+ wrap_with :div, class: "pointer-list" do
26
+ # limit to first 10 items to optimize
27
+ pointer_items(view: item_view, limit: 10, offset: 0).join ", "
28
+ end
29
+ end
30
+
31
+ def wrap_item rendered, item_view
32
+ %(<div class="pointer-item item-#{item_view}">#{rendered}</div>)
33
+ end
34
+
35
+ view :input do
36
+ _render_hidden_content_field + super()
37
+ end
38
+
39
+ def default_input_type
40
+ :list
41
+ end
42
+
43
+ view :list, cache: :never do
44
+ list_input
45
+ end
46
+
47
+ # view :nav_item do
48
+ # nav_dropdown
49
+ # end
50
+
51
+ def list_input args={}
52
+ items = items_for_input args[:item_list]
53
+ extra_class = "pointer-list-ul"
54
+ ul_classes = classy "pointer-list-editor", extra_class
55
+ haml :list_input, items: items, ul_classes: ul_classes,
56
+ options_card: options_card_name
57
+ end
58
+
59
+ %i[autocomplete checkbox radio select multiselect].each do |editor_view|
60
+ view(editor_view) { send "#{editor_view}_input" }
61
+ end
62
+
63
+ def autocomplete_input
64
+ items = items_for_input
65
+ haml :autocomplete_input, item: items.first, options_card: options_card_name
66
+ end
67
+
68
+ def checkbox_input
69
+ haml :checkbox_input, submit_on_change: @submit_on_change
70
+ end
71
+
72
+ def radio_input
73
+ haml :radio_input, submit_on_change: @submit_on_change
74
+ end
75
+
76
+ def select_input
77
+ options = { "-- Select --" => "" }.merge card.options_hash
78
+ select_tag("pointer_select-#{unique_id}",
79
+ options_for_select(options, card.item_name),
80
+ class: "pointer-select form-control")
81
+ end
82
+
83
+ def multiselect_input
84
+ select_tag "pointer_multiselect-#{unique_id}",
85
+ options_for_select(card.options_hash, card.item_names),
86
+ multiple: true, class: "pointer-multiselect form-control"
87
+ end
88
+
89
+ def add_item_modal_link
90
+ modal_link "Add Item",
91
+ size: :large,
92
+ class: "btn btn-sm btn-outline-secondary _add-item-link",
93
+ path: { view: :filter_items_modal,
94
+ item: implicit_item_view,
95
+ filter_card: filter_card.name,
96
+ slot_selector: filtered_list_slot_class,
97
+ item_selector: "_filtered-list-item",
98
+ slot: { hide: [:modal_footer] },
99
+ filter: { not_ids: not_ids_value } }
100
+ end
101
+
102
+ def not_ids_value
103
+ card.item_ids.map(&:to_s).join(",")
104
+ end
105
+
106
+ def add_item_overlay_link; end
107
+
108
+ def one_line_content
109
+ if count == 1
110
+ card.first_name
111
+ else
112
+ short_content
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ # currently only used by :list and :autocomplete. could be generalized?
119
+ def items_for_input items=nil
120
+ items ||= card.item_names context: :raw
121
+ items.empty? ? [""] : items
122
+ end
123
+ end
@@ -0,0 +1,3 @@
1
+ .pointer-list-editor.pointer-list-ul
2
+ = text_field_tag 'pointer_item', item, class: "pointer-item-text form-control",
3
+ "data-options-card": options_card
@@ -0,0 +1,8 @@
1
+ .pointer-checkbox-list
2
+ - card.options_hash.each do |option_label, option_name|
3
+ - id = "pointer-checkbox-#{option_name.to_name.key}"
4
+ - checked = card.item_names.include? option_name
5
+ .pointer-checkbox
6
+ = check_box_tag "pointer_checkbox-#{unique_id}", option_name, checked,
7
+ id: id, class: "pointer-checkbox-button #{'_submit-on-change' if submit_on_change}"
8
+ = option_label option_label, id
@@ -0,0 +1,62 @@
1
+ format :html do
2
+ view :filtered_list, unknown: true do
3
+ filtered_list_input
4
+ end
5
+
6
+ view :filter_items_modal, unknown: true, wrap: :modal do
7
+ render_filter_items
8
+ end
9
+
10
+ view :filter_items, unknown: true, wrap: :slot, template: :haml
11
+
12
+ def filtered_list_input
13
+ with_nest_mode :normal do
14
+ class_up "card-slot", filtered_list_slot_class
15
+ with_class_up "card-slot", filtered_list_slot_class do
16
+ wrap do
17
+ haml :filtered_list_input
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ # NOCACHE because params alter view
24
+ view :add_selected_link, cache: :never, unknown: true do
25
+ link_to "Add Selected",
26
+ path: { filter_card: params[:filter_card] },
27
+ class: "_add-selected slotter _close-modal btn btn-primary disabled",
28
+ data: { "slot-selector": ".#{params[:slot_selector]}",
29
+ "item-selector": ".#{params[:item_selector]}",
30
+ remote: true }
31
+ end
32
+
33
+ def filtered_list_item item_card
34
+ nest_item item_card do |rendered, item_view|
35
+ wrap_item rendered, item_view
36
+ end
37
+ end
38
+
39
+ # for override
40
+ # @return [Card] search card on which filtering is based
41
+ def filter_card
42
+ filter_card_from_params || default_filter_card
43
+ end
44
+
45
+ def default_filter_card
46
+ fcard = card.options_rule_card || Card[:all]
47
+ return fcard if fcard.respond_to? :cql_hash
48
+
49
+ fcard.fetch :referred_to_by, new: {}
50
+ end
51
+
52
+ def filter_card_from_params
53
+ return unless params[:filter_card]
54
+ Card.fetch params[:filter_card], new: {}
55
+ end
56
+
57
+ # currently actually used as a class
58
+ # (because we don't have api to override slot's id)
59
+ def filtered_list_slot_class
60
+ @filtered_list_slot_class ||= "filtered-list-#{unique_id}"
61
+ end
62
+ end
@@ -0,0 +1,28 @@
1
+ ._filter-items.container-fluid.nodblclick._noFilterUrlUpdates
2
+ .row
3
+ = nest filter_card, view: :filter_form
4
+ ._unselected.col-6.border.mt-2.px-0
5
+ = nest filter_card, view: :select_item,
6
+ items: { view: implicit_item_view },
7
+ cql: { limit: 10 }
8
+ ._selected.col-6.border.mt-2.pl-0.pr-0
9
+ .selected-box
10
+ .card-header
11
+ %h5
12
+ Selected
13
+ .badge.badge-secondary
14
+ %span._selected-items 0
15
+ ._selected-item-list{ style: "display:none" }
16
+ .deselector.p-2
17
+ %input#deselect-all._deselect-all{ type: "checkbox", checked: true, disabled: true }
18
+ %label{ for: "deselect-all" }
19
+ deselect
20
+ %span._selected-items 0
21
+ following
22
+ ._selected-bin.p-2
23
+ ._filter-help.alert.alert-secondary
24
+ Filter and select items to add them here.
25
+ .form-group
26
+ .selected-item-buttons.p-2
27
+ = button_tag "Cancel", class: "cancel-modal", data: { dismiss: :modal }
28
+ = render :add_selected_link
@@ -0,0 +1,21 @@
1
+ %div.filtered-list-editor
2
+ %ul.pointer-list.filtered-list-review._pointer-filtered-list.list-group.vertical.nopadding
3
+ - card.item_cards(context: :raw).each do |item_card|
4
+ %li._filtered-list-item.clearfix{ data: item_card.format.wrap_data(false) }
5
+ %span._handle.float-left.m-2
6
+ = icon_tag :reorder
7
+ - nest_item item_card do |rendered, view|
8
+ %span{ class: "item-#{view} float-left w-75"}
9
+ = rendered
10
+ %span.filtered-list-item-button
11
+ %button._filtered-list-item-delete.btn.btn-secondary.btn-sm.m-2{:type => "button"}
12
+ = icon_tag :remove
13
+ %br
14
+ .clearfix
15
+ = add_item_modal_link
16
+ -# "data-target": "#modal-filtered-list"
17
+ -# = modal_slot "filtered-list", "modal-lg"
18
+
19
+ // note: passing item and filter card because in some cases (eg Project+Metric on wikirate)
20
+ // the link was losing set-identifying information (type of left)
21
+ // would be preferable to have a more general solution to retain set-identifying info.
@@ -0,0 +1,16 @@
1
+ %ul{class: ul_classes}
2
+ - items.each do |item|
3
+ %li.pointer-li.mb-1
4
+ %span.input-group
5
+ .input-group-prepend.handle
6
+ %span.input-group-text
7
+ = icon_tag :reorder
8
+ = text_field_tag "pointer_item", item, class: "pointer-item-text form-control",
9
+ "data-options-card": options_card
10
+ .input-group-append
11
+ %button.pointer-item-delete.btn.btn-secondary{ type: "button"}
12
+ = icon_tag :remove
13
+ %span.input-group
14
+ %button._pointer-item-add.btn.btn-secondary{ type: "submit" }
15
+ = icon_tag "add"
16
+ add another
@@ -0,0 +1,12 @@
1
+ // TODO: delete me? Is this file in use?
2
+
3
+ %li.pointer-li.mb-1
4
+ %span.input-group
5
+ .input-group-prepend.handle
6
+ %span.input-group-text
7
+ = icon_tag :reorder
8
+ = text_field_tag "pointer_item", item, class: "pointer-item-text form-control",
9
+ "data-options-card": options_card
10
+ .input-group-append
11
+ %button.pointer-item-delete.btn.btn-secondary{:type => "button"}
12
+ = icon_tag :remove
@@ -0,0 +1,13 @@
1
+ %ul.pointer-radio-list
2
+ - options_hash = card.options_hash
3
+ - if options_hash.empty?
4
+ no options
5
+ - else
6
+ - input_name = "pointer_radio_button-#{card.key}"
7
+ - options_hash.each do |option_label, option_name|
8
+ - checked = option_name == card.item_name
9
+ - id = "pointer-radio-#{option_name.to_name.key}"
10
+ %li.pointer-radio.radio
11
+ = radio_button_tag input_name, option_name, checked,
12
+ id: id, class: "pointer-radio-button #{'_submit-on-change' if submit_on_change}"
13
+ = option_label option_label, id
@@ -0,0 +1,78 @@
1
+ # TODO: some of this should be moved to right/options!!
2
+ # or to type/JSON?
3
+
4
+ def options_hash
5
+ json_options? ? options_card.parse_content : option_hash_from_names
6
+ end
7
+
8
+ def json_options?
9
+ options_card&.type_id == JsonID
10
+ end
11
+
12
+ def option_hash_from_names
13
+ option_names.each_with_object({}) do |name, hash|
14
+ hash[name] = name
15
+ end
16
+ end
17
+
18
+ def option_names
19
+ if (selected_options = item_names)
20
+ (standard_option_names + selected_options).uniq
21
+ else
22
+ standard_option_names
23
+ end
24
+ end
25
+
26
+ def option_cards
27
+ option_names.map do |name|
28
+ Card.fetch name, new: {}
29
+ end
30
+ end
31
+
32
+ def options_rule_card
33
+ rule_card :content_options
34
+ end
35
+
36
+ def standard_option_names
37
+ if json_options?
38
+ options_hash.values.map(&:to_name)
39
+ else
40
+ option_names_from_items
41
+ end
42
+ end
43
+
44
+ def option_names_from_items
45
+ o_card = options_card
46
+ limit = o_card.try(:default_limit).to_i
47
+ o_card.item_names context: name, limit: limit
48
+ end
49
+
50
+ def options_card
51
+ options_rule_card || Card[:all]
52
+ end
53
+
54
+ def options_card_name
55
+ options_rule_card&.name&.url_key || ":all"
56
+ end
57
+
58
+ format do
59
+ def options_card_name
60
+ card.options_card_name
61
+ end
62
+ end
63
+
64
+ format :html do
65
+ def option_label option_name, id
66
+ %(<label for="#{id}">#{option_label_text option_name}</label>)
67
+ end
68
+
69
+ def option_view
70
+ @option_view ||= card.rule(:content_option_view) || :smart_label
71
+ end
72
+
73
+ def option_label_text option_name
74
+ return option_name unless (option_card = Card.fetch option_name)
75
+
76
+ nest option_card, view: option_view
77
+ end
78
+ end
@@ -0,0 +1,102 @@
1
+ # BASE views
2
+
3
+ format do
4
+ def default_limit
5
+ 20
6
+ end
7
+
8
+ def item_links args={}
9
+ card.item_cards(args).map do |item_card|
10
+ subformat(item_card).render_link
11
+ end
12
+ end
13
+
14
+ def nest_item_array
15
+ card.item_cards.map do |item|
16
+ nest_item item
17
+ end
18
+ end
19
+
20
+ view :core do
21
+ pointer_items.join ", "
22
+ end
23
+
24
+ def pointer_items args={}
25
+ page_args = args.extract! :limit, :offset
26
+ listing card.item_cards(page_args), args
27
+ end
28
+ end
29
+
30
+ # JavaScript views
31
+
32
+ format :js do
33
+ view :core do
34
+ nest_item_array.join "\n\n"
35
+ end
36
+ end
37
+
38
+ # Data views
39
+
40
+ format :data do
41
+ view :core do
42
+ nest_item_array
43
+ end
44
+ end
45
+
46
+ # JSON views
47
+
48
+ format :json do
49
+ view :content do
50
+ card.item_names
51
+ end
52
+
53
+ def item_cards
54
+ card.item_cards
55
+ end
56
+
57
+ def max_depth
58
+ params[:max_depth] || 1
59
+ end
60
+
61
+ def items_for_export
62
+ card.item_cards
63
+ end
64
+
65
+ def essentials
66
+ return {} if depth > max_depth
67
+ card.item_cards.map do |item|
68
+ nest item, view: :essentials
69
+ end
70
+ end
71
+
72
+ view :links do
73
+ []
74
+ end
75
+ end
76
+
77
+ # CSS views
78
+
79
+ format :css do
80
+ # generalize to all collections?
81
+ def default_item_view
82
+ :content
83
+ end
84
+
85
+ view :titled do
86
+ %(#{major_comment "STYLE GROUP: \"#{card.name}\"", '='}#{_render_core})
87
+ end
88
+
89
+ view :core do
90
+ nest_item_array.join "\n\n"
91
+ end
92
+
93
+ view :content, :core
94
+ end
95
+
96
+ # RSS views
97
+
98
+ format :rss do
99
+ def raw_feed_items
100
+ @raw_feed_items ||= card.item_cards(limit: limit, offset: offset)
101
+ end
102
+ end
@@ -0,0 +1,35 @@
1
+ include_set Abstract::Pointer
2
+
3
+ abstract_basket :item_codenames
4
+
5
+ # simplify api
6
+ # Self::MyCodePointerSet.add_item :my_item_codename
7
+ # instead of
8
+ # Self::MyCodePointerSet.add_to_basket :item_codenames, :my_item_codename
9
+ module ClassMethods
10
+ def add_item codename
11
+ valid_codename codename do
12
+ add_to_basket :item_codenames, codename
13
+ end
14
+ end
15
+
16
+ def unshift_item codename
17
+ valid_codename codename do
18
+ unshift_basket :item_codenames, codename
19
+ end
20
+ end
21
+
22
+ def valid_codename codename
23
+ if Card::Codename.exist? codename
24
+ yield
25
+ else
26
+ Rails.logger.info "unknown codename '#{codename}' added to code pointer"
27
+ end
28
+ end
29
+ end
30
+
31
+ def content
32
+ item_codenames.map do |codename|
33
+ Card.fetch_name codename
34
+ end.compact.to_pointer_content
35
+ end
@@ -0,0 +1,21 @@
1
+ # store items as ids, not names
2
+
3
+ def standardize_item cardish
4
+ if (id = Card.fetch_id cardish)
5
+ "~#{id}"
6
+ else
7
+ Rails.logger.info "no id for '#{cardish}' added to id pointer"
8
+ nil
9
+ end
10
+ end
11
+
12
+ def item_ids args={}
13
+ item_strings(args).map do |item|
14
+ item = standardize_item item unless item.match?(/^~/)
15
+ item.to_s.tr("~", "").to_i
16
+ end.compact
17
+ end
18
+
19
+ def item_names args={}
20
+ item_ids(args).map(&:cardname).compact
21
+ end
@@ -0,0 +1,7 @@
1
+ def supports_content_options?
2
+ false
3
+ end
4
+
5
+ def supports_content_option_view?
6
+ false
7
+ end
@@ -0,0 +1,10 @@
1
+ format :html do
2
+ def quick_edit
3
+ if card.left.prototype_default_card&.try(:show_content_options?) &&
4
+ card.left.prototype.rule_card(:input_type)&.supports_content_option_view?
5
+ super
6
+ else
7
+ ""
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ def default_limit
2
+ cql_limit = fetch_query.limit if respond_to?(:fetch_query)
3
+ cql_limit || 50
4
+ end
5
+
6
+ format :html do
7
+ def quick_edit
8
+ card.left.prototype_default_card.try(:show_content_options?) ? super : ""
9
+ end
10
+
11
+ def quick_editor
12
+ wrap_type_formgroup do
13
+ type_field class: "type-field rule-type-field _submit-on-select"
14
+ end +
15
+ wrap_content_formgroup do
16
+ text_field :content, class: "d0-card-content _submit-after-typing"
17
+ end
18
+ end
19
+
20
+ def visible_cardtype_groups
21
+ { "Organize" => %w[List Pointer] }
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ setting_opts group: :editing, position: 6,
2
+ restricted_to_type: %i[list pointer session],
3
+ rule_type_editable: false,
4
+ help_text: "Label view for radio button and checkbox items. "\
5
+ "[[http://decko.org/Pointer|more]]",
6
+ applies: lambda { |prototype|
7
+ prototype.supports_content_options? &&
8
+ prototype.rule_card(:input_type)&.supports_content_option_view?
9
+ }
@@ -0,0 +1,9 @@
1
+ setting_opts group: :editing, position: 5,
2
+ restricted_to_type: %i[list pointer session],
3
+ rule_type_editable: true,
4
+ help_text: "Value options for [[List]] and [[Pointer]] and cards. "\
5
+ "Can itself be a List or a [[Search]]. "\
6
+ "[[http://decko.org/Pointer|more]]",
7
+ applies: lambda { |prototype|
8
+ prototype.rule_card(:input_type).supports_content_options?
9
+ }
@@ -0,0 +1,13 @@
1
+ include_set Abstract::Pointer
2
+
3
+ basket :options
4
+ add_to_basket :options, "radio"
5
+ add_to_basket :options, "checkbox"
6
+ add_to_basket :options, "select"
7
+ add_to_basket :options, "multiselect"
8
+ add_to_basket :options, "list"
9
+ add_to_basket :options, "filtered list"
10
+
11
+ def content
12
+ options.to_pointer_content
13
+ end
@@ -0,0 +1,40 @@
1
+ include_set Abstract::Pointer
2
+
3
+ def raw_item_strings content
4
+ reference_chunks(content).map(&:referee_name)
5
+ end
6
+
7
+ def item_titles default_to_name=true
8
+ reference_chunks.map do |chunk|
9
+ chunk.options[:title] || (default_to_name ? chunk.referee_name : nil)
10
+ end
11
+ end
12
+
13
+ format do
14
+ def chunk_list
15
+ :references
16
+ end
17
+ end
18
+
19
+ format :html do
20
+ def input_type
21
+ :link_list
22
+ end
23
+
24
+ view :link_list_input, cache: :never do
25
+ link_list_input
26
+ end
27
+
28
+ def items_for_input items=nil
29
+ items ||= card.item_names context: :raw
30
+ items.empty? ? [["", ""]] : items.zip(card.item_titles(false))
31
+ end
32
+
33
+ def link_list_input args={}
34
+ items = items_for_input args[:item_list]
35
+ extra_class = "pointer-link-list-ul"
36
+ ul_classes = classy "pointer-list-editor", extra_class
37
+ haml :link_list_input, items: items, ul_classes: ul_classes,
38
+ options_card: options_card_name
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ %ul{class: ul_classes}
2
+ - items.each.with_index do |(reference, title), index|
3
+ %li.pointer-li.mb-1{"data-index": index}
4
+ %span.input-group
5
+ .input-group-prepend.handle
6
+ %span.input-group-text
7
+ = icon_tag :reorder
8
+ %span.input-group-text.text-muted.group-text-left
9
+ [[
10
+ = text_field_tag "pointer_item", reference, class: "_reference pointer-item-text form-control group-text-middle",
11
+ "data-options-card": options_card
12
+ %span.input-group-text.text-muted.group-text-middle
13
+ |
14
+ = text_field_tag "pointer_item_title", title, class: "_title pointer-item-text form-control group-text-middle"
15
+ %span.input-group-text.text-muted.group-text-right
16
+ ]]
17
+ .input-group-append
18
+ %span.input-group-text.p-0
19
+ %button.pointer-item-delete.btn.btn-secondary{ type: "button"}
20
+ = icon_tag :remove
21
+ %span.input-group
22
+ %button._pointer-item-add.btn.btn-secondary{ type: "submit" }
23
+ = icon_tag "add"
24
+ add another
@@ -0,0 +1,16 @@
1
+ include_set Abstract::Pointer
2
+
3
+ def each_reference_out
4
+ item_names.each do |name|
5
+ yield(name, Card::Content::Chunk::Link::CODE)
6
+ end
7
+ end
8
+
9
+ format :html do
10
+ view :view_list do
11
+ %i[info_bar bar box closed titled labeled].map do |view|
12
+ voo.items[:view] = view
13
+ wrap_with :p, [content_tag(:h3, "#{view} items"), render_content]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ include_set Abstract::Items
2
+
3
+ def raw_item_strings content
4
+ reference_chunks(content).map(&:referee_name)
5
+ end
6
+
7
+ def item_options
8
+ nest_chunks.map(&:raw_options)
9
+ end
10
+
11
+ def items_to_content array
12
+ items = array.map { |i| standardize_item i }.reject(&:blank?)
13
+ self.content = items.join("\n")
14
+ end
15
+
16
+ format do
17
+ def chunk_list
18
+ :references
19
+ end
20
+ end
21
+
22
+ format :html do
23
+ def input_type
24
+ :nest_list
25
+ end
26
+
27
+ view :nest_list_input, cache: :never do
28
+ nest_list_input
29
+ end
30
+
31
+ view :input do
32
+ _render_hidden_content_field + super()
33
+ end
34
+
35
+ def items_for_input items=nil
36
+ items ||= card.item_names context: :raw
37
+ items.empty? ? [["", ""]] : items.zip(card.item_options)
38
+ end
39
+
40
+ def nest_list_input args={}
41
+ items = items_for_input args[:item_list]
42
+ extra_class = "_nest-list-ul"
43
+ ul_classes = classy "pointer-list-editor", extra_class
44
+ haml :nest_list_input, items: items, ul_classes: ul_classes
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ %ul{class: ul_classes}
2
+ - items.each.with_index do |(reference, title), index|
3
+ %li.pointer-li.mb-1._nest-form{"data-index": index}
4
+ %span.input-group
5
+ .input-group-prepend.handle
6
+ %span.input-group-text
7
+ = icon_tag :reorder
8
+ %span.input-group-text.text-muted.group-text-left
9
+ {{
10
+ = text_field_tag "pointer_item", reference, class: "_reference pointer-item-text form-control group-text-middle"
11
+ %span.input-group-text.text-muted.group-text-middle
12
+ = "|"
13
+ = text_field_tag "pointer_item_title", title, class: "_title _nest-options pointer-item-text form-control group-text-middle"
14
+ %span.input-group-text.text-muted.group-text-right
15
+ }}
16
+ .input-group-append
17
+ %span.input-group-text.p-0
18
+ %button.btn.btn-secondary._open-nest-editor{ type: "button"}
19
+ = icon_tag :edit
20
+ .input-group-append
21
+ %span.input-group-text.p-0
22
+ %button.pointer-item-delete.btn.btn-secondary{ type: "button"}
23
+ = icon_tag :remove
24
+
25
+ %span.input-group
26
+ %button._pointer-item-add.btn.btn-secondary{ type: "submit" }
27
+ = icon_tag "add"
28
+ add another
@@ -0,0 +1,10 @@
1
+ include_set Abstract::Pointer
2
+
3
+ format :html do
4
+ view :view_list do
5
+ %i[info_bar bar box closed titled labeled].map do |view|
6
+ voo.items[:view] = view
7
+ wrap_with :p, [content_tag(:h3, "#{view} items"), render_content]
8
+ end
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: card-mod-list
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.11.0
5
+ platform: ruby
6
+ authors:
7
+ - Ethan McCutchen
8
+ - Philipp Kühl
9
+ - Gerry Gleason
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2020-12-24 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: card
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.101.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '='
27
+ - !ruby/object:Gem::Version
28
+ version: 1.101.0
29
+ - !ruby/object:Gem::Dependency
30
+ name: card-mod-format
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '='
34
+ - !ruby/object:Gem::Version
35
+ version: 0.11.0
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '='
41
+ - !ruby/object:Gem::Version
42
+ version: 0.11.0
43
+ - !ruby/object:Gem::Dependency
44
+ name: card-mod-collection
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '='
48
+ - !ruby/object:Gem::Version
49
+ version: 0.11.0
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '='
55
+ - !ruby/object:Gem::Version
56
+ version: 0.11.0
57
+ description: ''
58
+ email:
59
+ - info@decko.org
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - db/migrate_core_cards/20160804112340_add_pointer_cards.rb
65
+ - set/abstract/01_pointer.rb
66
+ - set/abstract/01_pointer/events.rb
67
+ - set/abstract/01_pointer/html_views.rb
68
+ - set/abstract/01_pointer/html_views/autocomplete_input.haml
69
+ - set/abstract/01_pointer/html_views/checkbox_input.haml
70
+ - set/abstract/01_pointer/html_views/filter.rb
71
+ - set/abstract/01_pointer/html_views/filter/filter_items.haml
72
+ - set/abstract/01_pointer/html_views/filter/filtered_list_input.haml
73
+ - set/abstract/01_pointer/html_views/list_input.haml
74
+ - set/abstract/01_pointer/html_views/list_item.haml
75
+ - set/abstract/01_pointer/html_views/radio_input.haml
76
+ - set/abstract/01_pointer/options_api.rb
77
+ - set/abstract/01_pointer/other_views.rb
78
+ - set/abstract/code_pointer.rb
79
+ - set/abstract/id_pointer.rb
80
+ - set/all/supports_content_options.rb
81
+ - set/right/content_option_view.rb
82
+ - set/right/content_options.rb
83
+ - set/self/content_option_view.rb
84
+ - set/self/content_options.rb
85
+ - set/self/input_options.rb
86
+ - set/type/link_list.rb
87
+ - set/type/link_list/link_list_input.haml
88
+ - set/type/list.rb
89
+ - set/type/nest_list.rb
90
+ - set/type/nest_list/nest_list_input.haml
91
+ - set/type/pointer.rb
92
+ homepage: http://decko.org
93
+ licenses:
94
+ - GPL-3.0
95
+ metadata:
96
+ card-mod: list
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '2.5'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubygems_version: 3.0.3
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: list of cards
116
+ test_files: []