card-mod-edit 0.14.1 → 0.15.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.
- checksums.yaml +4 -4
- data/assets/script/autosave.js.coffee +30 -0
- data/assets/script/bridge.js.coffee +31 -0
- data/assets/script/components.js.coffee +32 -0
- data/assets/script/doubleclick.js.coffee +44 -0
- data/assets/script/editor.js.coffee +51 -0
- data/assets/script/name_editor.js.coffee +43 -0
- data/assets/script/type_editor.js.coffee +21 -0
- data/assets/style/bridge.scss +109 -0
- data/assets/style/edit.scss +34 -0
- data/data/files/mod_edit_script_asset_output/file.js +14 -0
- data/data/real.yml +14 -0
- data/set/all/bridge/bridge_pills.rb +2 -2
- data/set/all/bridge/follow_section.rb +1 -1
- data/set/all/bridge/tab_views.rb +5 -1
- data/set/all/bridge.rb +5 -1
- data/set/all/edit_content.rb +3 -8
- data/set/all/edit_inline.rb +3 -3
- data/set/all/edit_name_skip_referers.haml +1 -1
- data/set/all/editor.rb +5 -1
- data/set/all/form.rb +21 -14
- data/set/all/form_buttons.rb +4 -4
- data/set/all/formgroup.rb +5 -1
- data/set/all/overlay_guide.haml +3 -3
- data/set/all/read_formgroup.haml +2 -2
- data/set/right/input_type.rb +7 -1
- data/set/right/thanks.rb +1 -0
- data/set/type/list.rb +1 -1
- metadata +34 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afce63912d505d4b4bc0ab869141825249708e5e28ada92bc52b4694ab326c8a
|
4
|
+
data.tar.gz: 381d27bdb3d18ec10f272e696d33f147ed759693617fd2c27f4eb23cef38fcc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40bca91d72c45a04ad34fa8c4601455552c1218ce964452f679faee3f8fa73d76f263a740c833c6683c4401d270b535ef87c33027b0d4745c8801a0b43472b00
|
7
|
+
data.tar.gz: 452ed1ff6b62ffe356b753d92dce7ebb5a1270b2e47a79b8ffdbd61c6e3853eb6ef29696d4204e2713d67100389b800f09fc3e842b5889de8ff1a81f222f55c1
|
@@ -0,0 +1,30 @@
|
|
1
|
+
jQuery.fn.extend
|
2
|
+
autosave: ->
|
3
|
+
slot = @slot()
|
4
|
+
return if @attr 'no-autosave'
|
5
|
+
multi = @closest '.form-group'
|
6
|
+
if multi[0]
|
7
|
+
return unless id = multi.data 'cardId'
|
8
|
+
reportee = ': ' + multi.data 'cardName'
|
9
|
+
else
|
10
|
+
id = slot.data 'cardId'
|
11
|
+
reportee = ''
|
12
|
+
|
13
|
+
return unless id
|
14
|
+
|
15
|
+
# might be better to put this href base in the html
|
16
|
+
submit_url = decko.path 'update/~' + id
|
17
|
+
form_data = $('#edit_card_'+id).serializeArray().reduce( ((obj, item) ->
|
18
|
+
obj[item.name] = item.value
|
19
|
+
return obj
|
20
|
+
), { 'draft' : 'true', 'success[view]' : 'blank'});
|
21
|
+
$.ajax submit_url, {
|
22
|
+
data : form_data,
|
23
|
+
type : 'POST'
|
24
|
+
}
|
25
|
+
##{ 'card[content]' : @val() },
|
26
|
+
|
27
|
+
$(window).ready ->
|
28
|
+
$('body').on 'change', '.autosave .d0-card-content', ->
|
29
|
+
content_field = $(this)
|
30
|
+
setTimeout ( -> content_field.autosave() ), 500
|
@@ -0,0 +1,31 @@
|
|
1
|
+
decko.slot.ready (slot, slotter) ->
|
2
|
+
slot.updateBridge(false, slotter)
|
3
|
+
|
4
|
+
links = slot.find('ul._auto-single-select > li.nav-item > a.nav-link')
|
5
|
+
if links.length == 1
|
6
|
+
$(links[0]).click()
|
7
|
+
|
8
|
+
jQuery.fn.extend
|
9
|
+
# overlayClosed=true means the bridge update was
|
10
|
+
# triggered by closing an overlay
|
11
|
+
updateBridge: (overlayClosed=false, slotter) ->
|
12
|
+
return unless @closest(".bridge").length > 0
|
13
|
+
if @data("breadcrumb")
|
14
|
+
@updateBreadcrumb()
|
15
|
+
else if slotter and $(slotter).data("breadcrumb")
|
16
|
+
$(slotter).updateBreadcrumb()
|
17
|
+
|
18
|
+
if overlayClosed
|
19
|
+
$(".bridge-pills > .nav-item > .nav-link.active").removeClass("active")
|
20
|
+
|
21
|
+
updateBreadcrumb: () ->
|
22
|
+
bc_item = $(".modal-header ._bridge-breadcrumb li:last-child")
|
23
|
+
bc_item.text(this.data("breadcrumb"))
|
24
|
+
bc_item.attr("class", "breadcrumb-item active #{this.data('breadcrumb-class')}")
|
25
|
+
|
26
|
+
$(window).ready ->
|
27
|
+
$('body').on "select2:select", "._close-rule-overlay-on-select", (event) ->
|
28
|
+
$(".overlay-container > ._overlay.card-slot.overlay_rule-view.RULE").removeOverlay()
|
29
|
+
|
30
|
+
$('body').on "click", "._update-history-pills", (event) ->
|
31
|
+
$(this).closest(".slotter").data("update-foreign-slot", ".card-slot.history_tab-view")
|
@@ -0,0 +1,32 @@
|
|
1
|
+
submitAfterTyping = null
|
2
|
+
|
3
|
+
$(window).ready ->
|
4
|
+
$('body').on "change", "._submit-on-change", (event) ->
|
5
|
+
$(event.target).closest('form').submit()
|
6
|
+
false
|
7
|
+
|
8
|
+
# TODO: consider refactoring so that all of this is handled by _submit-on-change
|
9
|
+
|
10
|
+
# submit form if user stops typing for a second
|
11
|
+
$('body').on "input", "._submit-after-typing", (event) ->
|
12
|
+
form = $(event.target).closest('form')
|
13
|
+
form.slot().find(".autosubmit-success-notification").remove()
|
14
|
+
clearTimeout(submitAfterTyping) if submitAfterTyping
|
15
|
+
submitAfterTyping = setTimeout ->
|
16
|
+
$(event.target).closest('form').submit()
|
17
|
+
submitAfterTyping = null
|
18
|
+
, 1000
|
19
|
+
|
20
|
+
# if "enter/return" is pressed, submit right away
|
21
|
+
$('body').on "keydown", "._submit-after-typing", (event) ->
|
22
|
+
if event.which == 13 # enter/return
|
23
|
+
clearTimeout(submitAfterTyping) if submitAfterTyping
|
24
|
+
submitAfterTyping = null
|
25
|
+
$(event.target).closest('form').submit()
|
26
|
+
false
|
27
|
+
|
28
|
+
$('body').on "change", "._edit-item", (event) ->
|
29
|
+
cb = $(event.target)
|
30
|
+
cb.attr "name", (cb.is(":checked") && "add_item" || "drop_item")
|
31
|
+
$(event.target).closest('form').submit()
|
32
|
+
false
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
$(window).ready ->
|
3
|
+
doubleClickActiveMap = { off: false, on: true, signed_in: decko.currentUserId }
|
4
|
+
|
5
|
+
doubleClickActive = () ->
|
6
|
+
doubleClickActiveMap[decko.doubleClick]
|
7
|
+
|
8
|
+
if doubleClickActive()
|
9
|
+
$('body').on 'dblclick', 'div', (_event) ->
|
10
|
+
if doubleClickApplies $(this)
|
11
|
+
triggerDoubleClickEditingOn $(this)
|
12
|
+
false # don't propagate up to next slot
|
13
|
+
|
14
|
+
# else alert "illegal configuration: " + decko.doubleClick
|
15
|
+
|
16
|
+
doubleClickApplies = (el) ->
|
17
|
+
return false if ['.nodblclick', '.d0-card-header', '.card-editor'].some (klass) ->
|
18
|
+
el.closest(klass)[0]
|
19
|
+
# double click inactive inside header, editor, or tag with "nodblclick" class
|
20
|
+
!el.slot().find('.card-editor')[0]?
|
21
|
+
|
22
|
+
triggerDoubleClickEditingOn = (el)->
|
23
|
+
slot = el.slot()
|
24
|
+
edit_link = slotEditLink(slot)
|
25
|
+
|
26
|
+
if edit_link
|
27
|
+
edit_link.click()
|
28
|
+
else
|
29
|
+
edit_view = slotEditView(slot)
|
30
|
+
url = decko.path("~#{slot.data('cardId')}?view=#{edit_view}")
|
31
|
+
slot.slotReload url
|
32
|
+
|
33
|
+
slotEditLink = (slot) ->
|
34
|
+
edit_links =
|
35
|
+
slot.find(".edit-link").filter (i, el) ->
|
36
|
+
$(el).slot().data('slotId') == slot.data('slotId')
|
37
|
+
|
38
|
+
if edit_links[0] then $(edit_links[0]) else false
|
39
|
+
|
40
|
+
slotEditView = (slot) ->
|
41
|
+
switch slot.data("slot").edit
|
42
|
+
when "inline" then "edit_inline"
|
43
|
+
when "full" then "bridge"
|
44
|
+
else "edit"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
decko.editors.init["textarea"] = -> $(this).autosize()
|
2
|
+
|
3
|
+
$.extend decko,
|
4
|
+
contentLoaded: (el, slotter)->
|
5
|
+
decko.initializeEditors(el)
|
6
|
+
notice = slotter.attr('notify-success')
|
7
|
+
|
8
|
+
el.notify notice, "success" if notice?
|
9
|
+
el.triggerSlotReady(slotter)
|
10
|
+
|
11
|
+
initializeEditors: (range, map) ->
|
12
|
+
map = decko.editors.init unless map?
|
13
|
+
$.each map, (selector, fn) ->
|
14
|
+
$.each range.find(selector), ->
|
15
|
+
fn.call $(this)
|
16
|
+
|
17
|
+
jQuery.fn.extend
|
18
|
+
contentField: ->
|
19
|
+
@closest('.card-editor').find '.d0-card-content'
|
20
|
+
|
21
|
+
setContentFieldsFromMap: (map) ->
|
22
|
+
map = decko.editors.content unless map?
|
23
|
+
this_form = $(this)
|
24
|
+
$.each map, (selector, fn) ->
|
25
|
+
this_form.setContentFields(selector, fn)
|
26
|
+
|
27
|
+
setContentFields: (selector, fn) ->
|
28
|
+
$.each @find(selector), ->
|
29
|
+
$(this).setContentField(fn)
|
30
|
+
|
31
|
+
setContentField: (fn) ->
|
32
|
+
field = @contentField()
|
33
|
+
init_val = field.val() # tinymce-jquery overrides val();
|
34
|
+
# that's why we're not using it.
|
35
|
+
new_val = fn.call this
|
36
|
+
field.val new_val
|
37
|
+
field.change() if init_val != new_val
|
38
|
+
|
39
|
+
$(window).ready ->
|
40
|
+
# decko.initializeEditors $('body > :not(.modal)')
|
41
|
+
setTimeout (-> decko.initializeEditors $('body > :not(.modal)')), 10
|
42
|
+
# dislike the timeout, but without this forms with multiple TinyMCE editors
|
43
|
+
# were failing to load properly
|
44
|
+
# I couldn't reproduce that problem described above -pk
|
45
|
+
|
46
|
+
$('body').on 'submit', '.card-form', ->
|
47
|
+
$(this).setContentFieldsFromMap()
|
48
|
+
$(this).find('.d0-card-content').attr('no-autosave','true')
|
49
|
+
true
|
50
|
+
|
51
|
+
setInterval (-> $('.card-form').setContentFieldsFromMap()), 20000
|
@@ -0,0 +1,43 @@
|
|
1
|
+
checkNameAfterTyping = null
|
2
|
+
|
3
|
+
$(window).ready ->
|
4
|
+
$('body').on 'keyup', '.name-editor input', (event) ->
|
5
|
+
clearTimeout(checkNameAfterTyping) if checkNameAfterTyping
|
6
|
+
input = $(this)
|
7
|
+
if event.which == 13
|
8
|
+
checkName(input)
|
9
|
+
checkNameAfterTyping = null
|
10
|
+
else
|
11
|
+
checkNameAfterTyping = setTimeout ->
|
12
|
+
checkName(input)
|
13
|
+
checkNameAfterTyping = null
|
14
|
+
, 400
|
15
|
+
|
16
|
+
decko.pingName = (name, success)->
|
17
|
+
$.getJSON decko.path(''), format: 'json', view: 'status', 'card[name]': name, success
|
18
|
+
|
19
|
+
|
20
|
+
checkName = (box) ->
|
21
|
+
name = box.val()
|
22
|
+
decko.pingName name, (data)->
|
23
|
+
return null if box.val() != name # avert race conditions
|
24
|
+
status = data['status']
|
25
|
+
if status
|
26
|
+
ed = box.parent()
|
27
|
+
leg = box.closest('fieldset').find('legend')
|
28
|
+
msg = leg.find '.name-messages'
|
29
|
+
unless msg[0]
|
30
|
+
msg = $('<span class="name-messages"></span>')
|
31
|
+
leg.append msg?
|
32
|
+
ed.removeClass 'real-name virtual-name known-name'
|
33
|
+
|
34
|
+
# use id to avoid warning when renaming to name variant
|
35
|
+
slot_id = box.slot().data 'cardId'
|
36
|
+
if status != 'unknown' and !(slot_id && parseInt(slot_id) == data['id'])
|
37
|
+
ed.addClass status + '-name known-name'
|
38
|
+
qualifier = if status == 'virtual' then 'in virtual' else 'already in'
|
39
|
+
href = decko.path(data['url_key'])
|
40
|
+
msg.html "\"<a href='#{href}'>#{name}</a>\" #{qualifier} use"
|
41
|
+
else
|
42
|
+
msg.html ''
|
43
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$(window).ready ->
|
2
|
+
$('body').on "change", '._live-type-field', ->
|
3
|
+
$this = $(this)
|
4
|
+
|
5
|
+
setSlotMode($this)
|
6
|
+
|
7
|
+
$this.data 'params', $this.closest('form').serialize()
|
8
|
+
$this.data 'url', $this.attr 'href'
|
9
|
+
|
10
|
+
$('body').on 'change', '.edit-type-field', ->
|
11
|
+
$(this).closest('form').submit()
|
12
|
+
|
13
|
+
setSlotMode = ($el, mode=null) ->
|
14
|
+
$slotter = $el.closest(".slotter")
|
15
|
+
if $slotter.length
|
16
|
+
if $slotter.attr('data-slotter-mode')
|
17
|
+
$slotter.attr 'data-original-slotter-mode', $slotter.attr('data-slotter-mode')
|
18
|
+
$slotter.attr 'data-slotter-mode', mode
|
19
|
+
if $slotter.attr('data-slot-selector')
|
20
|
+
$slotter.attr 'data-original-slot-selector', $slotter.attr('data-slot-selector')
|
21
|
+
$slotter.removeAttr 'data-slot-selector'
|
@@ -0,0 +1,109 @@
|
|
1
|
+
|
2
|
+
// Bridge
|
3
|
+
._modal-stack {
|
4
|
+
z-index: 1010;
|
5
|
+
}
|
6
|
+
|
7
|
+
.modal-header .card-title {
|
8
|
+
margin-bottom: 0;
|
9
|
+
}
|
10
|
+
|
11
|
+
.modal-dialog.no-gaps > .modal-content {
|
12
|
+
> .modal-body {
|
13
|
+
padding: 0;
|
14
|
+
}
|
15
|
+
> .modal-header > nav > ol.breadcrumb {
|
16
|
+
margin-bottom: 0;
|
17
|
+
padding: 0.2rem 0.3rem;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
$bridge-line-color: $border-color;
|
22
|
+
|
23
|
+
.bridge-sidebar {
|
24
|
+
background-color: darken($body-bg, 15%);
|
25
|
+
padding-left: 0;
|
26
|
+
padding-right: 0;
|
27
|
+
min-height: calc(100vh - 90px);
|
28
|
+
|
29
|
+
.guide-text {
|
30
|
+
padding: 15px;
|
31
|
+
background-color: $body-bg;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
.bg-body {
|
36
|
+
background-color: $body-bg !important;
|
37
|
+
}
|
38
|
+
|
39
|
+
.bridge-main {
|
40
|
+
border-right: 1px solid $bridge-line-color;
|
41
|
+
padding-left: 0;
|
42
|
+
padding-right: 0;
|
43
|
+
> ._overlay-container-placeholder > .bridge-view {
|
44
|
+
padding-top: 10px;
|
45
|
+
padding-left: 15px;
|
46
|
+
padding-right: 15px;
|
47
|
+
}
|
48
|
+
> .overlay-container > .bridge-view {
|
49
|
+
padding-top: 0px;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
.bridge-pills {
|
56
|
+
.help-text {
|
57
|
+
font-size: 0.8rem;
|
58
|
+
}
|
59
|
+
> .nav-item {
|
60
|
+
padding: 0;
|
61
|
+
> a {
|
62
|
+
color: inherit
|
63
|
+
}
|
64
|
+
background-color: $body-bg;
|
65
|
+
border: 1px solid $nav-tabs-border-color;
|
66
|
+
border-left: 3px solid $nav-tabs-border-color;
|
67
|
+
margin-bottom: -1px;
|
68
|
+
|
69
|
+
&:hover, &.active, &:focus {
|
70
|
+
border-left-color: $nav-pills-link-active-bg;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
.bridge {
|
76
|
+
.perm-editor {
|
77
|
+
margin-left: 0;
|
78
|
+
}
|
79
|
+
|
80
|
+
.set-editor {
|
81
|
+
ul {
|
82
|
+
background: $white;
|
83
|
+
padding-left: 0;
|
84
|
+
margin-left: 15px;
|
85
|
+
|
86
|
+
&:first-child {
|
87
|
+
margin-left: 0;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
li.radio {
|
91
|
+
padding: 10px 0px 0px 15px;
|
92
|
+
border-left: 1px solid $bridge-line-color;
|
93
|
+
border-top: 1px solid $bridge-line-color;
|
94
|
+
margin-top: 10px;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
.bridge-sidebar {
|
99
|
+
.history_tab-view > div {
|
100
|
+
margin: 0.5rem;
|
101
|
+
}
|
102
|
+
.d0-card-header-title > .card-title {
|
103
|
+
font-size: 1rem;
|
104
|
+
}
|
105
|
+
.nav-link {
|
106
|
+
padding: 0.5rem 0.5rem;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
.card-editor {
|
2
|
+
white-space: normal;
|
3
|
+
padding-bottom: 15px;
|
4
|
+
}
|
5
|
+
|
6
|
+
.button-form-group {
|
7
|
+
display: flex
|
8
|
+
}
|
9
|
+
.rename-button-form-group .btn {
|
10
|
+
margin-right: 1rem;
|
11
|
+
}
|
12
|
+
|
13
|
+
.d0-card-header a {
|
14
|
+
color: $body-color;
|
15
|
+
&.edit-link, &.bridge-link, &.help-link {
|
16
|
+
color: $text-muted;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
//
|
21
|
+
///*-------------------- */
|
22
|
+
///*- EDIT INTERFACE - */
|
23
|
+
///*-------------------- */
|
24
|
+
//
|
25
|
+
//textarea,
|
26
|
+
//.content-editor > input[type=text],
|
27
|
+
//.content-editor > input[type=password],
|
28
|
+
//.name-editor input {
|
29
|
+
// width: 97.5%;
|
30
|
+
//}
|
31
|
+
///* width + padding = 99.5%, which leaves 0.5% for the borders. This is imprecise, but borders can't be specified as a percentage */
|
32
|
+
//textarea {
|
33
|
+
// max-height: 500px;
|
34
|
+
//}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
// autosave.js.coffee
|
2
|
+
(function(){jQuery.fn.extend({autosave:function(){var t,a,e,r,n;if(r=this.slot(),!this.attr("no-autosave")){if((e=this.closest(".form-group"))[0]){if(!(a=e.data("cardId")))return;": "+e.data("cardName")}else a=r.data("cardId"),"";if(a)return n=decko.path("update/~"+a),t=$("#edit_card_"+a).serializeArray().reduce(function(t,a){return t[a.name]=a.value,t},{draft:"true","success[view]":"blank"}),$.ajax(n,{data:t,type:"POST"})}}}),$(window).ready(function(){return $("body").on("change",".autosave .d0-card-content",function(){var t;return t=$(this),setTimeout(function(){return t.autosave()},500)})})}).call(this);
|
3
|
+
// bridge.js.coffee
|
4
|
+
(function(){decko.slot.ready(function(e,t){var r;if(e.updateBridge(!1,t),1===(r=e.find("ul._auto-single-select > li.nav-item > a.nav-link")).length)return $(r[0]).click()}),jQuery.fn.extend({updateBridge:function(e,t){if(null==e&&(e=!1),this.closest(".bridge").length>0)return this.data("breadcrumb")?this.updateBreadcrumb():t&&$(t).data("breadcrumb")&&$(t).updateBreadcrumb(),e?$(".bridge-pills > .nav-item > .nav-link.active").removeClass("active"):void 0},updateBreadcrumb:function(){var e;return(e=$(".modal-header ._bridge-breadcrumb li:last-child")).text(this.data("breadcrumb")),e.attr("class","breadcrumb-item active "+this.data("breadcrumb-class"))}}),$(window).ready(function(){return $("body").on("select2:select","._close-rule-overlay-on-select",function(){return $(".overlay-container > ._overlay.card-slot.overlay_rule-view.RULE").removeOverlay()}),$("body").on("click","._update-history-pills",function(){return $(this).closest(".slotter").data("update-foreign-slot",".card-slot.history_tab-view")})})}).call(this);
|
5
|
+
// components.js.coffee
|
6
|
+
(function(){var t;t=null,$(window).ready(function(){return $("body").on("change","._submit-on-change",function(t){return $(t.target).closest("form").submit(),!1}),$("body").on("input","._submit-after-typing",function(e){return $(e.target).closest("form").slot().find(".autosubmit-success-notification").remove(),t&&clearTimeout(t),t=setTimeout(function(){return $(e.target).closest("form").submit(),t=null},1e3)}),$("body").on("keydown","._submit-after-typing",function(e){if(13===e.which)return t&&clearTimeout(t),t=null,$(e.target).closest("form").submit(),!1}),$("body").on("change","._edit-item",function(t){var e;return(e=$(t.target)).attr("name",e.is(":checked")?"add_item":"drop_item"),$(t.target).closest("form").submit(),!1})})}).call(this);
|
7
|
+
// doubleclick.js.coffee
|
8
|
+
(function(){var t,n,i,r;$(window).ready(function(){var n;if(n={off:!1,on:!0,signed_in:decko.currentUserId},function(){return n[decko.doubleClick]}())return $("body").on("dblclick","div",function(){return t($(this))&&r($(this)),!1})}),t=function(t){return![".nodblclick",".d0-card-header",".card-editor"].some(function(n){return t.closest(n)[0]})&&null==t.slot().find(".card-editor")[0]},r=function(t){var r,e,d,o;return d=t.slot(),(r=n(d))?r.click():(e=i(d),o=decko.path("~"+d.data("cardId")+"?view="+e),d.slotReload(o))},n=function(t){var n;return!!(n=t.find(".edit-link").filter(function(n,i){return $(i).slot().data("slotId")===t.data("slotId")}))[0]&&$(n[0])},i=function(t){switch(t.data("slot").edit){case"inline":return"edit_inline";case"full":return"bridge";default:return"edit"}}}).call(this);
|
9
|
+
// editor.js.coffee
|
10
|
+
(function(){decko.editors.init.textarea=function(){return $(this).autosize()},$.extend(decko,{contentLoaded:function(t,n){var e;return decko.initializeEditors(t),null!=(e=n.attr("notify-success"))&&t.notify(e,"success"),t.triggerSlotReady(n)},initializeEditors:function(t,n){return null==n&&(n=decko.editors.init),$.each(n,function(n,e){return $.each(t.find(n),function(){return e.call($(this))})})}}),jQuery.fn.extend({contentField:function(){return this.closest(".card-editor").find(".d0-card-content")},setContentFieldsFromMap:function(t){var n;return null==t&&(t=decko.editors.content),n=$(this),$.each(t,function(t,e){return n.setContentFields(t,e)})},setContentFields:function(t,n){return $.each(this.find(t),function(){return $(this).setContentField(n)})},setContentField:function(t){var n,e,i;if(e=(n=this.contentField()).val(),i=t.call(this),n.val(i),e!==i)return n.change()}}),$(window).ready(function(){return setTimeout(function(){return decko.initializeEditors($("body > :not(.modal)"))},10),$("body").on("submit",".card-form",function(){return $(this).setContentFieldsFromMap(),$(this).find(".d0-card-content").attr("no-autosave","true"),!0})}),setInterval(function(){return $(".card-form").setContentFieldsFromMap()},2e4)}).call(this);
|
11
|
+
// name_editor.js.coffee
|
12
|
+
(function(){var n,e;e=null,$(window).ready(function(){return $("body").on("keyup",".name-editor input",function(a){var t;return e&&clearTimeout(e),t=$(this),13===a.which?(n(t),e=null):e=setTimeout(function(){return n(t),e=null},400)})}),decko.pingName=function(n,e){return $.getJSON(decko.path(""),{format:"json",view:"status","card[name]":n},e)},n=function(n){var e;return e=n.val(),decko.pingName(e,function(a){var t,r,l,u,i,s,o;return n.val()!==e?null:(o=a.status)?(t=n.parent(),(u=(l=n.closest("fieldset").find("legend")).find(".name-messages"))[0]||(u=$('<span class="name-messages"></span>'),l.append(null!=u)),t.removeClass("real-name virtual-name known-name"),s=n.slot().data("cardId"),"unknown"===o||s&&parseInt(s)===a.id?u.html(""):(t.addClass(o+"-name known-name"),i="virtual"===o?"in virtual":"already in",r=decko.path(a.url_key),u.html("\"<a href='"+r+"'>"+e+'</a>" '+i+" use"))):void 0})}}).call(this);
|
13
|
+
// type_editor.js.coffee
|
14
|
+
(function(){var t;$(window).ready(function(){return $("body").on("change","._live-type-field",function(){var a;return a=$(this),t(a),a.data("params",a.closest("form").serialize()),a.data("url",a.attr("href"))}),$("body").on("change",".edit-type-field",function(){return $(this).closest("form").submit()})}),t=function(t,a){var e;if(null==a&&(a=null),(e=t.closest(".slotter")).length&&(e.attr("data-slotter-mode")&&(e.attr("data-original-slotter-mode",e.attr("data-slotter-mode")),e.attr("data-slotter-mode",a)),e.attr("data-slot-selector")))return e.attr("data-original-slot-selector",e.attr("data-slot-selector")),e.removeAttr("data-slot-selector")}}).call(this);
|
data/data/real.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
- :name: "*input type"
|
2
|
+
:type: :setting
|
3
|
+
:codename: input_type
|
4
|
+
|
5
|
+
- :name:
|
6
|
+
- :input_type
|
7
|
+
- :right
|
8
|
+
:fields:
|
9
|
+
# TODO: refactor so that we don't need a compound card to have a codename
|
10
|
+
:content_options:
|
11
|
+
:type: :pointer
|
12
|
+
:codename: input_options
|
13
|
+
:content: overridden
|
14
|
+
:input_type: radio
|
@@ -19,7 +19,7 @@ format :html do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def bridge_pill_item_opts breadcrumb, extra_opts, text
|
22
|
-
opts = bridge_link_opts.merge("data-toggle": "pill")
|
22
|
+
opts = bridge_link_opts.merge("data-bs-toggle": "pill")
|
23
23
|
opts.merge! breadcrumb_data(breadcrumb)
|
24
24
|
|
25
25
|
if extra_opts
|
@@ -39,7 +39,7 @@ format :html do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def bridge_pill_section tab_name, title, items
|
42
|
-
wrap_with(:h6, title, class: "
|
42
|
+
wrap_with(:h6, title, class: "ms-1 mt-3") +
|
43
43
|
wrap_each_with(:li, class: BRIDGE_PILL_LI_CLASSES) do
|
44
44
|
bridge_pill_items(items, tab_name)
|
45
45
|
end.html_safe
|
@@ -31,7 +31,7 @@ format :html do
|
|
31
31
|
def followers_bridge_link
|
32
32
|
cnt = card.followers_count
|
33
33
|
link_to_card card.name.field(:followers), "#{cnt} follower#{'s' unless cnt == 1}",
|
34
|
-
bridge_link_opts(class: "btn btn-sm
|
34
|
+
bridge_link_opts(class: "btn btn-sm ms-2 btn-secondary slotter",
|
35
35
|
remote: true, "data-cy": "followers")
|
36
36
|
end
|
37
37
|
end
|
data/set/all/bridge/tab_views.rb
CHANGED
@@ -18,9 +18,13 @@ format :html do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
view :rules_tab, unknown: true do
|
21
|
+
set_list_type = :related
|
21
22
|
class_up "card-slot", "flex-column"
|
22
23
|
wrap do
|
23
|
-
|
24
|
+
[
|
25
|
+
set_select(set_list_type),
|
26
|
+
# set_alert(set_list_type)
|
27
|
+
]
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
data/set/all/bridge.rb
CHANGED
@@ -5,6 +5,8 @@ BRIDGE_TABS = { "Account" => :account_tab,
|
|
5
5
|
"Related" => :related_tab,
|
6
6
|
"Rules" => :rules_tab }.freeze
|
7
7
|
|
8
|
+
BRIDGE_TAB_NAMES = BRIDGE_TABS.invert.freeze
|
9
|
+
|
8
10
|
format :html do
|
9
11
|
wrapper :bridge do
|
10
12
|
class_up "modal-dialog", "no-gaps"
|
@@ -16,7 +18,9 @@ format :html do
|
|
16
18
|
|
17
19
|
def bridge_tabs
|
18
20
|
wrap do
|
19
|
-
tabs(visible_bridge_tabs, bridge_tab, load: :lazy)
|
21
|
+
tabs(visible_bridge_tabs, BRIDGE_TAB_NAMES[bridge_tab], load: :lazy) do
|
22
|
+
_render bridge_tab
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
data/set/all/edit_content.rb
CHANGED
@@ -16,8 +16,8 @@ format :html do
|
|
16
16
|
# home_view is necessary for cancel to work correctly.
|
17
17
|
# it seems a little strange to have to think about home_view here,
|
18
18
|
# but the issue is that something currently has to happen prior to the
|
19
|
-
# render to get voo.slot_options to have the
|
20
|
-
# the slot wrap.
|
19
|
+
# render to get voo.slot_options to have the right home view in
|
20
|
+
# the slot wrap. I'd think this would probably best be handled as an
|
21
21
|
# option to #wrap that triggers a new heir voo
|
22
22
|
_render_content_formgroups,
|
23
23
|
_render(voo.buttons_view || :edit_buttons)
|
@@ -34,12 +34,7 @@ format :html do
|
|
34
34
|
with_nest_mode :edit do
|
35
35
|
voo.show :help
|
36
36
|
voo.hide :save_button
|
37
|
-
wrap
|
38
|
-
[
|
39
|
-
frame_help,
|
40
|
-
_render_edit_form
|
41
|
-
]
|
42
|
-
end
|
37
|
+
wrap(true) { [frame_help, _render_edit_form] }
|
43
38
|
end
|
44
39
|
end
|
45
40
|
|
data/set/all/edit_inline.rb
CHANGED
@@ -35,16 +35,16 @@ format :html do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def edit_row_fixed_width title, content, edit_view, width=50
|
38
|
-
class_up "card-slot", "d-flex"
|
38
|
+
class_up "card-slot", "d-flex form-group"
|
39
39
|
wrap do
|
40
|
-
["<label
|
40
|
+
["<label style='width: #{width}px'>#{title}</label>",
|
41
41
|
content,
|
42
42
|
edit_inline_link(edit_view, align: :right)]
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def edit_inline_link view=:edit_inline, align: :left
|
47
|
-
align = align == :left ? "
|
47
|
+
align = align == :left ? "ms-2" : "ms-auto"
|
48
48
|
link_to_view view, menu_icon, class: "#{align} edit-link", "data-cy": "edit-link"
|
49
49
|
end
|
50
50
|
|
data/set/all/editor.rb
CHANGED
@@ -29,7 +29,7 @@ format :html do
|
|
29
29
|
nil
|
30
30
|
end
|
31
31
|
|
32
|
-
view :input, unknown: true do
|
32
|
+
view :input, unknown: true, cache: :never do
|
33
33
|
try(input_method(input_type)) ||
|
34
34
|
input_defined_by_card ||
|
35
35
|
send(input_method(default_input_type))
|
@@ -51,4 +51,8 @@ format :html do
|
|
51
51
|
def text_field_input
|
52
52
|
text_field :content, class: classy("d0-card-content")
|
53
53
|
end
|
54
|
+
|
55
|
+
def hidden_input
|
56
|
+
hidden_field :content, class: classy("d0-card-content")
|
57
|
+
end
|
54
58
|
end
|
data/set/all/form.rb
CHANGED
@@ -2,7 +2,7 @@ format :html do
|
|
2
2
|
# FIELDSET VIEWS
|
3
3
|
|
4
4
|
# sometimes multiple card formgroups, sometimes just one
|
5
|
-
view :content_formgroups, cache: :never do
|
5
|
+
view :content_formgroups, unknown: true, cache: :never do
|
6
6
|
wrap_with :fieldset, edit_slot, class: classy("card-editor", "editor")
|
7
7
|
end
|
8
8
|
|
@@ -99,12 +99,19 @@ format :html do
|
|
99
99
|
|
100
100
|
def editor_in_multi_card
|
101
101
|
add_junction_class
|
102
|
-
|
103
|
-
input: "content", help: true, class: classy("card-editor") do
|
102
|
+
wrap_editor_in_multi_card do
|
104
103
|
[content_field, (form.hidden_field(:type_id) if card.new_card?)]
|
105
104
|
end
|
106
105
|
end
|
107
106
|
|
107
|
+
def wrap_editor_in_multi_card &block
|
108
|
+
return yield if input_type == :hidden
|
109
|
+
|
110
|
+
formgroup render_title,
|
111
|
+
input: "content", help: true, class: classy("card-editor"),
|
112
|
+
&block
|
113
|
+
end
|
114
|
+
|
108
115
|
def multi_card_edit fields_only=false
|
109
116
|
field_configs = edit_field_configs fields_only
|
110
117
|
return structure_link if field_configs.empty?
|
@@ -121,18 +128,18 @@ format :html do
|
|
121
128
|
"<p><em>Uneditable; content is #{structured} without nests</em></p>"
|
122
129
|
end
|
123
130
|
|
124
|
-
# @param [Hash|Array] fields either an array with field names and/or field
|
125
|
-
# cards or a hash with the fields as keys and a hash with nest options as
|
126
|
-
# values
|
127
|
-
def process_edit_fields fields
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
132
|
-
###
|
131
|
+
# # @param [Hash|Array] fields either an array with field names and/or field
|
132
|
+
# # cards or a hash with the fields as keys and a hash with nest options as
|
133
|
+
# # values
|
134
|
+
# def process_edit_fields fields
|
135
|
+
# fields.map do |field, opts|
|
136
|
+
# field_nest field, opts
|
137
|
+
# end.join "\n"
|
138
|
+
# end
|
139
|
+
# ###
|
133
140
|
|
134
|
-
# If you use
|
135
|
-
# then the
|
141
|
+
# If you use field cards to render a form for a new card
|
142
|
+
# then the field cards should be created on the new card not the existing
|
136
143
|
# card that build the form
|
137
144
|
|
138
145
|
def form
|
data/set/all/form_buttons.rb
CHANGED
@@ -6,7 +6,7 @@ format :html do
|
|
6
6
|
def standard_save_button opts={}
|
7
7
|
return if voo&.hide?(:save_button)
|
8
8
|
|
9
|
-
add_class opts, "submit-button btn-sm
|
9
|
+
add_class opts, "submit-button btn-sm me-3 _update-history-pills"
|
10
10
|
opts[:text] ||= "Save"
|
11
11
|
opts["data-cy"] = "save"
|
12
12
|
submit_button opts
|
@@ -18,7 +18,7 @@ format :html do
|
|
18
18
|
def standard_save_and_close_button opts={}
|
19
19
|
close = opts.delete(:close) || :modal
|
20
20
|
text = opts[:text] || "Save and Close"
|
21
|
-
add_class opts, "submit-button btn-sm
|
21
|
+
add_class opts, "submit-button btn-sm me-3 _close-on-success"
|
22
22
|
add_class opts, "_update-origin" unless opts[:no_origin_update]
|
23
23
|
opts.reverse_merge! text: text, "data-cy": "submit-#{close}"
|
24
24
|
|
@@ -26,7 +26,7 @@ format :html do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def standard_cancel_button args={}
|
29
|
-
args.reverse_merge! class: "cancel-button
|
29
|
+
args.reverse_merge! class: "cancel-button ms-4", href: path, "data-cy": "cancel"
|
30
30
|
cancel_button args
|
31
31
|
end
|
32
32
|
|
@@ -49,7 +49,7 @@ format :html do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def delete_button_opts opts={}
|
52
|
-
add_class opts, "slotter btn btn-outline-danger
|
52
|
+
add_class opts, "slotter btn btn-outline-danger ms-auto btn-sm"
|
53
53
|
opts["data-confirm"] = delete_confirm opts
|
54
54
|
opts[:path] = { action: :delete }
|
55
55
|
opts[:path][:success] = delete_success(opts)
|
data/set/all/formgroup.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
format :html do
|
2
2
|
view :read_form do
|
3
|
-
|
3
|
+
read_field_configs.map do |field, args|
|
4
4
|
args[:view] = :read_formgroup
|
5
5
|
nest field, args
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
def read_field_configs
|
10
|
+
edit_field_configs
|
11
|
+
end
|
12
|
+
|
9
13
|
view :read_formgroup, template: :haml, unknown: true, wrap: :slot
|
10
14
|
|
11
15
|
# a formgroup has a label (with helptext) and an input
|
data/set/all/overlay_guide.haml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
%div
|
2
|
-
.d-flex.
|
3
|
-
.
|
4
|
-
= link_to fa_icon(:close), path: "#", "data-dismiss": "overlay", class: "text-dark p-1
|
2
|
+
.d-flex.ms-2
|
3
|
+
.ms-auto
|
4
|
+
= link_to fa_icon(:close), path: "#", "data-bs-dismiss": "overlay", class: "text-dark p-1 ms-1"
|
5
5
|
|
6
6
|
= guide
|
7
7
|
|
data/set/all/read_formgroup.haml
CHANGED
data/set/right/input_type.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
+
assign_type :pointer
|
2
|
+
|
1
3
|
format :html do
|
4
|
+
def default_item_view
|
5
|
+
:name
|
6
|
+
end
|
7
|
+
|
2
8
|
def quick_editor
|
3
9
|
@submit_on_change = true
|
4
10
|
super
|
@@ -31,5 +37,5 @@ def option_names
|
|
31
37
|
end
|
32
38
|
|
33
39
|
def supports_content_option_view?
|
34
|
-
|
40
|
+
first_name.in? %w[checkbox radio]
|
35
41
|
end
|
data/set/right/thanks.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
assign_type :phrase
|
data/set/type/list.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: card-mod-edit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan McCutchen
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-01-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: card
|
@@ -18,28 +18,42 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
21
|
+
version: 1.105.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 1.
|
28
|
+
version: 1.105.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: card-mod-rules
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - '='
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 0.
|
35
|
+
version: 0.15.0
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - '='
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 0.
|
42
|
+
version: 0.15.0
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: card-mod-list
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - '='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.15.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.15.0
|
43
57
|
description: ''
|
44
58
|
email:
|
45
59
|
- info@decko.org
|
@@ -47,6 +61,17 @@ executables: []
|
|
47
61
|
extensions: []
|
48
62
|
extra_rdoc_files: []
|
49
63
|
files:
|
64
|
+
- assets/script/autosave.js.coffee
|
65
|
+
- assets/script/bridge.js.coffee
|
66
|
+
- assets/script/components.js.coffee
|
67
|
+
- assets/script/doubleclick.js.coffee
|
68
|
+
- assets/script/editor.js.coffee
|
69
|
+
- assets/script/name_editor.js.coffee
|
70
|
+
- assets/script/type_editor.js.coffee
|
71
|
+
- assets/style/bridge.scss
|
72
|
+
- assets/style/edit.scss
|
73
|
+
- data/files/mod_edit_script_asset_output/file.js
|
74
|
+
- data/real.yml
|
50
75
|
- set/all/bridge.rb
|
51
76
|
- set/all/bridge/bridge.haml
|
52
77
|
- set/all/bridge/bridge_pills.rb
|
@@ -71,6 +96,7 @@ files:
|
|
71
96
|
- set/all/read_formgroup.haml
|
72
97
|
- set/all/template_nest.rb
|
73
98
|
- set/right/input_type.rb
|
99
|
+
- set/right/thanks.rb
|
74
100
|
- set/self/input_type.rb
|
75
101
|
- set/type/list.rb
|
76
102
|
- set/type/plain_text.rb
|
@@ -85,6 +111,7 @@ metadata:
|
|
85
111
|
wiki_uri: https://decko.org
|
86
112
|
documentation_url: http://docs.decko.org/
|
87
113
|
card-mod: edit
|
114
|
+
card-mod-group: gem-defaults
|
88
115
|
post_install_message:
|
89
116
|
rdoc_options: []
|
90
117
|
require_paths:
|
@@ -100,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
127
|
- !ruby/object:Gem::Version
|
101
128
|
version: '0'
|
102
129
|
requirements: []
|
103
|
-
rubygems_version: 3.
|
130
|
+
rubygems_version: 3.3.11
|
104
131
|
signing_key:
|
105
132
|
specification_version: 4
|
106
133
|
summary: Edit handling
|