}
function oilsRptGetIsAgg(tform) {
+ return OILS_RPT_TRANSFORMS[tform].aggregate;
+
+ /* DEPRECATED */
var sel = $n(DOM.oils_rpt_tform_table,'selector');
for( var i = 0; i < sel.options.length; i++ ) {
var opt = sel.options[i];
column: { transform: tform, colname: oilsRptPathCol(path) },
condition : {}
};
- where.condition[filter] = oilsRptNextParam();
+ if( filter == 'is' || filter == 'is not' )
+ where.condition[filter] = null;
+ else where.condition[filter] = oilsRptNextParam();
switch(tform) {
case 'substring' : where.column.params = oilsRptNextParam();
}
}
+ var tformPicker = new oilsRptTformPicker( {
+ node : DOM.oils_rpt_filter_tform_table,
+ datatype : field.datatype,
+ non_aggregate : true
+ }
+ );
+
+ DOM.oils_rpt_filter_submit.onclick = function() {
+ oilsAddRptFilterItem(
+ path, tformPicker.getSelected(), getSelectorVal(fsel));
+ }
+
+ /*
DOM.oils_rpt_filter_submit.onclick = function() {
var tsel = $n(DOM.oils_rpt_filter_tform_table,'selector');
var tform = getSelectorVal(tsel);
oilsAddRptFilterItem(path, tform, filter);
}
oilsRptShowFilters($n(DOM.oils_rpt_filter_tform_table,'selector'), field.datatype, false, true);
+ */
/*
oilsRptCurrentFilterTform = new oilsRptTFormManager(DOM.oils_rpt_filter_tform_table);
DOM.oils_rpt_tform_label_input.value = oilsRptMakeLabel(path);
var dtype = field.datatype;
+ var tformPicker = new oilsRptTformPicker( {
+ node : DOM.oils_rpt_tform_table,
+ datatype : field.datatype,
+ non_aggregate : true,
+ aggregate : true
+ }
+ );
+
DOM.oils_rpt_tform_submit.onclick =
function(){
- var sel = $n(DOM.oils_rpt_tform_table,'selector');
- var tform = getSelectorVal(sel);
- oilsAddRptDisplayItem(path, DOM.oils_rpt_tform_label_input.value, tform )
+ oilsAddRptDisplayItem(path,
+ DOM.oils_rpt_tform_label_input.value, tformPicker.getSelected() );
};
oilsRptCurrentTform.build(dtype, true, true);
*/
+ /*
_debug($n(DOM.oils_rpt_tform_table,'selector'));
oilsRptShowFilters($n(DOM.oils_rpt_tform_table,'selector'), dtype, true, true);
+ */
/*
oilsRptHideTformFields();
*/
/* hides all of the filter widgets */
+/*
function oilsRptHideFilterWidgets(node) {
if(!node)
node = DOM.oils_rpt_filter_tform_widget_td;
oilsRptHideFilterWidgets(cs[i]);
}
}
-
-/* what does this need to do? */
-function oilsRptSetFilterOpActions() {
-}
-
+*/
/* hides/unhides the appropriate widgets and returns the parameter
array appropriate for the selected widget */
+/*
function oilsRptDoFilterWidgets() {
filter = getSelectorVal(DOM.oils_rpt_filter_tform_selector);
oilsRptHideFilterWidgets();
switch(filter) {
- /* generic transforms */
case 'equals':
if(!op) op = 'equals';
case 'like':
params = [DOM.oils_rpt_filter_tform_input.value];
break;
- /* timestamp transforms */
case 'date_between':
if(!op) op = 'between';
case 'date_not_between':
if(!tform) tform = 'age';
break;
- /* string transforms */
case 'substring':
if(!tform) tform = 'substring';
break;
if(!op) op = '';
if(!tform) tform = 'dow';
- /* numeric transforms */
case 'round':
if(!op) op = '';
if(!tform) tform = 'dow';
return { op : op, params : params, tform : tform };
}
+ */
<input size='28' id='oils_rpt_tform_label_input'/>
<div class='oils_rpt_field_editor_window'>
<div style='margin-bottom: 10px;'>Select how this field should be displayed:</div>
- <!--#set var="OILS_RPT_TFORM_TABLE_ID" value="oils_rpt_tform_table"-->
- <!--#include virtual="oils_rpt_tforms.xhtml"-->
+ <div id='oils_rpt_tform_table'/>
</div>
<br/><br/>
<button id='oils_rpt_tform_submit'>Add Item</button>
<table><tbody><tr>
<td>Choose a Transform: </td>
<td>
- <!--#set var="OILS_RPT_TFORM_TABLE_ID" value="oils_rpt_filter_tform_table"-->
- <!--#include virtual="oils_rpt_tforms.xhtml"-->
+ <div id='oils_rpt_filter_tform_table'/>
</td>
</tr>
<tr>
<script type="text/javascript" src="oils_rpt_folder_window.js"></script>
<script type="text/javascript" src="oils_rpt_widget.js"></script>
<script type="text/javascript" src="oils_rpt_param_editor.js"></script>
+<script type="text/javascript" src="oils_rpt_tforms.js"></script>
<script type="text/javascript" src="oils_rpt.js"></script>
<script type="text/javascript" src="oils_rpt_report_editor.js"></script>
break;
case 'delete_output':
for( var i = 0; i < objs.length; i++ ) {
- if( objs[i].runner() != USER.id() )
+ if( objs[i].runner().id() != USER.id() )
return alertId('oils_rpt_folder_contents_no_delete');
}
this.deleteOutputs(objs,0,
oilsRptFolderWindow.prototype.deleteReport = function(report) {
- if( report.owner() != USER.id() )
+ if( report.owner().id() != USER.id() )
return alertId('oils_rpt_folder_contents_no_delete');
if(!confirmId('oils_rpt_folder_contents_confirm_report_delete')) return;
var req = new Request(OILS_RPT_DELETE_REPORT, SESSION, report.id());
}
oilsRptFolderWindow.prototype.deleteTemplate = function(tmpl) {
- if( tmpl.owner() != USER.id() )
+ if( tmpl.owner().id() != USER.id() )
return alertId('oils_rpt_folder_contents_no_delete');
var req0 = new Request( OILS_RPT_TEMPLATE_HAS_RPTS, SESSION, tmpl.id() );
req0.callback(
<option value='not in'>Not in (comma separated list)</option>
<option value='between'>Between</option>
<option value='not between'>Not between</option>
+ <option value='is'>Is NULL</option>
+ <option value='is not'>Is not NULL</option>
</select>
</td>
- <td class='hide_me' name='widget_td'> <!-- DEPRECATED -->
- <!-- Define all of the helpful user data widgets here -->
-
- <input widget='1' id='oils_rpt_filter_tform_input' size='12' type='text'/>
-
- <input widget='1' id='oils_rpt_filter_tform_date_1' size='10' maxlength='10' type='text'/>
- <input widget='1' id='oils_rpt_filter_tform_date_2' size='10' maxlength='10' type='text'/>
- <span widget='1' id='oils_rpt_filter_tform_date_hint'>(YYYY-MM-DD)</span>
-
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_day_selector'>
- <!--#include virtual="oils_rpt_day_opts.xhtml"-->
- </select>
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_dom_selector'>
- <!--#include virtual="oils_rpt_dom_opts.xhtml"-->
- </select>
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_month_selector'>
- <!--#include virtual="oils_rpt_month_opts.xhtml"-->
- </select>
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_quarter_selector'>
- <!--#include virtual="oils_rpt_quarter_opts.xhtml"-->
- </select>
-
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_day_selector_2'>
- <!--#include virtual="oils_rpt_day_opts.xhtml"-->
- </select>
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_dom_selector_2'>
- <!--#include virtual="oils_rpt_dom_opts.xhtml"-->
- </select>
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_month_selector_2'>
- <!--#include virtual="oils_rpt_month_opts.xhtml"-->
- </select>
-
- <select widget='1' id='oils_rpt_filter_tform_timestamp_quarter_selector_2'>
- <!--#include virtual="oils_rpt_quarter_opts.xhtml"-->
- </select>
-
- <input widget='1' id='oils_rpt_filter_tform_input_2' size='10' type='text'/>
-
- </td>
</tr>
</tbody>
</table>
$n(row, 'action').appendChild(text(par.op));
par.widget = this.buildWidget(par, $n(row, 'widget'));
par.widget.draw();
+ this.buildRelWidget(par, row);
this.tbody.appendChild(row);
}
}
+/* display the time-relative options if necessary */
+oilsRptParamEditor.prototype.buildRelWidget = function(par, row) {
+ var field = oilsRptFindField(
+ oilsIDL[oilsRptPathClass(par.path)], oilsRptPathCol(par.path));
+ _debug('checking rel widget for datatype '+field.datatype);
+ if( field.datatype != 'timestamp' ) return;
+
+ var dom = $n(row,'reldate_div');
+ unHideMe(dom);
+ par.relWidget = new oilsRptRelDatePicker({node:$n(dom,'reldate'),relative:true});
+ par.relWidget.draw();
+ var cb = $n(row,'choose_rel');
+ cb.onclick = function() {
+ par.relWidgetChecked = false;
+ if( cb.checked ) par.relWidgetChecked = true;
+ }
+}
+
+
oilsRptParamEditor.prototype.buildWidget = function(param, node) {
- //var cls = param.relation.split(/-/).pop();
var path = param.path.split(/-/);
path.pop();
var cls = path.pop();
+
+ var field = oilsRptFindField(
+ oilsIDL[oilsRptPathClass(par.path)], oilsRptPathCol(par.path));
+ var dtype = field.datatype;
+ var transform = param.column.transform;
+
_debug("building widget with param class:" + cls + ' col: '+param.column.colname + ' op: '+ param.op);
+
+ switch(transform) {
+
+ }
+
+
switch(param.op) {
case 'in':
case 'not in':
- /* we have to special case org selection for now,
- until we have generic object fetch support */
+ /* special case the org tree selector */
if( cls == 'aou' ) {
return new oilsRptOrgMultiSelect({node:node});
} else {
return new oilsRptMultiInputWidget({node:node});
default:
- return new oilsRptWidget({node:node});
+ switch(dtype) {
+ case 'timestamp':
+ return new oilsRptRelDatePicker({node:node});
+ default:
+ return new oilsRptWidget({node:node});
+ }
}
}
<th>Recurance Interval</th>
<td>
<select name="oils_rpt_recur_count">
- <option>1</option>
- <option>2</option>
- <option>3</option>
- <option>4</option>
- <option>5</option>
- <option>6</option>
- <option>7</option>
- <option>8</option>
- <option>9</option>
- <option>10</option>
- <option>11</option>
- <option>12</option>
- <option>13</option>
- <option>14</option>
- <option>15</option>
- <option>16</option>
- <option>17</option>
- <option>18</option>
- <option>19</option>
- <option>20</option>
- <option>21</option>
- <option>22</option>
- <option>23</option>
- <option>24</option>
+ <option value='1'>1</option>
+ <option value='2'>2</option>
+ <option value='3'>3</option>
+ <option value='4'>4</option>
+ <option value='5'>5</option>
+ <option value='6'>6</option>
+ <option value='7'>7</option>
+ <option value='8'>8</option>
+ <option value='9'>9</option>
+ <option value='10'>10</option>
+ <option value='11'>11</option>
+ <option value='12'>12</option>
+ <option value='13'>13</option>
+ <option value='14'>14</option>
+ <option value='15'>15</option>
+ <option value='16'>16</option>
+ <option value='17'>17</option>
+ <option value='18'>18</option>
+ <option value='19'>19</option>
+ <option value='20'>20</option>
+ <option value='21'>21</option>
+ <option value='22'>22</option>
+ <option value='23'>23</option>
+ <option value='24'>24</option>
</select>
<select name="oils_rpt_recur_interval_type">
<!--
<td name='column'/>
<td name='transform'/>
<td name='action'/>
- <td name='widget'/>
+ <td>
+ <div name='widget'/>
+ <div name='reldate_div' style='margin-top: 5px;' class='hide_me'>
+ <div><b> - OR - </b></div>
+ <input type='checkbox' name='choose_rel'/> Use a relative date instead.
+ <div name='reldate'/>
+ </div>
+ </td>
</tr>
</tbody>
</table>
+
+ <div class='hide_me' id='oils_rpt_relative_date_picker'>
+ <table>
+ <tbody>
+ <tr>
+ <td>
+ <select name="count">
+ <option value='1'>1</option>
+ <option value='2'>2</option>
+ <option value='3'>3</option>
+ <option value='4'>4</option>
+ <option value='5'>5</option>
+ <option value='6'>6</option>
+ <option value='7'>7</option>
+ <option value='8'>8</option>
+ <option value='9'>9</option>
+ <option value='10'>10</option>
+ <option value='11'>11</option>
+ <option value='12'>12</option>
+ <option value='13'>13</option>
+ <option value='14'>14</option>
+ <option value='15'>15</option>
+ <option value='16'>16</option>
+ <option value='17'>17</option>
+ <option value='18'>18</option>
+ <option value='19'>19</option>
+ <option value='20'>20</option>
+ <option value='21'>21</option>
+ <option value='22'>22</option>
+ <option value='23'>23</option>
+ <option value='24'>24</option>
+ </select>
+ <select name="type">
+ <option value="days">Day(s)</option>
+ <option value="weeks">Week(s)</option>
+ <option value="months">Month(s)</option>
+ </select>
+ <span> ago</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
</div>
for( var p in this.paramEditor.params ) {
var par = this.paramEditor.params[p];
_debug("adding report param "+par.key+" to report data");
- data[par.key] = par.widget.getValue();
+ if( par.relWidgetChecked )
+ data[par.key] = par.relWidget.getValue();
+ else
+ data[par.key] = par.widget.getValue();
}
data = js2JSON(data);
--- /dev/null
+/*
+var OILS_RPT_DTYPE_STRING = 'string';
+var OILS_RPT_DTYPE_NUMERIC = 'numeric';
+var OILS_RPT_DTYPE_FLOAT = 'float';
+var OILS_RPT_DTYPE_TIMESTAMP = 'timestamp';
+*/
+
+var OILS_RPT_TRANSFORMS = {
+ Bare : {
+ label : 'Raw Data'
+ },
+
+ first : {
+ label : 'First Value'
+ },
+
+ last : {
+ label : 'Last Value'
+ },
+
+ count : {
+ aggregate : true,
+ label : 'Count'
+ },
+
+ count_distinct : {
+ aggregate : true,
+ label : 'Count Distinct'
+ },
+
+ min : {
+ aggregate : true,
+ label : 'Min'
+ },
+
+ max : {
+ aggregate : true,
+ label : 'Max'
+ },
+
+ /* string transforms ------------------------- */
+
+ substring : {
+ datatype : OILS_RPT_DTYPE_STRING,
+ label : 'Substring'
+ },
+
+ lower : {
+ datatype : OILS_RPT_DTYPE_STRING,
+ label : 'Lower case'
+ },
+
+ upper : {
+ datatype : OILS_RPT_DTYPE_STRING,
+ label : 'Upper case'
+ },
+
+ /* timestamp transforms ----------------------- */
+ dow : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Day of Week',
+ regex : /^[0-6]$/
+ },
+ dom : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Day of Month',
+ regex : /^[0-9]{1,2}$/
+ },
+
+ doy : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Day of Year',
+ regex : /^[0-9]{1,3}$/
+ },
+
+ woy : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Week of Year',
+ regex : /^[0-9]{1,2}$/
+ },
+
+ moy : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Month of Year',
+ regex : /^[0-9]{1,2}$/
+ },
+
+ qoy : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Quarter of Year',
+ regex : /^[1234]$/
+ },
+
+ date : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Date',
+ regex : /^\d{4}-\d{2}-\d{2}$/,
+ hint : 'YYYY-MM-DD',
+ cal_format : '%Y-%m-%d'
+ },
+
+ month_trunc : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Year + Month',
+ regex : /^\d{4}-\d{2}$/,
+ hint : 'YYYY-MM',
+ cal_format : '%Y-%m'
+ },
+
+ year_trunc : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Year',
+ regex : /^\d{4}$/,
+ hint : 'YYYY',
+ cal_format : '%Y'
+ },
+
+ day_name : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Day Name'
+ },
+
+ month_name : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Month Name'
+ },
+ age : {
+ datatype : OILS_RPT_DTYPE_TIMESTAMP,
+ label : 'Age'
+ },
+
+
+ /* int / float transforms ----------------------------------- */
+ sum : {
+ datatype : [ OILS_RPT_DTYPE_INT, OILS_RPT_DTYPE_FLOAT ],
+ label : 'Sum',
+ aggregate : true
+ },
+
+ average : {
+ datatype : [ OILS_RPT_DTYPE_INT, OILS_RPT_DTYPE_FLOAT ],
+ label : 'Average',
+ aggregate : true
+ },
+
+ round : {
+ datatype : [ OILS_RPT_DTYPE_INT, OILS_RPT_DTYPE_FLOAT ],
+ label : 'Round',
+ },
+
+ 'int' : {
+ datatype : OILS_RPT_DTYPE_FLOAT,
+ label : 'Drop trailing decimals'
+ }
+}
+
+
+function oilsRptGetTforms(args) {
+ var dtype = args.datatype;
+ var agg = args.aggregate;
+ var tforms = OILS_RPT_TRANSFORMS;
+ var nonagg = args.non_aggregate;
+
+ var keys = oilsRptObjectKeys(OILS_RPT_TRANSFORMS);
+ var tforms = [];
+
+ _debug('getting tform '+dtype+' : ' + agg + ' : ' + nonagg);
+
+ for( var i = 0; i < keys.length; i++ ) {
+ var key = keys[i];
+ var obj = OILS_RPT_TRANSFORMS[key];
+ if( dtype && !oilsRptTformIsDtype(key,dtype) ) continue;
+ if( agg && !nonagg && !obj.aggregate ) continue;
+ if( !agg && nonagg && obj.aggregate ) continue;
+ tforms.push(key);
+ }
+
+ return tforms;
+}
+
+
+function oilsRptTformIsDtype(tform, dtype) {
+ var obj = OILS_RPT_TRANSFORMS[tform];
+ if( typeof obj.datatype == 'string' )
+ return (obj.datatype == dtype);
+ return !obj.datatype || grep(obj.datatype, function(d) { return (d == dtype) });
+}
+
+
+
+
+/* builds a new transform picker */
+function oilsRptTformPicker(args) {
+ this.node = args.node;
+ this.selector = elem('select');
+ this.tforms = oilsRptGetTforms(args);
+ for( var i = 0; i < this.tforms.length; i++ )
+ this.addOpt(this.tforms[i]);
+ appendClear(this.node, this.selector);
+}
+
+oilsRptTformPicker.prototype.addOpt = function(key) {
+ _debug("drawing tform opt with key " + key);
+ var tform = OILS_RPT_TRANSFORMS[key];
+ var obj = this;
+ insertSelectorVal(
+ this.selector, -1, tform.label, key,
+ function() {
+ obj.setSelected(getSelectorVal(obj.selector));
+ _debug("setting selected to " + obj.getSelected());
+ }
+ );
+}
+
+oilsRptTformPicker.prototype.setSelected = function(key) {
+ this.selected = key;
+}
+oilsRptTformPicker.prototype.getSelected = function(key) {
+ return this.selected;
+}
+
+
+
<option value='year_trunc' datatype='timestamp'>Year</option>
<option value='day_name' datatype='timestamp'>Day Name</option>
<option value='month_name' datatype='timestamp'>Month Name</option>
+ <option value='age' datatype='timestamp'>Age</option>
<!-- int transforms -->
<option value='count' datatype='int' aggregate='1'>Count</option>
//var oilsRptFolderWindowCache = {};
var oilsRptObjectCache = {};
+
+var OILS_RPT_DTYPE_STRING = 'string';
+var OILS_RPT_DTYPE_INT = 'int';
+var OILS_RPT_DTYPE_FLOAT = 'float';
+var OILS_RPT_DTYPE_TIMESTAMP = 'timestamp';
}
oilsRptWidget.prototype.getValue = function() {
- return this.dest.value;
+ return this.dest.value ;
}
oilsRptWidget.prototype.draw = function() {
/* ----------------------------------------------------------- */
-/* multiple input boxes */
+/* multiple input boxes, no separate source, optional box labels */
oilsRptSetSubClass('oilsRptMultiInputWidget', 'oilsRptWidget');
function oilsRptMultiInputWidget(args) {
this.initInputWidget(args);
/* ----------------------------------------------------------- */
+/* abstract class, multi-select output (dest),
+ add and delete buttons, you provide intput */
oilsRptSetSubClass('oilsRptMultiWidget', 'oilsRptWidget');
function oilsRptMultiWidget(args) {
this.initMultiWidget(args);
/* ----------------------------------------------------------- */
+/* single text box as source, multiwidget output (select) as dest */
oilsRptSetSubClass('oilsRptInputMultiWidget', 'oilsRptMultiWidget');
function oilsRptInputMultiWidget(args) {
this.initInputMultiWidget(args);
/* ----------------------------------------------------------- */
+/* multi-select source */
oilsRptSetSubClass('oilsRptSelectorMultiWidget', 'oilsRptMultiWidget');
function oilsRptSelectorMultiWidget(args) {
this.initSelectorMultiWidget(args);
/* ----------------------------------------------------------- */
+/* in process */
oilsRptSetSubClass('oilsRptRemoteWidget', 'oilsRptSelectorMultiWidget');
function oilsRptRemoteWidget(args) {
this.initRemoteWidget(args);
/* --------------------------------------------------------------------- */
-/* standalone org widget */
+/* custom my-orgs picker */
function oilsRptMyOrgsWidget(node, orgid) {
this.node = node;
this.orgid = orgid;
/* --------------------------------------------------------------------- */
+/* custom all-orgs picker */
oilsRptSetSubClass('oilsRptOrgMultiSelect','oilsRptSelectorMultiWidget');
function oilsRptOrgMultiSelect(args) {
this.initSelectorMultiWidget(args);
}
-
oilsRptOrgMultiSelect.prototype.draw = function(org) {
if(!org) org = globalOrgTree;
var opt = insertSelectorVal( this.source, -1,
}
+/* --------------------------------------------------------------------- */
+function oilsRptRelDatePicker(args) {
+ this.node = args.node;
+ this.relative = args.relative;
+ this.div = DOM.oils_rpt_relative_date_picker.cloneNode(true);
+}
+
+oilsRptRelDatePicker.prototype.draw = function() {
+ this.node.appendChild(this.div);
+ unHideMe(this.div);
+}
+
+oilsRptRelDatePicker.prototype.getValue = function() {
+ var str =
+ getSelectorVal($n(this.div, 'count')) +
+ getSelectorVal($n(this.div,'type'));
+ if( this.relative ) str = '-'+str;
+ return str;
+}
+/* --------------------------------------------------------------------- */