<commit_before>var cdb = require('cartodb.js-v3');
var $ = require('jquery-cdb-v3');
var RemoveNotificationDialog = require('./delete_notification_dialog_view');
var SendButton = require('./send_button_view');
var markdown = require('markdown');

module.exports = cdb.core.View.extend({

  events: {
    'click .js-resend': '_onClickResend',
    'click .js-remove': '_onClickRemove',
    'keydown .js-textarea': '_onTextareaKeydown',
    'input .js-textarea': '_updateCounter',
    'propertychange .js-textarea': '_updateCounter'
  },

  render: function () {
    this.$textarea = this.$('#carto_notification_body');

    this._initViews();
    this._updateCounter();

    return this;
  },

  _initViews: function () {
    this.sendButton = new SendButton();

    this.$('.js-send').html(this.sendButton.render().el);
    this.addView(this.sendButton);

    this.sendButton.bind('submitForm', this._submitForm, this);
  },

  _submitForm: function () {
    if(navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
      this.$('form').clone().appendTo('body').submit(); // FF only
    } else {
      this.$('form').submit();
    }
  },

  _updateCounter: function () {
    var strLen = $(markdown.toHTML(this.$textarea.val())).text().length;
    this.sendButton.updateCounter(strLen);
  },

  _onClickResend: function (event) {
    var $notificationItem = $(event.target).closest('.js-NotificationsList-item');
    var title = $notificationItem.find('.js-html_body').data('body');
    var recipients = $notificationItem.find('.js-recipients').data('recipients');

    this.$textarea.val(title);
    this.$('input[name="carto_notification[recipients]"]').prop('checked', false);
    this.$('input[name="carto_notification[recipients]"][value="' + recipients + '"]').prop('checked', true);

    $('body').animate({
      scrollTop: 0
    });

    this._updateCounter();
  },

  _onTextareaKeydown: function (event) {
    if (event.keyCode === 13 && event.metaKey) {
      this.sendButton.onUpdate();
    }
  },

  _onClickRemove: function (event) {
    var $target = $(event.target);
    this.remove_notification_dialog = new RemoveNotificationDialog({
      authenticityToken: this.options.authenticityToken,
      notificationId: $target.data('id')
    });
    this.remove_notification_dialog.appendToBody();
    this.addView(this.remove_notification_dialog);
  }
});
<commit_msg>remove org. notifications: dialog view<commit_after>var cdb = require('cartodb.js-v3');
var $ = require('jquery-cdb-v3');
var RemoveNotificationDialog = require('./delete_notification_dialog_view');
var SendButton = require('./send_button_view');
var markdown = require('markdown');

module.exports = cdb.core.View.extend({

  events: {
    'click .js-resend': '_onClickResend',
    'click .js-remove': '_onClickRemove',
    'keydown .js-textarea': '_onTextareaKeydown',
    'input .js-textarea': '_updateCounter',
    'propertychange .js-textarea': '_updateCounter'
  },

  render: function () {
    this.$textarea = this.$('#carto_notification_body');

    this._initViews();
    this._updateCounter();

    return this;
  },

  _initViews: function () {
    this.sendButton = new SendButton();

    this.$('.js-send').html(this.sendButton.render().el);
    this.addView(this.sendButton);

    this.sendButton.bind('submitForm', this._submitForm, this);
  },

  _submitForm: function () {
    if(navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
      this.$('form').clone().appendTo('body').submit(); // FF only
    } else {
      this.$('form').submit();
    }
  },

  _updateCounter: function () {
    var strLen = $(markdown.toHTML(this.$textarea.val())).text().length;
    this.sendButton.updateCounter(strLen);
  },

  _onClickResend: function (event) {
    var $notificationItem = $(event.target).closest('.js-NotificationsList-item');
    var title = $notificationItem.find('.js-html_body').data('body');
    var recipients = $notificationItem.find('.js-recipients').data('recipients');

    this.$textarea.val(title);
    this.$('input[name="carto_notification[recipients]"]').prop('checked', false);
    this.$('input[name="carto_notification[recipients]"][value="' + recipients + '"]').prop('checked', true);

    $('body').animate({
      scrollTop: 0
    });

    this._updateCounter();
  },

  _onTextareaKeydown: function (event) {
    if (event.keyCode === 13 && event.metaKey) {
      this.sendButton.onUpdate();
    }
  },

  _destroyRemoveNotificationDialog: function () {
    if (this.remove_notification_dialog) {
      this._unbindRemoveNotificationDialog();
      this.remove_notification_dialog.remove();
      this.removeView(this.remove_notification_dialog);
      this.remove_notification_dialog.hide();
      delete this.remove_notification_dialog;
    }
  },

  _bindRemoveNotificationDialog: function () {
    cdb.god.bind('closeDialogs:delete', this._destroyRemoveNotificationDialog, this);
  },

  _unbindRemoveNotificationDialog: function () {
    cdb.god.unbind('closeDialogs:delete', this._destroyRemoveNotificationDialog, this);
  },

  _onClickRemove: function (event) {
    cdb.god.trigger('closeDialogs:delete');

    var $target = $(event.target);

    this.remove_notification_dialog = new RemoveNotificationDialog({
      authenticityToken: this.options.authenticityToken,
      notificationId: $target.data('id')
    });
    this.remove_notification_dialog.appendToBody();
    this._bindRemoveNotificationDialog();
    this.addView(this.remove_notification_dialog);
  }
});
<|endoftext|>


<commit_before>import climate from 'assets/images/climate.jpg';
import biodiversity from 'assets/images/biodiversity.jpg';
import water from 'assets/images/water.jpg';
import commodities from 'assets/images/commodities.jpg';
import userStories from 'assets/images/user-stories.jpg';
import mongabay from 'assets/images/mongabay.jpg';
import earthJournalism from 'assets/images/earth-journalism.jpg';

import basemaps, {
  labels
} from 'components/map-v2/components/basemaps/basemaps-schema';

export const descriptions = {
  topics:
    'Topics are curated map presets for exploring the drivers of deforestation and understanding their impacts in ecosystems around the world.',
  placesToWatch:
    'A GFW service that identifies areas of high-priority GLAD alerts on a monthly basis.',
  stories:
    'Explore stories ralated to conservation from our users and other journalism sources.'
};

export const stories = {
  user: {
    slug: 'user',
    title: 'User stories',
    summary: 'Stories submitted by GFW users.',
    image: userStories,
    buttons: [
      {
        text: 'READ MORE',
        theme: 'theme-button-light theme-button-small',
        extLink: '/stories'
      },
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          }
        ]
      }
    }
  },
  monga: {
    slug: 'monga',
    title: 'Mongabay stories',
    summary:
      'This layer displays stories from Mongabay, a leading environmental science and conservation news website.',
    image: mongabay,
    buttons: [
      {
        text: 'READ MORE',
        theme: 'theme-button-light theme-button-small',
        extLink: '/stories'
      },
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'd7b12b17-9ed4-43ab-b8e4-efa2668c47f8',
            layers: ['e097ebfe-56d9-4564-8e2a-d3328bdaea38'],
            opacity: 1,
            visibility: true
          }
        ]
      }
    }
  },
  earthJournalism: {
    slug: 'earth-journalism',
    title: 'Earth Journalism Network Stories',
    summary:
      'This layer displays stories sourced from the Earth Journalism Network, a project of Internews that empowers and enables journalists from developing countries to cover the environment more effectively.',
    image: earthJournalism,
    buttons: [
      {
        text: 'READ MORE',
        theme: 'theme-button-light theme-button-small',
        extLink: '/stories'
      },
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          }
        ]
      }
    }
  }
};

export const topics = {
  biodiversity: {
    slug: 'biodiversity',
    title: 'Biodiversity',
    summary:
      'Protecting forest habitats is key to maintaining biodiversity. In the last ten years, one in ten trees were lost in protected areas.',
    image: biodiversity,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // biodiversity hotspots
          {
            dataset: 'a684a9bb-63f2-4bea-bf62-fd5e80d23d75',
            layers: ['dfd9deb6-8d39-4640-8571-4389d5d8898a'],
            opacity: 1,
            visibility: true
          },
          // biodiversity intactness
          {
            dataset: 'fee5fc38-7a62-49b8-8874-dfa31cbb1ef6',
            layers: ['43a205fe-aad3-4db1-8807-c399a3264349'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.default,
        label: labels.default
      }
    }
  },
  climate: {
    slug: 'climate',
    title: 'Climate',
    summary:
      'Forests remove carbon from the atmosphere, their loss or degradation compromises their ability to remove our ever-increasing emissions.',
    image: climate,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // biomass loss
          {
            dataset: 'a9cc6ec0-5c1c-4e36-9b26-b4ee0b50587b',
            layers: ['b32a2f15-25e8-4ecc-98e0-68782ab1c0fe'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.dark,
        label: labels.lightLabels
      },
      analysis: {
        showAnalysis: true
      }
    }
  },
  commodities: {
    slug: 'commodities',
    title: 'Commodities',
    summary:
      'To assist in increasing supply-chain transparency, our platform lets users track deforestation and estimate production over time in concession areas.',
    image: commodities,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // mining
          {
            dataset: '7a4d9a64-ecb1-45ec-a01e-658f1364fb2e',
            layers: ['fcd10026-e892-4fb8-8d79-8d76e3b94005'],
            opacity: 1,
            visibility: true
          },
          // managed forests
          {
            dataset: '4fc24a03-cb3e-4df3-a2ee-e2a8dca342b3',
            layers: ['c26db41a-b586-461c-b648-93205eafea0b'],
            opacity: 1,
            visibility: true
          },
          // oil palm
          {
            dataset: 'c4d4e07c-c5b4-4e2c-9db1-5c3bec185f0e',
            layers: ['0911abc4-d861-4d7a-84d6-0fa07b51d7d8'],
            opacity: 1,
            visibility: true
          },
          // wood fiber
          {
            dataset: '93e67a77-1a31-4d04-a75d-86a4d6e35d54',
            layers: ['557dc2cf-0ba7-4410-813c-99d692725fe7'],
            opacity: 1,
            visibility: true
          },
          // loss
          {
            dataset: '897ecc76-2308-4c51-aeb3-495de0bdca79',
            layers: ['c3075c5a-5567-4b09-bc0d-96ed1673f8b6'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.default,
        label: labels.default
      }
    }
  },
  water: {
    slug: 'water',
    title: 'Water',
    summary:
      'Healthy forested lands provide critical watershed functions, acting as natural infrastructure by minimizing erosion, purifying water, and reducing the impact of floods and droughts.',
    image: water,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: '63295b05-55a1-456c-a56c-c9ccb3a711ec',
            layers: ['d590f83c-9b54-4542-8d27-f61b8b19df46'],
            opacity: 1,
            visibility: true
          },
          // gain
          {
            dataset: '70e2549c-d722-44a6-a8d7-4a385d78565e',
            layers: ['3b22a574-2507-4b4a-a247-80057c1a1ad4'],
            opacity: 1,
            visibility: true
          },
          // loss
          {
            dataset: '897ecc76-2308-4c51-aeb3-495de0bdca79',
            layers: ['c3075c5a-5567-4b09-bc0d-96ed1673f8b6'],
            opacity: 1,
            visibility: true
          },
          // extent
          {
            dataset: '044f4af8-be72-4999-b7dd-13434fc4a394',
            layers: ['78747ea1-34a9-4aa7-b099-bdb8948200f4'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.default,
        label: labels.default
      }
    }
  }
};
<commit_msg>add user stories layer id<commit_after>import climate from 'assets/images/climate.jpg';
import biodiversity from 'assets/images/biodiversity.jpg';
import water from 'assets/images/water.jpg';
import commodities from 'assets/images/commodities.jpg';
import userStories from 'assets/images/user-stories.jpg';
import mongabay from 'assets/images/mongabay.jpg';
import earthJournalism from 'assets/images/earth-journalism.jpg';

import basemaps, {
  labels
} from 'components/map-v2/components/basemaps/basemaps-schema';

export const descriptions = {
  topics:
    'Topics are curated map presets for exploring the drivers of deforestation and understanding their impacts in ecosystems around the world.',
  placesToWatch:
    'A GFW service that identifies areas of high-priority GLAD alerts on a monthly basis.',
  stories:
    'Explore stories ralated to conservation from our users and other journalism sources.'
};

export const stories = {
  user: {
    slug: 'user',
    title: 'User stories',
    summary: 'Stories submitted by GFW users.',
    image: userStories,
    buttons: [
      {
        text: 'READ MORE',
        theme: 'theme-button-light theme-button-small',
        extLink: '/stories'
      },
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // stories
          {
            dataset: 'd7b12b17-9ed4-43ab-b8e4-efa2668c47f8',
            layers: ['ecddc53a-f7b9-42a8-9e7a-94a30aeef134'],
            opacity: 1,
            visibility: true
          }
        ]
      }
    }
  },
  monga: {
    slug: 'monga',
    title: 'Mongabay stories',
    summary:
      'This layer displays stories from Mongabay, a leading environmental science and conservation news website.',
    image: mongabay,
    buttons: [
      {
        text: 'READ MORE',
        theme: 'theme-button-light theme-button-small',
        extLink: '/stories'
      },
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'd7b12b17-9ed4-43ab-b8e4-efa2668c47f8',
            layers: ['e097ebfe-56d9-4564-8e2a-d3328bdaea38'],
            opacity: 1,
            visibility: true
          }
        ]
      }
    }
  },
  earthJournalism: {
    slug: 'earth-journalism',
    title: 'Earth Journalism Network Stories',
    summary:
      'This layer displays stories sourced from the Earth Journalism Network, a project of Internews that empowers and enables journalists from developing countries to cover the environment more effectively.',
    image: earthJournalism,
    buttons: [
      {
        text: 'READ MORE',
        theme: 'theme-button-light theme-button-small',
        extLink: '/stories'
      },
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          }
        ]
      }
    }
  }
};

export const topics = {
  biodiversity: {
    slug: 'biodiversity',
    title: 'Biodiversity',
    summary:
      'Protecting forest habitats is key to maintaining biodiversity. In the last ten years, one in ten trees were lost in protected areas.',
    image: biodiversity,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // biodiversity hotspots
          {
            dataset: 'a684a9bb-63f2-4bea-bf62-fd5e80d23d75',
            layers: ['dfd9deb6-8d39-4640-8571-4389d5d8898a'],
            opacity: 1,
            visibility: true
          },
          // biodiversity intactness
          {
            dataset: 'fee5fc38-7a62-49b8-8874-dfa31cbb1ef6',
            layers: ['43a205fe-aad3-4db1-8807-c399a3264349'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.default,
        label: labels.default
      }
    }
  },
  climate: {
    slug: 'climate',
    title: 'Climate',
    summary:
      'Forests remove carbon from the atmosphere, their loss or degradation compromises their ability to remove our ever-increasing emissions.',
    image: climate,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // biomass loss
          {
            dataset: 'a9cc6ec0-5c1c-4e36-9b26-b4ee0b50587b',
            layers: ['b32a2f15-25e8-4ecc-98e0-68782ab1c0fe'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.dark,
        label: labels.lightLabels
      },
      analysis: {
        showAnalysis: true
      }
    }
  },
  commodities: {
    slug: 'commodities',
    title: 'Commodities',
    summary:
      'To assist in increasing supply-chain transparency, our platform lets users track deforestation and estimate production over time in concession areas.',
    image: commodities,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: 'fdc8dc1b-2728-4a79-b23f-b09485052b8d',
            layers: [
              '6f6798e6-39ec-4163-979e-182a74ca65ee',
              'c5d1e010-383a-4713-9aaa-44f728c0571c'
            ],
            opacity: 1,
            visibility: true
          },
          // mining
          {
            dataset: '7a4d9a64-ecb1-45ec-a01e-658f1364fb2e',
            layers: ['fcd10026-e892-4fb8-8d79-8d76e3b94005'],
            opacity: 1,
            visibility: true
          },
          // managed forests
          {
            dataset: '4fc24a03-cb3e-4df3-a2ee-e2a8dca342b3',
            layers: ['c26db41a-b586-461c-b648-93205eafea0b'],
            opacity: 1,
            visibility: true
          },
          // oil palm
          {
            dataset: 'c4d4e07c-c5b4-4e2c-9db1-5c3bec185f0e',
            layers: ['0911abc4-d861-4d7a-84d6-0fa07b51d7d8'],
            opacity: 1,
            visibility: true
          },
          // wood fiber
          {
            dataset: '93e67a77-1a31-4d04-a75d-86a4d6e35d54',
            layers: ['557dc2cf-0ba7-4410-813c-99d692725fe7'],
            opacity: 1,
            visibility: true
          },
          // loss
          {
            dataset: '897ecc76-2308-4c51-aeb3-495de0bdca79',
            layers: ['c3075c5a-5567-4b09-bc0d-96ed1673f8b6'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.default,
        label: labels.default
      }
    }
  },
  water: {
    slug: 'water',
    title: 'Water',
    summary:
      'Healthy forested lands provide critical watershed functions, acting as natural infrastructure by minimizing erosion, purifying water, and reducing the impact of floods and droughts.',
    image: water,
    buttons: [
      {
        text: 'VIEW ON MAP',
        theme: 'theme-button-small'
      }
    ],
    payload: {
      map: {
        center: {
          lat: 27,
          lng: 12
        },
        zoom: 3,
        datasets: [
          // admin boundaries
          {
            dataset: '63295b05-55a1-456c-a56c-c9ccb3a711ec',
            layers: ['d590f83c-9b54-4542-8d27-f61b8b19df46'],
            opacity: 1,
            visibility: true
          },
          // gain
          {
            dataset: '70e2549c-d722-44a6-a8d7-4a385d78565e',
            layers: ['3b22a574-2507-4b4a-a247-80057c1a1ad4'],
            opacity: 1,
            visibility: true
          },
          // loss
          {
            dataset: '897ecc76-2308-4c51-aeb3-495de0bdca79',
            layers: ['c3075c5a-5567-4b09-bc0d-96ed1673f8b6'],
            opacity: 1,
            visibility: true
          },
          // extent
          {
            dataset: '044f4af8-be72-4999-b7dd-13434fc4a394',
            layers: ['78747ea1-34a9-4aa7-b099-bdb8948200f4'],
            opacity: 1,
            visibility: true
          }
        ],
        basemap: basemaps.default,
        label: labels.default
      }
    }
  }
};
<|endoftext|>


<commit_before>var columnDefs = [
    {field: "employeeId", hide: true},
    {field: "employeeName", hide: true},
    {field: "employmentType"},
    {field: "startDate"},
];

var gridOptions = {
    defaultColDef: {
        width: 235,
        resizable: true
    },
    rowModelType: 'serverSide',
    treeData: true,
    columnDefs: columnDefs,
    rowSelection: 'multiple',
    animateRows: true,
    cacheBlockSize: 100,
    maxBlocksInCache: 2,
    isServerSideGroup: function (dataItem) {
        // indicate if node is a group
        return dataItem.group;
    },
    getServerSideGroupKey: function (dataItem) {
        // specify which group key to use
        return dataItem.employeeName;
    },
    onGridReady: function (params) {
        // initialise with the first 2 groups arbitrarily expanded
        setTimeout(function () {
            // expands first node
            params.api.getDisplayedRowAtIndex(0).setExpanded(true);
        }, 1500);
        setTimeout(function () {
            // expands second node
            params.api.getDisplayedRowAtIndex(1).setExpanded(true);
        }, 2000);
    }
};

function purgeCache(route) {
    gridOptions.api.purgeServerSideCache(route);
}

// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function () {
    var gridDiv = document.querySelector('#myGrid');
    new agGrid.Grid(gridDiv, gridOptions);

    agGrid.simpleHttpRequest({url: 'https://raw.githubusercontent.com/ag-grid/ag-grid/latest/packages/ag-grid-docs/src/javascript-grid-server-side-model-tree-data/purging-tree-data/data/data.json'}).then(function (data) {
        var fakeServer = createFakeServer(data);
        var datasource = createServerSideDatasource(fakeServer);
        gridOptions.api.setServerSideDatasource(datasource);
    });
});

function createFakeServer(data) {
    function FakeServer(allData) {
        this.data = allData;
    }

    FakeServer.prototype.getData = function (request) {
        function extractRowsFromData(groupKeys, data) {
            if (groupKeys.length === 0) {
                return data.map(function(d) {
                    return {
                        group: !!d.underlings,
                        employeeId: d.employeeId + "",
                        employeeName: d.employeeName,
                        employmentType: d.employmentType,
                        startDate: d.startDate
                    }
                });
            }

            var key = groupKeys[0];
            for (var i = 0; i < data.length; i++) {
                if (data[i].employeeName === key) {
                    return extractRowsFromData(groupKeys.slice(1), data[i].underlings.slice());
                }
            }
        }

        return extractRowsFromData(request.groupKeys, this.data);
    };

    return new FakeServer(data)
}

function createServerSideDatasource(fakeServer) {
    function ServerSideDatasource(fakeServer) {
        this.fakeServer = fakeServer;
    }

    ServerSideDatasource.prototype.getRows = function (params) {
        console.log('ServerSideDatasource.getRows: params = ', params);

        var rows = this.fakeServer.getData(params.request);

        setTimeout(function () {
            params.successCallback(rows, rows.length);
        }, 200);
    };

    return new ServerSideDatasource(fakeServer);
}
<commit_msg>AG-3389 - added infinite scrolling to SSRM Tree Data example.<commit_after>var columnDefs = [
    {field: "employeeId", hide: true},
    {field: "employeeName", hide: true},
    {field: "employmentType"},
    {field: "startDate"},
];

var gridOptions = {
    defaultColDef: {
        width: 235,
        resizable: true
    },
    rowModelType: 'serverSide',
    treeData: true,
    columnDefs: columnDefs,
    rowSelection: 'multiple',
    animateRows: true,
    cacheBlockSize: 10,
    isServerSideGroup: function (dataItem) {
        // indicate if node is a group
        return dataItem.group;
    },
    getServerSideGroupKey: function (dataItem) {
        // specify which group key to use
        return dataItem.employeeName;
    },
    onGridReady: function (params) {
        // initialise with the first 2 groups arbitrarily expanded
        setTimeout(function () {
            // expands first node
            params.api.getDisplayedRowAtIndex(0).setExpanded(true);
        }, 1500);
        setTimeout(function () {
            // expands second node
            params.api.getDisplayedRowAtIndex(1).setExpanded(true);
        }, 2000);
    }
};

function purgeCache(route) {
    gridOptions.api.purgeServerSideCache(route);
}

// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function () {
    var gridDiv = document.querySelector('#myGrid');
    new agGrid.Grid(gridDiv, gridOptions);

    agGrid.simpleHttpRequest({url: 'https://raw.githubusercontent.com/ag-grid/ag-grid/latest/packages/ag-grid-docs/src/javascript-grid-server-side-model-tree-data/purging-tree-data/data/data.json'}).then(function (data) {
        var fakeServer = createFakeServer(data);
        var datasource = createServerSideDatasource(fakeServer);
        gridOptions.api.setServerSideDatasource(datasource);
    });
});

function createFakeServer(data) {
    function FakeServer(allData) {
        this.data = allData;
    }

    FakeServer.prototype.getData = function (request) {
        function extractRowsFromData(groupKeys, data) {
            if (groupKeys.length === 0) {
                return data.map(function(d) {
                    return {
                        group: !!d.underlings,
                        employeeId: d.employeeId + "",
                        employeeName: d.employeeName,
                        employmentType: d.employmentType,
                        startDate: d.startDate
                    }
                });
            }

            var key = groupKeys[0];
            for (var i = 0; i < data.length; i++) {
                if (data[i].employeeName === key) {
                    return extractRowsFromData(groupKeys.slice(1), data[i].underlings.slice());
                }
            }
        }

        return extractRowsFromData(request.groupKeys, this.data);
    };

    return new FakeServer(data)
}

function createServerSideDatasource(fakeServer) {
    function ServerSideDatasource(fakeServer) {
        this.fakeServer = fakeServer;
    }

    ServerSideDatasource.prototype.getRows = function (params) {
        console.log('ServerSideDatasource.getRows: params = ', params);
        var request = params.request;
        var allRows = this.fakeServer.getData(request);
        var resultsForBlock = allRows.slice(request.startRow, request.endRow);
        setTimeout(function () {
            params.successCallback(resultsForBlock, allRows.length);
        }, 500);
    };

    return new ServerSideDatasource(fakeServer);
}
<|endoftext|>


<commit_before>const getSelectStyles = theme => {
  return {
    clearIndicator: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
    container: base => ({
      ...base,
      background: theme.colors.neutral0,
      fontFamily: 'Arial',
      lineHeight: 'normal',
    }),
    control: (base, state) => {
      let border;
      let borderBottom;
      let backgroundColor;

      if (state.isFocused) {
        border = `1px solid ${theme.colors.primary600} !important`;
      } else {
        border = `1px solid ${theme.colors.neutral200} !important`;
      }

      if (state.menuIsOpen === true) {
        borderBottom = `1px solid ${theme.colors.primary600} !important`;
      }

      if (state.isDisabled) {
        backgroundColor = '#fafafb !important';
      }

      return {
        ...base,
        fontSize: 14,
        height: 40,
        border,
        outline: 0,
        boxShadow: 0,
        borderRadius: '2px !important',
        borderBottom,
        backgroundColor,
        borderTopLeftRadius: '4px !important',
        borderTopRightRadius: '4px !important',
        borderBottomLeftRadius: '4px !important',
        borderBottomRightRadius: '4px !important',
      };
    },
    indicatorContainer: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
    input: base => ({ ...base, margin: 0, padding: 0 }),
    menu: base => {
      return {
        ...base,
        width: '100%',
        marginTop: theme.spaces[1],
        borderRadius: '4px !important',
        borderTopLeftRadius: '4px !important',
        borderTopRightRadius: '4px !important',
        border: `1px solid ${theme.colors.neutral200} !important`,
        boxShadow: 0,
        fontSize: '14px',
        fontFamily: 'Arial',
        zIndex: 2,
      };
    },
    menuList: base => ({
      ...base,
      paddingLeft: theme.spaces[1],
      paddingTop: theme.spaces[1],
      paddingRight: theme.spaces[1],
      paddingBottom: theme.spaces[1],
    }),
    option: (base, state) => {
      let backgroundColor = base.backgroundColor;

      if (state.isFocused) {
        backgroundColor = theme.colors.primary100;
      }

      return { ...base, lineHeight: theme.spaces[5], backgroundColor, borderRadius: 4 };
    },
    placeholder: base => ({ ...base, marginLeft: 0 }),
    singleValue: base => ({ ...base, marginLeft: 0 }),
    valueContainer: base => ({
      ...base,
      padding: 0,
      paddingLeft: theme.spaces[4],
      marginLeft: 0,
      marginRight: 0,
    }),
  };
};

export default getSelectStyles;
<commit_msg>fix(dark-mode): fixed cm relation select bg color<commit_after>const getSelectStyles = theme => {
  return {
    clearIndicator: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
    container: base => ({
      ...base,
      background: theme.colors.neutral0,
      fontFamily: 'Arial',
      lineHeight: 'normal',
    }),
    control: (base, state) => {
      let border;
      let borderBottom;
      let backgroundColor;

      if (state.isFocused) {
        border = `1px solid ${theme.colors.primary600} !important`;
      } else {
        border = `1px solid ${theme.colors.neutral200} !important`;
      }

      if (state.menuIsOpen === true) {
        borderBottom = `1px solid ${theme.colors.primary600} !important`;
      }

      if (state.isDisabled) {
        backgroundColor = '#fafafb !important';
      }

      return {
        ...base,
        fontSize: 14,
        height: 40,
        border,
        outline: 0,
        boxShadow: 0,
        borderRadius: '2px !important',
        borderBottom,
        backgroundColor,
        borderTopLeftRadius: '4px !important',
        borderTopRightRadius: '4px !important',
        borderBottomLeftRadius: '4px !important',
        borderBottomRightRadius: '4px !important',
      };
    },
    indicatorContainer: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
    input: base => ({ ...base, margin: 0, padding: 0 }),
    menu: base => {
      return {
        ...base,
        width: '100%',
        marginTop: theme.spaces[1],
        backgroundColor: theme.colors.neutral0,
        borderRadius: '4px !important',
        borderTopLeftRadius: '4px !important',
        borderTopRightRadius: '4px !important',
        border: `1px solid ${theme.colors.neutral200} !important`,
        boxShadow: 0,
        fontSize: '14px',
        fontFamily: 'Arial',
        zIndex: 2,
      };
    },
    menuList: base => ({
      ...base,
      paddingLeft: theme.spaces[1],
      paddingTop: theme.spaces[1],
      paddingRight: theme.spaces[1],
      paddingBottom: theme.spaces[1],
    }),
    option: (base, state) => {
      let backgroundColor = base.backgroundColor;

      if (state.isFocused) {
        backgroundColor = theme.colors.primary100;
      }

      return { ...base, lineHeight: theme.spaces[5], backgroundColor, borderRadius: 4 };
    },
    placeholder: base => ({ ...base, marginLeft: 0 }),
    singleValue: base => ({ ...base, marginLeft: 0 }),
    valueContainer: base => ({
      ...base,
      padding: 0,
      paddingLeft: theme.spaces[4],
      marginLeft: 0,
      marginRight: 0,
    }),
  };
};

export default getSelectStyles;
<|endoftext|>


<commit_before>'use strict';

function Floating2DText(w, text, type, scene, current_color) {
    this.__init__(w, text, type, scene, current_color);
}

Floating2DText.prototype = {

    material: null,
    dynamic_texture: null,

    get_text_length: function() {
        return this.dynamic_texture.getTextLength(this.text);
    },

    clear_text: function() {
        this.dynamic_texture.clear();
        this.dynamic_texture.needsUpdate = true;
    },

    _update_text: function() {
        this.dynamic_texture.clear('black').drawText(this.text, 0, this.height, this.current_color, 'black');
        this.dynamic_texture.needsUpdate = true;
    },

    _update_color: function() {
        this.dynamic_texture.clear('black').drawText(this.text, 0, this.height, this.current_color, 'black');
        this.dynamic_texture.needsUpdate = true;
    },

    initialize: function() {
        if (this.type == TYPE_TITLE) {
            this.height = 32;
        } else {
            this.height = 16;
        }

        // PlaneGeometry takes in a width, height, optionalWidthSegments (default 1), optionalHeightSegments (default 1)
        this.geometry = new THREE.PlaneGeometry(this.width, this.height);

        var texture_width  = get_nearest_power_of_two_for_number(this.width * 2);
        var texture_height = get_nearest_power_of_two_for_number(this.height * 2);
        var font_size = Math.round(texture_height * .4);

        l('Font size is : ' + font_size);

        this.dynamic_texture = new THREEx.DynamicTexture(texture_width, texture_height);
        if (this.type == TYPE_TITLE) {
            this.dynamic_texture.context.font = 'Bold ' + str(font_size) + 'px Arial';
        } else {
            this.dynamic_texture.context.font = str(font_size) + 'px Arial';
        }
        // TODO : Investigate this
        //this.dynamic_texture.texture.anisotropy = renderer_api.renderer.capabilities.getMaxAnisotropy()

        this.material = new THREE.MeshBasicMaterial({
            map : this.dynamic_texture.texture
        });

        this.material.transparent = false;
        this.material.side = THREE.FrontSide;

        this._update_color();

        this.mesh = new THREE.Mesh(this.geometry, this.material);

        this.object3D.add(this.mesh);
        this.scene.add(this.object3D);
    },

    __init__: function(w, text, type, scene, current_color) {
        this.is_2d_text = true;

        // Inherit from FloatingText.
        FloatingText.call(this, w, text, type, scene, current_color);
        // Inherit from Interactive.
        Interactive.call(this);
        // Inherit from Visibility.
        Visibility.call(this);
    }

};
<commit_msg>general updating 86<commit_after>'use strict';

function Floating2DText(w, text, type, scene, current_color) {
    this.__init__(w, text, type, scene, current_color);
}

Floating2DText.prototype = {

    material: null,
    dynamic_texture: null,

    get_text_length: function() {
        return this.dynamic_texture.getTextLength(this.text);
    },

    clear_text: function() {
        this.dynamic_texture.clear();
        this.dynamic_texture.needsUpdate = true;
    },

    _update_text: function() {
        this.dynamic_texture.clear('black').drawText(this.text, 0, this.height, this.current_color, 'black');
        this.dynamic_texture.needsUpdate = true;
    },

    _update_color: function() {
        this.dynamic_texture.clear('black').drawText(this.text, 0, this.height, this.current_color, 'black');
        this.dynamic_texture.needsUpdate = true;
    },

    initialize: function() {
        if (this.type == TYPE_TITLE) {
            this.height = 32;
        } else {
            this.height = 16;
        }

        // PlaneGeometry takes in a width, height, optionalWidthSegments (default 1), optionalHeightSegments (default 1)
        this.geometry = new THREE.PlaneGeometry(this.width, this.height);

        var texture_width  = get_nearest_power_of_two_for_number(this.width * 2);
        var texture_height = get_nearest_power_of_two_for_number(this.height * 2);
        var font_size = Math.round(texture_height * .5);

        l('Font size is : ' + font_size);

        this.dynamic_texture = new THREEx.DynamicTexture(texture_width, texture_height);
        if (this.type == TYPE_TITLE) {
            this.dynamic_texture.context.font = 'Bold ' + str(font_size) + 'px Arial';
        } else {
            this.dynamic_texture.context.font = str(font_size) + 'px Arial';
        }
        // TODO : Investigate this
        //this.dynamic_texture.texture.anisotropy = renderer_api.renderer.capabilities.getMaxAnisotropy()

        this.material = new THREE.MeshBasicMaterial({
            map : this.dynamic_texture.texture
        });

        this.material.transparent = false;
        this.material.side = THREE.FrontSide;

        this._update_color();

        this.mesh = new THREE.Mesh(this.geometry, this.material);

        this.object3D.add(this.mesh);
        this.scene.add(this.object3D);
    },

    __init__: function(w, text, type, scene, current_color) {
        this.is_2d_text = true;

        // Inherit from FloatingText.
        FloatingText.call(this, w, text, type, scene, current_color);
        // Inherit from Interactive.
        Interactive.call(this);
        // Inherit from Visibility.
        Visibility.call(this);
    }

};
<|endoftext|>


<commit_before><commit_msg>Solved more challenges<commit_after><|endoftext|>


<commit_before>/**
 *
 *
 */
(function (window) {
    'use strict';

    window.widgets = {

        const: {
            css: {
                base: 'widget',
                selector: {
                    general: '.widget',
                    prefix: '.widget.',
                    form: 'form.form-widget',
                    group: '.form-group',
                    label: 'label .label-text'
                }
            },
            attr: {
                name: 'name'
            },
            tag: {
                input: ['input', 'select', 'textarea']
            }
        },

        registered: {},

        /**
         * Register a widget type by a DOM selector as key for this type.
         * @param selector    the jQuery selector to find the widgets instances
         * @param widgetClass the widget implementation class (required)
         * @param options     additional options (see richtext-widget for example)
         */
        register: function (selector, widgetClass, options) {
            widgets.registered[selector] = _.extend({
                selector: selector,
                widgetClass: widgetClass
            }, options);
        },

        /**
         * Set up all components of a DOM element; add a view at each element marked with
         * a widget css class. Uses the 'core.getView()' function to add the View to the
         * DOM element itself to avoid multiple View instances for one DOM element.
         */
        setUp: function (root) {
            var $root = root ? $(root) : $(document);
            _.keys(widgets.registered).forEach(function (selector) {
                $root.find(selector).each(function () {
                    var widget = widgets.registered[selector];
                    core.getView(this, widget.widgetClass);
                });
            });
        },

        /**
         * applies the abstract 'option' (must be a function) to all widgets which have such
         * an option registered and are matching to the widgets selector in the 'root's context
         * used for example
         *  - by the multi-form-widget to apply the 'afterClone' option after item creation (cloning)
         */
        apply: function (root, option) {
            _.keys(widgets.registered).forEach(function (selector) {
                var widget = widgets.registered[selector];
                var method = widget[option];
                if (_.isFunction(method)) {
                    var $root = $(root);
                    if ($root.is(widget.selector)) {
                        method.apply(root);
                    } else {
                        $root.find(widget.selector).each(function () {
                            method.apply(this);
                        });
                    }
                }
            });
        },

        /**
         *
         * #abstract
         */
        Widget: Backbone.View.extend({

            initialize: function (options) {
                this.$input = this.retrieveInput();
                this.name = this.retrieveName();
                this.form = this.retrieveForm();
            },

            retrieveInput: function () {
                var $inputEl = [];
                for (var i = 0; $inputEl.length === 0 && i < widgets.const.tag.input.length; i++) {
                    $inputEl = this.$el.is(widgets.const.tag.input[i]) ? this.$el
                        : this.$(widgets.const.tag.input[i] + ':not([type="hidden"])');
                }
                return $inputEl;
            },

            retrieveName: function () {
                return this.$input.attr(widgets.const.attr.name);
            },

            retrieveLabel: function () {
                var c = widgets.const.css.selector;
                var $label = this.$el.closest(c.group).find(c.label);
                return $label.length === 1 ? $label.text().trim() : this.retrieveName();
            },

            declareName: function (name) {
                if (name) {
                    this.$input.attr(widgets.const.attr.name, name);
                } else {
                    this.$input.removeAttr(widgets.const.attr.name);
                }
            },

            retrieveForm: function () {
                var $form = this.$el.closest(widgets.const.css.selector.form);
                return $form.length > 0 ? $form[0].view : undefined;
            },

            /**
             * #abstract
             * @returns {undefined}
             */
            getValue: function () {
                return undefined;
            },

            /**
             * #abstract
             */
            setValue: function (value) {
            },

            /**
             * #default
             */
            setDefaultValue: function (value) {
            },

            /**
             * #abstract
             */
            reset: function () {
            },

            /**
             * returns the current validation state, calls 'validate' if no state is present
             */
            isValid: function (alertMethod) {
                if (this.valid === undefined) {
                    this.valid = _.isFunction(this.validate)
                        ? this.validate(alertMethod)
                        : true;
                }
                this.alertFlush(alertMethod);
                return this.valid;
            },

            validationReset: function () {
                this.valid = undefined;
                this.alertMessage = undefined;
            },

            /**
             * validates the current value using the 'rules' and the 'pattern' if present
             */
            validate: function (alertMethod) {
                this.valid = true;
                // check only if this field has a 'name' (included in a form) and is visible
                // prevent from validation check if the 'name' is removed or the class contains 'hidden'
                if (!this.$el.hasClass('hidden') && this.retrieveName()) {
                    var value = this.getValue();
                    if (this.rules) {
                        var valid;
                        if (this.valid && this.rules.pattern) {
                            // check pattern only if not blank (blank is valid if allowed explicitly)
                            valid = this.valid = (this.rules.blank && (!value || value.trim().length < 1))
                                || this.rules.pattern.test(value);
                            if (!valid) {
                                this.alert(alertMethod, 'danger', '',
                                    this.rules.patternHint || core.i18n.get("value doesn't match pattern"),
                                    ('' + this.rules.pattern).replace(/^\//, '').replace(/\/$/, ''));
                            }
                        }
                        if (this.valid && this.rules.required) {
                            // check for a defined and not blank value
                            valid = this.valid = (value !== undefined &&
                                (this.rules.blank || value.trim().length > 0));
                            if (!valid) {
                                this.alert(alertMethod, 'danger', '', core.i18n.get('value is required'));
                            }
                        }
                    }
                    // the extension hook for further validation in 'subclasses'
                    if (this.valid && _.isFunction(this.extValidate)) {
                        this.valid = this.extValidate(value);
                    }
                    if (this.valid) {
                        this.$el.closest('.form-group').removeClass('has-error');
                    } else {
                        this.$el.closest('.form-group').addClass('has-error');
                    }
                }
                return this.valid;
            },

            initRules: function ($element) {
                if (!$element) {
                    $element = this.$el;
                }
                this.label = $element.data('label') || this.retrieveLabel();
                // scan 'data-pattern' attribute
                var pattern = $element.data('pattern');
                if (pattern) {
                    try {
                        this.rules = _.extend(this.rules || {}, {
                            pattern: pattern.indexOf('/') === 0
                                // use '/.../ig' to specify pattern and flags
                                ? eval(pattern)
                                // pure strings can not have additional flags...
                                : new RegExp(pattern)
                        });
                    } catch (ex) {
                        core.log.error("widget[" + this.name + "]: " + ex);
                    }
                    var patternHint = $element.data('pattern-hint');
                    if (patternHint) {
                        this.rules.patternHint = patternHint;
                    }
                }
                // scan 'data-rules' attribute
                var rules = $element.data('rules');
                if (rules) {
                    this.rules = _.extend(this.rules || {}, {
                        required: rules.indexOf('required') >= 0 || rules.indexOf('mandatory') >= 0,
                        blank: rules.indexOf('blank') >= 0,
                        unique: rules.indexOf('unique') >= 0
                    });
                }
            },

            grabFocus: function () {
                this.$input.focus();
            },

            alert: function (alertMethod, type, label, message, hint) {
                if (_.isFunction(alertMethod)) {
                    alertMethod(type, label || this.label, message, hint);
                } else {
                    this.alertMessage = {
                        type: type,
                        label: label,
                        message: message,
                        hint: hint
                    }
                }
            },

            /**
             * print out a probably delayed message
             */
            alertFlush: function (alertMethod) {
                if (_.isFunction(alertMethod) && this.alertMessage) {
                    alertMethod(this.alertMessage.type, this.alertMessage.label || this.label,
                        this.alertMessage.message, this.alertMessage.hint);
                    this.alertMessage = undefined;
                }
            }
        })
    };

    /**
     * register the 'hidden' input as a widget to add the widgets behaviour to such hidden values
     */
    window.widgets.register('.widget.hidden-widget', window.widgets.Widget);

})(window);
<commit_msg>enable value preparation on input validation<commit_after>/**
 *
 *
 */
(function (window) {
    'use strict';

    window.widgets = {

        const: {
            css: {
                base: 'widget',
                selector: {
                    general: '.widget',
                    prefix: '.widget.',
                    form: 'form.form-widget',
                    group: '.form-group',
                    label: 'label .label-text'
                }
            },
            attr: {
                name: 'name'
            },
            tag: {
                input: ['input', 'select', 'textarea']
            }
        },

        registered: {},

        /**
         * Register a widget type by a DOM selector as key for this type.
         * @param selector    the jQuery selector to find the widgets instances
         * @param widgetClass the widget implementation class (required)
         * @param options     additional options (see richtext-widget for example)
         */
        register: function (selector, widgetClass, options) {
            widgets.registered[selector] = _.extend({
                selector: selector,
                widgetClass: widgetClass
            }, options);
        },

        /**
         * Set up all components of a DOM element; add a view at each element marked with
         * a widget css class. Uses the 'core.getView()' function to add the View to the
         * DOM element itself to avoid multiple View instances for one DOM element.
         */
        setUp: function (root) {
            var $root = root ? $(root) : $(document);
            _.keys(widgets.registered).forEach(function (selector) {
                $root.find(selector).each(function () {
                    var widget = widgets.registered[selector];
                    core.getView(this, widget.widgetClass);
                });
            });
        },

        /**
         * applies the abstract 'option' (must be a function) to all widgets which have such
         * an option registered and are matching to the widgets selector in the 'root's context
         * used for example
         *  - by the multi-form-widget to apply the 'afterClone' option after item creation (cloning)
         */
        apply: function (root, option) {
            _.keys(widgets.registered).forEach(function (selector) {
                var widget = widgets.registered[selector];
                var method = widget[option];
                if (_.isFunction(method)) {
                    var $root = $(root);
                    if ($root.is(widget.selector)) {
                        method.apply(root);
                    } else {
                        $root.find(widget.selector).each(function () {
                            method.apply(this);
                        });
                    }
                }
            });
        },

        /**
         *
         * #abstract
         */
        Widget: Backbone.View.extend({

            initialize: function (options) {
                this.$input = this.retrieveInput();
                this.name = this.retrieveName();
                this.form = this.retrieveForm();
            },

            retrieveInput: function () {
                var $inputEl = [];
                for (var i = 0; $inputEl.length === 0 && i < widgets.const.tag.input.length; i++) {
                    $inputEl = this.$el.is(widgets.const.tag.input[i]) ? this.$el
                        : this.$(widgets.const.tag.input[i] + ':not([type="hidden"])');
                }
                return $inputEl;
            },

            retrieveName: function () {
                return this.$input.attr(widgets.const.attr.name);
            },

            retrieveLabel: function () {
                var c = widgets.const.css.selector;
                var $label = this.$el.closest(c.group).find(c.label);
                return $label.length === 1 ? $label.text().trim() : this.retrieveName();
            },

            declareName: function (name) {
                if (name) {
                    this.$input.attr(widgets.const.attr.name, name);
                } else {
                    this.$input.removeAttr(widgets.const.attr.name);
                }
            },

            retrieveForm: function () {
                var $form = this.$el.closest(widgets.const.css.selector.form);
                return $form.length > 0 ? $form[0].view : undefined;
            },

            /**
             * #abstract
             * @returns {undefined}
             */
            getValue: function () {
                return undefined;
            },

            /**
             * @returns the - probably prepared - value for the input validation
             */
            getValueForValidation: function(){
                return this.getValue();
            },

            /**
             * #abstract
             */
            setValue: function (value) {
            },

            /**
             * #default
             */
            setDefaultValue: function (value) {
            },

            /**
             * #abstract
             */
            reset: function () {
            },

            /**
             * returns the current validation state, calls 'validate' if no state is present
             */
            isValid: function (alertMethod) {
                if (this.valid === undefined) {
                    this.valid = _.isFunction(this.validate)
                        ? this.validate(alertMethod)
                        : true;
                }
                this.alertFlush(alertMethod);
                return this.valid;
            },

            validationReset: function () {
                this.valid = undefined;
                this.alertMessage = undefined;
            },

            /**
             * validates the current value using the 'rules' and the 'pattern' if present
             */
            validate: function (alertMethod) {
                this.valid = true;
                // check only if this field has a 'name' (included in a form) and is visible
                // prevent from validation check if the 'name' is removed or the class contains 'hidden'
                if (!this.$el.hasClass('hidden') && this.retrieveName()) {
                    var value = this.getValueForValidation();
                    if (this.rules) {
                        var valid;
                        if (this.valid && this.rules.pattern) {
                            // check pattern only if not blank (blank is valid if allowed explicitly)
                            valid = this.valid = (this.rules.blank && (!value || value.trim().length < 1))
                                || this.rules.pattern.test(value);
                            if (!valid) {
                                this.alert(alertMethod, 'danger', '',
                                    this.rules.patternHint || core.i18n.get("value doesn't match pattern"),
                                    ('' + this.rules.pattern).replace(/^\//, '').replace(/\/$/, ''));
                            }
                        }
                        if (this.valid && this.rules.required) {
                            // check for a defined and not blank value
                            valid = this.valid = (value !== undefined &&
                                (this.rules.blank || value.trim().length > 0));
                            if (!valid) {
                                this.alert(alertMethod, 'danger', '', core.i18n.get('value is required'));
                            }
                        }
                    }
                    // the extension hook for further validation in 'subclasses'
                    if (this.valid && _.isFunction(this.extValidate)) {
                        this.valid = this.extValidate(value);
                    }
                    if (this.valid) {
                        this.$el.closest('.form-group').removeClass('has-error');
                    } else {
                        this.$el.closest('.form-group').addClass('has-error');
                    }
                }
                return this.valid;
            },

            initRules: function ($element) {
                if (!$element) {
                    $element = this.$el;
                }
                this.label = $element.data('label') || this.retrieveLabel();
                // scan 'data-pattern' attribute
                var pattern = $element.data('pattern');
                if (pattern) {
                    try {
                        this.rules = _.extend(this.rules || {}, {
                            pattern: pattern.indexOf('/') === 0
                                // use '/.../ig' to specify pattern and flags
                                ? eval(pattern)
                                // pure strings can not have additional flags...
                                : new RegExp(pattern)
                        });
                    } catch (ex) {
                        core.log.error("widget[" + this.name + "]: " + ex);
                    }
                    var patternHint = $element.data('pattern-hint');
                    if (patternHint) {
                        this.rules.patternHint = patternHint;
                    }
                }
                // scan 'data-rules' attribute
                var rules = $element.data('rules');
                if (rules) {
                    this.rules = _.extend(this.rules || {}, {
                        required: rules.indexOf('required') >= 0 || rules.indexOf('mandatory') >= 0,
                        blank: rules.indexOf('blank') >= 0,
                        unique: rules.indexOf('unique') >= 0
                    });
                }
            },

            grabFocus: function () {
                this.$input.focus();
            },

            alert: function (alertMethod, type, label, message, hint) {
                if (_.isFunction(alertMethod)) {
                    alertMethod(type, label || this.label, message, hint);
                } else {
                    this.alertMessage = {
                        type: type,
                        label: label,
                        message: message,
                        hint: hint
                    }
                }
            },

            /**
             * print out a probably delayed message
             */
            alertFlush: function (alertMethod) {
                if (_.isFunction(alertMethod) && this.alertMessage) {
                    alertMethod(this.alertMessage.type, this.alertMessage.label || this.label,
                        this.alertMessage.message, this.alertMessage.hint);
                    this.alertMessage = undefined;
                }
            }
        })
    };

    /**
     * register the 'hidden' input as a widget to add the widgets behaviour to such hidden values
     */
    window.widgets.register('.widget.hidden-widget', window.widgets.Widget);

})(window);
<|endoftext|>


<commit_before>import React from 'react';
import classNames from 'classnames';
import propTypes from 'prop-types';
import SprkInputLabel from './SprkInputLabel'

const SprkLabelLocationCheck = ({
  children,
  type,
  label,
  leadingIcon,
  hiddenLabel,
  id,
}) => {
  if (type === 'hugeTextInput') {
    return (
      <>
        {children}
        <SprkInputLabel
          id={id}
          leadingIcon={id}
          hiddenLabel={hiddenLabel}
          label={label}
        />
      </>
    );
  }
  return (
    <>
      <SprkInputLabel
        id={id}
        leadingIcon={id}
        hiddenLabel={hiddenLabel}
        label={label}
      />
      {children}
    </>
  );
};

SprkLabelLocationCheck.propTypes = {
  type: propTypes.string,
  label: propTypes.string,
  leadingIcon: propTypes.string,
  id: propTypes.string,
  hiddenLabel: propTypes.bool,
};

export default SprkLabelLocationCheck;
<commit_msg>SprkLabelLocationCheck was passing the wrong prop to leadingIcon<commit_after>import React from 'react';
import propTypes from 'prop-types';
import SprkInputLabel from './SprkInputLabel'

const SprkLabelLocationCheck = ({
  children,
  type,
  label,
  leadingIcon,
  hiddenLabel,
  id,
}) => {
  if (type === 'hugeTextInput' || type === 'hugeSelect') {
    return (
      <>
        {children}
        <SprkInputLabel
          id={id}
          leadingIcon={leadingIcon}
          hiddenLabel={hiddenLabel}
          label={label}
        />
      </>
    );
  }
  return (
    <>
      <SprkInputLabel
        id={id}
        leadingIcon={id}
        hiddenLabel={hiddenLabel}
        label={label}
      />
      {children}
    </>
  );
};

SprkLabelLocationCheck.propTypes = {
  type: propTypes.string,
  label: propTypes.string,
  leadingIcon: propTypes.string,
  id: propTypes.string,
  hiddenLabel: propTypes.bool,
};

export default SprkLabelLocationCheck;
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/** Namespace for this file */
var CodeHighlighting = {}

CodeHighlighting.ADD_COMMENT_FORM_ID = 'add-comment-form';

/**
 * Called when document rendering is completed. Highlight code and
 * sets up handlers for code review if needed.
 */
$(document).ready(function () {
    prettyPrint(function () {
        var hasCodeReview = $('#has-code-review').val();
        if (hasCodeReview == 'true') {
            CodeHighlighting.displayReviewComments().done(CodeHighlighting.setupEditButtons);

            var branchId = $('#branchId').val();
            PermissionService.hasPermission(branchId, 'BRANCH',
                    'BranchPermission.LEAVE_COMMENTS_IN_CODE_REVIEW',
                    CodeHighlighting.setupAddCommentFormHandlers);

			CodeHighlighting.setupEditCommentHandlers();
        }
    });
});

/**
 * Function to append comment to HTML
 */
CodeHighlighting.addComment = function (comment) {
    $('.script-first-post ol.linenums li:nth-child(' + comment.lineNumber + ')')
			.append(CodeHighlighting.getCommentHtml(comment));
}

/**
 * Function to update existing comment
 */
CodeHighlighting.updateComment = function (comment) {
    var reviewContainer = $('.script-first-post .review-container input[name=id][value=' + comment.id + ']').parent();
	reviewContainer.find('.review-body').html(CodeHighlighting.htmlEncode(comment.body));
	reviewContainer.show();
}

/**
 * Get review comments for this topic from server and display them
 * @return deffered object for AJAX request (displaying comments)
 */
CodeHighlighting.displayReviewComments = function () {
    var codeReviewId = $('#codeReviewId').val();
    return $.ajax({
        url: baseUrl + '/reviews/' + codeReviewId + '/json',
        type: "GET",
        success: function (data) {
            var comments = data.result.comments;
            for (var i = 0; i < comments.length; i++) {
                CodeHighlighting.addComment(comments[i]);
            }
        },
        error: function () {
            bootbox.alert($labelUnexpectedError);
        }
    });
}

/**
 * Initializes handlers for 'Add comment' action
 */
CodeHighlighting.setupAddCommentFormHandlers = function () {
    $('.script-first-post').on('click', 'input:button[name=cancel-add]', function (event) {
        event.stopPropagation();
        CodeHighlighting.removeCommentForm();
    });

	// don't handle clicks on comments
	$('.script-first-post').on('click', 'ol.linenums li div.review-container', function () {
		return false;
	});

    $('.script-first-post').on('click', 'ol.linenums li', function () {
        var addCommentForm = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
        if (addCommentForm.length == 0) {
            var index = $(this).index();
			// display form before first comment
			CodeHighlighting.showAddCommentForm($(this).find('div:first').prev(), index + 1);
        }

    });

    $('.script-first-post').on('click', "input:button[name=add]", function (event) {
        event.stopPropagation();

        var formContainer = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
        if (Antimultipost.beingSubmitted(formContainer)) {
            return;
        }
        Antimultipost.disableSubmit(formContainer);

		var data = {id: 0, authorId:0, authorUsername:""};
        data.lineNumber = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=lineNumber]').val();
        data.body = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=body]').val();
		data.reviewId = $('#codeReviewId').val();

        $.post(baseUrl + '/reviewcomments/new', data)
                .success(function (data) {
                    if (data.status == 'Success') {
                        CodeHighlighting.removeCommentForm();
						CodeHighlighting.addComment(data.result)
                    }
                    else if (data.reason == 'validation') {
                        CodeHighlighting.displayValidationErrors(data.result);
                    }
                    else {
                        bootbox.alert($labelUnexpectedError);
                    }
                })
                .error(function (data) {
                    bootbox.alert($labelUnexpectedError);
                })
                .complete(function () {
                    Antimultipost.enableSubmit(formContainer);
                });
    });
}

/**
 * Initializes handlers for 'Edit comment' actions
 */
CodeHighlighting.setupEditCommentHandlers = function() {
    $('.script-first-post').on('click', 'input:button[name=cancel-edit]', function (event) {
        event.stopPropagation();
		$('#' + CodeHighlighting.ADD_COMMENT_FORM_ID).prev().show();
        CodeHighlighting.removeCommentForm();
    });

	$('.script-first-post').on('click', 'div.review-container a[name=edit-review]', function() {
		var addCommentForm = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
		if (addCommentForm.length == 0) {
			var reviewContainer = $(this).closest('.review-container');
			var comment = {};
			comment.id = reviewContainer.find('input[name=id]').val();
			comment.body = reviewContainer.find('.review-body').html();
			CodeHighlighting.showEditCommentForm(reviewContainer, comment);
        }

		return false;
	});

	$('.script-first-post').on('click', "input:button[name=edit]", function (event) {
        event.stopPropagation();

        var formContainer = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
        if (Antimultipost.beingSubmitted(formContainer)) {
            return;
        }
        Antimultipost.disableSubmit(formContainer);

		var data = {authorId:0, authorUsername:""};
		data.id = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=id]').val();
        data.lineNumber = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=lineNumber]').val();
        data.body = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=body]').val();
		data.branchId = $('#branchId').val();

        $.post(baseUrl + '/reviewcomments/edit', data)
                .success(function (data) {
                    if (data.status == 'Success') {
						CodeHighlighting.updateComment(data.result);
						CodeHighlighting.removeCommentForm();
                    }
                    else if (data.reason == 'validation') {
                        CodeHighlighting.displayValidationErrors(data.result);
                    }
                    else {
                        bootbox.alert($labelUnexpectedError);
                    }
                })
                .error(function (data) {
                    bootbox.alert($labelUnexpectedError);
                })
                .complete(function () {
                    Antimultipost.enableSubmit(formContainer);
                });
    });
}

/**
 * Loop through the comments and add edit buttons to those which current user
 * can edit
 */
CodeHighlighting.setupEditButtons = function() {
	var branchId = $('#branchId').val();
	var userId = $('#userId').val();
	var canEditOwnPosts = PermissionService.getHasPermission(branchId, 'BRANCH',
                    'BranchPermission.EDIT_OWN_POSTS');
	var canEditOtherPosts = PermissionService.getHasPermission(branchId, 'BRANCH',
                    'BranchPermission.EDIT_OTHERS_POSTS');

	$('.script-first-post div.review-container').each(function() {
		var authorId = $(this).find('input[name=authorId]').val();
		if (canEditOtherPosts || (authorId == userId && canEditOwnPosts)) {
			$(this).find('.review-buttons').append(
				'' + $labelEdit + ''
			);
		}
	});
}

/**
 * Build HTML piece for review comment
 * @param comment code review comment
 * @return div (string) with comment data
 */
CodeHighlighting.getCommentHtml = function (comment) {
    var result =
            '
 '
				+ '<input type=hidden name=id value="' + comment.id + '"/>'
				+ '<input type=hidden name=authorId value="' + comment.authorId + '"/>'
                + '
'
                    + ''
                + '
'
                + '
'
				    + '
'
                    + '
'
						+ '' + CodeHighlighting.htmlEncode(comment.authorUsername) + ''
						+ ' ' + $labelReviewSays + ': '
                    + '
'
                    + '
'
						+ CodeHighlighting.htmlEncode(comment.body)
                    + '
'
                + '
'
            + '
';
    return result;
}

/**
 * Build HTML piece for add comment form
 * @param submitButtonTitle title of submit button
 * @param action name of action (name being added to button names)
 * @param lineNumber number of line where form will be placed
 * @param comment data to fill form if defined
 * @return string with HTML piece for the form
 */
CodeHighlighting.getCommentForm = function (submitButtonTitle, action, lineNumber, comment) {
    if (comment === undefined) {
		comment = {id:0,body:''};
	}
    var result =
            '
'
                + '
'
                    + '<input type=hidden name=lineNumber value="' + lineNumber + '"/>'
					+ '<input type=hidden name=id value="' + comment.id + '"/>'
                    + '<textarea name="body" class="review-container-content">' + comment.body + '</textarea>'
                + '
'
                + '
'
                    + '<input type=button name="' + action + '" value="' + submitButtonTitle + '" class="btn btn-primary review-container-controls-ok"/>'
                    + '<input type=button name=cancel-' + action + ' value="' + $labelCancel + '" class="btn review-container-controls-cancel"/>'
                + '
'
                + '' + $labelKeymapsReview + ''
            + '
';
    return result;
}

/**
 * Show comment form below given element
 * @param element jquery element after which show form
 * @param submitButtonTitle title of submit button
 * @param submitButtonName name of submit button element
 * @param lineNumber number of line where form will be placed
 * @param comment data to fill form if defined
 */
CodeHighlighting.showCommentForm = function(element, submitButtonTitle, submitButtonName, lineNumber, comment) {
	element.after(CodeHighlighting.getCommentForm(submitButtonTitle, submitButtonName, lineNumber, comment));
	var reviewContent = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' textarea');
    reviewContent.keydown(Keymaps.review);
    reviewContent.focus();
}

/**
 * Show 'add comment' form below given element
 * @param element jquery element after which show form
 * @param lineNumber number of line where form will be placed
 */
CodeHighlighting.showAddCommentForm = function(element, lineNumber) {
	CodeHighlighting.showCommentForm(element, $labelAdd, 'add', lineNumber);
}

/**
 * Show 'edit comment' form at the location of given element. Element will
 * be hide from the document.
 * @param element jquery element after which show form
 * @param comment data to fill form
 */
CodeHighlighting.showEditCommentForm = function(element, comment) {
	CodeHighlighting.showCommentForm(element, $labelEdit, 'edit', 0, comment);
	element.hide();
}

/**
 * Remove comment form from the page
 */
CodeHighlighting.removeCommentForm = function () {
    $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID).remove();
}

/**
 * Display error messages
 *
 * @param errors list or errors
 */
CodeHighlighting.displayValidationErrors = function (errors) {
    $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' span.help-inline').remove();

    if (errors.length > 0) {
        var currentControlGroup = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=body]').parent();
        currentControlGroup.addClass("error");
        currentControlGroup.append('');

        var errorsContainer = currentControlGroup.find('span.help-inline');
        for (var i = 0; i < errors.length; i++) {
            errorsContainer.append(errors[i].message + '
');
        }
    }
}

/**
 * Encodes given string by escaping special HTML characters
 *
 * @param s string to be encoded
 */
CodeHighlighting.htmlEncode = function(s)
{
  var el = document.createElement("div");
  el.innerText = el.textContent = s;
  s = el.innerHTML;
  return s;
}<commit_msg>#JC-1200. Permission are checked for edit button when adding comment<commit_after>/*
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/** Namespace for this file */
var CodeHighlighting = {}

CodeHighlighting.ADD_COMMENT_FORM_ID = 'add-comment-form';

/** ID of branch where we currently are */
CodeHighlighting.branchId = 0;
/** ID of current user */
CodeHighlighting.currentUserId = 0;
/** Indicates if current user has EDIT_OWN_POSTS permission */
CodeHighlighting.canEditOwnPosts = false;
/** Indicates if current user has EDIT_OTHERS_POSTS permission */
CodeHighlighting.canEditOtherPosts = false;

/**
 * Called when document rendering is completed. Highlight code and
 * sets up handlers for code review if needed.
 */
$(document).ready(function () {
    prettyPrint(function () {
        var hasCodeReview = $('#has-code-review').val();
        if (hasCodeReview == 'true') {
        	CodeHighlighting.initializeVariabled();
            CodeHighlighting.displayReviewComments();

            var branchId = $('#branchId').val();
            PermissionService.hasPermission(branchId, 'BRANCH',
                    'BranchPermission.LEAVE_COMMENTS_IN_CODE_REVIEW',
                    CodeHighlighting.setupAddCommentFormHandlers);

			CodeHighlighting.setupEditCommentHandlers();
        }
    });
});

/**
 * Function to append comment to HTML
 */
CodeHighlighting.addComment = function (comment) {
    $('.script-first-post ol.linenums li:nth-child(' + comment.lineNumber + ')')
			.append(CodeHighlighting.getCommentHtml(comment));
}

/**
 * Function to update existing comment
 */
CodeHighlighting.updateComment = function (comment) {
    var reviewContainer = $('.script-first-post .review-container input[name=id][value=' + comment.id + ']').parent();
	reviewContainer.find('.review-body').html(CodeHighlighting.htmlEncode(comment.body));
	reviewContainer.show();
}

/**
 * Get review comments for this topic from server and display them
 * @return deffered object for AJAX request (displaying comments)
 */
CodeHighlighting.displayReviewComments = function () {
    var codeReviewId = $('#codeReviewId').val();
    return $.ajax({
        url: baseUrl + '/reviews/' + codeReviewId + '/json',
        type: "GET",
        success: function (data) {
            var comments = data.result.comments;
            for (var i = 0; i < comments.length; i++) {
                CodeHighlighting.addComment(comments[i]);
            }
        },
        error: function () {
            bootbox.alert($labelUnexpectedError);
        }
    });
}

/**
 * Initialize variables used in this scope.
 */
CodeHighlighting.initializeVariabled = function() {
	CodeHighlighting.branchId = $('#branchId').val();
	CodeHighlighting.currentUserId = $('#userId').val();
	CodeHighlighting.canEditOwnPosts = PermissionService.getHasPermission(branchId, 'BRANCH',
	                'BranchPermission.EDIT_OWN_POSTS');
	CodeHighlighting.canEditOtherPosts = PermissionService.getHasPermission(branchId, 'BRANCH',
	                'BranchPermission.EDIT_OTHERS_POSTS');
}

/**
 * Initializes handlers for 'Add comment' action
 */
CodeHighlighting.setupAddCommentFormHandlers = function () {
    $('.script-first-post').on('click', 'input:button[name=cancel-add]', function (event) {
        event.stopPropagation();
        CodeHighlighting.removeCommentForm();
    });

	// don't handle clicks on comments
	$('.script-first-post').on('click', 'ol.linenums li div.review-container', function () {
		return false;
	});

    $('.script-first-post').on('click', 'ol.linenums li', function () {
        var addCommentForm = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
        if (addCommentForm.length == 0) {
            var index = $(this).index();
			// display form before first comment
			CodeHighlighting.showAddCommentForm($(this).find('div:first').prev(), index + 1);
        }

    });

    $('.script-first-post').on('click', "input:button[name=add]", function (event) {
        event.stopPropagation();

        var formContainer = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
        if (Antimultipost.beingSubmitted(formContainer)) {
            return;
        }
        Antimultipost.disableSubmit(formContainer);

		var data = {id: 0, authorId:0, authorUsername:""};
        data.lineNumber = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=lineNumber]').val();
        data.body = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=body]').val();
		data.reviewId = $('#codeReviewId').val();

        $.post(baseUrl + '/reviewcomments/new', data)
                .success(function (data) {
                    if (data.status == 'Success') {
                        CodeHighlighting.removeCommentForm();
						CodeHighlighting.addComment(data.result)
                    }
                    else if (data.reason == 'validation') {
                        CodeHighlighting.displayValidationErrors(data.result);
                    }
                    else {
                        bootbox.alert($labelUnexpectedError);
                    }
                })
                .error(function (data) {
                    bootbox.alert($labelUnexpectedError);
                })
                .complete(function () {
                    Antimultipost.enableSubmit(formContainer);
                });
    });
}

/**
 * Initializes handlers for 'Edit comment' actions
 */
CodeHighlighting.setupEditCommentHandlers = function() {
    $('.script-first-post').on('click', 'input:button[name=cancel-edit]', function (event) {
        event.stopPropagation();
		$('#' + CodeHighlighting.ADD_COMMENT_FORM_ID).prev().show();
        CodeHighlighting.removeCommentForm();
    });

	$('.script-first-post').on('click', 'div.review-container a[name=edit-review]', function() {
		var addCommentForm = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
		if (addCommentForm.length == 0) {
			var reviewContainer = $(this).closest('.review-container');
			var comment = {};
			comment.id = reviewContainer.find('input[name=id]').val();
			comment.body = reviewContainer.find('.review-body').html();
			CodeHighlighting.showEditCommentForm(reviewContainer, comment);
        }

		return false;
	});

	$('.script-first-post').on('click', "input:button[name=edit]", function (event) {
        event.stopPropagation();

        var formContainer = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID);
        if (Antimultipost.beingSubmitted(formContainer)) {
            return;
        }
        Antimultipost.disableSubmit(formContainer);

		var data = {authorId:0, authorUsername:""};
		data.id = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=id]').val();
        data.lineNumber = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=lineNumber]').val();
        data.body = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=body]').val();
		data.branchId = $('#branchId').val();

        $.post(baseUrl + '/reviewcomments/edit', data)
                .success(function (data) {
                    if (data.status == 'Success') {
						CodeHighlighting.updateComment(data.result);
						CodeHighlighting.removeCommentForm();
                    }
                    else if (data.reason == 'validation') {
                        CodeHighlighting.displayValidationErrors(data.result);
                    }
                    else {
                        bootbox.alert($labelUnexpectedError);
                    }
                })
                .error(function (data) {
                    bootbox.alert($labelUnexpectedError);
                })
                .complete(function () {
                    Antimultipost.enableSubmit(formContainer);
                });
    });
}

/**
 * Build HTML piece for review comment
 * @param comment code review comment
 * @return div (string) with comment data
 */
CodeHighlighting.getCommentHtml = function (comment) {
	var editButtonHtml = '';
	if (CodeHighlighting.canEditOtherPosts
			|| (CodeHighlighting.currentUserId = comment.authorId
					&& Codehighlighting.canEditOwnPosts)) {
		editButtonHtml = '' + $labelEdit + '';
	}
    var result =
            '
 '
				+ '<input type=hidden name=id value="' + comment.id + '"/>'
				+ '<input type=hidden name=authorId value="' + comment.authorId + '"/>'
                + '
'
                    + ''
                + '
'
                + '
'
				    + '
'
				    	+ editButtonHtml
				    + '
'
                    + '
'
						+ '' + CodeHighlighting.htmlEncode(comment.authorUsername) + ''
						+ ' ' + $labelReviewSays + ': '
                    + '
'
                    + '
'
						+ CodeHighlighting.htmlEncode(comment.body)
                    + '
'
                + '
'
            + '
';
    return result;
}

/**
 * Build HTML piece for add comment form
 * @param submitButtonTitle title of submit button
 * @param action name of action (name being added to button names)
 * @param lineNumber number of line where form will be placed
 * @param comment data to fill form if defined
 * @return string with HTML piece for the form
 */
CodeHighlighting.getCommentForm = function (submitButtonTitle, action, lineNumber, comment) {
    if (comment === undefined) {
		comment = {id:0,body:''};
	}
    var result =
            '
'
                + '
'
                    + '<input type=hidden name=lineNumber value="' + lineNumber + '"/>'
					+ '<input type=hidden name=id value="' + comment.id + '"/>'
                    + '<textarea name="body" class="review-container-content">' + comment.body + '</textarea>'
                + '
'
                + '
'
                    + '<input type=button name="' + action + '" value="' + submitButtonTitle + '" class="btn btn-primary review-container-controls-ok"/>'
                    + '<input type=button name=cancel-' + action + ' value="' + $labelCancel + '" class="btn review-container-controls-cancel"/>'
                + '
'
                + '' + $labelKeymapsReview + ''
            + '
';
    return result;
}

/**
 * Show comment form below given element
 * @param element jquery element after which show form
 * @param submitButtonTitle title of submit button
 * @param submitButtonName name of submit button element
 * @param lineNumber number of line where form will be placed
 * @param comment data to fill form if defined
 */
CodeHighlighting.showCommentForm = function(element, submitButtonTitle, submitButtonName, lineNumber, comment) {
	element.after(CodeHighlighting.getCommentForm(submitButtonTitle, submitButtonName, lineNumber, comment));
	var reviewContent = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' textarea');
    reviewContent.keydown(Keymaps.review);
    reviewContent.focus();
}

/**
 * Show 'add comment' form below given element
 * @param element jquery element after which show form
 * @param lineNumber number of line where form will be placed
 */
CodeHighlighting.showAddCommentForm = function(element, lineNumber) {
	CodeHighlighting.showCommentForm(element, $labelAdd, 'add', lineNumber);
}

/**
 * Show 'edit comment' form at the location of given element. Element will
 * be hide from the document.
 * @param element jquery element after which show form
 * @param comment data to fill form
 */
CodeHighlighting.showEditCommentForm = function(element, comment) {
	CodeHighlighting.showCommentForm(element, $labelEdit, 'edit', 0, comment);
	element.hide();
}

/**
 * Remove comment form from the page
 */
CodeHighlighting.removeCommentForm = function () {
    $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID).remove();
}

/**
 * Display error messages
 *
 * @param errors list or errors
 */
CodeHighlighting.displayValidationErrors = function (errors) {
    $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' span.help-inline').remove();

    if (errors.length > 0) {
        var currentControlGroup = $('#' + CodeHighlighting.ADD_COMMENT_FORM_ID + ' [name=body]').parent();
        currentControlGroup.addClass("error");
        currentControlGroup.append('');

        var errorsContainer = currentControlGroup.find('span.help-inline');
        for (var i = 0; i < errors.length; i++) {
            errorsContainer.append(errors[i].message + '
');
        }
    }
}

/**
 * Encodes given string by escaping special HTML characters
 *
 * @param s string to be encoded
 */
CodeHighlighting.htmlEncode = function(s)
{
  var el = document.createElement("div");
  el.innerText = el.textContent = s;
  s = el.innerHTML;
  return s;
}<|endoftext|>


<commit_before>/**
 * init function that is called from the Wicket Component
 */
var init = function (parameters) {
    'use strict';

    var chart = new PlotlyChart(parameters);
    chart.render();
};

/**
 * Object.assign for ES5
 */
if (typeof Object.assign != 'function') {
    Object.assign = function(target) {
        'use strict';
        if (target == null) {
            throw new TypeError('Cannot convert undefined or null to object');
        }

        target = Object(target);
        for (var index = 1; index < arguments.length; index++) {
            var source = arguments[index];
            if (source != null) {
                for (var key in source) {
                    if (Object.prototype.hasOwnProperty.call(source, key)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        return target;
    };
}

/**
 * Use this if you want to configure some default properties for a plot.ly chart.
 */
PlotlyChart.prototype.defaultProps = {
    chartId:          'chartId',
    layout: {
        showlegend:    true,
    }
};

/**
 * Use this constructor in order to initialize a PlotlyChart.
 * If you want to render the chart use the `render()` function.
 */
function PlotlyChart(parameters) {
    this.props = Object.assign({}, this.defaultProps, parameters);
}

/**
 * Function that actually renders the chart using plot.ly
 */
PlotlyChart.prototype.render = function() {
    var chartId = this.props.chartId;
    var data = this.props.data;
    var layout = this.props.layout;

    // console.log(JSON.stringify(this.props, null, '\t'));

    Plotly.newPlot(chartId, data, layout, {displayModeBar: true, displaylogo: false});
};
<commit_msg>update js code.<commit_after>/**
 * init function that is called from the Wicket Component
 */
var initChart = function (parameters) {
    'use strict';

    // check if we have the 'colors' property for a marker and copy it to 'color' property as well.
    for(var i = 0; i < parameters.data.length; i++) {
        if (parameters.data[i].marker !== undefined && parameters.data[i].marker.colors !== undefined) {
            parameters.data[i].marker.color = parameters.data[i].marker.colors;
        }
    }

    var chart = new PlotlyChart(parameters);
    chart.render();
};

/**
 * Object.assign for ES5
 */
if (typeof Object.assign != 'function') {
    Object.assign = function(target) {
        'use strict';
        if (target == null) {
            throw new TypeError('Cannot convert undefined or null to object');
        }

        target = Object(target);
        for (var index = 1; index < arguments.length; index++) {
            var source = arguments[index];
            if (source != null) {
                for (var key in source) {
                    if (Object.prototype.hasOwnProperty.call(source, key)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        return target;
    };
}

/**
 * Use this if you want to configure some default properties for a plot.ly chart.
 */
PlotlyChart.prototype.defaultProps = {
    chartId:          'chartId',
    layout: {
        showlegend:    true,
    }
};

/**
 * Use this constructor in order to initialize a PlotlyChart.
 * If you want to render the chart use the `render()` function.
 */
function PlotlyChart(parameters) {
    this.props = Object.assign({}, this.defaultProps, parameters);
}

/**
 * Function that actually renders the chart using plot.ly
 */
PlotlyChart.prototype.render = function() {
    var chartId = this.props.chartId;
    var data = this.props.data;
    var layout = this.props.layout;

    // console.log(JSON.stringify(this.props, null, '\t'));

    Plotly.newPlot(chartId, data, layout, {displayModeBar: true, displaylogo: false});
};
<|endoftext|>


<commit_before>var cdb = require('cartodb.js');

/**
 *  Add column view
 *
 */

module.exports = cdb.core.View.extend({

  className: 'AddColumn js-addField',

  events: {
    'click .js-addColumn': '_addColumn'
  },

  initialize: function() {
    this.model = new cdb.core.Model({
      state: 'idle'
    });
    this.table = this.options.table;
    this.template = cdb.templates.getTemplate('common/dialogs/feature_data/add_column/add_column');
    this._initBinds();
  },

  render: function() {
    this.$el.html(
      this.template({
        state: this.model.get('state')
      })
    )
    return this;
  },

  _initBinds: function() {
    this.model.bind('change:state', this.render, this);
  },

  _addColumn: function() {
    var self = this;
    // Loading
    this.model.set('state', 'loading');

    // we could use table.addColumn method
    // but we need to have more info when
    // request fails
    var c = new cdb.admin.Column({
      table: this.table,
      _name: new Date().getTime(),
      type: 'string'
    }).save(null, {
      success: function(r) {
        self.trigger('newColumn', r, this);
        self.model.set('state', 'idle');
      },
      error: function(e, resp) {
        self.model.set('state', 'error');
      }
    });
  }

});
<commit_msg>Using table.addColumn method instead of creating a new column model<commit_after>var cdb = require('cartodb.js');

/**
 *  Add column view
 *
 */

module.exports = cdb.core.View.extend({

  className: 'AddColumn js-addField',

  events: {
    'click .js-addColumn': '_addColumn'
  },

  initialize: function() {
    this.model = new cdb.core.Model({
      state: 'idle'
    });
    this.table = this.options.table;
    this.template = cdb.templates.getTemplate('common/dialogs/feature_data/add_column/add_column');
    this._initBinds();
  },

  render: function() {
    this.$el.html(
      this.template({
        state: this.model.get('state')
      })
    )
    return this;
  },

  _initBinds: function() {
    this.model.bind('change:state', this.render, this);
  },

  _addColumn: function() {
    var self = this;
    // Loading
    this.model.set('state', 'loading');

    this.table.addColumn('column_' + new Date().getTime(), 'string', {
      success: function(mdl, data) {
        self.trigger('newColumn', mdl, this);
        self.model.set('state', 'idle');
      },
      error: function() {
        self.model.set('state', 'error');
      }
    });
  }

});
<|endoftext|>