Merge lp:~openerp-dev/openerp-web/trunk-widget-tooltip-mba into lp:openerp-web

Proposed by Richard Mathot (Odoo, formerly OpenERP)
Status: Work in progress
Proposed branch: lp:~openerp-dev/openerp-web/trunk-widget-tooltip-mba
Merge into: lp:openerp-web
Diff against target: 527 lines (+422/-8)
5 files modified
addons/web/static/src/css/base.css (+66/-0)
addons/web/static/src/css/base.sass (+59/-1)
addons/web/static/src/js/view_form.js (+145/-0)
addons/web/static/src/xml/base.xml (+35/-0)
addons/web_kanban/static/src/js/kanban.js (+117/-7)
To merge this branch: bzr merge lp:~openerp-dev/openerp-web/trunk-widget-tooltip-mba
Reviewer Review Type Date Requested Status
OpenERP R&D Web Team Pending
Review via email: mp+215669@code.launchpad.net
To post a comment you must log in.
3940. By Mahendra Barad(OpenERP)

[Remove]unwanted code

3941. By Mahendra Barad(OpenERP)

[Merge]with trunk

3942. By Mahendra Barad(OpenERP)

[Merge]with trunk

3943. By Mahendra Barad(OpenERP)

[IMP]remove unwanted css

3944. By Mahendra Barad(OpenERP)

[Merge]with trunk

3945. By Mahendra Barad(OpenERP)

[Merge]with trunk

Unmerged revisions

3945. By Mahendra Barad(OpenERP)

[Merge]with trunk

3944. By Mahendra Barad(OpenERP)

[Merge]with trunk

3943. By Mahendra Barad(OpenERP)

[IMP]remove unwanted css

3942. By Mahendra Barad(OpenERP)

[Merge]with trunk

3941. By Mahendra Barad(OpenERP)

[Merge]with trunk

3940. By Mahendra Barad(OpenERP)

[Remove]unwanted code

3939. By Mahendra Barad(OpenERP)

[IMP]css

3938. By Mahendra Barad(OpenERP)

[IMP]improve the left for priority widget

3937. By Mahendra Barad(OpenERP)

[Merge]with trunk

3936. By Mahendra Barad(OpenERP)

[Merge]with trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'addons/web/static/src/css/base.css'
2--- addons/web/static/src/css/base.css 2014-05-02 12:33:55 +0000
3+++ addons/web/static/src/css/base.css 2014-05-07 10:11:07 +0000
4@@ -3378,3 +3378,69 @@
5 background-color: black;
6 opacity: 0.6;
7 }
8+.openerp .dropdown-menu.state {
9+ background: white;
10+ background: white !important;
11+ min-width: 100%;
12+ padding-right: 10px !important;
13+}
14+.openerp .dropdown-menu.state li a, .openerp .dropdown-menu.state li a:hover, .openerp .dropdown-menu.state li a:focus {
15+ text-decoration: none;
16+ color: #333333;
17+ padding-left: 5px;
18+ padding-right: 0px;
19+ font-size: 13px;
20+}
21+.openerp .btn-group.state {
22+ padding-top: 8px;
23+}
24+.openerp .btn-group.state a {
25+ color: #333333;
26+}
27+.openerp .btn-group.state a:hover {
28+ text-decoration: none;
29+ color: #333333;
30+}
31+.openerp .btn-group.state .dropdown-toggle {
32+ -webkit-box-shadow: None;
33+}
34+.openerp .status {
35+ display: inline-block;
36+ position: relative;
37+ height: 12px;
38+ width: 12px;
39+ -moz-border-radius: 6px;
40+ -webkit-border-radius: 6px;
41+ border-radius: 6px;
42+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
43+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
44+ -box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
45+ background-position: center center;
46+ background-image: radial-gradient(#dddddd 0%, #aaaaaa 40%, #999999 100%);
47+ background-image: -moz-radial-gradient(#dddddd 0%, #aaaaaa 40%, #999999 100%);
48+ background-image: -webkit-radial-gradient(circle, #dddddd 0%, #aaaaaa 40%, #999999 100%);
49+}
50+.openerp .status.error {
51+ background: #cc3333;
52+ background-position: center center;
53+ background-image: radial-gradient(#ee7777 0%, #cc3333 40%, #bb0808 100%);
54+ background-image: -moz-radial-gradient(#ee7777 0%, #cc3333 40%, #bb0808 100%);
55+ background-image: -webkit-radial-gradient(circle, #ee7777 0%, #cc3333 40%, #bb0808 100%);
56+}
57+.openerp .status.ok {
58+ background: #44dd44;
59+ background-position: center center;
60+ background-image: radial-gradient(#55dd55 0%, #44cc44 40%, #33bb33 100%);
61+ background-image: -moz-radial-gradient(#55dd55 0%, #44cc44 40%, #33bb33 100%);
62+ background-image: -webkit-radial-gradient(circle, #55dd55 0%, #44cc44 40%, #33bb33 100%);
63+}
64+.openerp .oe_star_left a:hover {
65+ text-decoration: none;
66+}
67+.openerp .oe_star_left {
68+ float: left;
69+ margin-right: 8px;
70+}
71+.openerp .oe_star_on {
72+ color: gold;
73+}
74
75=== modified file 'addons/web/static/src/css/base.sass'
76--- addons/web/static/src/css/base.sass 2014-05-02 12:33:55 +0000
77+++ addons/web/static/src/css/base.sass 2014-05-07 10:11:07 +0000
78@@ -2680,7 +2680,6 @@
79 .openerp div.oe_mail_wall
80 overflow: hidden !important
81 // }}}
82-
83 // End of customize
84
85 // Customize bootstrap3 for tooltip
86@@ -2720,6 +2719,65 @@
87 .oe_tooltip_message
88 max-width: 310px
89
90+.openerp
91+ .dropdown-menu.state
92+ background: white
93+ background: white !important
94+ min-width: 100%
95+ padding-right: 10px !important
96+ .dropdown-menu.state li a, .dropdown-menu.state li a:hover, .dropdown-menu.state li a:focus
97+ text-decoration: none
98+ color: #333
99+ padding-left: 5px
100+ padding-right: 0px
101+ font-size: 13px
102+ .btn-group.state
103+ padding-top: 8px
104+ .btn-group.state a
105+ color: #333333
106+ .btn-group.state a:hover
107+ text-decoration: none
108+ color: #333333
109+ .btn-group.state .dropdown-toggle
110+ -webkit-box-shadow: None
111+ .status
112+ display: inline-block
113+ position: relative
114+ height: 12px
115+ width: 12px
116+ -moz-border-radius: 6px
117+ -webkit-border-radius: 6px
118+ border-radius: 6px
119+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6)
120+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6)
121+ -box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6)
122+ background-position: center center
123+ background-image: radial-gradient(#dddddd 0%, #aaaaaa 40%, #999999 100%)
124+ background-image: -moz-radial-gradient(#dddddd 0%, #aaaaaa 40%, #999999 100%)
125+ background-image: -webkit-radial-gradient(circle, #dddddd 0%, #aaaaaa 40%, #999999 100%)
126+
127+ .status.error
128+ background: #cc3333
129+ background-position: center center
130+ background-image: radial-gradient(#ee7777 0%, #cc3333 40%, #bb0808 100%)
131+ background-image: -moz-radial-gradient(#ee7777 0%, #cc3333 40%, #bb0808 100%)
132+ background-image: -webkit-radial-gradient(circle, #ee7777 0%, #cc3333 40%, #bb0808 100%)
133+
134+ .status.ok
135+ background: #44dd44
136+ background-position: center center
137+ background-image: radial-gradient(#55dd55 0%, #44cc44 40%, #33bb33 100%)
138+ background-image: -moz-radial-gradient(#55dd55 0%, #44cc44 40%, #33bb33 100%)
139+ background-image: -webkit-radial-gradient(circle, #55dd55 0%, #44cc44 40%, #33bb33 100%)
140+ .oe_star_left a:hover
141+ text-decoration: none
142+ .oe_star_left
143+ float: left
144+ margin-right: 8px
145+ .oe_star_on
146+ color: #FFD700
147+// End hack }}}
148+
149 // Hack for ui icon {{{
150 .ui-icon
151 width: 18px
152
153=== modified file 'addons/web/static/src/js/view_form.js'
154--- addons/web/static/src/js/view_form.js 2014-05-02 12:33:55 +0000
155+++ addons/web/static/src/js/view_form.js 2014-05-07 10:11:07 +0000
156@@ -2365,6 +2365,149 @@
157 }
158 });
159
160+instance.web.form.DropdownSelection = instance.web.form.FieldChar.extend({
161+ init: function (field_manager, node) {
162+ this._super(field_manager, node);
163+ },
164+ prepare_dropdown_selection: function() {
165+ var self = this;
166+ var data = [];
167+ var selection = self.field.selection || [];
168+ _.map(selection, function(res) {
169+ var state_class;
170+ if (res[0] == 'normal')
171+ state_class = 'status'
172+ else if(res[0] == 'done')
173+ state_class = 'status ok'
174+ else
175+ state_class = 'status error'
176+ value = {
177+ 'name': res[0],
178+ 'tooltip': res[1],
179+ 'state_name': res[1],
180+ 'state_class': state_class
181+ }
182+ data.push(value)
183+ });
184+ return data;
185+ },
186+ render_value: function() {
187+ var self = this;
188+ var data = {'widget': self }
189+ self.record_id = self.view.datarecord.id;
190+ data['states'] = self.prepare_dropdown_selection();
191+ self.$el.html(QWeb.render("DropdownSelection", data));
192+ self.$el.find('.oe_legend').click(self.do_action.bind(self));
193+ this.$el.on('mouseenter mouseleave', function(e) {
194+ self.$el.find('.caret').toggleClass('hidden', e.type == 'mouseleave');
195+ });
196+
197+ if (self.view.datarecord.stage_id) {
198+ var stage_id = _.isArray(self.view.datarecord.stage_id) ? self.view.datarecord.stage_id[0] : self.view.datarecord.stage_id
199+ return (new openerp.web.Model(self.view.fields.stage_id.field.relation)).query([])
200+ .filter([["id", "=", stage_id]]).first().then(function(res) {
201+ var title = res['legend_'+self.get('value')]
202+ if (title) {
203+ self.$(".oe_state").attr("title", title)
204+ }
205+ });
206+ }
207+ },
208+ do_action: function(e) {
209+ var self = this;
210+ var li = $(e.target).closest( "li" );
211+ if (li.length) {
212+ var value = {};
213+ value[self.name] = String(li.data('value'));
214+ if (self.record_id) {
215+ return self.view.dataset._model.call('write', [[self.record_id], value, self.view.dataset.get_context()]).done(self.reload_record.bind(self));
216+ } else {
217+ return self.view.on_button_save().done(function(result) {
218+ if (result) {
219+ self.view.dataset._model.call('write', [[result], value, self.view.dataset.get_context()]).done(self.reload_record.bind(self));
220+ }
221+ });
222+ }
223+ }
224+ },
225+ reload_record: function() {
226+ this.view.reload();
227+ },
228+});
229+
230+instance.web.form.Priority = instance.web.form.FieldChar.extend({
231+ init: function (field_manager, node) {
232+ this._super(field_manager, node);
233+ },
234+ prepare_priority: function() {
235+ var self = this;
236+ var data = [];
237+ var selection = this.field.selection || [];
238+ _.map(selection, function(res) {
239+ value = {
240+ 'name': res[0],
241+ 'legend_name': res[1]
242+ }
243+ if (res[0] == '0') {
244+ value['legend']= '<span class="oe_e oe_star_off">7</span>';
245+ } else {
246+ value['legend']= '<span class="oe_e oe_star_on">7</span>';
247+ }
248+ data.push(value)
249+ });
250+ return data;
251+ },
252+ render_value: function() {
253+ var self = this;
254+ var data = {'widget': self }
255+ self.record_id = self.view.datarecord.id;
256+ data['legends'] = self.prepare_priority();
257+ self.$el.html(QWeb.render("Priority", data));
258+ self.$el.find('.oe_legend').click(self.do_action.bind(self));
259+
260+ if (self.view.datarecord.stage_id) {
261+ var stage_id = _.isArray(self.view.datarecord.stage_id) ? self.view.datarecord.stage_id[0] : self.view.datarecord.stage_id
262+ return (new openerp.web.Model(self.view.fields.stage_id.field.relation)).query([])
263+ .filter([["id", "=", stage_id]]).first().then(function(res) {
264+ var li = self.$('li');
265+ for (i=1; i<=li.length; i++){
266+ var title = res['legend_star'+i]
267+ if (title) {
268+ self.$("ul").find("[data-value='" + i + "']").attr("title", title);
269+ }
270+ }
271+ });
272+ }
273+ },
274+ do_action: function(e) {
275+ var self = this;
276+ var li = $(e.target).closest( "li" );
277+ if (li.length) {
278+ var value = {};
279+ if (self.val == li.data('value') && self.check_star) {
280+ value[self.name] = String(li.data('value') - 1);
281+ self.check_star = false
282+ } else {
283+ value[self.name] = String(li.data('value'));
284+ self.check_star = true;
285+ }
286+ self.val = li.data('value')
287+ if (self.record_id) {
288+ return self.view.dataset._model.call('write', [[self.record_id], value, self.view.dataset.get_context()]).done(self.reload_record.bind(self));
289+ } else {
290+ return self.view.on_button_save().done(function(result) {
291+ if (result) {
292+ self.view.dataset._model.call('write', [[result], value, self.view.dataset.get_context()]).done(self.reload_record.bind(self));
293+ }
294+ });
295+ }
296+ }
297+ },
298+ reload_record: function() {
299+ this.view.reload();
300+ },
301+});
302+
303 instance.web.form.FieldID = instance.web.form.FieldChar.extend({
304 process_modifiers: function () {
305 this._super();
306@@ -6115,6 +6258,8 @@
307 'monetary': 'instance.web.form.FieldMonetary',
308 'many2many_checkboxes': 'instance.web.form.FieldMany2ManyCheckBoxes',
309 'x2many_counter': 'instance.web.form.X2ManyCounter',
310+ 'priority':'instance.web.form.Priority',
311+ 'dropdown_selection':'instance.web.form.DropdownSelection',
312 'statinfo': 'instance.web.form.StatInfo',
313 });
314
315
316=== modified file 'addons/web/static/src/xml/base.xml'
317--- addons/web/static/src/xml/base.xml 2014-05-02 12:33:55 +0000
318+++ addons/web/static/src/xml/base.xml 2014-05-07 10:11:07 +0000
319@@ -1029,6 +1029,41 @@
320 </t>
321 </span>
322 </t>
323+
324+<t t-name="DropdownSelection">
325+ <span class="btn-group state">
326+ <t t-foreach="states" t-as="rec">
327+ <a t-att-class="'oe_state '+rec.state_class" t-if="widget.get('value') === rec.name" t-att-title="rec.tooltip" >
328+ <a class="oe_legend dropdown-toggle" data-toggle="dropdown">
329+ <span class="caret hidden"></span>
330+ <span class="sr-only">Toggle Dropdown</span> </a>
331+ </a>
332+ </t>
333+ <ul class="dropdown-menu state" role="menu">
334+ <t t-foreach="states" t-as="rec">
335+ <t t-if="widget.get('value') !== rec.name">
336+ <li class="oe_legend" t-att-data-value="rec.name" ><a href="#">
337+ <span t-att-class="rec.state_class"/> <t t-raw="rec.state_name" /></a>
338+ </li>
339+ </t>
340+ </t>
341+ </ul>
342+ </span>
343+</t>
344+<t t-name="Priority">
345+ <ul style="list-style: none; padding-left: 2px;">
346+ <t t-foreach="legends" t-as="rec" >
347+ <t t-if="widget.get('value') gte rec.name and !rec_first">
348+ <li t-att-data-value="rec.name" class="oe_star_left oe_legend" t-att-title="rec.legend_name"><a href="#"><t t-raw="rec.legend"/></a></li>
349+ </t>
350+ </t>
351+ <t t-foreach="legends" t-as="rec" >
352+ <t t-if="widget.get('value') lt rec.name">
353+ <li t-att-data-value="rec.name" class="oe_star_left oe_legend" t-att-title="rec.legend_name"><a href="#"><t t-raw="legends[0].legend"/></a></li>
354+ </t>
355+ </t>
356+ </ul>
357+</t>
358 <t t-name="FieldEmail">
359 <span class="oe_form_field oe_form_field_email" t-att-style="widget.node.attrs.style">
360 <a t-if="widget.get('effective_readonly')" href="#" class="oe_form_uri" target="_blank"/>
361
362=== modified file 'addons/web_kanban/static/src/js/kanban.js'
363--- addons/web_kanban/static/src/js/kanban.js 2014-04-23 07:38:40 +0000
364+++ addons/web_kanban/static/src/js/kanban.js 2014-05-07 10:11:07 +0000
365@@ -562,6 +562,7 @@
366 this.dataset = dataset;
367 this.dataset_offset = 0;
368 this.aggregates = {};
369+ this.legend = {};
370 this.value = this.title = null;
371 if (this.group) {
372 this.value = group.get('value');
373@@ -646,7 +647,10 @@
374 }
375 this.$el.data('widget', this);
376 this.$records.data('widget', this);
377- this.$has_been_started.resolve();
378+ var def_tooltip = this.fetch_tooltip();
379+ $.when(def_tooltip).done(function (){
380+ self.$has_been_started.resolve();
381+ });
382 var add_btn = this.$el.find('.oe_kanban_add');
383 add_btn.tooltip({delay: { show: 500, hide:1000 }});
384 this.$records.find(".oe_kanban_column_cards").click(function (ev) {
385@@ -657,8 +661,6 @@
386 }
387 });
388 this.is_started = true;
389- var def_tooltip = this.fetch_tooltip();
390- return $.when(def_tooltip);
391 },
392 fetch_tooltip: function() {
393 if (! this.group)
394@@ -682,13 +684,13 @@
395 var options = instance.web.py_eval(field_desc.attrs.options || '{}')
396 if (! options.tooltip_on_group_by)
397 return;
398-
399 var self = this;
400 if (this.value) {
401 return (new instance.web.Model(field.relation)).query([options.tooltip_on_group_by])
402- .filter([["id", "=", this.value]]).first().then(function(res) {
403- self.tooltip = res[options.tooltip_on_group_by];
404- self.$(".oe_kanban_group_title_text").attr("title", self.tooltip || self.title || "").tooltip();
405+ .filter([["id", "=", this.value]]).first().then(function(res) {
406+ self.legend = res[options.tooltip_on_group_by];
407+ var title = self.legend.tooltip || self.title || ""
408+ self.$(".oe_kanban_group_title_text").attr("title", title).tooltip({html: true,className: 'oe_tooltip_kanban_message'});
409 });
410 }
411 },
412@@ -1259,7 +1261,115 @@
413 },
414 });
415
416+instance.web_kanban.Priority = instance.web_kanban.AbstractField.extend({
417+ init: function(parent, field, $node) {
418+ this._super.apply(this, arguments);
419+ this.name = $node.attr('name')
420+ this.parent = parent;
421+ },
422+ prepare_priority: function() {
423+ var self = this;
424+ var data = [];
425+ var selection = self.field.selection || [];
426+ _.map(selection, function(res) {
427+ value = {
428+ 'name': res[0],
429+ 'legend_name': self.parent.group.legend['legend_star'+res[0]] || res[1]
430+ }
431+ if (res[0] == '0') {
432+ value['legend'] = '<span class="oe_e oe_star_off">7</span>';
433+ } else {
434+ value['legend'] = '<span class="oe_e oe_star_on">7</span>';
435+ }
436+ data.push(value)
437+ });
438+ return data;
439+ },
440+ renderElement: function() {
441+ var self = this;
442+ self.record_id = self.parent.id;
443+ var data = {'widget': self }
444+ data['legends'] = self.prepare_priority();
445+ this.$el = $(QWeb.render("Priority", data));
446+ this.$el.find('.oe_legend').click(self.do_action.bind(self));
447+ },
448+ do_action: function(e) {
449+ var self = this;
450+ var li = $(e.target).closest( "li" );
451+ if (li.length) {
452+ var value = {};
453+ if (self.parent.val == li.data('value') && self.parent.check_star) {
454+ value[self.name] = String(li.data('value') - 1);
455+ self.parent.check_star = false
456+ } else {
457+ value[self.name] = String(li.data('value'));
458+ self.parent.check_star = true;
459+ }
460+ self.parent.val = li.data('value')
461+ return self.parent.view.dataset._model.call('write', [[self.record_id], value, self.parent.view.dataset.get_context()]).done(self.reload_record.bind(self.parent));
462+ }
463+ },
464+ reload_record: function() {
465+ this.do_reload();
466+ },
467+});
468+
469+instance.web_kanban.DropdownSelection = instance.web_kanban.AbstractField.extend({
470+ init: function(parent, field, $node) {
471+ this._super.apply(this, arguments);
472+ this.name = $node.attr('name')
473+ this.parent = parent;
474+ },
475+ prepare_dropdown_selection: function() {
476+ var self = this;
477+ var data = [];
478+ var selection = self.field.selection || [];
479+ _.map(selection, function(res) {
480+ var state_class;
481+ if (res[0] == 'normal')
482+ state_class = 'status'
483+ else if(res[0] == 'done')
484+ state_class = 'status ok'
485+ else
486+ state_class = 'status error'
487+ value = {
488+ 'name': res[0],
489+ 'tooltip': self.parent.group.legend['legend_'+res[0]] || res[1],
490+ 'state_name': res[1],
491+ 'state_class': state_class
492+ }
493+ data.push(value)
494+ });
495+ return data;
496+ },
497+ renderElement: function() {
498+ var self = this;
499+ self.record_id = self.parent.id;
500+ var data = {'widget': self }
501+ data['states'] = self.prepare_dropdown_selection();
502+ this.$el = $(QWeb.render("DropdownSelection", data));
503+ this.$el.find('.oe_legend').click(self.do_action.bind(self));
504+ this.$el.on('mouseenter mouseleave', function(e) {
505+ self.$el.find('.caret').toggleClass('hidden', e.type == 'mouseleave');
506+ });
507+ },
508+ do_action: function(e) {
509+ var self = this;
510+ var li = $(e.target).closest( "li" );
511+ if (li.length) {
512+ var value = {};
513+ value[self.name] = String(li.data('value'));
514+ return self.parent.view.dataset._model.call('write', [[self.record_id], value, self.parent.view.dataset.get_context()]).done(self.reload_record.bind(self.parent));
515+ }
516+ },
517+ reload_record: function() {
518+ this.do_reload();
519+ },
520+});
521+
522 instance.web_kanban.fields_registry = new instance.web.Registry({});
523+instance.web_kanban.fields_registry.add('priority','instance.web_kanban.Priority');
524+instance.web_kanban.fields_registry.add('dropdown_selection','instance.web_kanban.DropdownSelection');
525 };
526
527 // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: