card-mod-edit 0.14.1 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|