From c8bd690a3bc7b83f8824980e6495e5f2db6b82cf Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Mon, 12 May 2014 14:13:25 -0400 Subject: [PATCH] LP#1332138 Report template / field documentation * Report templates support a new External URL field, which may contain a link to template-specific, local documentation. ** When set, a link to the external documentation will be displayed in a new column in the template list and within the report editor. ** URL's are set in the 'Documentation URL' entry. * Template display fields and filters support a new Field Hint value. When set, hints are displayed in the report editor. ** Values are set via the 'Change Field Hint' option along the bottom of the template editor. ------ from commits ---- * Initial template-level support for inline template and field documentation * Use external documenation url in clark output * Show the docs link and strings in the report editor * Set the href of a link, instead of the text content of a span * Attempt to pop up a new window (may require more pushups in the XUL staff client) * Add calculated column support, use it for external docs url * Realign field names Signed-off-by: Mike Rylander Signed-off-by: Bill Erickson Signed-off-by: Kathy Lussier Signed-off-by: Ben Shum --- Open-ILS/src/reporter/clark-kent.pl | 28 ++++++++- Open-ILS/src/reporter/report-fail | 3 + Open-ILS/src/reporter/report-success | 3 + .../js/dojo/openils/reports/nls/reports.js | 1 + Open-ILS/web/opac/common/js/fm_table.js | 16 ++++- Open-ILS/web/opac/common/js/fm_table_conf.js | 14 +++++ Open-ILS/web/opac/locale/en-US/reports.dtd | 3 + Open-ILS/web/reports/oils_rpt_editor.xhtml | 3 + Open-ILS/web/reports/oils_rpt_param_editor.js | 4 +- .../web/reports/oils_rpt_report_editor.js | 6 ++ Open-ILS/web/reports/oils_rpt_utils.js | 7 ++- Open-ILS/web/reports/xul/template-config.js | 63 +++++++++++++++---- Open-ILS/web/reports/xul/template_builder.xul | 11 ++++ 13 files changed, 140 insertions(+), 22 deletions(-) diff --git a/Open-ILS/src/reporter/clark-kent.pl b/Open-ILS/src/reporter/clark-kent.pl index 9030825988..2e9bbd9899 100755 --- a/Open-ILS/src/reporter/clark-kent.pl +++ b/Open-ILS/src/reporter/clark-kent.pl @@ -373,6 +373,11 @@ sub send_success { $tmpl =~ s/{COMPLETE_TIME}/$r->{complete_time}/smog; $tmpl =~ s/{OUTPUT_URL}/$url/smog; + my $tdata = OpenSRF::Utils::JSON->JSON2perl( $r->{report}->{template}->{data} ); + if ($$tdata{version} >= 4) { + $tmpl =~ s/{EXTERNAL_URL}/$$tdata{doc_url}/smog; + } + my $sender = Email::Send->new({mailer => 'SMTP'}); $sender->mailer_args([Host => $email_server]); $sender->send($tmpl); @@ -394,6 +399,11 @@ sub send_fail { $tmpl =~ s/{ERROR_TEXT}/$r->{error_text}/smog; $tmpl =~ s/{SQL}/$sql/smog; + my $tdata = OpenSRF::Utils::JSON->JSON2perl( $r->{report}->{template}->{data} ); + if ($$tdata{version} >= 4) { + $tmpl =~ s/{EXTERNAL_URL}/$$tdata{doc_url}/smog; + } + my $sender = Email::Send->new({mailer => 'SMTP'}); $sender->mailer_args([Host => $email_server]); $sender->send($tmpl); @@ -438,6 +448,8 @@ sub build_html { my $r = shift; my $index = new FileHandle (">$file") or die "Cannot write to '$file'"; + + my $tdata = OpenSRF::Utils::JSON->JSON2perl( $r->{report}->{template}->{data} ); # index header print $index <<" HEADER"; @@ -456,9 +468,15 @@ sub build_html {

$$r{report}{name}

- $$r{report}{description}


+ $$r{report}{description}
HEADER + if ($$tdata{version} >= 4 and $$tdata{doc_url}) { + print $index "External template documentation
"; + } + + print $index "

"; + my @links; my $br4 = '
' x 4; @@ -478,11 +496,15 @@ sub build_html { print $debug "DEBUG: $$r{report}{name}"; { no warnings; + if ($$tdata{version} >= 4 and $$tdata{doc_url}) { + print $debug "External template documentation
Back to output index
"; + } + print $debug '

Generated SQL

' . $r->{resultset}->toSQL() . "
Back to output index
"; print $debug '

Template

' . Dumper( $r->{report}->{template} ) . "
Back to output index
"; - print $debug '

Template Data

' . Dumper( OpenSRF::Utils::JSON->JSON2perl( $r->{report}->{template}->{data} ) ) . "
Back to output index
"; + print $debug '

Template Data

' . Dumper( $tdata ) . "
Back to output index
"; print $debug '

Report Parameter

' . Dumper( $r->{report} ) . "
Back to output index
"; - print $debug '

Report Parameter Data

' . Dumper( OpenSRF::Utils::JSON->JSON2perl( $r->{report}->{data} ) ) . "
Back to output index
"; + print $debug '

Report Parameter Data

' . Dumper( $tdata ) . "
Back to output index
"; print $debug '

Report Run Time

' . $r->{resultset}->relative_time . "
Back to output index
"; print $debug '

OpenILS::Reporter::SQLBuilder::ResultSet Object

' . Dumper( $r->{resultset} ) . "
Back to output index"; } diff --git a/Open-ILS/src/reporter/report-fail b/Open-ILS/src/reporter/report-fail index d49a13a750..569bc541ac 100644 --- a/Open-ILS/src/reporter/report-fail +++ b/Open-ILS/src/reporter/report-fail @@ -8,6 +8,9 @@ has failed with the following error message: {ERROR_TEXT} +External documentation for the template is available at the following URL: + {EXTERNAL_URL} + The SQL command attempted was: {SQL} diff --git a/Open-ILS/src/reporter/report-success b/Open-ILS/src/reporter/report-success index a49a1a8d36..873943d55b 100644 --- a/Open-ILS/src/reporter/report-success +++ b/Open-ILS/src/reporter/report-success @@ -8,3 +8,6 @@ time of {COMPLETE_TIME}. You can view the report at the following URL: {OUTPUT_URL} + +External documentation for the template is available at the following URL: +{EXTERNAL_URL} diff --git a/Open-ILS/web/js/dojo/openils/reports/nls/reports.js b/Open-ILS/web/js/dojo/openils/reports/nls/reports.js index 34bd06ff49..1ae57f6cbf 100644 --- a/Open-ILS/web/js/dojo/openils/reports/nls/reports.js +++ b/Open-ILS/web/js/dojo/openils/reports/nls/reports.js @@ -121,6 +121,7 @@ "TEMPLATE_CONF_EQUALS": "Equals", "TEMPLATE_CONF_CONFIRM_RESET": "You have already added the [${0}] field\nfrom the [${1}] source. Click OK if you\nwould like to reset this field.", "TEMPLATE_CONF_PROMPT_CHANGE": "Change the column header to: ${0}", + "TEMPLATE_FIELD_DOC_PROMPT_CHANGE": "Change the field hint to:", "TEMPLATE_CONF_BOOLEAN_VALUE": "Boolean Value", "TEMPLATE_CONF_SELECT_CANCEL": "Select the value, or cancel:", "TEMPLATE_CONF_TRUE": "True", diff --git a/Open-ILS/web/opac/common/js/fm_table.js b/Open-ILS/web/opac/common/js/fm_table.js index a0608eb665..11602dbb2d 100644 --- a/Open-ILS/web/opac/common/js/fm_table.js +++ b/Open-ILS/web/opac/common/js/fm_table.js @@ -151,6 +151,7 @@ FMObjectBuilder.prototype.setKeys = function(o) { this.bold = this.display[o.classname].bold; this.money = this.display[o.classname].money; this.sortdata = this.display[o.classname].sortdata; + this.calculate = this.display[o.classname].calculate; } if(!this.keys && FM_TABLE_DISPLAY[o.classname]) @@ -165,6 +166,9 @@ FMObjectBuilder.prototype.setKeys = function(o) { if(!this.sortdata && FM_TABLE_DISPLAY[o.classname]) this.sortdata = FM_TABLE_DISPLAY[o.classname].sortdata; + if(!this.calculate && FM_TABLE_DISPLAY[o.classname]) + this.calculate = FM_TABLE_DISPLAY[o.classname].calculate; + if(!this.keys) { this.keys = fmclasses[o.classname]; sortme = true; @@ -193,9 +197,15 @@ FMObjectBuilder.prototype.buildObjectRow = function(obj) { for( var i = 0; i < this.keys.length; i++ ) { var td = elem('td'); - var data = obj[this.keys[i]](); - data = this.munge(data); - this.fleshData(td, data, this.keys[i]); + var data = ''; + if (this.caclulate[i]) { // fake data! pass the object + td.appendChild(this.calculate[i](obj); + } else { + data = obj[this.keys[i]](); + data = this.munge(data); + this.fleshData(td, data, this.keys[i]); + } + row.appendChild(td); } this.tbody.appendChild(row); diff --git a/Open-ILS/web/opac/common/js/fm_table_conf.js b/Open-ILS/web/opac/common/js/fm_table_conf.js index e5db8877fd..b7f2887ad0 100644 --- a/Open-ILS/web/opac/common/js/fm_table_conf.js +++ b/Open-ILS/web/opac/common/js/fm_table_conf.js @@ -106,9 +106,23 @@ var FM_TABLE_DISPLAY = { fields : [ 'name', 'description', + 'docs', 'create_time', 'owner', ], + calculate : { + docs : function (t) { + var d = JSON2js(t.data()); + if (d.version >= 4 && d.doc_url) { + return elem( + 'a', + { href : d.doc_url, target : '_blank'}, + 'External Documentation' + ); + } + return text(''); + } + }, sortdata : [ 'name', 1 ] }, 'rs' : { diff --git a/Open-ILS/web/opac/locale/en-US/reports.dtd b/Open-ILS/web/opac/locale/en-US/reports.dtd index f5725157f6..2c9e8f9ecb 100644 --- a/Open-ILS/web/opac/locale/en-US/reports.dtd +++ b/Open-ILS/web/opac/locale/en-US/reports.dtd @@ -69,6 +69,7 @@ + @@ -197,6 +198,7 @@ + @@ -213,6 +215,7 @@ + diff --git a/Open-ILS/web/reports/oils_rpt_editor.xhtml b/Open-ILS/web/reports/oils_rpt_editor.xhtml index 0c5dcc7df6..c2cf7082d8 100644 --- a/Open-ILS/web/reports/oils_rpt_editor.xhtml +++ b/Open-ILS/web/reports/oils_rpt_editor.xhtml @@ -13,6 +13,9 @@ &reports.oils_rpt_editor.template_description; + + &reports.oils_rpt_editor.doc_url; + &reports.oils_rpt_editor.report_name; diff --git a/Open-ILS/web/reports/oils_rpt_param_editor.js b/Open-ILS/web/reports/oils_rpt_param_editor.js index d99c7b0775..947f0649e0 100644 --- a/Open-ILS/web/reports/oils_rpt_param_editor.js +++ b/Open-ILS/web/reports/oils_rpt_param_editor.js @@ -37,7 +37,7 @@ oilsRptParamEditor.prototype.draw = function() { var par = params[p]; var row = oilsRptParamEditor.row.cloneNode(true); this.tbody.appendChild(row); - $n(row, 'column').appendChild(text(oilsRptMakeLabel(par.path))); + $n(row, 'column').appendChild(text(oilsRptMakeLabel(par.path, par.field_doc))); $n(row, 'transform').appendChild(text(OILS_RPT_TRANSFORMS[par.column.transform].label)); $n(row, 'action').appendChild(text(OILS_RPT_FILTERS[par.op].label)); par.widget = this.buildWidget(par, $n(row, 'widget')); @@ -52,7 +52,7 @@ oilsRptParamEditor.prototype.draw = function() { var par = tparams[p]; var row = oilsRptParamEditor.row.cloneNode(true); this.tbody.appendChild(row); - $n(row, 'column').appendChild(text(oilsRptMakeLabel(par.path))); + $n(row, 'column').appendChild(text(oilsRptMakeLabel(par.path, par.field_doc))); $n(row, 'transform').appendChild(text(OILS_RPT_TRANSFORMS[par.column.transform].label)); $n(row, 'action').appendChild(text(OILS_RPT_FILTERS[par.op].label)); par.widget = this.buildWidget(par, $n(row, 'widget')); diff --git a/Open-ILS/web/reports/oils_rpt_report_editor.js b/Open-ILS/web/reports/oils_rpt_report_editor.js index ed9d564780..41c8db406a 100644 --- a/Open-ILS/web/reports/oils_rpt_report_editor.js +++ b/Open-ILS/web/reports/oils_rpt_report_editor.js @@ -16,6 +16,12 @@ function oilsRptReportEditor(rptObject, folderWindow) { appendClear(DOM.oils_rpt_report_editor_template_name, tmpl.name()); appendClear(DOM.oils_rpt_report_editor_template_creator, tmpl.owner().usrname()); appendClear(DOM.oils_rpt_report_editor_template_description, tmpl.description()); + + if (rptObject.def.version >= 4) { + DOM.oils_rpt_report_editor_template_doc_url.setAttribute( 'href', rptObject.def.doc_url ); + } else { + hideMe(DOM.oils_rpt_report_editor_template_doc_url_row); + } appendClear(DOM.oils_rpt_report_editor_cols,''); iterate(rptObject.def.select, diff --git a/Open-ILS/web/reports/oils_rpt_utils.js b/Open-ILS/web/reports/oils_rpt_utils.js index 676d4c7268..3d7602dd69 100644 --- a/Open-ILS/web/reports/oils_rpt_utils.js +++ b/Open-ILS/web/reports/oils_rpt_utils.js @@ -89,7 +89,7 @@ function oilsRptPathRel(path) { } /* creates a label "path" based on the column path */ -function oilsRptMakeLabel(path) { +function oilsRptMakeLabel(path, hint) { var parts = path.split(/-/); var str = ''; for( var i = 0; i < parts.length; i++ ) { @@ -103,6 +103,11 @@ function oilsRptMakeLabel(path) { str += " -> "+f.label; } } + + if (hint) { + str += '
' + hint + '' + } + return str; } diff --git a/Open-ILS/web/reports/xul/template-config.js b/Open-ILS/web/reports/xul/template-config.js index e936880da5..69f70d2d03 100644 --- a/Open-ILS/web/reports/xul/template-config.js +++ b/Open-ILS/web/reports/xul/template-config.js @@ -80,6 +80,7 @@ function addReportAtoms () { var colname = item.getAttribute('idlfield'); var jointype = item.getAttribute('join'); var field_label = item.firstChild.firstChild.getAttribute('label'); + var field_doc = item.firstChild.lastChild.getAttribute('label'); var table_name = getSourceDefinition(field_class); @@ -104,6 +105,7 @@ function addReportAtoms () { params : transform && transform.getAttribute('params'), transform_label: (transform && transform.getAttribute('alias')) || rpt_strings.TEMPLATE_CONF_RAW_DATA, alias : field_label, + field_doc : field_doc, join : jointype, datatype : datatype, op : (datatype == 'array') ? '= any' : '=', @@ -125,6 +127,7 @@ function addReportAtoms () { params : transform && transform.getAttribute('params'), transform_label: (transform && transform.getAttribute('alias')) || rpt_strings.TEMPLATE_CONF_RAW_DATA, alias : field_label, + field_doc : field_doc, join : jointype, datatype : datatype, op : '=', @@ -214,6 +217,39 @@ function alterColumnLabel () { return true; } +function changeFieldDoc () { + var active_tab = filterByAttribute( + $('used-source-fields-tabbox').getElementsByTagName('tab'), + 'selected', + 'true' + )[0]; + + var tabname = active_tab.getAttribute('id'); + + var tabpanel = $( tabname + 'panel' ); + var tree = tabpanel.getElementsByTagName('tree')[0]; + var item_pos = tree.view.selection.currentIndex; + + var item = getSelectedItems(tree)[0]; + var relation_alias = item.getAttribute('relation'); + + var field = item.firstChild.lastChild; + var colname = item.firstChild.firstChild.nextSibling.getAttribute('label'); + + var old_label = field.getAttribute("label"); + var new_label = prompt( rpt_strings.TEMPLATE_FIELD_DOC_PROMPT_CHANGE, old_label ); + + if (new_label) { + rpt_rel_cache[relation_alias].fields[tabname][colname].field_doc = new_label; + renderSources(true); + tree.view.selection.select( item_pos ); + tree.focus(); + tree.click(); + } + + return true; +} + function alterColumnTransform (trans) { var transform = OILS_RPT_TRANSFORMS[trans]; @@ -695,7 +731,15 @@ function renderSources (selected) { fieldtree.lastChild.firstChild.appendChild( createTreeCell({ label : op_value.label }) ); - } + } else { + fieldtree.lastChild.firstChild.appendChild( + createTreeCell({}) + ); + } + + fieldtree.lastChild.firstChild.appendChild( + createTreeCell({ label : field_doc }) + ); } } } @@ -726,20 +770,11 @@ function renderSources (selected) { createTreeCell({ label : colname }), createTreeCell({ label : datatype }), createTreeCell({ label : transform_label }), - createTreeCell({ label : transform }) + createTreeCell({ label : transform }), + createTreeCell({ label : field_doc }) ) ) ); - - fieldtree.lastChild.firstChild.appendChild( - createTreeCell({ op : op, label : op_label }) - ); - - if (op_value.value != undefined) { - fieldtree.lastChild.firstChild.appendChild( - createTreeCell({ label : op_value.label }) - ); - } } } } @@ -756,7 +791,8 @@ function save_template () { param_count = 0; var template = { - version : 3, + version : 4, + doc_url : $('template-doc-url').value, core_class : $('sources-treetop').getElementsByTagName('treeitem')[0].getAttribute('idlclass'), select : [], from : {}, @@ -942,6 +978,7 @@ function fleshTemplateField ( template, rel, tab_name, field ) { var element = { alias : tab[field].alias, + field_doc : tab[field].field_doc, column : { colname : field, transform : tab[field].transform, diff --git a/Open-ILS/web/reports/xul/template_builder.xul b/Open-ILS/web/reports/xul/template_builder.xul index 2a03b23457..5b27102c06 100644 --- a/Open-ILS/web/reports/xul/template_builder.xul +++ b/Open-ILS/web/reports/xul/template_builder.xul @@ -155,10 +155,12 @@ +