From 2d317c57bd10d5ab9716b05caa67fc441308bf3a Mon Sep 17 00:00:00 2001 From: Pacman Ghost Date: Mon, 5 Sep 2022 19:27:22 +1000 Subject: [PATCH] Moved the "edit template" buttons into a drop-down menu. --- vasl_templates/webapp/static/css/main.css | 3 - vasl_templates/webapp/static/main.js | 134 +++++++++++++----- vasl_templates/webapp/templates/tabs-ob1.html | 7 +- .../webapp/templates/tabs-scenario.html | 4 +- vasl_templates/webapp/tests/test_snippets.py | 25 ++-- .../webapp/tests/test_template_packs.py | 35 +++-- 6 files changed, 141 insertions(+), 67 deletions(-) diff --git a/vasl_templates/webapp/static/css/main.css b/vasl_templates/webapp/static/css/main.css index 1db3724..7a5af5a 100644 --- a/vasl_templates/webapp/static/css/main.css +++ b/vasl_templates/webapp/static/css/main.css @@ -38,9 +38,6 @@ label { height: 1.25em ; } .snippet-control .ui-selectmenu-button-closed { height: 26px ; } .snippet-control .ui-selectmenu-icon.ui-icon { margin-top: -8px ; } -button.edit-template { height: 28px ; padding: 4px 10px ; margin-right: 0 ; } -button.edit-template img { height: 18px ; vertical-align: middle ; margin: -2px 0.4em 0 0 ; } - input.snippet-width { width: 3.75em ; } .ui-dialog-titlebar { padding: 0.2em 0.5em 0.2em 0.5em !important ; } diff --git a/vasl_templates/webapp/static/main.js b/vasl_templates/webapp/static/main.js index ff81ec0..1b29f16 100644 --- a/vasl_templates/webapp/static/main.js +++ b/vasl_templates/webapp/static/main.js @@ -34,7 +34,7 @@ var NATIONALITY_SPECIFIC_BUTTONS = { } ; GENERATE_SNIPPET_HINT = "Generate an HTML snippet" ; -EDIT_TEMPLATE_HINT = "Edit the snippet template" ; +EDIT_TEMPLATE_HINT = "Edit the template" ; // -------------------------------------------------------------------- @@ -407,9 +407,12 @@ $(document).ready( function () { } ) ; $(window).trigger( "resize" ) ; - // replace all the "generate" buttons with "generate/edit" button/droplist's + // replace the "generate" buttons with menu droplists $("button.generate").each( function() { init_snippet_button( $(this) ) ; } ) ; + // replace the "add sortable" buttons with menu droplists + $("button.sortable-add").each( function() { init_sortable_add_button( $(this) ) ; } ) ; + // add a tooltip to the snippet width textbox's $( "input.param.snippet-width" ).each( function() { // NOTE: I tried putting a little icon in the textbox background, and placeholder text, but it didn't @@ -436,13 +439,6 @@ $(document).ready( function () { updateCompassImage() ; } ) ; - // handle requests to edit the templates - $("button.edit-template").click( function() { - edit_template( $(this).data( "id" ) ) ; - } ).html( "
Edit
" ) - .attr( "title", EDIT_TEMPLATE_HINT ) - .button( {} ) ; - // watch for changes to the scenario details // NOTE: The following is to add/remove the "scenario modified" indicator. It's pretty inefficent // to do this using a timer, but we would otherwise have to attach a "on change" event handler @@ -498,26 +494,30 @@ $(document).ready( function () { $em.remove() ; // add some dummy links for the test suite to edit templates + function add_edit_template_link( $btn ) { + var template_id = $btn.attr( "data-id" ) ; + if ( ! template_id ) + return ; + if ( template_id.substring(0,9) === "ob_setup_" ) + template_id = "ob_setup" ; + else if ( template_id.substring(0,21) === "ob_vehicles_ma_notes_" ) + template_id = "ob_vehicles_ma_notes" ; + else if ( template_id.substring(0,21) === "ob_ordnance_ma_notes_" ) + template_id = "ob_ordnance_ma_notes" ; + else if ( template_id.substring(0,12) === "ob_vehicles_" ) + template_id = "ob_vehicles" ; + else if ( template_id.substring(0,12) === "ob_ordnance_" ) + template_id = "ob_ordnance" ; + else if ( template_id.substring(0,9) === "nat_caps_" ) + template_id = "nat_caps" ; + $( "" + ).appendTo( "body" ) ; + } if ( getUrlParam( "edit_template_links" ) ) { - $("button.generate").each( function() { - var template_id = $(this).attr( "data-id" ) ; - if ( template_id.substring(0,9) === "ob_setup_" ) - template_id = "ob_setup" ; - else if ( template_id.substring(0,21) === "ob_vehicles_ma_notes_" ) - template_id = "ob_vehicles_ma_notes" ; - else if ( template_id.substring(0,21) === "ob_ordnance_ma_notes_" ) - template_id = "ob_ordnance_ma_notes" ; - else if ( template_id.substring(0,12) === "ob_vehicles_" ) - template_id = "ob_vehicles" ; - else if ( template_id.substring(0,12) === "ob_ordnance_" ) - template_id = "ob_ordnance" ; - else if ( template_id.substring(0,9) === "nat_caps_" ) - template_id = "nat_caps" ; - $( "" - ).appendTo( "body" ) ; - } ) ; + $( "button.generate" ).each( function() { add_edit_template_link( $(this) ) ; } ) ; + $( "button.sortable-add" ).each( function() { add_edit_template_link( $(this) ) ; } ) ; } // flag that we've finished initialization @@ -633,7 +633,7 @@ function updatePlayerOBSplitters( playerNo ) nButtons += 1 ; nChars += $(this).find( "button.generate" ).text().length ; } ) ; - var minWidth = Math.max( 270 + 60*nButtons + gEmSize*nChars*0.5, 320 ) ; + var minWidth = Math.max( 160 + 60*nButtons + gEmSize*nChars*0.5, 320 ) ; $( "#tabs-ob" + playerNo + " .left" ).css( "min-width", minWidth ) ; } @@ -698,7 +698,6 @@ function init_snippet_button( $btn ) } ) ; } ) ; $newBtn.children( ".ui-button-icon-only" ).css( "width", "1em" ) ; - $newBtn.children( ".ui-selectmenu-button" ).click( function() { $btn.blur() ; } ) ; // handle requests to edit the template $newBtn.children( "select" ).on( "selectmenuselect", function( evt, ui ) { @@ -712,6 +711,66 @@ function init_snippet_button( $btn ) $btn.replaceWith( $newBtn ) ; } +function init_sortable_add_button( $btn ) +{ + // NOTE: We used to have buttons in the UI for editing templates for SCENARIO NOTE's and OB SETUP/NOTE's, + // which took up a lot of real estate for something that almost certainly nobody is using :-/, so we instead + // tuck them away in a droplist, attached to the ADD button. We could put a button for this functionality + // in the "edit simple note" dialog, but here is OK, as well. + // They are currenly only used by simple notes, and are identified by having an "id" data attribute + // that specifies the associated template ID. Note that we don't do this for SSR's since it already has + // a snippet control, which works a little differenly (all the simple notes are munged together into + // a single label). + + // check if this sortable-add button should be able to edit the underlying template + var template_id = $btn.data( "id" ) ; + if ( ! template_id ) + return ; + + // create the new button + // NOTE: It's important we retain the original button element, since it's already been initialized + // as a sortable helper. Since we want to replace the original button with the new one, we have to + // do a bit of stuffing around to figure out where to place it + var $btnPlaceholder = $( "" ) ; + $btn.before( $btnPlaceholder ) ; + $btn.detach() ; + var $newBtn = $( "
" ) ; + $newBtn.append( $btn ) ; + $newBtn.append( [ + "" + ].join( "" ) ) ; + + // add in the droplist + $newBtn.controlgroup() ; + $newBtn.children( "select" ).each( function() { + $(this).selectmenu( { + classes: { + "ui-selectmenu-button": "ui-button-icon-only", + "ui-selectmenu-menu": "snippet-control-menu-item", + }, + } ) ; + } ) ; + $newBtn.children( ".ui-button-icon-only" ).css( { + width: "1em", height: 28, "border-left": "none" + } ) ; + + // give the combined button rounded corners + $btn.css( "border-radius", "3px 0 0 3px" ) ; + $btn.parent().children( ".ui-selectmenu-button" ).css( "border-radius", "0 3px 3px 0" ) ; + + // handle menu items + $newBtn.children( "select" ).on( "selectmenuselect", function( evt, ui ) { + if ( ui.item.value === "edit" ) + edit_template( $(this).data( "id" ) ) ; + } ) ; + + // replace the existing button with the new replacement button + $btnPlaceholder.replaceWith( $newBtn ) ; +} + function updateCompassImage() { // update the image in the COMPASS snippet button var dirn = $( "input.param[name='COMPASS']" ).val() || "none" ; @@ -917,7 +976,7 @@ function install_template_pack( data ) } // update the snippet buttons - function update_button( $btn ) { + function update_generate_button( $btn ) { var template_id = $btn.attr( "data-id" ) ; if ( template_id.substr( 0, 7 ) === "extras/" ) return ; @@ -940,8 +999,17 @@ function install_template_pack( data ) } else $btn.button( enable ? "enable": "disable" ) ; } - $( "button.generate" ).each( function() { update_button( $(this) ) ; } ) ; - $( "button.edit-template" ).each( function() { update_button( $(this) ) ; } ) ; + function update_sortable_add_button( $btn ) { + var template_id = $btn.attr( "data-id" ) ; + if ( ! template_id ) + return ; + var $dropdown = $btn.parent().find( "select[data-id='" + template_id + "']" ) ; + var enable = is_template_available( template_id ) ; + $dropdown.find( "option.edit-template" ).attr( "disabled", !enable ) ; + $dropdown.selectmenu( "refresh" ) ; + } + $( "button.generate" ).each( function() { update_generate_button( $(this) ) ; } ) ; + $( "button.sortable-add" ).each( function() { update_sortable_add_button( $(this) ) ; } ) ; // update the turn track controls enable = is_template_available( "turn_track" ) ; diff --git a/vasl_templates/webapp/templates/tabs-ob1.html b/vasl_templates/webapp/templates/tabs-ob1.html index 6fa9628..e4b285e 100644 --- a/vasl_templates/webapp/templates/tabs-ob1.html +++ b/vasl_templates/webapp/templates/tabs-ob1.html @@ -9,10 +9,8 @@ @@ -24,7 +22,7 @@ diff --git a/vasl_templates/webapp/templates/tabs-scenario.html b/vasl_templates/webapp/templates/tabs-scenario.html index 53a68b5..76205b7 100644 --- a/vasl_templates/webapp/templates/tabs-scenario.html +++ b/vasl_templates/webapp/templates/tabs-scenario.html @@ -93,10 +93,8 @@ diff --git a/vasl_templates/webapp/tests/test_snippets.py b/vasl_templates/webapp/tests/test_snippets.py index 818166e..bd636ef 100644 --- a/vasl_templates/webapp/tests/test_snippets.py +++ b/vasl_templates/webapp/tests/test_snippets.py @@ -372,8 +372,9 @@ def test_edit_templates( webapp, webdriver ): if template_id in ("ob_vehicle_note","ob_ordnance_note"): return # nb: we currently don't support editing these in the UI # edit the template - elem = find_child( "a._edit-template-link_[data-id='{}']".format( template_id ) ) - webdriver.execute_script( "$(arguments[0]).click();", elem ) + webdriver.execute_script( "$(arguments[0]).click();", + find_child( "a._edit-template-link_[data-id='{}']".format( template_id ) ) + ) edit_template( orig_template_id ) # check that the new template is being used elem = find_child( "button.generate[data-id='{}']".format( orig_template_id ) ) @@ -383,8 +384,9 @@ def test_edit_templates( webapp, webdriver ): # customize the SCENARIO NOTE template select_tab( "scenario" ) - elem = find_child( "button[data-id='scenario_note']" ) - elem.click() + webdriver.execute_script( "$(arguments[0]).click();", + find_child( "a._edit-template-link_[data-id='scenario_note']" ) + ) edit_template( "scenario_note" ) # check that the new template is being used @@ -396,8 +398,9 @@ def test_edit_templates( webapp, webdriver ): # customize the OB SETUP template select_tab( "ob1" ) - elem = find_child( "#tabs-ob1 button[data-id='ob_setup']" ) - elem.click() + webdriver.execute_script( "$(arguments[0]).click();", + find_child( "a._edit-template-link_[data-id='ob_setup']" ) + ) edit_template( "ob_setup" ) # check that the new template is being used @@ -411,8 +414,9 @@ def test_edit_templates( webapp, webdriver ): # customize the OB NOTE template select_tab( "ob2" ) - elem = find_child( "#tabs-ob2 button[data-id='ob_note']" ) - elem.click() + webdriver.execute_script( "$(arguments[0]).click();", + find_child( "a._edit-template-link_[data-id='ob_note']" ) + ) edit_template( "ob_note" ) # check that the new template is being used @@ -584,8 +588,9 @@ def test_jinja_in( webapp, webdriver ): def do_test( search_for, search_in, expected ): """Test the IN operator.""" # install a new template - elem = find_child( "a._edit-template-link_[data-id='victory_conditions']" ) - webdriver.execute_script( "$(arguments[0]).click();", elem ) + webdriver.execute_script( "$(arguments[0]).click();", + find_child( "a._edit-template-link_[data-id='victory_conditions']" ) + ) elem = find_child( "#edit-template textarea" ) elem.clear() buf = [ diff --git a/vasl_templates/webapp/tests/test_template_packs.py b/vasl_templates/webapp/tests/test_template_packs.py index 926e036..d7e49dd 100644 --- a/vasl_templates/webapp/tests/test_template_packs.py +++ b/vasl_templates/webapp/tests/test_template_packs.py @@ -197,8 +197,8 @@ def test_missing_templates( webapp, webdriver ): else: return template_id - def check_buttons( fname, sel, is_snippet_control ): #pylint: disable=missing-docstring - for btn in find_children( sel ): + def check_generate_buttons( fname ): + for btn in find_children( "button.generate" ): # check the UI state of the next button template_id = adjust_template_id( btn.get_attribute( "data-id" ) ) if fname == "national-capabilities.json": @@ -212,16 +212,13 @@ def test_missing_templates( webapp, webdriver ): # check that snippet control groups have been enabled/disabled correctly parent = get_parent_elem( btn ) parent_classes = get_css_classes( parent ) - if is_snippet_control: - assert "snippet-control" in parent_classes - elem = find_child( ".ui-selectmenu-button", parent ) - elem_classes = get_css_classes( elem ) - if expected: - assert "ui-selectmenu-disabled" in elem_classes - else: - assert "ui-selectmenu-disabled" not in elem_classes + assert "snippet-control" in parent_classes + elem = find_child( ".ui-selectmenu-button", parent ) + elem_classes = get_css_classes( elem ) + if expected: + assert "ui-selectmenu-disabled" in elem_classes else: - assert "snippet-control" not in parent_classes + assert "ui-selectmenu-disabled" not in elem_classes # check if the button has an associated "snippet-width" textbox sel = btn.get_attribute( "data-id" ) if sel.endswith( ( "_1", "_2" ) ): @@ -232,6 +229,18 @@ def test_missing_templates( webapp, webdriver ): if elem: assert not elem.is_enabled() == expected + def check_sortable_add_buttons( fname ): + for btn in find_children( "button.sortable-add" ): + template_id = btn.get_attribute( "data-id" ) + if not template_id: + continue + # check the UI state of the next button + expected = os.path.splitext( fname )[0] == template_id + dropdown = find_child( "select[data-id='{}']".format( template_id ), get_parent_elem(btn) ) + opt = find_child( "option.edit-template", dropdown ) + disabled = opt.get_attribute( "disabled" ) is not None + assert disabled == expected + # upload the template pack, with one file missing each time for fname in files: @@ -243,8 +252,8 @@ def test_missing_templates( webapp, webdriver ): # check the state of each button (everything should be enabled, except for the one # corresponding to the template file we excluded from the upload) - check_buttons( fname, "button.generate", True ) - check_buttons( fname, "button.edit-template", False ) + check_generate_buttons( fname ) + check_sortable_add_buttons( fname ) # NOTE: We should really check that the "generate snippet" buttons don't appear in sortable entries, # but that's more trouble than it's worth - templates such as ob_setup and ob_vehicles are never