← Back to team overview

openerp-dev-web team mailing list archive

lp:~openerp-dev/openobject-client-web/trunk-cal-events-readonly into lp:openobject-client-web

 

Olivier (Open ERP) has proposed merging lp:~openerp-dev/openobject-client-web/trunk-cal-events-readonly into lp:openobject-client-web.

Requested reviews:
  OpenERP SA's Web Client R&D (openerp-dev-web): functional tests (different browsers), non regression tests


Some events have their 'starting date' and 'end date' read only depending on their state. For example, you cannot edit crm.meeting dates if it's state is 'done'.

But the calendar was not taking care of this and you could drag and drop events regardless of their state.

This branch is supposed to fix that. 

-- 
https://code.launchpad.net/~openerp-dev/openobject-client-web/trunk-cal-events-readonly/+merge/39348
Your team OpenERP SA's Web Client R&D is requested to review the proposed merge of lp:~openerp-dev/openobject-client-web/trunk-cal-events-readonly into lp:openobject-client-web.
=== modified file 'addons/view_calendar/static/javascript/calendar_month.js'
--- addons/view_calendar/static/javascript/calendar_month.js	2010-09-28 12:02:18 +0000
+++ addons/view_calendar/static/javascript/calendar_month.js	2010-10-26 08:46:07 +0000
@@ -404,23 +404,32 @@
         e = toISOTimestamp(new Date(e))
 
         var self = this;
-        var req = saveCalendarRecord(id, s, e);
-
-        req.addCallback(function(obj) {
-
-            if (obj.error) {
-                return error_display(obj.error);
+
+        // check that the object was really modified to avoid unnecessary warning popups:
+        if (record.starts != s && record.ends != e) {
+            if (hasElementClass(draggable, 'is-not-droppable')) {
+                self.calendar.onResize();
+                return error_display(_("This calendar object can no longer be moved !"));
+            } else {
+                var req = saveCalendarRecord(id, s, e);
+
+                req.addCallback(function(obj) {
+
+                    if (obj.error) {
+                        return error_display(obj.error);
+                    }
+
+                    record.starts = s;
+                    record.ends = e;
+
+                    self.calendar.makeEvents();
+                });
+                req.addBoth(function(obj) {
+                    self.calendar.onResize();
+                });
             }
-
-            record.starts = s;
-            record.ends = e;
-
-            self.calendar.makeEvents();
-        });
-
-        req.addBoth(function(obj) {
-            self.calendar.onResize();
-        });
+        }
+        self.calendar.onResize();
     },
 
     makeEventContainers : function() {

=== modified file 'addons/view_calendar/static/javascript/calendar_utils.js'
--- addons/view_calendar/static/javascript/calendar_utils.js	2010-08-19 14:11:12 +0000
+++ addons/view_calendar/static/javascript/calendar_utils.js	2010-10-26 08:46:07 +0000
@@ -154,7 +154,6 @@
 }
 
 function saveCalendarRecord(record_id, starts, ends) {
-
     var params = getFormParams('_terp_concurrency_info');
     MochiKit.Base.update(params, {
         '_terp_id': record_id,

=== modified file 'addons/view_calendar/static/javascript/calendar_week.js'
--- addons/view_calendar/static/javascript/calendar_week.js	2010-10-25 12:26:19 +0000
+++ addons/view_calendar/static/javascript/calendar_week.js	2010-10-26 08:46:07 +0000
@@ -245,7 +245,6 @@
     },
 
     onDrop : function(draggable, droppable, evt) {
-
         var dt = MochiKit.DateTime.isoDate(getNodeAttribute(droppable, 'dtDay'));
         var id = getNodeAttribute(draggable, 'nRecordID');
 
@@ -263,23 +262,32 @@
         e = toISOTimestamp(new Date(e))
 
         var self = this;
-        var req = saveCalendarRecord(id, s, e);
-
-        req.addCallback(function(obj) {
-
-            if (obj.error) {
-                return error_display(obj.error);
+
+        // check that the object was really modified to avoid unnecessary warning popups:
+        if (record.starts != s && record.ends != e) {
+            if (hasElementClass(draggable, 'is-not-droppable')) {
+                self.adjust();
+                return error_display(_("This calendar object can no longer be moved !"));
+            } else {
+                var req = saveCalendarRecord(id, s, e);
+
+                req.addCallback(function(obj) {
+
+                    if (obj.error) {
+                        return error_display(obj.error);
+                    }
+
+                    record.starts = s;
+                    record.ends = e;
+
+                    self.makeEvents();
+                });
+                req.addBoth(function(obj) {
+                    self.adjust();
+                });
             }
-
-            record.starts = s;
-            record.ends = e;
-
-            self.makeEvents();
-        });
-
-        req.addBoth(function(obj) {
-            self.adjust();
-        });
+        }
+        self.adjust();
     },
 
     onMouseDown : function(evt) {
@@ -638,10 +646,15 @@
     },
 
     onDrop : function(draggable, droppable, evt) {
-
         var dt = MochiKit.DateTime.isoDate(getNodeAttribute(droppable, 'dtDay'));
         var id = getNodeAttribute(draggable, 'nRecordID');
 
+        var record = {
+            starts: getNodeAttribute(draggable, 'dtStart'),
+            ends : getNodeAttribute(draggable, 'dtEnd'),
+            is_not_droppable: hasElementClass(draggable, 'is-not-droppable') || hasElementClass(draggable.parentNode, 'is-not-droppable'),
+        }
+            
         var y = parseInt(draggable.style.top);
         var h = parseInt(draggable.style.height) + 2;
 
@@ -655,6 +668,15 @@
         e = new Date(e);
 
         var self = this;
+
+        // check that the object was really modified to avoid unnecessary warning popups:
+        if (record.starts != toISOTimestamp(s) && record.ends != toISOTimestamp(e)) {
+            if (record.is_not_droppable) {
+                self.adjust();
+                return error_display(_("This calendar object can no longer be moved !"));
+            }
+        }
+
         var req = saveCalendarRecord(id, toISOTimestamp(s), toISOTimestamp(e));
 
         req.addCallback(function(obj) {
@@ -676,7 +698,7 @@
             t.shift();
             t = t.join(' - ');
 
-            title.innerHTML = s.strftime('%I:%M %P') + ' - ' + t;
+            title.innerHTML = s.strftime('%H:%M') + ' - ' + t;
         });
 
         req.addBoth(function(obj) {

=== modified file 'addons/view_calendar/widgets/_base.py'
--- addons/view_calendar/widgets/_base.py	2010-10-25 09:07:29 +0000
+++ addons/view_calendar/widgets/_base.py	2010-10-26 08:46:07 +0000
@@ -75,7 +75,7 @@
     record = {}
     record_id = False
 
-    def __init__(self, record, starts, ends, title='', description='', dayspan=0, color=None):
+    def __init__(self, record, starts, ends, title='', description='', dayspan=0, color=None, droppable=True):
 
         super(TinyEvent, self).__init__()
 
@@ -91,6 +91,7 @@
         self.title = title
         self.description = description or ''
         self.color = color
+        self.droppable = droppable
         self.create_date = ustr(record.get('create_date'))
         self.create_uid = ustr(record.get('create_uid'))
         self.write_uid = ustr(record.get('write_uid'))
@@ -174,7 +175,7 @@
         self.info_fields = self.parse(root, view['fields'])
 
         fields = view['fields']
-        fields = fields.keys() + [self.date_start, self.date_stop, self.date_delay, self.color_field]
+        fields = fields.keys() + [self.date_start, self.date_stop, self.date_delay, self.color_field, 'state']
 
         fields = list(set([x for x in fields if x]))
 
@@ -228,9 +229,11 @@
         proxy = rpc.RPCProxy(self.model)
 
         if self.date_stop:
+            # use the correct algorithm:
             domain = self.domain + [(self.date_start, '<=', days[-1].isoformat() + ' 23:59:59'),
                                     (self.date_stop, '>=', days[0].isoformat() + ' 00:00:00')]
         else:
+            # cannot use the correct algorithm, use the old one:
             first = days[0].month2.prev()[0] #HACK: add prev month
             domain = self.domain + [(self.date_start, '>', first.isoformat()),
                                     (self.date_start, '<', days[-1].next().isoformat())]
@@ -271,6 +274,7 @@
         ids = proxy.search(domain, 0, 0, order_by, ctx)
 
         result = proxy.read(ids, self.fields.keys()+['__last_update'], ctx)
+
         self._update_concurrency_info(self.model, result)
         self.concurrency_info = ConcurrencyInfo(self.model, ids)
         if self.color_field:
@@ -310,7 +314,6 @@
         return result
 
     def get_event_widget(self, event):
-
         title = ''       # the title
         description = [] # the description
         if self.info_fields:
@@ -377,19 +380,29 @@
 
         color_key = event.get(self.color_field)
         color = self.colors.get(color_key)
+        droppable = self._is_event_droppable(event)
 
         title = title.strip()
         description = ', '.join(description).strip()
         if isinstance(event['id'], int):
             event_log = rpc.session.execute('object', 'execute', self.model, 'perm_read', [event['id']])[0]
-            
+
             event['create_date'] = event_log['create_date']
             event['create_uid'] = event_log['create_uid'][1]
             if isinstance(event_log['write_uid'], tuple):
                 event_log['write_uid'] = event_log['write_uid'][1]
             event['write_uid'] = event_log['write_uid']
             event['write_date'] = event_log['write_date']
-        return TinyEvent(event, starts, ends, title, description, dayspan=span, color=(color or None) and color[-1])
+        return TinyEvent(event, starts, ends, title, description, dayspan=span, color=(color or None) and color[-1], droppable=droppable)
+
+    def _is_event_droppable(self, event):
+        # get field definition:
+        defs = self.fields[self.date_start].get('states', {}).get(event['state'], [])
+        for item in defs:
+            if len(item) == 2 and 'readonly' in item and item[1]:
+                return False
+
+        return True
 
 
 class TinyCalendar(ICalendar):

=== modified file 'addons/view_calendar/widgets/templates/day.mako'
--- addons/view_calendar/widgets/templates/day.mako	2010-10-21 15:25:44 +0000
+++ addons/view_calendar/widgets/templates/day.mako	2010-10-26 08:46:07 +0000
@@ -63,7 +63,7 @@
                                         nWriteDate="${evt.write_date}"
                                         nWriteId="${evt.write_uid}"
                                         style="background-color: ${evt.color}" 
-                                        class="calEvent allDay">${evt.title}</div>
+                                        class="calEvent allDay ${evt.droppable and 'is-droppable' or 'is-not-droppable'}">${evt.title}</div>
                             % endif
                         % endfor
                     </div>
@@ -79,7 +79,7 @@
                             nWriteDate="${evt.write_date}"
                             nWriteId="${evt.write_uid}" 
                             style="background-color: ${evt.color}" 
-                            class="calEvent noAllDay">
+                            class="calEvent noAllDay ${evt.droppable and 'is-droppable' or 'is-not-droppable'}">
                            <div style="height: 10px;" class="calEventTitle">${evt.starts.strftime('%I:%M %P')} - ${evt.title}</div>
                            <div class="calEventDesc">${evt.description}</div>
                            <div class="calEventGrip"></div>

=== modified file 'addons/view_calendar/widgets/templates/month.mako'
--- addons/view_calendar/widgets/templates/month.mako	2010-10-21 15:25:44 +0000
+++ addons/view_calendar/widgets/templates/month.mako	2010-10-26 08:46:07 +0000
@@ -51,7 +51,7 @@
                     <div id="calBodySect">
                         % for evt in events:
                             % if evt.dayspan > 0:
-                                <div class="calEvent"
+                                <div class="calEvent ${evt.droppable and 'is-droppable' or 'is-not-droppable'}"
                                     nRecordID="${evt.record_id}"
                                     nDaySpan="${evt.dayspan}"
                                     dtStart="${str(evt.starts)}"
@@ -64,7 +64,7 @@
                                     style="background-color: ${evt.color}">${evt.title}</div>
                             % endif
                             % if evt.dayspan == 0:
-                                <div class="calEvent calEventInfo"
+                                <div class="calEvent calEventInfo ${evt.droppable and 'is-droppable' or 'is-not-droppable'}"
                                     nRecordID="${evt.record_id}"
                                     nDaySpan="${evt.dayspan}"
                                     dtStart="${str(evt.starts)}"

=== modified file 'addons/view_calendar/widgets/templates/week.mako'
--- addons/view_calendar/widgets/templates/week.mako	2010-10-21 15:25:44 +0000
+++ addons/view_calendar/widgets/templates/week.mako	2010-10-26 08:46:07 +0000
@@ -51,33 +51,33 @@
                     <div id="calAllDaySect">
                         % for evt in events:
                             % if evt.dayspan > 0:
-                                <div nRecordID="${evt.record_id}" 
-                                    nDaySpan="${evt.dayspan}" 
-                                    dtStart="${str(evt.starts)}" 
-                                    dtEnd="${str(evt.ends)}" 
+                                <div nRecordID="${evt.record_id}"
+                                    nDaySpan="${evt.dayspan}"
+                                    dtStart="${str(evt.starts)}"
+                                    dtEnd="${str(evt.ends)}"
                                     title="${evt.description}"
                                     nCreationDate="${evt.create_date}"
                                     nCreationId="${evt.create_uid}"
                                     nWriteDate="${evt.write_date}"
-                                    nWriteId="${evt.write_uid}" 
-                                    style="background-color: ${evt.color};" 
-                                    class="calEvent allDay">${evt.title}</div>
+                                    nWriteId="${evt.write_uid}"
+                                    style="background-color: ${evt.color};"
+                                    class="calEvent allDay ${evt.droppable and 'is-droppable' or 'is-not-droppable'}">${evt.title}</div>
                             % endif
                         % endfor
                     </div>
                     <div id="calBodySect">
                         % for evt in events:
                             % if evt.dayspan == 0:
-                        <div nRecordID="${evt.record_id}" 
-                            dtStart="${str(evt.starts)}" 
+                        <div nRecordID="${evt.record_id}"
+                            dtStart="${str(evt.starts)}"
                             dtEnd="${str(evt.ends)}"
                             nCreationDate="${evt.create_date}"
                             nCreationId="${evt.create_uid}"
                             nWriteDate="${evt.write_date}"
                             nWriteId="${evt.write_uid}"
-                            style="background-color: ${evt.color};" 
-                            class="calEvent noAllDay">
-                           <div style="height: 10px;" class="calEventTitle">${evt.starts.strftime('%I:%M %P')} - ${evt.title}</div>
+                            style="background-color: ${evt.color};"
+                            class="calEvent noAllDay ${evt.droppable and 'is-droppable' or 'is-not-droppable'}">
+                           <div style="height: 10px;" class="calEventTitle">${evt.starts.strftime('%H:%M')} - ${evt.title}</div>
                            <div class="calEventDesc">${evt.description}</div>
                            <div class="calEventGrip"></div>
                         </div>

=== modified file 'addons/view_calendar/widgets/widgets.py'
--- addons/view_calendar/widgets/widgets.py	2010-10-25 12:26:19 +0000
+++ addons/view_calendar/widgets/widgets.py	2010-10-26 08:46:07 +0000
@@ -142,8 +142,6 @@
         self.month = Month(y, m)
         self.events = self.get_events(self.month.days)
 
-
-
         self.selected_day = _get_selection_day(Day(y, m, 1), self.selected_day, 'month')
 
         minical = MiniCalendar(self.selected_day)


Follow ups