Allow snippets to be generated from the "add/edit simple note" dialog.

master
Pacman Ghost 2 years ago
parent 2a707863d2
commit 95167f4888
  1. 103
      vasl_templates/webapp/static/simple_notes.js
  2. 38
      vasl_templates/webapp/static/snippets.js
  3. 3
      vasl_templates/webapp/static/utils.js
  4. 106
      vasl_templates/webapp/tests/test_snippets.py

@ -4,30 +4,73 @@
// --------------------------------------------------------------------
function add_scenario_note() { _do_edit_simple_note( $("#scenario_notes-sortable"), null, gDefaultScenario._SCENARIO_NOTE_WIDTH ) ; }
function add_scenario_note() { _do_edit_simple_note( "scenario_note", null, $("#scenario_notes-sortable"), null, gDefaultScenario._SCENARIO_NOTE_WIDTH ) ; }
function do_add_scenario_note( $sortable2, data ) { _do_add_simple_note($sortable2,data) ; }
function edit_scenario_note( $sortable2, $entry ) { _do_edit_simple_note( $sortable2, $entry, null ) ; }
function edit_scenario_note( $sortable2, $entry ) { _do_edit_simple_note( "scenario_note", null, $sortable2, $entry, null ) ; }
function add_ssr() { _do_edit_simple_note( $("#ssr-sortable"), null, null ) ; }
function add_ssr() { _do_edit_simple_note( "ssr", null, $("#ssr-sortable"), null, null ) ; }
function do_add_ssr( $sortable2, data ) { _do_add_simple_note($sortable2,data) ; }
function edit_ssr( $sortable2, $entry ) { _do_edit_simple_note( $sortable2, $entry, null ) ; }
function edit_ssr( $sortable2, $entry ) { _do_edit_simple_note( "ssr", null, $sortable2, $entry, null ) ; }
function add_ob_setup( player_no ) { _do_edit_simple_note( $("#ob_setups-sortable_"+player_no), null, gDefaultScenario._OB_SETUP_WIDTH ) ; }
function add_ob_setup( player_no ) { _do_edit_simple_note( "ob_setup", player_no, $("#ob_setups-sortable_"+player_no), null, gDefaultScenario._OB_SETUP_WIDTH ) ; }
function do_add_ob_setup( $sortable2, data ) { _do_add_simple_note($sortable2,data) ; }
function edit_ob_setup( $sortable2, $entry ) { _do_edit_simple_note( $sortable2, $entry, null ) ; }
function edit_ob_setup( $sortable2, $entry ) { _do_edit_simple_note( "ob_setup", get_player_no_for_element($sortable2), $sortable2, $entry, null ) ; }
function add_ob_note( player_no ) { _do_edit_simple_note( $("#ob_notes-sortable_"+player_no), null, gDefaultScenario._OB_NOTE_WIDTH ) ; }
function add_ob_note( player_no ) { _do_edit_simple_note( "ob_note", player_no, $("#ob_notes-sortable_"+player_no), null, gDefaultScenario._OB_NOTE_WIDTH ) ; }
function do_add_ob_note( $sortable2, data ) { _do_add_simple_note($sortable2,data) ; }
function edit_ob_note( $sortable2, $entry ) { _do_edit_simple_note( $sortable2, $entry, null ) ; }
function edit_ob_note( $sortable2, $entry ) { _do_edit_simple_note( "ob_note", get_player_no_for_element($sortable2), $sortable2, $entry, null ) ; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function _do_edit_simple_note( $sortable2, $entry, default_width )
function _do_edit_simple_note( template_id, player_no, $sortable2, $entry, default_width )
{
// figure out what we're editing
var note_type = _get_note_type_for_sortable( $sortable2 ) ;
var note_type0 = note_type.substring( 0, note_type.length-1 ) ; // plural -> singular :-/
// determine the next available ID
var usedIds = {} ;
$sortable2.children( "li" ).each( function() {
usedIds[ $(this).data("sortable2-data").id ] = true ;
} ) ;
var nextAvailableId = auto_assign_id( usedIds, "id" ) ;
function makeSimpleSnippet( evt ) {
// initialize
var $btnPane = $( ".ui-dialog.edit-simple_note .ui-dialog-buttonpane" ) ;
var $btn = $btnPane.find( "button.snippet" ) ;
var caption = $caption.val().trim() ;
var width = $width.val().trim() ;
// prepare the template parameters
// NOTE: We don't bother handling the case of an empty caption.
var extraParams = {} ;
if ( template_id === "ssr" ) {
// NOTE: All the SSR's are combined into a single snippet, so it doesn't actually make sense
// to have a snippet button for individual SSR's, but it's convenient. We unload all the SSR's
// from the UI, then update the content for the one being edited (if it already exists), or
// add it to the end of the list (if it's a new one).
var ssrs = unload_ssrs() ;
if ( $entry ) {
// find and update the SSR being edited
$( "#ssr-sortable > li" ).each( function( index ) {
if ( $(this)[0] === $entry[0] )
ssrs[ index ] = caption ;
} ) ;
} else {
// add the new SSR to the end of the list
ssrs.push( caption ) ;
}
extraParams.SSR = ssrs ;
} else {
// override the template parameters unloaded from the UI with the current values from the dialog
var paramKey = template_id.toUpperCase() ;
extraParams[ paramKey ] = caption ;
extraParams[ paramKey+"_WIDTH" ] = width ;
}
// generate the snippet
generate_snippet( $btn, evt.shiftKey, extraParams ) ;
}
// let the user edit the note
var $caption, $width ;
$("#edit-simple_note").dialog( {
@ -45,16 +88,35 @@ function _do_edit_simple_note( $sortable2, $entry, default_width )
on_dialog_open( $(this), $caption ) ;
add_flag_to_dialog_titlebar( $(this), get_player_no_for_element($sortable2) ) ;
var $btn_pane = $(".ui-dialog.edit-simple_note .ui-dialog-buttonpane") ;
$width = $btn_pane.children( "input[name='width']" ) ;
var $btn = $btn_pane.find( "button.snippet" ) ;
$btn.prepend(
$( "<img src='" + gImagesBaseUrl+"/snippet.png" + "' style='height:0.9em;margin:0 0 -2px -2px;'>" )
) ;
$width = $btn_pane.find( "input[name='width']" ) ;
if ( $width.length === 0 ) {
// create the width controls
$btn_pane.prepend( $("<label for='width'>Width:</label>&nbsp;<input type='text' name='width' size='5'>") ) ;
$width = $btn_pane.children( "input[name='width']" ) ;
$btn_pane.prepend( $( "<div style='position:absolute;left:15px;height:28px;display:flex;align-items:center;'>" +
"<label for='width'>Width:</label>&nbsp;<input type='text' name='width' size='4' style='margin-top:-1px;'>" +
"</div>" ) ) ;
$width = $btn_pane.find( "input[name='width']" ) ;
}
// tweak the SNIPPETS button so that snippets will work
$btn.data( { id: template_id, "player-no": player_no } ) ;
var snippet_id = template_id ;
if ( player_no )
snippet_id += "_" + player_no ;
var entryData = $entry ? $entry.data("sortable2-data") : null ;
if ( template_id !== "ssr" )
snippet_id += "." + (entryData ? entryData.id : nextAvailableId) ;
$btn.data( "snippet-id", snippet_id ) ;
$btn.button( is_template_available( template_id ) ? "enable" : "disable" ) ;
// show/hide the width controls (nb: SSR's have a separate width setting that affects all of them)
var show = (note_type !== "ssr") ;
$btn_pane.children( "label[for='width']" ).css( "display", show?"inline":"none" ) ;
$btn_pane.find( "label[for='width']" ).css( "display", show?"inline":"none" ) ;
$width.css( "display", show?"inline":"none" ) ;
$btn.css( { position: "absolute", left:
show ? $width.offset().left + $width.width() - $btn_pane.find("label[for='width']").offset().left + 25 : 15
} ) ;
// enable auto-dismiss for the dialog
var $dlg = $(this) ;
$width.keydown( function(evt) { auto_dismiss_dialog( $dlg, evt, "OK" ) ; } ) ;
@ -65,12 +127,12 @@ function _do_edit_simple_note( $sortable2, $entry, default_width )
border: "1px solid "+colors[2]
} ) ;
// load the dialog
var data = $entry ? $entry.data("sortable2-data") : null ;
$caption.val( data ? data.caption : "" ).focus() ;
$width.val( data ? data.width : default_width ) ;
$caption.val( entryData ? entryData.caption : "" ).focus() ;
$width.val( entryData ? entryData.width : default_width ) ;
$(this).height( $(this).height() ) ; // fudge: force the textarea to resize
},
buttons: {
Snippet: { text:" Snippet", class: "snippet", click: makeSimpleSnippet },
OK: function() {
var caption = $caption.val().trim() ;
var width = $width.val().trim() ;
@ -88,13 +150,8 @@ function _do_edit_simple_note( $sortable2, $entry, default_width )
// create a new note
if ( caption !== "" ) {
data = { caption: caption, width: width } ;
if ( note_type === "scenario_notes" || note_type === "ob_setups" || note_type === "ob_notes" ) {
var usedIds = {} ;
$sortable2.children( "li" ).each( function() {
usedIds[ $(this).data("sortable2-data").id ] = true ;
} ) ;
data.id = auto_assign_id( usedIds, "id" ) ;
}
if ( note_type === "scenario_notes" || note_type === "ob_setups" || note_type === "ob_notes" )
data.id = nextAvailableId ;
$entry = _do_add_simple_note( $sortable2, data ) ;
}
}

@ -162,15 +162,20 @@ function make_snippet( $btn, params, extra_params, show_date_warnings )
}
// set the snippet ID
var data ;
if ( ["ob_setup","ob_note","ob_vehicle_note","ob_ordnance_note"].indexOf( template_id ) !== -1 ) {
data = $btn.parent().parent().data( "sortable2-data" ) ;
params.SNIPPET_ID = template_id + "_" + player_no + "." + data.id ;
} else if ( template_id === "scenario_note" ) {
data = $btn.parent().parent().data( "sortable2-data" ) ;
params.SNIPPET_ID = template_id + "." + data.id ;
} else
params.SNIPPET_ID = template_id ;
var snippetId = $btn.data( "snippet-id" ) ;
if ( snippetId )
params.SNIPPET_ID = snippetId ;
else {
var data ;
if ( ["ob_setup","ob_note","ob_vehicle_note","ob_ordnance_note"].indexOf( template_id ) !== -1 ) {
data = $btn.parent().parent().data( "sortable2-data" ) ;
params.SNIPPET_ID = template_id + "_" + player_no + "." + data.id ;
} else if ( template_id === "scenario_note" ) {
data = $btn.parent().parent().data( "sortable2-data" ) ;
params.SNIPPET_ID = template_id + "." + data.id ;
} else
params.SNIPPET_ID = template_id ;
}
if ( player_nat )
params.SNIPPET_ID = player_nat + "/" + params.SNIPPET_ID ;
@ -985,10 +990,7 @@ function unload_snippet_params( unpack_scenario_date, template_id )
} ) ;
// collect the SSR's
params.SSR = [] ;
var data = $("#ssr-sortable").sortable2( "get-entry-data" ) ;
for ( var i=0 ; i < data.length ; ++i )
params.SSR.push( data[i].caption ) ;
params.SSR = unload_ssrs() ;
// collect the vehicles/ordnance
function get_vo( vo_type, player_no, key, show_warnings ) {
@ -1084,6 +1086,16 @@ function unload_snippet_params( unpack_scenario_date, template_id )
return params ;
}
function unload_ssrs()
{
// unload the SSR's
ssrs = [] ;
var data = $( "#ssr-sortable" ).sortable2( "get-entry-data" ) ;
for ( var i=0 ; i < data.length ; ++i )
ssrs.push( data[i].caption ) ;
return ssrs ;
}
function get_vo_comments( vo_entry, month, year )
{
if ( ! vo_entry.comments )

@ -77,6 +77,9 @@ function make_player_flag_url( nat, for_snippet, force_local_image ) {
function get_player_no_for_element( $elem )
{
// get the player that owns the specified element
var playerNo = $elem.data( "player-no" ) ;
if ( playerNo )
return playerNo ;
if ( $.contains( $("#tabs-ob1")[0], $elem[0] ) )
return 1 ;
if ( $.contains( $("#tabs-ob2")[0], $elem[0] ) )

@ -1,5 +1,6 @@
""" Test HTML snippet generation. """
import re
import base64
import pytest
@ -9,8 +10,8 @@ from selenium.webdriver.common.keys import Keys
from vasl_templates.webapp.tests import pytest_options
from vasl_templates.webapp.tests.utils import \
init_webapp, select_tab, find_snippet_buttons, set_template_params, wait_for, wait_for_clipboard, \
get_stored_msg, set_stored_msg_marker, find_child, find_children, adjust_html, \
for_each_template, add_simple_note, edit_simple_note, \
get_stored_msg, set_stored_msg_marker, find_child, find_children, find_sortable_helper, adjust_html, \
for_each_template, add_simple_note, edit_simple_note, click_dialog_button, \
get_sortable_entry_count, generate_sortable_entry_snippet, drag_sortable_entry_to_trash, \
new_scenario, set_scenario_date
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario
@ -229,6 +230,107 @@ def test_players_snippets( webapp, webdriver ):
# ---------------------------------------------------------------------
def test_simple_snippets_from_dialog( webapp, webdriver ):
"""Test generating snippets from the "add/edit simple note" dialog."""
# initialize
webapp.control_tests.set_data_dir( "{REAL}" )
init_webapp( webapp, webdriver, scenario_persistence=1 )
load_scenario( {
"SCENARIO_NOTES": [
{ "id": 1, "caption": "scenario note 1", "width": "111px" },
{ "id": 2, "caption": "scenario note 2" }
],
"SSR": [ "SSR #1", "SSR #2" ],
"SSR_WIDTH": "222px",
"OB_SETUPS_1": [
{ "id": 1, "caption": "german ob setup #1", "width": "991px" },
{ "id": 2, "caption": "german ob setup #2" }
],
"OB_NOTES_2": [
{ "id": 1, "caption": "russian setup note #1", "width": "992px" },
{ "id": 2, "caption": "russian setup note #2" }
]
} )
def test_existing_simple_note( sortable, entry_no, expected ):
# edit the simple note
elems = find_children( "li", sortable )
ActionChains(webdriver).double_click( elems[entry_no] ).perform()
# change the snippet content
elem = find_child( ".ui-dialog.edit-simple_note textarea" )
elem.clear()
elem.send_keys( "modified content" )
# change the snippet width
elem = find_child( ".ui-dialog.edit-simple_note input[name='width']" )
if elem.is_displayed():
elem.clear()
elem.send_keys( "123px" )
# generate the snippet
click_dialog_button( "Snippet" )
if isinstance( expected, str ):
# NOTE: We also check that the snippet ID is correct.
expected = re.compile( ".*".join( [
"<!-- vasl-templates:id {} -->".format( expected ),
"width: 123px",
"modified content",
] ), re.DOTALL )
wait_for_clipboard( 2, expected )
click_dialog_button( "Cancel" )
def test_new_simple_note( sortable, expected ) :
# add a new simple note
find_sortable_helper( sortable, "add" ).click()
elem = find_child( ".ui-dialog.edit-simple_note textarea" )
elem.send_keys( "new content" )
elem = find_child( ".ui-dialog.edit-simple_note input[name='width']" )
if elem.is_displayed():
elem.clear()
elem.send_keys( "789px" )
# generate the snippet
click_dialog_button( "Snippet" )
if isinstance( expected, str ):
# NOTE: We also check that the snippet ID is correct.
expected = re.compile( ".*".join( [
"<!-- vasl-templates:id {} -->".format( expected ),
"width: 789px",
"new content",
] ), re.DOTALL )
wait_for_clipboard( 2, expected )
click_dialog_button( "Cancel" )
# test scenario notes
sortable = find_child( "#scenario_notes-sortable" )
test_existing_simple_note( sortable, 1, "scenario_note.2" )
test_new_simple_note( sortable, "scenario_note.3" )
# test SSR's
sortable = find_child( "#ssr-sortable" )
test_existing_simple_note( sortable, 1, re.compile( ".*".join( [
"<!-- vasl-templates:id ssr -->",
"width: 222px",
r'<ul id="ssr">\s*<li>\s*SSR #1\s*<li>\s*modified content\s*</ul>',
] ), re.DOTALL ) )
test_new_simple_note( sortable, re.compile( ".*".join( [
"<!-- vasl-templates:id ssr -->",
"width: 222px",
r'<ul id="ssr">\s*<li>\s*SSR #1\s*<li>\s*SSR #2\s*<li>\s*new content\s*</ul>',
] ), re.DOTALL ) )
# test OB setups
select_tab( "ob1" )
sortable = find_child( "#ob_setups-sortable_1" )
test_existing_simple_note( sortable, 1, "german/ob_setup_1.2" )
test_new_simple_note( sortable, "german/ob_setup_1.3" )
# test OB setups
select_tab( "ob2" )
sortable = find_child( "#ob_notes-sortable_2" )
test_existing_simple_note( sortable, 1, "russian/ob_note_2.2" )
test_new_simple_note( sortable, "russian/ob_note_2.3" )
# ---------------------------------------------------------------------
def test_edit_templates( webapp, webdriver ):
"""Test editing templates."""

Loading…
Cancel
Save