<commit_before>- if !params[:embedded]
  %h2.title
    %a{:href => course_path(@assignment.course)}=h @assignment.course.name
    &gt;
    %a{:href => assignment_path(@assignment)}= 'Assignment #'  + @assignment.position.to_s
    &gt;
    Messages
    - if @assignment.course.is_assistant?(@user)
      for
      =h @assignment_submission.user.name rescue 'unknown'
    
#message-panel
- tabs = [ { :title => 'You', :html => (@assignment_submission.show_info(@current_module_position, @user) rescue ''), :itemId => 'own-portfolio', :autoScroll => true } ]
- @assignment_participations.each do |p|
  - next if p.author_name.blank?
  - tabs << { :title => p.author_name, :html => p.assignment_submission.show_info(@current_module_position,@user), :itemId => 'portfolio-' + p.id.to_s }

:javascript
  Ext.onReady(function(){
    var message_panel_tools = new Array;
    if(#{ @we_allow_new_messages.to_json }) {
      message_panel_tools[message_panel_tools.length] = {
        text: 'Refresh',
        iconCls: 'silk-arrow-refresh',
        handler: function(b,e) {
          var panel = Ext.ComponentMgr.get('message-list');
          panel.getStore().reload();
        }
      };
      
      if(#{@recipients.size} > 0) {
        message_panel_tools[message_panel_tools.length] = {
          text: 'New Message',
          iconCls: 'silk-add',
          handler: function(b,e) {
            var panel = Ext.ComponentMgr.get('message-list');
            var compose_form = new WLC.ux.ComposeMessageWindow({
              title: 'New Message',
              renderTo: document.body,
              url: #{(assignment_messages_path(@assignment)+"?format=ext_json_html").to_json},
              store: panel.getStore(),
              recipientStore: new Ext.data.ArrayStore({
                id: 0,
                fields: [
                  'myId',
                  'displayText'
                ],
                data: #{@recipients.to_json}
              }),
              form_authenticity_token: #{form_authenticity_token.to_json}
            });
            compose_form.setPosition(50,50);
            compose_form.show();
          }
        };

        message_panel_tools[message_panel_tools.length] = {
          text: 'Reply',
          iconCls: 'silk-arrow-turn-left',
          disabled: true,
          id: 'message-reply-button',
          handler: function(b,e) {
            var panel = Ext.ComponentMgr.get('message-list');
            /* get the selected message for the reply */
            var rec = panel.selModel.getSelected();
            WLC.debug(rec);

            if(rec) {
              Ext.Ajax.request({
                url: rec.get('url') + '?format=ext_json', /* '/messages/' + rec.get('id') + '?format=ext_json', */
                success: function(response, opts) {
                  var obj = Ext.decode(response.responseText);
                  WLC.debug(obj);

                  var compose_form = new WLC.ux.ComposeMessageWindow({
                    title: 'Reply to Message',
                    renderTo: document.body,
                    url: #{(assignment_messages_path(@assignment)+"?format=ext_json_html").to_json},
                    store: panel.getStore(),
                    messageContent: '> ' + obj.data["message[content]"].replace(/(\r\n)|(\n\r)/g, "\n> "),
                    messageRecipient: obj.data["message[assignment_participation_id]"],
                    messageSubject: ('Re: ' + obj.data["message[subject]"]).replace(/^(Re: )+/, 'Re: '),
                    recipientStore: new Ext.data.ArrayStore({
                      id: 0,
                      fields: [
                        'myId',
                        'displayText'
                      ],
                      data: #{@recipients.to_json}
                    }),
                    form_authenticity_token: #{form_authenticity_token.to_json}
                  });
                  compose_form.setPosition(50,50);
                  compose_form.show();
                }
              });
            }
          }
        };
      }
    }

  WLC.debug(message_panel_tools);

  var dims = document.viewport.getDimensions();
  var h = dims['height'];
  if(h < 600) { h = 600; }
  var w = 660;
  var message_panel;
  var message_store = new Ext.data.JsonStore({
    url: #{(@store_url + "?format=ext_json").to_json},
    autoLoad: true,
    storeId: 'messageStore',
    root: 'messages',
    idProperty: 'id',
    restful: true,
    fields: ['id', 'user', 'created_at', {name:'is_read', type:'boolean'}, 'subject', 'recipient', 'recipient-portfolio', 'url' ]
  });

  if( #{@we_allow_new_messages.to_json} ) {
    Ext.TaskMgr.start({
      run: function(){ message_store.reload(); },
      interval: 10*60*1000 /* every 10 minutes */
    });
  }

  message_panel = new Ext.Panel({
      renderTo: 'message-panel',
      layout:'border',
      height: h - 165,
      width: w,
      items: [{
        region: 'north',
        layout: 'hbox',
        align: 'stretchmax',
        pack: 'center',
        flex: 1,
        height: 150,
        items: [{
          /* title: 'Messages', */
          flex: 3,
          xtype: 'grid',
          id: 'message-list',
          tbar: message_panel_tools,
          height: 150,
          store: message_store,
          colModel: new Ext.grid.ColumnModel({
            defaults: {
              sortable: true
            },
            columns: [
              {id: 'subject', header: 'Subject', dataIndex: 'subject', width: (w*0.5-35)*0.5 },
              {id: 'sent_from', header: 'From', dataIndex: 'user' , width: (w*0.5-35)*0.2 },
              {id: 'sent_to', header: 'To', dataIndex: 'recipient' , width: (w*0.5-35)*0.2 },
              {id: 'when', header: 'Date', dataIndex: 'created_at', width: (w*0.5-35)*0.2 }
            ]
          }),
          autoFill: true,
          forceFit: true,
          selModel: new Ext.grid.RowSelectionModel({
            singleSelect: true
          }),
          viewConfig: {
            getRowClass: function(record, index) {
                var c = record.get('is_read');
                if(c) { return 'message-read'; } else { return 'message-unread'; }
            },
            forceFit: true
          },
          listeners: {
            beforerefresh: function(v) {
               v.scrollTop = v.scroller.dom.scrollTop;
               v.scrollHeight = v.scroller.dom.scrollHeight;
            },
            refresh: function(v) {
               v.scroller.dom.scrollTop = v.scrollTop + 
                (!v.scrollTop ? 0 : v.scroller.dom.scrollHeight - v.scrollHeight);
            },
            rowclick: function(grid, index, e) {
              var panel = message_panel.getComponent('message-content-panel');
              var store = grid.getStore();
              var rec = store.getAt(index);
              var btn = Ext.ComponentMgr.get('message-reply-button');
              if(btn) { btn.setDisabled(false); }
              panel.load({
                url: rec.get('url'), /* '/messages/' + rec.get('id'), */
                scripts: true
              });
              /* mark record as read, and select appropriate portfolio tab */
              if(! rec.get('is_read')) {
                rec.set('is_read', true);
                grid.getView().refreshRow(rec);
              }

              message_panel.layout.north.panel.getComponent('message-portfolios').setActiveTab(rec.get('recipient-portfolio'));
            }
          },
          onLoad: Ext.emptyFn
        }, {
          title: 'Portfolios',
          xtype: 'tabpanel',
          flex: 2,
          itemId: 'message-portfolios',
          height: 150,
          activeItem: 0,
          items:#{tabs.to_json}
      }]
      }, {
        region: 'center',
        itemId: 'message-content-panel',
        autoScroll: true,
        html: '<p>The message content will go here.</p>'
      }]
    });
  });
<commit_msg>Add autoScroll for the rest of the portfolio tabs<commit_after>- if !params[:embedded]
  %h2.title
    %a{:href => course_path(@assignment.course)}=h @assignment.course.name
    &gt;
    %a{:href => assignment_path(@assignment)}= 'Assignment #'  + @assignment.position.to_s
    &gt;
    Messages
    - if @assignment.course.is_assistant?(@user)
      for
      =h @assignment_submission.user.name rescue 'unknown'
    
#message-panel
- tabs = [ { :title => 'You', :html => (@assignment_submission.show_info(@current_module_position, @user) rescue ''), :itemId => 'own-portfolio', :autoScroll => true } ]
- @assignment_participations.each do |p|
  - next if p.author_name.blank?
  - tabs << { :title => p.author_name, :html => p.assignment_submission.show_info(@current_module_position,@user), :itemId => 'portfolio-' + p.id.to_s, :autoScroll => true }

:javascript
  Ext.onReady(function(){
    var message_panel_tools = new Array;
    if(#{ @we_allow_new_messages.to_json }) {
      message_panel_tools[message_panel_tools.length] = {
        text: 'Refresh',
        iconCls: 'silk-arrow-refresh',
        handler: function(b,e) {
          var panel = Ext.ComponentMgr.get('message-list');
          panel.getStore().reload();
        }
      };
      
      if(#{@recipients.size} > 0) {
        message_panel_tools[message_panel_tools.length] = {
          text: 'New Message',
          iconCls: 'silk-add',
          handler: function(b,e) {
            var panel = Ext.ComponentMgr.get('message-list');
            var compose_form = new WLC.ux.ComposeMessageWindow({
              title: 'New Message',
              renderTo: document.body,
              url: #{(assignment_messages_path(@assignment)+"?format=ext_json_html").to_json},
              store: panel.getStore(),
              recipientStore: new Ext.data.ArrayStore({
                id: 0,
                fields: [
                  'myId',
                  'displayText'
                ],
                data: #{@recipients.to_json}
              }),
              form_authenticity_token: #{form_authenticity_token.to_json}
            });
            compose_form.setPosition(50,50);
            compose_form.show();
          }
        };

        message_panel_tools[message_panel_tools.length] = {
          text: 'Reply',
          iconCls: 'silk-arrow-turn-left',
          disabled: true,
          id: 'message-reply-button',
          handler: function(b,e) {
            var panel = Ext.ComponentMgr.get('message-list');
            /* get the selected message for the reply */
            var rec = panel.selModel.getSelected();
            WLC.debug(rec);

            if(rec) {
              Ext.Ajax.request({
                url: rec.get('url') + '?format=ext_json', /* '/messages/' + rec.get('id') + '?format=ext_json', */
                success: function(response, opts) {
                  var obj = Ext.decode(response.responseText);
                  WLC.debug(obj);

                  var compose_form = new WLC.ux.ComposeMessageWindow({
                    title: 'Reply to Message',
                    renderTo: document.body,
                    url: #{(assignment_messages_path(@assignment)+"?format=ext_json_html").to_json},
                    store: panel.getStore(),
                    messageContent: '> ' + obj.data["message[content]"].replace(/(\r\n)|(\n\r)/g, "\n> "),
                    messageRecipient: obj.data["message[assignment_participation_id]"],
                    messageSubject: ('Re: ' + obj.data["message[subject]"]).replace(/^(Re: )+/, 'Re: '),
                    recipientStore: new Ext.data.ArrayStore({
                      id: 0,
                      fields: [
                        'myId',
                        'displayText'
                      ],
                      data: #{@recipients.to_json}
                    }),
                    form_authenticity_token: #{form_authenticity_token.to_json}
                  });
                  compose_form.setPosition(50,50);
                  compose_form.show();
                }
              });
            }
          }
        };
      }
    }

  WLC.debug(message_panel_tools);

  var dims = document.viewport.getDimensions();
  var h = dims['height'];
  if(h < 600) { h = 600; }
  var w = 660;
  var message_panel;
  var message_store = new Ext.data.JsonStore({
    url: #{(@store_url + "?format=ext_json").to_json},
    autoLoad: true,
    storeId: 'messageStore',
    root: 'messages',
    idProperty: 'id',
    restful: true,
    fields: ['id', 'user', 'created_at', {name:'is_read', type:'boolean'}, 'subject', 'recipient', 'recipient-portfolio', 'url' ]
  });

  if( #{@we_allow_new_messages.to_json} ) {
    Ext.TaskMgr.start({
      run: function(){ message_store.reload(); },
      interval: 10*60*1000 /* every 10 minutes */
    });
  }

  message_panel = new Ext.Panel({
      renderTo: 'message-panel',
      layout:'border',
      height: h - 165,
      width: w,
      items: [{
        region: 'north',
        layout: 'hbox',
        align: 'stretchmax',
        pack: 'center',
        flex: 1,
        height: 150,
        items: [{
          /* title: 'Messages', */
          flex: 3,
          xtype: 'grid',
          id: 'message-list',
          tbar: message_panel_tools,
          height: 150,
          store: message_store,
          colModel: new Ext.grid.ColumnModel({
            defaults: {
              sortable: true
            },
            columns: [
              {id: 'subject', header: 'Subject', dataIndex: 'subject', width: (w*0.5-35)*0.5 },
              {id: 'sent_from', header: 'From', dataIndex: 'user' , width: (w*0.5-35)*0.2 },
              {id: 'sent_to', header: 'To', dataIndex: 'recipient' , width: (w*0.5-35)*0.2 },
              {id: 'when', header: 'Date', dataIndex: 'created_at', width: (w*0.5-35)*0.2 }
            ]
          }),
          autoFill: true,
          forceFit: true,
          selModel: new Ext.grid.RowSelectionModel({
            singleSelect: true
          }),
          viewConfig: {
            getRowClass: function(record, index) {
                var c = record.get('is_read');
                if(c) { return 'message-read'; } else { return 'message-unread'; }
            },
            forceFit: true
          },
          listeners: {
            beforerefresh: function(v) {
               v.scrollTop = v.scroller.dom.scrollTop;
               v.scrollHeight = v.scroller.dom.scrollHeight;
            },
            refresh: function(v) {
               v.scroller.dom.scrollTop = v.scrollTop + 
                (!v.scrollTop ? 0 : v.scroller.dom.scrollHeight - v.scrollHeight);
            },
            rowclick: function(grid, index, e) {
              var panel = message_panel.getComponent('message-content-panel');
              var store = grid.getStore();
              var rec = store.getAt(index);
              var btn = Ext.ComponentMgr.get('message-reply-button');
              if(btn) { btn.setDisabled(false); }
              panel.load({
                url: rec.get('url'), /* '/messages/' + rec.get('id'), */
                scripts: true
              });
              /* mark record as read, and select appropriate portfolio tab */
              if(! rec.get('is_read')) {
                rec.set('is_read', true);
                grid.getView().refreshRow(rec);
              }

              message_panel.layout.north.panel.getComponent('message-portfolios').setActiveTab(rec.get('recipient-portfolio'));
            }
          },
          onLoad: Ext.emptyFn
        }, {
          title: 'Portfolios',
          xtype: 'tabpanel',
          flex: 2,
          itemId: 'message-portfolios',
          height: 150,
          activeItem: 0,
          items:#{tabs.to_json}
      }]
      }, {
        region: 'center',
        itemId: 'message-content-panel',
        autoScroll: true,
        html: '<p>The message content will go here.</p>'
      }]
    });
  });

{'fraction_non_alphanumeric': 0.1447492310589417, 'fraction_numerical': 0.009038980603854121, 'mean_word_length': 1.7021709633649933, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1537479', 'n_tokens_mistral': 4871, 'n_tokens_neox': 4639, 'n_words': 854}