[Rt-commit] rt branch, lcore, updated. 16a214eaff54dce4af902225a2113fac0b2e797a
clkao at bestpractical.com
clkao at bestpractical.com
Thu Sep 10 01:41:52 EDT 2009
The branch, lcore has been updated
via 16a214eaff54dce4af902225a2113fac0b2e797a (commit)
via dbe2977a1bfd1a44929e9230e1de7bcd6a32d4c4 (commit)
via 5309d67747ae752c0da1084bf8d0f6140b770d21 (commit)
via cdb68f8027a42ced31462d4494686dddc07c645a (commit)
via 69c59a9a7162108aa9c5be74f853f1533e67ce9f (commit)
from 15860210fb79387908c4dd82a92d3893c4e6a927 (commit)
Summary of changes:
lib/RT/Lorzy.pm | 19 ++--
lib/RT/View/RuleBuilder.pm | 11 ++-
share/web/static/css/rulebuilder.css | 57 +++++++---
share/web/static/js/rulebuilder.js | 201 ++++++++++++++++++++++++++++------
4 files changed, 231 insertions(+), 57 deletions(-)
- Log -----------------------------------------------------------------
commit 69c59a9a7162108aa9c5be74f853f1533e67ce9f
Author: Chia-liang Kao <clkao at bestpractical.com>
Date: Thu Sep 10 12:08:16 2009 +0900
rulebuilder context object.
diff --git a/share/web/static/css/rulebuilder.css b/share/web/static/css/rulebuilder.css
index bf945e7..d7c8534 100644
--- a/share/web/static/css/rulebuilder.css
+++ b/share/web/static/css/rulebuilder.css
@@ -1,34 +1,43 @@
div.application-params span.param-placeholder,
div.function span.return-type,
-div.expression span.type {
+div.context span.return-type,
+div.expression span.return-type {
color:#555555;
font-style:italic;
}
-div.application-params span.param-placeholder,
-div.function span.return-type {
- background-color:lightBlue;
- border:2px solid blue;
-
-}
.signature .parameter {
- border: 1px solid red;
+ border: 1px solid red;
}
.expression .type {
- background-color: lightGreen;
- border: 2px solid green;
+ background-color: lightGreen;
+ border: 2px solid green;
}
.signature .parameter {
- background-color: lightGreen;
- border: 2px solid green;
+ background-color: lightBlue;
+ border: 2px solid blue;
+}
+
+div.top-context {
+ position: relative;
+ left: 20em;
+}
+
+div.context {
+ border: 1px dashed;
+ min-height: 1.5em;
+}
+
+div.current {
+ border: 1px dotted red;
}
div.application-params span.param-placeholder,
div.function span.return-type,
.signature .parameter,
-.expression .type {
+.expression .return-type {
font-size: 0.8em;
display: inline-block;
text-align: left;
@@ -51,7 +60,7 @@ div#body {
#expressionbuilder {
}
-.application {
+.application-old {
position: relative;
top: -7em;
left: 20em;
@@ -72,8 +81,8 @@ div#body {
div.application-params span.param {
padding:0.5em;
- background: lightGreen;
- border 1px solid green;
+ background: lightBlue;
+ border 1px solid blue;
}
@@ -87,6 +96,20 @@ div.application-params span.param-placeholder.current {
background: #f99;
}
+.return-type.unmatched {
+ background: #f99;
+ border: 1px solid red;
+}
+
+.return-type.matched {
+ background: lightGreen;
+ border: 1px solid green;
+}
+
.signature {
padding-left: 2em;
}
+
+div.context span.expression {
+ padding-left: 1em;
+}
\ No newline at end of file
diff --git a/share/web/static/js/rulebuilder.js b/share/web/static/js/rulebuilder.js
index f9f7102..0bf28e3 100644
--- a/share/web/static/js/rulebuilder.js
+++ b/share/web/static/js/rulebuilder.js
@@ -11,7 +11,7 @@ RuleBuilder = function (sel) {
that.functions = response;
that.init();
},
- 'json'); // handle errors.
+ 'json'); // XXX: handle errors.
};
RuleBuilder.expressions = [
@@ -28,17 +28,17 @@ RuleBuilder.prototype.init = function () {
var ebuilder = jQuery(sel);
var that = this;
- jQuery._div({'class': 'application'})
- ._h3_().text("New Expression")
- ._div_({'class': 'application-function function'})
- ._div_({'class': 'application-params signature'})
- .div_()
+ this.ebuilder = ebuilder;
+
+ jQuery._div_({'class': 'context top-context'})
.appendTo(ebuilder);
- jQuery("#add-expression")
- .appendTo(jQuery(".application"));
-
-
+ this.top_context = new RuleBuilder.Context(
+ 'Bool',
+ jQuery(".top-context").get(0),
+ null,
+ this
+ );
this.update_expressions();
ebuilder.append('<div class="functions">');
@@ -53,8 +53,9 @@ RuleBuilder.prototype.init = function () {
jQuery(this.sel+' div.function').click(
function(e) {
var func_name = jQuery('span.function-name', this).text();
- that.current_application = func_name;
- that.update_application();
+ that.push_application(func_name);
+// that.current_application = func_name;
+// that.update_application();
});
// jQuery(this.sel+' div.application').hide();
function render_signature(sig) {
@@ -74,6 +75,37 @@ RuleBuilder.prototype.init = function () {
});
return content;
}
+
+ this.focus(this.top_context);
+};
+
+RuleBuilder.prototype.push_application = function(func_name) {
+ this.current_ctx.set_application(func_name, this.functions[func_name]);
+};
+
+
+RuleBuilder.prototype.push_expression = function(expression) {
+ this.current_ctx.set_expression(expression);
+};
+
+RuleBuilder.prototype.focus = function(ctx) {
+ if( this.current_ctx )
+ jQuery(this.current_ctx.element).removeClass('current');
+
+ this.current_ctx = ctx;
+ jQuery(this.current_ctx.element).addClass('current');
+ var type = this.current_ctx.expected_type;
+ jQuery('.functions .return-type', this.ebuilder).removeClass('matched')
+ .addClass('unmatched');
+
+ jQuery('.expressions .return-type', this.ebuilder).removeClass('matched')
+ .addClass('unmatched');
+
+ jQuery('.functions .return-type:contains('+type+')', this.ebuilder)
+ .addClass('matched');
+
+ jQuery('.expressions .return-type:contains('+type+')', this.ebuilder)
+ .addClass('matched');
};
RuleBuilder.prototype.update_expressions = function() {
@@ -93,24 +125,15 @@ RuleBuilder.prototype.update_expressions = function() {
jQuery.each(this.expressions,
function(idx, val) {
jQuery._div({'class': 'expression ret_'+val.type})
- ._span_({ 'class': 'type' }).text(val.type)
+ ._span_({ 'class': 'return-type' }).text(val.type)
._span_({ 'class': 'expression-text' }).text(val.expression)
.div_().click(function(e) {
- if (that.current_application_param != null) {
- if (val.type !=
- that.functions[that.current_application].parameters[that.current_application_param].type) {
- alert("type mismatch: "+val.type+" vs "+that.functions[that.current_application].parameters[that.current_application_param].type);
- return;
- }
- jQuery(that.sel+ ' .param:eq('+parseInt(idx)+')').removeClass('param-placeholder').text(val.expression);
- }
- else {
- alert("must select param first");
- }
+ that.push_expression(val);
})
.appendTo(expressions_div);
});
+
var options = {
onClick: function(e,item) { x=e;y=item },
minWidth: 120,
@@ -123,14 +146,14 @@ RuleBuilder.prototype.update_expressions = function() {
{src: 'test2', subMenu: [ {src: 'sub 1'},
{src: 'sub 2' },
{src: 'sub 3'}]}];
- jQuery('.ret_'+e_sel('RT::Model::Ticket')).menu(options, items);
+// jQuery('.ret_'+e_sel('RT::Model::Ticket')).menu(options, items);
};
RuleBuilder.prototype.update_application = function () {
/* might be an expression too */
jQuery(this.sel+' div.application-function').html(this.current_application);
- jQuery(this.sel+' div.application').show();
+ jQuery(this.sel+' div.application-old').show();
jQuery(this.sel+' div.application-params').html('');
var params = jQuery(this.sel+' div.application-params');
var that = this;
@@ -182,3 +205,85 @@ RuleBuilder.prototype.filter_expression_type = function (type) {
jQuery(this.sel+' .expression:not(.ret_'+e_sel(type)+')').hide();
};
+
+RuleBuilder.Context = function(expected_type, element, parent, rb) {
+ this.expected_type = expected_type;
+ this.element = element;
+ this.parent = parent;
+ this.rb = rb;
+
+ var that = this;
+ jQuery(this.element).click(function(e) { rb.focus(that); return false });
+ jQuery._span_({ 'class': 'return-type'})
+ .text(expected_type)
+ .appendTo(this.element);
+};
+
+RuleBuilder.Context.prototype.update_return_type = function(type) {
+ if (this.expected_type == type) {
+ jQuery("span.return-type", this.element).removeClass("unmatched").addClass("matched");
+ }
+ else {
+ jQuery("span.return-type", this.element).removeClass("matched").addClass("unmatched");
+ }
+}
+
+RuleBuilder.Context.prototype.clear = function() {
+ jQuery('div.application', this.element).remove();
+ jQuery('span.expression', this.element).remove();
+}
+
+RuleBuilder.Context.prototype.set_expression = function(expression) {
+ this.clear();
+ this.expression = expression.expression;
+ this.update_return_type(expression.type);
+
+ jQuery._span_({ 'class': 'expression'})
+ .text(this.expression)
+ .appendTo(this.element);
+}
+
+
+
+RuleBuilder.Context.prototype.set_application = function(func_name, func) {
+ this.clear();
+ this.func = func;
+ this.children = [];
+ this.update_return_type(func.return_type);
+ jQuery._div({'class': 'application'})
+ ._div_({'class': 'application-function function'})
+ ._div_({'class': 'application-params signature'})
+ .div_()
+ .appendTo(this.element);
+
+// jQuery(this.sel+' div.application-function').html(this.current_application);
+ jQuery('div.application-function',this.element).html(func_name);
+ jQuery('div.application', this.element).show();
+ jQuery('div.application-params', this.element).html('');
+ var params = jQuery('div.application-params', this.element);
+ var that = this;
+ jQuery.each(func.parameters,
+ function(idx, val) {
+ var x = jQuery._div_({'class': 'context'})
+ .appendTo(params);
+
+ var child = new RuleBuilder.Context(val.type, x, that, that.rb);
+ that.children.push(child);
+ });
+ if (this.children.length) {
+ this.rb.focus(this.children[0]);
+ }
+};
+
+RuleBuilder.Context.prototype.init = function() {
+
+};
+
+jQuery.fn.sort = function() {
+ return this.pushStack( [].sort.apply( this, arguments ), []);
+};
+
+function sortAlpha(a,b){
+ return a.innerHTML > b.innerHTML ? 1 : -1;
+};
+
commit cdb68f8027a42ced31462d4494686dddc07c645a
Author: Chia-liang Kao <clkao at bestpractical.com>
Date: Thu Sep 10 12:31:03 2009 +0900
basic accessor menu.
diff --git a/lib/RT/View/RuleBuilder.pm b/lib/RT/View/RuleBuilder.pm
index 98ae5d8..8ad827c 100644
--- a/lib/RT/View/RuleBuilder.pm
+++ b/lib/RT/View/RuleBuilder.pm
@@ -25,6 +25,16 @@ template 'allfunctions.json' => sub {
print to_json($data);
};
+template 'getfunctions.json' => sub {
+ Jifty->handler->apache->header_out('Content-Type' => 'application/json; charset=UTF-8' );
+ Jifty->handler->send_http_header;
+
+ my $functions = $RT::Lorzy::LCORE->env->find_functions_by_type(get('parameters'), get('return_type'));
+
+ my $data = { map { $_ => _function_as_hash($functions->{$_}) } keys %$functions };
+ print to_json($data);
+};
+
template 'index.html' => page {
title => "rule",
} content {
@@ -44,7 +54,6 @@ jQuery(function() {
var rb = new RuleBuilder("#expressionbuilder");
jQuery("#type-filter").click(function(e) { rb.filter_return_type(jQuery("#type-filter-type").val())});
jQuery("#type-unfilter").click(function(e) { rb.unfilter_return_type()});
- jQuery("#add-expression").click(function(e) { rb.add_expression()});
});
</script>
');
diff --git a/share/web/static/js/rulebuilder.js b/share/web/static/js/rulebuilder.js
index 0bf28e3..14a64ad 100644
--- a/share/web/static/js/rulebuilder.js
+++ b/share/web/static/js/rulebuilder.js
@@ -141,12 +141,18 @@ RuleBuilder.prototype.update_expressions = function() {
hoverOpenDelay: 500,
hideDelay: 500 };
- var items = [ {src: 'test' },
- {src: ''}, /* separator */
- {src: 'test2', subMenu: [ {src: 'sub 1'},
- {src: 'sub 2' },
- {src: 'sub 3'}]}];
-// jQuery('.ret_'+e_sel('RT::Model::Ticket')).menu(options, items);
+ jQuery.get('/rulebuilder/getfunctions.json',
+ { parameters: ['RT::Model::Ticket'] },
+ function(response, status) {
+ var entries = [];
+ for (var name in response) {
+ if (/^RT::Model::Ticket\./.match(name))
+ entries.push(name);
+ }
+ var x = jQuery.map(entries, function(val) { return {src: val}});
+ jQuery('.ret_'+e_sel('RT::Model::Ticket')).menu(options, x);
+ },
+ 'json');
};
commit 5309d67747ae752c0da1084bf8d0f6140b770d21
Author: Chia-liang Kao <clkao at bestpractical.com>
Date: Thu Sep 10 14:10:02 2009 +0900
make attribute menu actually work.
diff --git a/share/web/static/css/rulebuilder.css b/share/web/static/css/rulebuilder.css
index d7c8534..253ae2e 100644
--- a/share/web/static/css/rulebuilder.css
+++ b/share/web/static/css/rulebuilder.css
@@ -1,7 +1,8 @@
div.application-params span.param-placeholder,
div.function span.return-type,
div.context span.return-type,
-div.expression span.return-type {
+div.expression span.return-type,
+div.menu-item span.return-type {
color:#555555;
font-style:italic;
}
diff --git a/share/web/static/js/rulebuilder.js b/share/web/static/js/rulebuilder.js
index 14a64ad..d5a1d03 100644
--- a/share/web/static/js/rulebuilder.js
+++ b/share/web/static/js/rulebuilder.js
@@ -135,7 +135,12 @@ RuleBuilder.prototype.update_expressions = function() {
var options = {
- onClick: function(e,item) { x=e;y=item },
+ onClick: function(e,item) {
+ that.push_expression({ expression: "("+item.data.func+" "+item.data.expression+")",
+ type: item.data.type });
+ jQuery.Menu.closeAll();
+ return false;
+ },
minWidth: 120,
arrowSrc: '/images/arrow_right.gif',
hoverOpenDelay: 500,
@@ -149,8 +154,20 @@ RuleBuilder.prototype.update_expressions = function() {
if (/^RT::Model::Ticket\./.match(name))
entries.push(name);
}
- var x = jQuery.map(entries, function(val) { return {src: val}});
- jQuery('.ret_'+e_sel('RT::Model::Ticket')).menu(options, x);
+ jQuery('.ret_'+e_sel('RT::Model::Ticket'), that.ebuilder)
+ .each(function() {
+ var expression = jQuery('span.expression-text',this).text();
+ jQuery._span_().text('...')
+ .appendTo(this)
+ .menu(options,
+ jQuery.map(entries,
+ function(val) {
+ var attribute = val.replace(/^RT::Model::Ticket\./, '');
+ var type = that.functions[val].return_type;
+ attribute += ' <span class="return-type">'+type+'</span>';
+ return {src: attribute, data: { type: type, expression: expression, func: val } }}
+ ));
+ });
},
'json');
};
commit dbe2977a1bfd1a44929e9230e1de7bcd6a32d4c4
Author: Chia-liang Kao <clkao at bestpractical.com>
Date: Thu Sep 10 14:17:26 2009 +0900
refactor attribute menu heper to build_accessor_menu
diff --git a/share/web/static/js/rulebuilder.js b/share/web/static/js/rulebuilder.js
index d5a1d03..1bd1413 100644
--- a/share/web/static/js/rulebuilder.js
+++ b/share/web/static/js/rulebuilder.js
@@ -133,6 +133,11 @@ RuleBuilder.prototype.update_expressions = function() {
.appendTo(expressions_div);
});
+ this.build_accessor_menu('RT::Model::Ticket');
+}
+
+RuleBuilder.prototype.build_accessor_menu = function(model) {
+ var that = this;
var options = {
onClick: function(e,item) {
@@ -146,15 +151,17 @@ RuleBuilder.prototype.update_expressions = function() {
hoverOpenDelay: 500,
hideDelay: 500 };
+ var re = new RegExp('^'+model+'\.');
+
jQuery.get('/rulebuilder/getfunctions.json',
- { parameters: ['RT::Model::Ticket'] },
+ { parameters: [model] },
function(response, status) {
var entries = [];
for (var name in response) {
- if (/^RT::Model::Ticket\./.match(name))
+ if (re.match(name))
entries.push(name);
}
- jQuery('.ret_'+e_sel('RT::Model::Ticket'), that.ebuilder)
+ jQuery('.ret_'+e_sel(model), that.ebuilder)
.each(function() {
var expression = jQuery('span.expression-text',this).text();
jQuery._span_().text('...')
@@ -162,7 +169,7 @@ RuleBuilder.prototype.update_expressions = function() {
.menu(options,
jQuery.map(entries,
function(val) {
- var attribute = val.replace(/^RT::Model::Ticket\./, '');
+ var attribute = val.replace(re, '');
var type = that.functions[val].return_type;
attribute += ' <span class="return-type">'+type+'</span>';
return {src: attribute, data: { type: type, expression: expression, func: val } }}
commit 16a214eaff54dce4af902225a2113fac0b2e797a
Author: Chia-liang Kao <clkao at bestpractical.com>
Date: Thu Sep 10 14:41:27 2009 +0900
more model attributes.
diff --git a/lib/RT/Lorzy.pm b/lib/RT/Lorzy.pm
index 8c82c1e..4c4e02a 100644
--- a/lib/RT/Lorzy.pm
+++ b/lib/RT/Lorzy.pm
@@ -71,9 +71,11 @@ $LCORE->env->set_symbol('RT.RuleAction.Run' => LCore::Primitive->new
));
-sub install_ticket_accessors {
- my ($env) = @_;
- for my $column (RT::Model::Ticket->columns) {
+sub install_model_accessors {
+ my ($env, $model) = @_;
+ my $modelname = lc($model);
+ $modelname =~ s/.*://;
+ for my $column ($model->columns) {
my $name = $column->name;
my $type = $column->type;
$type = $type =~ m/^varchar/ ? 'Str'
@@ -85,19 +87,20 @@ sub install_ticket_accessors {
: $type eq 'serial' ? 'Int'
: next;
- $env->set_symbol('RT::Model::Ticket.'.$name => LCore::Primitive->new
+ $env->set_symbol($model.'.'.$name => LCore::Primitive->new
( body => sub {
- my ($ticket) = @_;
- $ticket->$name
+ my ($object) = @_;
+ $object->$name
},
lazy => 0,
- parameters => [ LCore::Parameter->new({ name => 'ticket', type => 'RT::Model::Ticket' }) ],
+ parameters => [ LCore::Parameter->new({ name => $modelname, type => $model }) ],
return_type => $type
));
}
}
-RT::Lorzy::install_ticket_accessors($RT::Lorzy::LCORE->env);
+install_model_accessors($RT::Lorzy::LCORE->env, $_)
+ for qw(RT::Model::Ticket RT::Model::Transaction RT::Model::Queue);
my %cond_compat_map = ( 'On Create' => 'OnCreate',
diff --git a/share/web/static/css/rulebuilder.css b/share/web/static/css/rulebuilder.css
index 253ae2e..34f6448 100644
--- a/share/web/static/css/rulebuilder.css
+++ b/share/web/static/css/rulebuilder.css
@@ -2,6 +2,7 @@ div.application-params span.param-placeholder,
div.function span.return-type,
div.context span.return-type,
div.expression span.return-type,
+div.parameter .type,
div.menu-item span.return-type {
color:#555555;
font-style:italic;
diff --git a/share/web/static/js/rulebuilder.js b/share/web/static/js/rulebuilder.js
index 1bd1413..74e8e58 100644
--- a/share/web/static/js/rulebuilder.js
+++ b/share/web/static/js/rulebuilder.js
@@ -134,6 +134,7 @@ RuleBuilder.prototype.update_expressions = function() {
});
this.build_accessor_menu('RT::Model::Ticket');
+ this.build_accessor_menu('RT::Model::Transaction');
}
RuleBuilder.prototype.build_accessor_menu = function(model) {
@@ -172,6 +173,7 @@ RuleBuilder.prototype.build_accessor_menu = function(model) {
var attribute = val.replace(re, '');
var type = that.functions[val].return_type;
attribute += ' <span class="return-type">'+type+'</span>';
+ // XXX: submenu here for known types
return {src: attribute, data: { type: type, expression: expression, func: val } }}
));
});
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list