<commit_before>/*
 *  Copyright 2020 Google LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      https:www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * Fills the webpage with the existing timeslots etc.
 */
function initialise() {
    populateRows();
}

/**
 * Inserts existing timeslots in webpage.
 */
function populateRows() {
    getExistingTimeSlots().then(rows => rows.forEach(row => addRow(row)));

    //TODO add delete button to each row

    //TODO validate fields so they're not empty, and start time is before end time
}

/**
 * Fetches the list of existing timeslots.
 * @returns {Promise<Array>} Array of timeslot objects.
 */
async function getExistingTimeSlots() {
    const slots = await (await fetch('/volunteer-availability')).json();
    const rows = await Promise.all(slots.map(slot => slotToRow(slot)));

    // Sort timeslots by start time
    return [...rows].sort((a, b) => (new Date(a.children["ISO-start-time"].value)).getTime() >
    (new Date(b.children["ISO-start-time"].value)).getTime() ? 1 : -1);
}

/**
 * Convert slot element to row div for insertion into form.
 * @param slot The slot element to convert.
 * @returns {Promise<HTMLDivElement>} The row containing the slot data.
 */
async function slotToRow(slot) {
    // Get start and end instant and display as local timezone.
    const startTime = new Date(slot.start.seconds * 1000);
    const endTime = new Date(slot.end.seconds * 1000);

    // Get local time in HH:MM format.
    const hours = String(endTime.getHours()).padStart(2, "0");
    const minutes = String(endTime.getMinutes()).padStart(2, "0");
    const end = hours + ":" + minutes;

    return constructNewRow(startTime.getTime(), end);
}

/**
 * Set value of hidden ISO start time element by parsing start date and time.
 * @param {HTMLInputElement} inputElement The start datetime element.
 */
function fillISOStartTime(inputElement) {
    if (inputElement.value == null || inputElement.value === "") return;
    inputElement.parentNode.children["ISO-start-time"].value = new Date(inputElement.value).toISOString();
    //TODO also update end time accordingly to date change
    //TODO re-sort this slot in list after changing?
}

/**
 * Set value of hidden ISO end time element by parsing start date and end time.
 * @param {HTMLInputElement} inputElement The end time element.
 */
function fillISOEndTime(inputElement) {
    const children = inputElement.parentNode.children;
    const endValue = inputElement.value;

    // Get the date from the start datetime object
    const date = new Date(children["ISO-start-time"].value);

    if (endValue == null || !endValue || date == null) return;

    const [first, second] = endValue.split(':');

    date.setHours(Number(first));
    date.setMinutes(Number(second));
    children["ISO-end-time"].value = date.toISOString();
}

/**
 * Creates a new row element with the timeslots details.
 * @param {Number} startTimeValue The initial value for datetime-local start date and time, as UNIX timestamp.
 * @param {String} endTimeValue The initial value for local end time, as HH:MM.
 * @returns {Promise<HTMLDivElement>} The div containing the row.
 */
async function constructNewRow(startTimeValue, endTimeValue) {
    const newRow = document.createElement("div");

    const [startElement, ISOStartElement, endElement, ISOEndElement] =
        await Promise.all([getStartElement(startTimeValue), getISOStartElement(),
            getEndTime(endTimeValue), getISOEndElement()]);

    newRow.appendChild(startElement);
    newRow.appendChild(ISOStartElement);
    newRow.appendChild(endElement);
    newRow.appendChild(ISOEndElement);

    fillISOStartTime(startElement);
    fillISOEndTime(endElement);

    return newRow;
}

/**
 * Construct the start datetime-local element in a timeslot row.
 * @param {Number} startTimeValue The value for datetime-local start date and time.
 * @returns {Promise<HTMLInputElement>} The start datetime-local element.
 */
async function getStartElement(startTimeValue) {
    const startTime = document.createElement("input");
    startTime.type = "datetime-local";
    startTime.name = "start-time";
    startTime.valueAsNumber = startTimeValue;
    startTime.required = true;

    startTime.addEventListener("change", (e) => fillISOStartTime(e.target));

    return startTime;
}

/**
 * Creates a hidden ISO start instant element.
 * @returns {Promise<HTMLInputElement>} The hidden text-input element.
 */
async function getISOStartElement() {
    const ISOStartTime = document.createElement("input");
    ISOStartTime.name = "ISO-start-time";
    ISOStartTime.hidden = true;
    return ISOStartTime;
}

/**
 * Creates a local time input element for the end time.
 * @param {String} endTimeValue The initial local time input, as HH:MM.
 * @returns {Promise<HTMLInputElement>} The local time input element.
 */
async function getEndTime(endTimeValue) {
    const endTime = document.createElement("input");
    endTime.type = "time";
    endTime.name = "end-time";
    endTime.value = endTimeValue;
    endTime.required = true;

    endTime.addEventListener("change", (e) => fillISOEndTime(e.target));

    return endTime;
}

/**
 * Creates a hidden ISO end instant element.
 * @returns {Promise<HTMLInputElement>} The hidden text-input element.
 */
async function getISOEndElement() {
    const ISOEndTime = document.createElement("input");
    ISOEndTime.name = "ISO-end-time";
    ISOEndTime.hidden = true;
    return ISOEndTime;
}

/**
 * Add a row to the submission form.
 * @param {HTMLDivElement} row The row to add.
 */
function addRow(row) {
    document.getElementById("availability-form").appendChild(row);
}

/**
 * Insert an empty row in the submission form.
 */
function addEmptyRow() {
    addRow(constructNewRow());
}<commit_msg>Extract timeslot sort function<commit_after>/*
 *  Copyright 2020 Google LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      https:www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * Fills the webpage with the existing timeslots etc.
 */
function initialise() {
    populateRows();
}

/**
 * Inserts existing timeslots in webpage.
 */
function populateRows() {
    getExistingTimeSlots().then(rows => rows.forEach(row => addRow(row)));

    //TODO add delete button to each row

    //TODO validate fields so they're not empty, and start time is before end time
}

/**
 * Fetches the list of existing timeslots.
 * @returns {Promise<Array>} Array of timeslot objects.
 */
async function getExistingTimeSlots() {
    const slots = await (await fetch('/volunteer-availability')).json();
    const rows = await Promise.all(slots.map(slot => slotToRow(slot)));
    await sortTimeSlots(rows);
    return rows;
}

/**
 * Sorts the rows of timeslots by start date & time.
 * @param rows The array of rows to sort.
 */
async function sortTimeSlots(rows) {
    rows.sort((a, b) => (new Date(a.children["ISO-start-time"].value)).getTime() >
    (new Date(b.children["ISO-start-time"].value)).getTime() ? 1 : -1);
}

/**
 * Convert slot element to row div for insertion into form.
 * @param slot The slot element to convert.
 * @returns {Promise<HTMLDivElement>} The row containing the slot data.
 */
async function slotToRow(slot) {
    // Get start and end instant and display as local timezone.
    const startTime = new Date(slot.start.seconds * 1000);
    const endTime = new Date(slot.end.seconds * 1000);

    // Get local time in HH:MM format.
    const hours = String(endTime.getHours()).padStart(2, "0");
    const minutes = String(endTime.getMinutes()).padStart(2, "0");
    const end = hours + ":" + minutes;

    return constructNewRow(startTime.getTime(), end);
}

/**
 * Set value of hidden ISO start time element by parsing start date and time.
 * @param {HTMLInputElement} inputElement The start datetime element.
 */
function fillISOStartTime(inputElement) {
    if (inputElement.value == null || inputElement.value === "") return;
    inputElement.parentNode.children["ISO-start-time"].value = new Date(inputElement.value).toISOString();
    //TODO also update end time accordingly to date change
    //TODO re-sort this slot in list after changing?
}

/**
 * Set value of hidden ISO end time element by parsing start date and end time.
 * @param {HTMLInputElement} inputElement The end time element.
 */
function fillISOEndTime(inputElement) {
    const children = inputElement.parentNode.children;
    const endValue = inputElement.value;

    // Get the date from the start datetime object
    const date = new Date(children["ISO-start-time"].value);

    if (endValue == null || !endValue || date == null) return;

    const [first, second] = endValue.split(':');

    date.setHours(Number(first));
    date.setMinutes(Number(second));
    children["ISO-end-time"].value = date.toISOString();
}

/**
 * Creates a new row element with the timeslots details.
 * @param {Number} startTimeValue The initial value for datetime-local start date and time, as UNIX timestamp.
 * @param {String} endTimeValue The initial value for local end time, as HH:MM.
 * @returns {Promise<HTMLDivElement>} The div containing the row.
 */
async function constructNewRow(startTimeValue, endTimeValue) {
    const newRow = document.createElement("div");

    const [startElement, ISOStartElement, endElement, ISOEndElement] =
        await Promise.all([getStartElement(startTimeValue), getISOStartElement(),
            getEndTime(endTimeValue), getISOEndElement()]);

    newRow.appendChild(startElement);
    newRow.appendChild(ISOStartElement);
    newRow.appendChild(endElement);
    newRow.appendChild(ISOEndElement);

    fillISOStartTime(startElement);
    fillISOEndTime(endElement);

    return newRow;
}

/**
 * Construct the start datetime-local element in a timeslot row.
 * @param {Number} startTimeValue The value for datetime-local start date and time.
 * @returns {Promise<HTMLInputElement>} The start datetime-local element.
 */
async function getStartElement(startTimeValue) {
    const startTime = document.createElement("input");
    startTime.type = "datetime-local";
    startTime.name = "start-time";
    startTime.valueAsNumber = startTimeValue;
    startTime.required = true;

    startTime.addEventListener("change", (e) => fillISOStartTime(e.target));

    return startTime;
}

/**
 * Creates a hidden ISO start instant element.
 * @returns {Promise<HTMLInputElement>} The hidden text-input element.
 */
async function getISOStartElement() {
    const ISOStartTime = document.createElement("input");
    ISOStartTime.name = "ISO-start-time";
    ISOStartTime.hidden = true;
    return ISOStartTime;
}

/**
 * Creates a local time input element for the end time.
 * @param {String} endTimeValue The initial local time input, as HH:MM.
 * @returns {Promise<HTMLInputElement>} The local time input element.
 */
async function getEndTime(endTimeValue) {
    const endTime = document.createElement("input");
    endTime.type = "time";
    endTime.name = "end-time";
    endTime.value = endTimeValue;
    endTime.required = true;

    endTime.addEventListener("change", (e) => fillISOEndTime(e.target));

    return endTime;
}

/**
 * Creates a hidden ISO end instant element.
 * @returns {Promise<HTMLInputElement>} The hidden text-input element.
 */
async function getISOEndElement() {
    const ISOEndTime = document.createElement("input");
    ISOEndTime.name = "ISO-end-time";
    ISOEndTime.hidden = true;
    return ISOEndTime;
}

/**
 * Add a row to the submission form.
 * @param {HTMLDivElement} row The row to add.
 */
function addRow(row) {
    document.getElementById("availability-form").appendChild(row);
}

/**
 * Insert an empty row in the submission form.
 */
async function addEmptyRow() {
    addRow(await constructNewRow());
}<|endoftext|>


<commit_before>import SHARED_CONFIG from '../../../shared/services/shared-config/shared-config'

import mapFetch from '../map-fetch/map-fetch'

import servicesByEndpointType, { endpointTypes } from '../map-services.config'

export const maxDisplayValuesPerProperty = 5

export const pageEndpointTypeMapping = {
  'explosieven/gevrijwaardgebied/': 'milieuthemas/explosieven/gevrijwaardgebied/',
  'explosieven/inslagen/': 'milieuthemas/explosieven/inslagen/',
  'explosieven/uitgevoerdonderzoek/': 'milieuthemas/explosieven/uitgevoerdonderzoek/',
  'explosieven/verdachtgebied/': 'milieuthemas/explosieven/verdachtgebied/',
}

export const pageTypeToEndpoint = (type, subtype, id) => {
  const endpoinType = pageEndpointTypeMapping[`${type}/${subtype}/`] || `${type}/${subtype}/`
  return `${SHARED_CONFIG.API_ROOT}${endpoinType}${id}/`
}

export const getEndpointTypeForResult = (endpointType, detail) => {
  if (endpointType === endpointTypes.adressenNummeraanduiding) {
    if (detail.ligplaats) {
      return endpointTypes.adressenLigplaats
    }
    if (detail.standplaats) {
      return endpointTypes.adressenStandplaats
    }
    return endpointTypes.adressenNummeraanduiding
  }
  return endpointType
}

export default async function fetchDetail(endpoint, user) {
  const endpointType = Object.keys(servicesByEndpointType).find(type => endpoint.includes(type))
  const endpointConfig = endpointType && servicesByEndpointType[endpointType]
  const authScope = endpointConfig && endpointConfig.authScope
  const isAuthorized = !authScope || user.scopes.includes(authScope)

  const detail = isAuthorized
    ? await mapFetch(endpoint, endpointConfig.mapDetail, endpointConfig.normalization)
    : endpointConfig.mapDetail(isAuthorized)

  const endpointTypeForResult = getEndpointTypeForResult(endpointType, detail)
  console.log(isAuthorized)
  return {
    ...detail,
    isAuthorized,
    endpointType: endpointTypeForResult,
  }
}

window.mapPreviewPanelDetailEndpointTypes = endpointTypes
<commit_msg>Update map-detail.js<commit_after>import SHARED_CONFIG from '../../../shared/services/shared-config/shared-config'

import mapFetch from '../map-fetch/map-fetch'

import servicesByEndpointType, { endpointTypes } from '../map-services.config'

export const maxDisplayValuesPerProperty = 5

export const pageEndpointTypeMapping = {
  'explosieven/gevrijwaardgebied/': 'milieuthemas/explosieven/gevrijwaardgebied/',
  'explosieven/inslagen/': 'milieuthemas/explosieven/inslagen/',
  'explosieven/uitgevoerdonderzoek/': 'milieuthemas/explosieven/uitgevoerdonderzoek/',
  'explosieven/verdachtgebied/': 'milieuthemas/explosieven/verdachtgebied/',
}

export const pageTypeToEndpoint = (type, subtype, id) => {
  const endpoinType = pageEndpointTypeMapping[`${type}/${subtype}/`] || `${type}/${subtype}/`
  return `${SHARED_CONFIG.API_ROOT}${endpoinType}${id}/`
}

export const getEndpointTypeForResult = (endpointType, detail) => {
  if (endpointType === endpointTypes.adressenNummeraanduiding) {
    if (detail.ligplaats) {
      return endpointTypes.adressenLigplaats
    }
    if (detail.standplaats) {
      return endpointTypes.adressenStandplaats
    }
    return endpointTypes.adressenNummeraanduiding
  }
  return endpointType
}

export default async function fetchDetail(endpoint, user) {
  const endpointType = Object.keys(servicesByEndpointType).find(type => endpoint.includes(type))
  const endpointConfig = endpointType && servicesByEndpointType[endpointType]
  const authScope = endpointConfig && endpointConfig.authScope
  const isAuthorized = !authScope || user.scopes.includes(authScope)

  const detail = isAuthorized
    ? await mapFetch(endpoint, endpointConfig.mapDetail, endpointConfig.normalization)
    : endpointConfig.mapDetail(isAuthorized)

  const endpointTypeForResult = getEndpointTypeForResult(endpointType, detail)

  return {
    ...detail,
    isAuthorized,
    endpointType: endpointTypeForResult,
  }
}

window.mapPreviewPanelDetailEndpointTypes = endpointTypes
<|endoftext|>


<commit_before>// @flow

const React     = require('react')
const shiny     = require('shiny')

const r = React.createElement

const ContentImage = (props/*: { src: ?Object, cover: boolean, max_size: ?number }*/) => {
    if (null == props.src || null == props.src.content || null == props.src.content['640']) {
        return null
    }

    const alt_text = props.src.alt_text

    if (props.plain) {
        return r('img', { src: props.src.content['640'] && props.src.content['640'].url })
    }

    const srcset = []

    const src_128     = props.src.content['128'] ? props.src.content['128'].url : null
    const src_640     = props.src.content['640'] ? props.src.content['640'].url : null
    const src_1280    = props.src.content['1280'] ? props.src.content['1280'].url : null
    const src_2560    = props.src.content['2560'] ? props.src.content['2560'].url : null

    if (null != src_128) {
        srcset.unshift(`${ src_128 } 128w`)
    }
    if (null != src_640) {
        srcset.unshift(`${ src_640 } 640w`)
    }
    if (null != src_1280) {
        srcset.unshift(`${ src_1280 } 1280w`)
    }
    if (null != src_2560) {
        srcset.unshift(`${ src_2560 } 2560w`)
    }

    const cx = shiny('ContentImage')
    cx.add('cover', props.cover)
    const sizes = ['100vw']
    if (null == props.max_size || props.max_size >= 640) {
        sizes.unshift(`(min-width: 640px) 640px`)
    }

    if (null == props.max_size || props.max_size >= 1280) {
        sizes.unshift(`(min-width: 1280px) 1280px`)
    }

    if (null == props.max_size || props.max_size >= 2560) {
        sizes.unshift(`(min-width: 2560px) 2560px`)
    }

    return r('img', {
        className       : cx,
        src             : src_640,
        srcSet          : srcset.join(','),
        sizes           : sizes.join(','),
        alt             : alt_text,
        'data-src_128'  : src_128,
        'data-src_640'  : src_640,
        'data-src_1280' : src_1280,
        'data-src_2560' : src_2560,
    })
}

ContentImage.defaultProps = {
    plain: false,
    cover: false,
    max_size: null,
}

module.exports = ContentImage
<commit_msg>Add focal_point functionality to ContentImage.<commit_after>// @flow

const React     = require('react')
const shiny     = require('shiny')

const r = React.createElement

const ContentImage = (props/*: { src: ?Object, cover: boolean, max_size: ?number }*/) => {
    if (null == props.src || null == props.src.content || null == props.src.content['640']) {
        return null
    }

    const alt_text = props.src.alt_text

    if (props.plain) {
        return r('img', { src: props.src.content['640'] && props.src.content['640'].url })
    }

    const srcset = []

    const src_128     = props.src.content['128'] ? props.src.content['128'].url : null
    const src_640     = props.src.content['640'] ? props.src.content['640'].url : null
    const src_1280    = props.src.content['1280'] ? props.src.content['1280'].url : null
    const src_2560    = props.src.content['2560'] ? props.src.content['2560'].url : null

    if (null != src_128) {
        srcset.unshift(`${ src_128 } 128w`)
    }
    if (null != src_640) {
        srcset.unshift(`${ src_640 } 640w`)
    }
    if (null != src_1280) {
        srcset.unshift(`${ src_1280 } 1280w`)
    }
    if (null != src_2560) {
        srcset.unshift(`${ src_2560 } 2560w`)
    }

    const cx = shiny('ContentImage')
    cx.add('cover', props.cover)
    const sizes = ['100vw']
    if (null == props.max_size || props.max_size >= 640) {
        sizes.unshift(`(min-width: 640px) 640px`)
    }

    if (null == props.max_size || props.max_size >= 1280) {
        sizes.unshift(`(min-width: 1280px) 1280px`)
    }

    if (null == props.max_size || props.max_size >= 2560) {
        sizes.unshift(`(min-width: 2560px) 2560px`)
    }

    const style = {}
    if (props.cover && null != props.src && null != props.src.focal_point) {
        style.objectPosition = `${ props.src.focal_point.x * 100 }% ${ props.src.focal_point.y * 100 }%`
    }

    return r('img', {
        className       : cx,
        src             : src_640,
        srcSet          : srcset.join(','),
        sizes           : sizes.join(','),
        alt             : alt_text,
        style           : style,
        'data-src_128'  : src_128,
        'data-src_640'  : src_640,
        'data-src_1280' : src_1280,
        'data-src_2560' : src_2560,
    })
}

ContentImage.defaultProps = {
    plain: false,
    cover: false,
    max_size: null,
}

module.exports = ContentImage
<|endoftext|>


<commit_before>'use strict';
/* global google */

function cdEditDojoCtrl($scope, cdDojoService, alertService, gmap, auth,
                        $state, $q, $translate, utilsService, currentUser, cdUsersService, $localStorage, $ngBootbox, $sce) {

  $scope.dojo = {};
  $scope.model = {};
  $scope.markers = [];
  $scope.markerPlaced = false;
  $scope.buttonText = $translate.instant('Update Dojo');
  $scope.hideUserSelect = true;
  $scope.changedLocation = false;
  $scope.disableDojoCountryChange = false;

  $scope.isCDFAdmin = currentUser && currentUser.data && _.contains(currentUser.data.roles, 'cdf-admin');

  var DEFAULT_COORDS = '53.3478,6.2597';

  auth.get_loggedin_user(function (user) {
    $scope.user = user;
  });

  cdDojoService.getDojoConfig(function (json) {
    $scope.dojoStages = _.map(json.dojoStages, function (item) {
      return {value: item.value, label: $translate.instant(item.label)};
    });
  });

  $scope.noop = angular.noop;

  $scope.toggleUserSelect = function (event) {
    $scope.hideUserSelect = !$scope.hideUserSelect;
  };

  $scope.scrollToInvalid = function (form) {
    if (form.$invalid) {
      angular.element('form[name=' + form.$name + '] .ng-invalid')[0].scrollIntoView();
    }
  };

  async.waterfall([function (done) {
    var dojoId = $state.params.id;

    cdDojoService.load(dojoId, function (response) {
      if (!_.isEmpty(response)) {
        return done(null, response);
      } else {
        return done($translate.instant('Failed to load Dojo'));
      }
    });
  }, function (dojo, done) {
    var query = {};

    query.dojoId = dojo.id;

    query.owner = 1;

    cdDojoService.getUsersDojos(query, function (response) {

      return done(null, dojo, response[0]);
    }, function () {
      return done($translate.instant('Failed to load Dojo'));
    });

  }, function (dojo, prevFounder, done) {

    if (_.isEmpty(prevFounder)) {
      return done(null, dojo);
    }

    cdUsersService.loadPrevFounder(prevFounder.userId, function(response){
      prevFounder.email = response.email;
      prevFounder.name = response.name;

      return done(null, dojo, prevFounder);
    }, function (err) {
      return done(err);
    });
  }], function (err, dojo, prevFounder) {
    if (err) {
      alertService.showError(err);
      return;
    }

    var initContent = "
" +
      $translate.instant('Suggested Notes:') + "

" + $translate.instant('Please bring:') +
      "

" + $translate.instant('A pack lunch.') + "
" +
      "
" + $translate.instant('A laptop. Borrow one from somebody if needs be.') + "
" +
      "
" + $translate.instant('A parent! (Very important). If you are 12 or under, your parent must stay with you during the session.') + "
" +
      "

";

    $scope.editorOptions = {
      language: 'en',
      uiColor: '#000000',
      height: '200px'
    };
    if (dojo.notes === '') $scope.editorOptions.initContent = initContent;

    $scope.originalDojoListing = angular.copy(dojo);
    $scope.dojo = dojo;
    $scope.disableDojoCountryChange = dojo.verified === 1;
    $scope.prevFounder = prevFounder;
    $scope.founder = angular.copy(prevFounder);
    loadDojoMap();
    updateFromLocalStorage();
  });

  $scope.getUsersByEmails = function (email) {
    if (!email || !email.length || email.length < 3) {
      $scope.users = [];
      return;
    }

    var win = function (users) {
      $scope.users = users;
    };

    var fail = function () {
      alertService.showError($translate.instant('An error has occurred while loading Dojos'));
    };

    cdUsersService.getUsersByEmails(email, win, fail);
  };

  $scope.setFounder = function (founder) {
    if (founder) {
      $scope.founder = founder;
      $scope.founder.previousFounderId = $scope.prevFounder.userId;
      $scope.founder.dojoId = $scope.dojo.id;
    }
  };

  function loadDojoMap() {
    $scope.$watch('model.map', function (map) {
      if (map) {
        var marker = new google.maps.Marker({
          map: $scope.model.map,
          position: new google.maps.LatLng(latitude, longitude)
        });
        $scope.markers.push(marker);
      }
    });

    if (gmap) {
      $scope.mapLoaded = true;

      var coordsStr = $scope.dojo.coordinates;

      if (!coordsStr) {
        coordsStr = DEFAULT_COORDS;
      }

      var coordinates = coordsStr.split(',');
      var latitude = coordinates[0];
      var longitude = coordinates[1];

      if (!isNaN(utilsService.filterFloat(latitude)) && !isNaN(utilsService.filterFloat(latitude))) {
        $scope.mapOptions = {
          center: new google.maps.LatLng(latitude, longitude),
          zoom: 15,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
      } else if ($scope.dojo.geoPoint && $scope.dojo.geoPoint.lat && $scope.dojo.geoPoint.lon) {
        //add map using coordinates from geopoint if possible
        $scope.mapOptions = {
          center: new google.maps.LatLng($scope.dojo.geoPoint.lat, $scope.dojo.geoPoint.lon),
          zoom: 15,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
      } else { //add empty map
        cdDojoService.loadCountriesLatLongData(function (countries) {
          var country = countries[$scope.dojo.alpha2];
          $scope.mapOptions = {
            center: new google.maps.LatLng(country[0], country[1]),
            zoom: 15,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
        })
      }
    }
    $scope.dojoPageReady = true;
  }

  function updateFromLocalStorage() {
    if ($localStorage[$scope.user.id] && $localStorage[$scope.user.id].editDojo && $localStorage[$scope.user.id].editDojo[$scope.dojo.id]) {
      alertService.showAlert($translate.instant('There are unsaved changes on this page'));
      var lsed = $localStorage[$scope.user.id].editDojo[$scope.dojo.id];
      if (lsed.name) $scope.dojo.name = lsed.name;
      if (lsed.email) $scope.dojo.email = lsed.email;
      if (lsed.time) $scope.dojo.time = lsed.time;
      if (lsed.country) {
        $scope.dojo.country = lsed.country;
        $scope.setCountry($scope.dojo, lsed.country);
      }
      if (lsed.place) {
        $scope.dojo.place = lsed.place;
        $scope.setPlace($scope.dojo, lsed.place);
      }
      if (lsed.country && lsed.place) {
        $scope.getLocationFromAddress();
      }
      if (lsed.address1) $scope.dojo.address1 = lsed.address1;
      if (lsed.coordinates) $scope.dojo.coordinates = lsed.coordinates;
      if (lsed.needMentors) $scope.dojo.needMentors = lsed.needMentors;
      if (lsed.stage) $scope.dojo.stage = lsed.stage;
      if (lsed.private) $scope.dojo.private = lsed.private;
      if (lsed.googleGroup) $scope.dojo.googleGroup = lsed.googleGroup;
      if (lsed.website) $scope.dojo.website = lsed.website;
      if (lsed.twitter) $scope.dojo.twitter = lsed.twitter;
      if (lsed.supporterImage) $scope.dojo.supporterImage = lsed.supporterImage;
      if (lsed.mailingList) $scope.dojo.mailingList = lsed.mailingList;
    }
  }

  cdDojoService.listCountries(function (countries) {
    $scope.countries = countries;
  });

  $scope.getPlaces = function (countryCode, $select) {
    return utilsService.getPlaces(countryCode, $select).then(function (data) {
      $scope.places = data;
    }, function (err) {
      $scope.places = [];
      console.error(err);
    });
  };

  $scope.setCountry = function (dojo, country) {
    dojo.countryName = country.countryName;
    dojo.countryNumber = country.countryNumber;
    dojo.continent = country.continent;
    dojo.alpha2 = country.alpha2;
    dojo.alpha3 = country.alpha3;
  };

  $scope.setPlace = function (dojo, place, form) {
    if(place.nameWithHierarchy.length > 40) {
      if(form) form.place.$setValidity("maxLength", false);
    } else {
      if(form) form.place.$setValidity("maxLength", true);
    }
    dojo.placeName = place.name || place.nameWithHierarchy;
    dojo.placeGeonameId = place.geonameId;
    dojo.county = {};
    dojo.state = {};
    dojo.city = {};
    for (var adminidx = 1; adminidx <= 4; adminidx++) {
      dojo['admin' + adminidx + 'Code'] = place['admin' + adminidx + 'Code'];
      dojo['admin' + adminidx + 'Name'] = place['admin' + adminidx + 'Name'];
    }
  };

  $scope.clearPlace = function (dojo) {
    dojo.placeName = "";
    dojo.placeGeonameId = "";
    dojo.county = {};
    dojo.state = {};
    dojo.city = {};
    for (var adminidx = 1; adminidx <= 4; adminidx++) {
      dojo['admin' + adminidx + 'Code'] = "";
      dojo['admin' + adminidx + 'Name'] = "";
    }
    $scope.dojo.place = "";
  };

  $scope.updateLocalStorage = function (localObj, item, value) {
    if (['address1', 'place'].indexOf(item) > -1) {
      $scope.changedLocation = true;
      $scope.setPlace($scope.dojo, $scope.dojo.place);
    }

    if ($scope.user && $state.current.name === "edit-dojo") {
      localObj = $scope.dojo.id;
      if (!$localStorage[$scope.user.id]) $localStorage[$scope.user.id] = {};
      if (!$localStorage[$scope.user.id].editDojo) $localStorage[$scope.user.id].editDojo = {};
      if (!$localStorage[$scope.user.id].editDojo[localObj]) $localStorage[$scope.user.id].editDojo[localObj] = {};
      if (typeof value === 'undefined') value = false;
      $localStorage[$scope.user.id].editDojo[localObj][item] = value;
    }
  };

  var deleteLocalStorage = function (localObj) {
    if ($scope.user && $state.current.name === "edit-dojo") {
      if ($localStorage[$scope.user.id] && $localStorage[$scope.user.id].editDojo && $localStorage[$scope.user.id].editDojo[$scope.dojo.id]) {
        delete $localStorage[$scope.user.id].editDojo[$scope.dojo.id]
      }
    }
  };

  $scope.save = function (dojo) {

    if ($scope.changedLocation && !$scope.markerPlaced) {
      $scope.getLocationFromAddress(finish);
    } else {
      finish();
    }

    function saveDojo() {

      dojo.emailSubject = $translate.instant('We created a new Google Email for your Dojo');
      dojo.editDojoFlag = true;
      cdDojoService.save(dojo, function (response) {
        if ($scope.founder && ($scope.founder.id !== ($scope.prevFounder && $scope.prevFounder.id))) {
          cdDojoService.updateFounder($scope.founder, function (response) {
            alertService.showAlert($translate.instant("Your Dojo has been successfully saved"), function () {
              deleteLocalStorage('editDojoListing');
              $state.go('my-dojos');
              $scope.$apply();
            });
          }, function (err) {
            alertService.showError($translate.instant('An error has occurred while saving'));
          });
        } else {
          alertService.showAlert($translate.instant("Your Dojo has been successfully saved"), function () {
            deleteLocalStorage('editDojoListing');
            $state.go('my-dojos');
            $scope.$apply();
          });
        }

      }, function (err) {
        alertService.showError(
          $translate.instant('An error has occurred while saving') + ':
 ' +
          (err.error || JSON.stringify(err))
        );
      });
    }

    function finish() {
      canUpdateDojo().then(function (isDojoAdmin) {
        if (isDojoAdmin) {
          if($scope.originalDojoListing.alpha2 !== $scope.dojo.alpha2 ||
            $scope.originalDojoListing.admin1Name !== $scope.dojo.admin1Name ||
            $scope.originalDojoListing.placeName !== $scope.dojo.placeName ||
            $scope.originalDojoListing.name !== $scope.dojo.name){

            var options = {
              message: $translate.instant('By changing one of the following: Dojo Name, Country, City/Town, your dojo public url will be changed. Do you agree with this?'),
              title: $translate.instant('Confirmation'),
              buttons: {
                success: {
                  label: $translate.instant('Yes'),
                  className: "btn-primary",
                  callback: function() {
                    saveDojo();
                  }
                },
                warning: {
                  label: $translate.instant('No'),
                  className: "btn-warning",
                  callback: function() {
                  }
                }
              }
            };

            $ngBootbox.customDialog(options);
          } else{
            saveDojo();
          }

        } else {
          alertService.showAlert($translate.instant('You do not have permission to update this Dojo.'));
        }
      });
    }
  };

  $scope.addMarker = function ($event, $params, dojo) {
    $scope.markerPlaced = true;
    angular.forEach($scope.markers, function (marker) {
      marker.setMap(null);
    });
    $scope.markers.push(new google.maps.Marker({
      map: $scope.model.map,
      position: $params[0].latLng
    }));
    dojo.coordinates = $params[0].latLng.lat() + ', ' + $params[0].latLng.lng();
  };

  $scope.getLocationFromAddress = function (cb) {
    var dojo = $scope.dojo;
    utilsService.getLocationFromAddress(dojo).then(function (data) {
      $scope.mapOptions.center = new google.maps.LatLng(data.lat, data.lng);
      $scope.model.map.panTo($scope.mapOptions.center);
      angular.forEach($scope.markers, function (marker) {
        marker.setMap(null);
      });
      $scope.markers.push(new google.maps.Marker({
        map: $scope.model.map,
        position: $scope.mapOptions.center
      }));
      dojo.coordinates = data.lat + ', ' + data.lng;
      if (_.isFunction(cb)) cb();
    }, function () {
      //Ask user to add location manually if google geocoding can't find location.
      if (!_.isFunction(cb)) alertService.showError($translate.instant('Please add your location manually by clicking on the map.'));
      if (_.isFunction(cb)) cb();
    });
  };

  function canUpdateDojo() {
    var deferred = $q.defer();
    var query = {userId: currentUser.data.id, dojoId: $state.params.id};
    var isCDFAdmin = _.contains(currentUser.data.roles, 'cdf-admin');
    if (isCDFAdmin) {
      deferred.resolve(isCDFAdmin);
    } else {
      cdDojoService.getUsersDojos(query, function (userDojo) {
        var isDojoAdmin = _.find(userDojo[0].userPermissions, function (userPermission) {
          return userPermission.name === 'dojo-admin';
        });
        deferred.resolve(isDojoAdmin);
      }, function (err) {
        deferred.reject(err);
      });
    }
    return deferred.promise;
  }
}

angular.module('cpZenPlatform')
  .controller('edit-dojo-controller', ['$scope', 'cdDojoService', 'alertService', 'gmap', 'auth',
    '$state', '$q', '$translate', 'utilsService', 'currentUser', 'cdUsersService', '$localStorage', '$ngBootbox', '$sce', cdEditDojoCtrl]);

<commit_msg>ref issue #145 redirect to manage-dojos after dojo founder is changed<commit_after>'use strict';
/* global google */

function cdEditDojoCtrl($scope, cdDojoService, alertService, gmap, auth,
                        $state, $q, $translate, utilsService, currentUser, cdUsersService, $localStorage, $ngBootbox, $sce) {

  $scope.dojo = {};
  $scope.model = {};
  $scope.markers = [];
  $scope.markerPlaced = false;
  $scope.buttonText = $translate.instant('Update Dojo');
  $scope.hideUserSelect = true;
  $scope.changedLocation = false;
  $scope.disableDojoCountryChange = false;

  $scope.isCDFAdmin = currentUser && currentUser.data && _.contains(currentUser.data.roles, 'cdf-admin');

  var DEFAULT_COORDS = '53.3478,6.2597';

  auth.get_loggedin_user(function (user) {
    $scope.user = user;
  });

  cdDojoService.getDojoConfig(function (json) {
    $scope.dojoStages = _.map(json.dojoStages, function (item) {
      return {value: item.value, label: $translate.instant(item.label)};
    });
  });

  $scope.noop = angular.noop;

  $scope.toggleUserSelect = function (event) {
    $scope.hideUserSelect = !$scope.hideUserSelect;
  };

  $scope.scrollToInvalid = function (form) {
    if (form.$invalid) {
      angular.element('form[name=' + form.$name + '] .ng-invalid')[0].scrollIntoView();
    }
  };

  async.waterfall([function (done) {
    var dojoId = $state.params.id;

    cdDojoService.load(dojoId, function (response) {
      if (!_.isEmpty(response)) {
        return done(null, response);
      } else {
        return done($translate.instant('Failed to load Dojo'));
      }
    });
  }, function (dojo, done) {
    var query = {};

    query.dojoId = dojo.id;

    query.owner = 1;

    cdDojoService.getUsersDojos(query, function (response) {

      return done(null, dojo, response[0]);
    }, function () {
      return done($translate.instant('Failed to load Dojo'));
    });

  }, function (dojo, prevFounder, done) {

    if (_.isEmpty(prevFounder)) {
      return done(null, dojo);
    }

    cdUsersService.loadPrevFounder(prevFounder.userId, function(response){
      prevFounder.email = response.email;
      prevFounder.name = response.name;

      return done(null, dojo, prevFounder);
    }, function (err) {
      return done(err);
    });
  }], function (err, dojo, prevFounder) {
    if (err) {
      alertService.showError(err);
      return;
    }

    var initContent = "
" +
      $translate.instant('Suggested Notes:') + "

" + $translate.instant('Please bring:') +
      "

" + $translate.instant('A pack lunch.') + "
" +
      "
" + $translate.instant('A laptop. Borrow one from somebody if needs be.') + "
" +
      "
" + $translate.instant('A parent! (Very important). If you are 12 or under, your parent must stay with you during the session.') + "
" +
      "

";

    $scope.editorOptions = {
      language: 'en',
      uiColor: '#000000',
      height: '200px'
    };
    if (dojo.notes === '') $scope.editorOptions.initContent = initContent;

    $scope.originalDojoListing = angular.copy(dojo);
    $scope.dojo = dojo;
    $scope.disableDojoCountryChange = dojo.verified === 1;
    $scope.prevFounder = prevFounder;
    $scope.founder = angular.copy(prevFounder);
    loadDojoMap();
    updateFromLocalStorage();
  });

  $scope.getUsersByEmails = function (email) {
    if (!email || !email.length || email.length < 3) {
      $scope.users = [];
      return;
    }

    var win = function (users) {
      $scope.users = users;
    };

    var fail = function () {
      alertService.showError($translate.instant('An error has occurred while loading Dojos'));
    };

    cdUsersService.getUsersByEmails(email, win, fail);
  };

  $scope.setFounder = function (founder) {
    if (founder) {
      $scope.founder = founder;
      $scope.founder.previousFounderId = $scope.prevFounder.userId;
      $scope.founder.dojoId = $scope.dojo.id;
    }
  };

  function loadDojoMap() {
    $scope.$watch('model.map', function (map) {
      if (map) {
        var marker = new google.maps.Marker({
          map: $scope.model.map,
          position: new google.maps.LatLng(latitude, longitude)
        });
        $scope.markers.push(marker);
      }
    });

    if (gmap) {
      $scope.mapLoaded = true;

      var coordsStr = $scope.dojo.coordinates;

      if (!coordsStr) {
        coordsStr = DEFAULT_COORDS;
      }

      var coordinates = coordsStr.split(',');
      var latitude = coordinates[0];
      var longitude = coordinates[1];

      if (!isNaN(utilsService.filterFloat(latitude)) && !isNaN(utilsService.filterFloat(latitude))) {
        $scope.mapOptions = {
          center: new google.maps.LatLng(latitude, longitude),
          zoom: 15,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
      } else if ($scope.dojo.geoPoint && $scope.dojo.geoPoint.lat && $scope.dojo.geoPoint.lon) {
        //add map using coordinates from geopoint if possible
        $scope.mapOptions = {
          center: new google.maps.LatLng($scope.dojo.geoPoint.lat, $scope.dojo.geoPoint.lon),
          zoom: 15,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
      } else { //add empty map
        cdDojoService.loadCountriesLatLongData(function (countries) {
          var country = countries[$scope.dojo.alpha2];
          $scope.mapOptions = {
            center: new google.maps.LatLng(country[0], country[1]),
            zoom: 15,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
        })
      }
    }
    $scope.dojoPageReady = true;
  }

  function updateFromLocalStorage() {
    if ($localStorage[$scope.user.id] && $localStorage[$scope.user.id].editDojo && $localStorage[$scope.user.id].editDojo[$scope.dojo.id]) {
      alertService.showAlert($translate.instant('There are unsaved changes on this page'));
      var lsed = $localStorage[$scope.user.id].editDojo[$scope.dojo.id];
      if (lsed.name) $scope.dojo.name = lsed.name;
      if (lsed.email) $scope.dojo.email = lsed.email;
      if (lsed.time) $scope.dojo.time = lsed.time;
      if (lsed.country) {
        $scope.dojo.country = lsed.country;
        $scope.setCountry($scope.dojo, lsed.country);
      }
      if (lsed.place) {
        $scope.dojo.place = lsed.place;
        $scope.setPlace($scope.dojo, lsed.place);
      }
      if (lsed.country && lsed.place) {
        $scope.getLocationFromAddress();
      }
      if (lsed.address1) $scope.dojo.address1 = lsed.address1;
      if (lsed.coordinates) $scope.dojo.coordinates = lsed.coordinates;
      if (lsed.needMentors) $scope.dojo.needMentors = lsed.needMentors;
      if (lsed.stage) $scope.dojo.stage = lsed.stage;
      if (lsed.private) $scope.dojo.private = lsed.private;
      if (lsed.googleGroup) $scope.dojo.googleGroup = lsed.googleGroup;
      if (lsed.website) $scope.dojo.website = lsed.website;
      if (lsed.twitter) $scope.dojo.twitter = lsed.twitter;
      if (lsed.supporterImage) $scope.dojo.supporterImage = lsed.supporterImage;
      if (lsed.mailingList) $scope.dojo.mailingList = lsed.mailingList;
    }
  }

  cdDojoService.listCountries(function (countries) {
    $scope.countries = countries;
  });

  $scope.getPlaces = function (countryCode, $select) {
    return utilsService.getPlaces(countryCode, $select).then(function (data) {
      $scope.places = data;
    }, function (err) {
      $scope.places = [];
      console.error(err);
    });
  };

  $scope.setCountry = function (dojo, country) {
    dojo.countryName = country.countryName;
    dojo.countryNumber = country.countryNumber;
    dojo.continent = country.continent;
    dojo.alpha2 = country.alpha2;
    dojo.alpha3 = country.alpha3;
  };

  $scope.setPlace = function (dojo, place, form) {
    if(place.nameWithHierarchy.length > 40) {
      if(form) form.place.$setValidity("maxLength", false);
    } else {
      if(form) form.place.$setValidity("maxLength", true);
    }
    dojo.placeName = place.name || place.nameWithHierarchy;
    dojo.placeGeonameId = place.geonameId;
    dojo.county = {};
    dojo.state = {};
    dojo.city = {};
    for (var adminidx = 1; adminidx <= 4; adminidx++) {
      dojo['admin' + adminidx + 'Code'] = place['admin' + adminidx + 'Code'];
      dojo['admin' + adminidx + 'Name'] = place['admin' + adminidx + 'Name'];
    }
  };

  $scope.clearPlace = function (dojo) {
    dojo.placeName = "";
    dojo.placeGeonameId = "";
    dojo.county = {};
    dojo.state = {};
    dojo.city = {};
    for (var adminidx = 1; adminidx <= 4; adminidx++) {
      dojo['admin' + adminidx + 'Code'] = "";
      dojo['admin' + adminidx + 'Name'] = "";
    }
    $scope.dojo.place = "";
  };

  $scope.updateLocalStorage = function (localObj, item, value) {
    if (['address1', 'place'].indexOf(item) > -1) {
      $scope.changedLocation = true;
      $scope.setPlace($scope.dojo, $scope.dojo.place);
    }

    if ($scope.user && $state.current.name === "edit-dojo") {
      localObj = $scope.dojo.id;
      if (!$localStorage[$scope.user.id]) $localStorage[$scope.user.id] = {};
      if (!$localStorage[$scope.user.id].editDojo) $localStorage[$scope.user.id].editDojo = {};
      if (!$localStorage[$scope.user.id].editDojo[localObj]) $localStorage[$scope.user.id].editDojo[localObj] = {};
      if (typeof value === 'undefined') value = false;
      $localStorage[$scope.user.id].editDojo[localObj][item] = value;
    }
  };

  var deleteLocalStorage = function (localObj) {
    if ($scope.user && $state.current.name === "edit-dojo") {
      if ($localStorage[$scope.user.id] && $localStorage[$scope.user.id].editDojo && $localStorage[$scope.user.id].editDojo[$scope.dojo.id]) {
        delete $localStorage[$scope.user.id].editDojo[$scope.dojo.id]
      }
    }
  };

  $scope.save = function (dojo) {

    if ($scope.changedLocation && !$scope.markerPlaced) {
      $scope.getLocationFromAddress(finish);
    } else {
      finish();
    }

    function saveDojo() {

      dojo.emailSubject = $translate.instant('We created a new Google Email for your Dojo');
      dojo.editDojoFlag = true;
      cdDojoService.save(dojo, function (response) {
        if ($scope.founder && ($scope.founder.id !== ($scope.prevFounder && $scope.prevFounder.id))) {
          cdDojoService.updateFounder($scope.founder, function (response) {
            alertService.showAlert($translate.instant("Your Dojo has been successfully saved"), function () {
              deleteLocalStorage('editDojoListing');
              $state.go('manage-dojos');
              $scope.$apply();
            });
          }, function (err) {
            alertService.showError($translate.instant('An error has occurred while saving'));
          });
        } else {
          alertService.showAlert($translate.instant("Your Dojo has been successfully saved"), function () {
            deleteLocalStorage('editDojoListing');
            $state.go('my-dojos');
            $scope.$apply();
          });
        }
      }, function (err) {
        alertService.showError(
          $translate.instant('An error has occurred while saving') + ':
 ' +
          (err.error || JSON.stringify(err))
        );
      });
    }

    function finish() {
      canUpdateDojo().then(function (isDojoAdmin) {
        if (isDojoAdmin) {
          if($scope.originalDojoListing.alpha2 !== $scope.dojo.alpha2 ||
            $scope.originalDojoListing.admin1Name !== $scope.dojo.admin1Name ||
            $scope.originalDojoListing.placeName !== $scope.dojo.placeName ||
            $scope.originalDojoListing.name !== $scope.dojo.name){

            var options = {
              message: $translate.instant('By changing one of the following: Dojo Name, Country, City/Town, your dojo public url will be changed. Do you agree with this?'),
              title: $translate.instant('Confirmation'),
              buttons: {
                success: {
                  label: $translate.instant('Yes'),
                  className: "btn-primary",
                  callback: function() {
                    saveDojo();
                  }
                },
                warning: {
                  label: $translate.instant('No'),
                  className: "btn-warning",
                  callback: function() {
                  }
                }
              }
            };

            $ngBootbox.customDialog(options);
          } else{
            saveDojo();
          }

        } else {
          alertService.showAlert($translate.instant('You do not have permission to update this Dojo.'));
        }
      });
    }
  };

  $scope.addMarker = function ($event, $params, dojo) {
    $scope.markerPlaced = true;
    angular.forEach($scope.markers, function (marker) {
      marker.setMap(null);
    });
    $scope.markers.push(new google.maps.Marker({
      map: $scope.model.map,
      position: $params[0].latLng
    }));
    dojo.coordinates = $params[0].latLng.lat() + ', ' + $params[0].latLng.lng();
  };

  $scope.getLocationFromAddress = function (cb) {
    var dojo = $scope.dojo;
    utilsService.getLocationFromAddress(dojo).then(function (data) {
      $scope.mapOptions.center = new google.maps.LatLng(data.lat, data.lng);
      $scope.model.map.panTo($scope.mapOptions.center);
      angular.forEach($scope.markers, function (marker) {
        marker.setMap(null);
      });
      $scope.markers.push(new google.maps.Marker({
        map: $scope.model.map,
        position: $scope.mapOptions.center
      }));
      dojo.coordinates = data.lat + ', ' + data.lng;
      if (_.isFunction(cb)) cb();
    }, function () {
      //Ask user to add location manually if google geocoding can't find location.
      if (!_.isFunction(cb)) alertService.showError($translate.instant('Please add your location manually by clicking on the map.'));
      if (_.isFunction(cb)) cb();
    });
  };

  function canUpdateDojo() {
    var deferred = $q.defer();
    var query = {userId: currentUser.data.id, dojoId: $state.params.id};
    var isCDFAdmin = _.contains(currentUser.data.roles, 'cdf-admin');
    if (isCDFAdmin) {
      deferred.resolve(isCDFAdmin);
    } else {
      cdDojoService.getUsersDojos(query, function (userDojo) {
        var isDojoAdmin = _.find(userDojo[0].userPermissions, function (userPermission) {
          return userPermission.name === 'dojo-admin';
        });
        deferred.resolve(isDojoAdmin);
      }, function (err) {
        deferred.reject(err);
      });
    }
    return deferred.promise;
  }
}

angular.module('cpZenPlatform')
  .controller('edit-dojo-controller', ['$scope', 'cdDojoService', 'alertService', 'gmap', 'auth',
    '$state', '$q', '$translate', 'utilsService', 'currentUser', 'cdUsersService', '$localStorage', '$ngBootbox', '$sce', cdEditDojoCtrl]);

<|endoftext|>


<commit_before>import { gql } from 'react-apollo'

export default gql`
query memoryFeaturedByLanguage(
  $language: String!,
) {
  allMemories(
    first: 5,
    orderBy: ID_DESC,,
    condition: { language: $language },
  ) {
    nodes {
      id,
      ownerFirstName,
      victimBornAt,
      victimDeadAt,
      victimHistory,
      victimName,
      victimPhoto,
      victimRememberText,
      victimSilhouette,
    }
  }
}
`
<commit_msg>fix(graphql): fetch only memories that authorizes close #172<commit_after>import { gql } from 'react-apollo'

export default gql`
query memoryFeaturedByLanguage(
  $language: String!,
) {
  allMemories(
    first: 5,
    orderBy: ID_DESC,,
    condition: {
      language: $language,
      authorizedToSite: true,
    },
  ) {
    nodes {
      id,
      ownerFirstName,
      victimBornAt,
      victimDeadAt,
      victimHistory,
      victimName,
      victimPhoto,
      victimRememberText,
      victimSilhouette,
    }
  }
}
`
<|endoftext|>


<commit_before>const uniqBy = require('lodash/uniqBy')

module.exports = (data, state) => {
  const results = uniqBy(state.results.concat(data.hits), (result) => {
    return result.document.identifier[0].id
  })
  // TODO: intelligent merging of results based on TF-IDF score
  return {
    results: results
  }
}
<commit_msg>Preserve selected paper if results change<commit_after>const uniqBy = require('lodash/uniqBy')

module.exports = (data, state) => {
  var selected = null
  if (state.selectedpaper) {
    state.results[state.selectedpaper]
  }

  const results = uniqBy(state.results.concat(data.hits), (result) => {
    return result.document.identifier[0].id
  })

  const update = {
    results: results
  }

  if (selected) {
    update.selectedpaper = results.indexOf(selected)
  }

  // TODO: intelligent merging of results based on TF-IDF score
  return update
}
<|endoftext|>


<commit_before>'use strict';

const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('electron-spellchecker');

const ConfigUtil = require(__dirname + '/utils/config-util.js');

function spellChecker() {
	// Implement spellcheck using electron api
	window.spellCheckHandler = new SpellCheckHandler();
	window.spellCheckHandler.attachToInput();

	const userLanguage = ConfigUtil.getConfigItem('spellcheckerLanguage');

	// On macOS, spellchecker fails to auto-detect the lanugage user is typing in
	// that's why we need to mention it explicitly
	if (process.platform === 'darwin') {
		window.spellCheckHandler.switchLanguage(userLanguage);
	}

	// On Linux and Windows, spellchecker can automatically detects the language the user is typing in
	// and silently switches on the fly; thus we can start off as US English
	window.spellCheckHandler.switchLanguage('en-US');

	const contextMenuBuilder = new ContextMenuBuilder(window.spellCheckHandler);
	const contextMenuListener = new ContextMenuListener(info => {
		contextMenuBuilder.showPopupMenu(info);
	});

	// Clean up events after you navigate away from this page;
	// otherwise, you may experience errors
	window.addEventListener('beforeunload', () => {
		// eslint-disable-next-line no-undef
		spellCheckHandler.unsubscribe();
		contextMenuListener.unsubscribe();
	});
}

module.exports = {
	spellChecker
};
<commit_msg>Set English as default language for spellchecker on Linux/Windows<commit_after>'use strict';

const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('electron-spellchecker');

const ConfigUtil = require(__dirname + '/utils/config-util.js');

function spellChecker() {
	// Implement spellcheck using electron api
	window.spellCheckHandler = new SpellCheckHandler();
	window.spellCheckHandler.attachToInput();

	const userLanguage = ConfigUtil.getConfigItem('spellcheckerLanguage');

	// eslint-disable-next-line no-unused-expressions
	process.platform === 'darwin' ?
		// On macOS, spellchecker fails to auto-detect the lanugage user is typing in
		// that's why we need to mention it explicitly
		window.spellCheckHandler.switchLanguage(userLanguage) :
		// On Linux and Windows, spellchecker can automatically detects the language the user is typing in
		// and silently switches on the fly; thus we can start off as US English
		window.spellCheckHandler.switchLanguage('en-US');

	const contextMenuBuilder = new ContextMenuBuilder(window.spellCheckHandler);
	const contextMenuListener = new ContextMenuListener(info => {
		contextMenuBuilder.showPopupMenu(info);
	});

	// Clean up events after you navigate away from this page;
	// otherwise, you may experience errors
	window.addEventListener('beforeunload', () => {
		// eslint-disable-next-line no-undef
		spellCheckHandler.unsubscribe();
		contextMenuListener.unsubscribe();
	});
}

module.exports = {
	spellChecker
};
<|endoftext|>


<commit_before>'use strict';

var api = require('../../app/controllers/api');

module.exports = function(app) {

	app.route('/requestTicket').post(api.requestTicket);
	app.route('/requestMatch').post(api.requestMatch);
	app.route('/waitTurn').post(api.waitTurn);
	app.route('/submitTurn').get(api.submitTurn);
	app.route('/getMatchStatus').get(api.getMatchStatus);
	app.route('/setMatchStatus').get(api.setMatchStatus);

};
<commit_msg>cambios en requestMatch y modelos<commit_after>'use strict';

var api = require('../../app/controllers/api');

module.exports = function(app) {

	app.route('/requestTicket').post(api.requestTicket);
	app.route('/requestMatch').post(api.requestMatch);
	app.route('/waitTurn').post(api.waitTurn);
	app.route('/submitTurn').post(api.submitTurn);
	app.route('/getMatchStatus').post(api.getMatchStatus);
	app.route('/setMatchStatus').post(api.setMatchStatus);

};
<|endoftext|>


<commit_before>//     Zepto.js
//     (c) 2010-2014 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

;(function($){
  function detect(ua){
    var os = this.os = {}, browser = this.browser = {},
      webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),
      android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
      osx = !!ua.match(/\(Macintosh\; Intel /),
      ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
      ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
      iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
      webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
      touchpad = webos && ua.match(/TouchPad/),
      kindle = ua.match(/Kindle\/([\d.]+)/),
      silk = ua.match(/Silk\/([\d._]+)/),
      blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
      bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
      rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
      playbook = ua.match(/PlayBook/),
      chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
      firefox = ua.match(/Firefox\/([\d.]+)/),
      ie = ua.match(/MSIE\s([\d.]+)/) || ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),
      webview = !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
      safari = webview || ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/)

    // Todo: clean this up with a better OS/browser seperation:
    // - discern (more) between multiple browsers on android
    // - decide if kindle fire in silk mode is android or not
    // - Firefox on Android doesn't specify the Android version
    // - possibly devide in os, device and browser hashes

    if (browser.webkit = !!webkit) browser.version = webkit[1]

    if (android) os.android = true, os.version = android[2]
    if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
    if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
    if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null
    if (webos) os.webos = true, os.version = webos[2]
    if (touchpad) os.touchpad = true
    if (blackberry) os.blackberry = true, os.version = blackberry[2]
    if (bb10) os.bb10 = true, os.version = bb10[2]
    if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2]
    if (playbook) browser.playbook = true
    if (kindle) os.kindle = true, os.version = kindle[1]
    if (silk) browser.silk = true, browser.version = silk[1]
    if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true
    if (chrome) browser.chrome = true, browser.version = chrome[1]
    if (firefox) browser.firefox = true, browser.version = firefox[1]
    if (ie) browser.ie = true, browser.version = ie[1]
    if (safari && (osx || os.ios)) {browser.safari = true; if (osx) browser.version = safari[1]}
    if (webview) browser.webview = true

    os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
      (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)))
    os.phone  = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||
      (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
      (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))))
  }

  detect.call($, navigator.userAgent)
  // make available to unit tests
  $.__detect = detect

})(Zepto);<commit_msg>Added windows phone detection<commit_after>//     Zepto.js
//     (c) 2010-2014 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

// windows phone
 // "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)"

;(function($){
  function detect(ua){
    var os = this.os = {}, browser = this.browser = {},
      webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),
      android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
      osx = !!ua.match(/\(Macintosh\; Intel /),
      ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
      ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
      iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
      wp = ua.match(/Windows Phone ([\d.]+)/),
      webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
      touchpad = webos && ua.match(/TouchPad/),
      kindle = ua.match(/Kindle\/([\d.]+)/),
      silk = ua.match(/Silk\/([\d._]+)/),
      blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
      bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
      rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
      playbook = ua.match(/PlayBook/),
      chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
      firefox = ua.match(/Firefox\/([\d.]+)/),
      ie = ua.match(/MSIE\s([\d.]+)/) || ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),
      webview = !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
      safari = webview || ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/)

    // Todo: clean this up with a better OS/browser seperation:
    // - discern (more) between multiple browsers on android
    // - decide if kindle fire in silk mode is android or not
    // - Firefox on Android doesn't specify the Android version
    // - possibly devide in os, device and browser hashes

    if (browser.webkit = !!webkit) browser.version = webkit[1]

    if (android) os.android = true, os.version = android[2]
    if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
    if (wp) os.wp = true, os.version = wp[1]
    if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
    if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null
    if (webos) os.webos = true, os.version = webos[2]
    if (touchpad) os.touchpad = true
    if (blackberry) os.blackberry = true, os.version = blackberry[2]
    if (bb10) os.bb10 = true, os.version = bb10[2]
    if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2]
    if (playbook) browser.playbook = true
    if (kindle) os.kindle = true, os.version = kindle[1]
    if (silk) browser.silk = true, browser.version = silk[1]
    if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true
    if (chrome) browser.chrome = true, browser.version = chrome[1]
    if (firefox) browser.firefox = true, browser.version = firefox[1]
    if (ie && !wp) browser.ie = true, browser.version = ie[1]
    if (safari && (osx || os.ios)) {browser.safari = true; if (osx) browser.version = safari[1]}
    if (webview) browser.webview = true

    os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
      (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)))
    os.phone  = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||
      (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
      (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))))
  }

  detect.call($, navigator.userAgent)
  // make available to unit tests
  $.__detect = detect

})(Zepto);<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name discussionToolApp.controller:AuthCtrl
 * @description
 * # AuthCtrl
 * Controller of the discussionToolApp
 */
angular.module('discussionToolApp')
  .controller('AuthCtrl', function ($rootScope, $scope, $location, config, $routeParams, authService) {
    // Decode twice because it gets encoded once more by the OIDC
    var targetUri = decodeURIComponent(decodeURIComponent($routeParams.target));

    $rootScope.targetEntityUri = targetUri;

    $scope.authMessageType = 'info';
    $scope.authMessage = 'Autentication in progress, please wait!';

    function setAuthMessage (type, message) {
      $scope.authMessageType = type;
      $scope.authMessage = message;
    }

    if ( !$scope.isLoggedIn() ) {
      if ( config.oidcAuthorizationUrl && config.oidcClientId ) {
        var queryObject = $location.search();

        if (  !queryObject.access_token ) {
          setAuthMessage('info', 'Redrecting to OpenID Connect Service Provider!');
          window.location.href = authService.buildOIDCRedirectUrl($location.absUrl());
        } else {
          setAuthMessage('info', 'Handling OpenID Connect authentication response!');
          authService.oidcAuth(queryObject.token_type + ' ' + queryObject.access_token, function (response) {
            setAuthMessage('success', 'Authentication successful, redirecting!');
            authService.setAuthCookie({
              authKey: response.key,
              userUri: response.user,
            });
            // Clear the search part
            $location.search({});
            $location.path('/discussions/' + encodeURIComponent(targetUri) + '/list');
          }, function () {
            setAuthMessage('danger', 'Authentication with SSS failed.');
          });
        }
      } else {
        setAuthMessage('danger', 'Authentication configuration missing!');
      }
    } else {
      setAuthMessage('warning', 'You already are authenticated, redirecting!');
      $location.path('/discussions/' + encodeURIComponent(targetUri) + '/list');
    }
  });
<commit_msg>One last fix for loading files lookup.<commit_after>'use strict';

/**
 * @ngdoc function
 * @name discussionToolApp.controller:AuthCtrl
 * @description
 * # AuthCtrl
 * Controller of the discussionToolApp
 */
angular.module('discussionToolApp')
  .controller('AuthCtrl', function ($rootScope, $scope, $location, config, $routeParams, authService) {
    // Decode twice because it gets encoded once more by the OIDC
    var targetUri = decodeURIComponent(decodeURIComponent($routeParams.target));

    $scope.authMessageType = 'info';
    $scope.authMessage = 'Autentication in progress, please wait!';

    function setAuthMessage (type, message) {
      $scope.authMessageType = type;
      $scope.authMessage = message;
    }

    if ( !$scope.isLoggedIn() ) {
      if ( config.oidcAuthorizationUrl && config.oidcClientId ) {
        var queryObject = $location.search();

        if (  !queryObject.access_token ) {
          setAuthMessage('info', 'Redrecting to OpenID Connect Service Provider!');
          window.location.href = authService.buildOIDCRedirectUrl($location.absUrl());
        } else {
          setAuthMessage('info', 'Handling OpenID Connect authentication response!');
          authService.oidcAuth(queryObject.token_type + ' ' + queryObject.access_token, function (response) {
            setAuthMessage('success', 'Authentication successful, redirecting!');
            authService.setAuthCookie({
              authKey: response.key,
              userUri: response.user,
            });
            // Clear the search part
            $location.search({});
            $location.path('/discussions/' + encodeURIComponent(targetUri) + '/list');
          }, function () {
            setAuthMessage('danger', 'Authentication with SSS failed.');
          });
        }
      } else {
        setAuthMessage('danger', 'Authentication configuration missing!');
      }
    } else {
      setAuthMessage('warning', 'You already are authenticated, redirecting!');
      $location.path('/discussions/' + encodeURIComponent(targetUri) + '/list');
    }
  });
<|endoftext|>


<commit_before>'use strict';

var shell = require('shell');
var remote = require('remote');
var appConfig = remote.require('./lib/app-config');

/**
 * @ngdoc function
 * @name hipslackApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the hipslackApp
 */
angular.module('hipslackApp')
  .controller('MainCtrl', function ($scope, $http, $modal, $location, $sce, config, Messages, Rooms, Members) {
    $scope.openedRooms = [];
    $scope.isLoading = false;
    $scope._activeMessageParam = null;
    $scope.roomsClick = function() {
      var roomsModal = $modal.open({
        animation: true,
        size: 'lg',
        templateUrl: 'roomsModal.html',
        controller: 'RoomsModalCtrl'
      });
      roomsModal.result.then(function (selectedItem){
        $scope.roomClick(selectedItem);
      });
    };
    $scope.roomClick = function(room) {
      $scope._loadRoom(room, function() {
        $scope._saveStates();
      });
    };
    $scope._loadRoom = function(room, callback) {
      $scope.isLoading = true;
      $scope._activeMessageParam = room;
      Rooms.open(room, function() {
        Members.setActive(null);
        $scope.activeRoomProperty = Rooms.activeRoomProperty;
        $scope._update();
        if (callback !== undefined) {
          callback();
        }
      });
    };
    $scope.membersClick = function() {
      var directMessagesModal = $modal.open({
        animation: true,
        size: 'lg',
        templateUrl: 'directMessagesModal.html',
        controller: 'DirectMessagesModalCtrl'
      });
      directMessagesModal.result.then(function (selectedItem){
        $scope.memberClick(selectedItem);
      });
    };
    $scope.memberClick = function(member) {
      $scope._loadMember(member, function() {
        $scope._saveStates();
      });
    };
    $scope._loadMember = function(member, callback) {
      $scope.isLoading = true;
      $scope._activeMessageParam = member;
      Members.open(member, function() {
        Rooms.setActive(null);
        $scope.activeRoomProperty = null;
        $scope._update();
        if (callback !== null) {
          callback();
        }
      });
    };
    $scope._redraw = function() {
      if ($scope._activeMessageParam === null) {
        return;
      }
      if ($scope.activeRoomProperty) {
        $scope._loadRoom($scope._activeMessageParam);
      } else {
        $scope._loadMember($scope._activeMessageParam);
      }
    };
    $scope._update = function() {
      $scope.groupMessages = Messages.messages;
      $scope.openedRooms = Rooms.openedItems;
      $scope.openedMembers = Members.openedItems;
      var last = Messages.getLast();
      if (last) {
        $location.hash('message-' + last.id);
      }
      $scope.isLoading = false;
    };
    $scope.closeRoom = function(room) {
      Rooms.close(room);
      $scope.openedRooms = Rooms.openedItems;
    };
    $scope.sendMessageClick = function() {
      var getUrl = function () {
        if ($scope.activeRoomProperty) {
          var roomId = Rooms.getActiveId();
          return config.backend + '/v2/room/' + roomId +  '/message';
        } else {
          var roomId2 = Members.getActiveId();
          return config.backend + '/v2/user/' + roomId2 +  '/message';
        }
      };
      var uri = getUrl();
      $http({
        method: 'POST',
        url: uri,
        data: { message: $scope.inputText },
        headers: { 'Authorization': 'Bearer ' + config.authkey }
      }).success(function() {
        $scope.inputText = "";
        $scope._redraw();
      });
    };
    $scope.messageBoxKeyDown = function() {
      $scope.sendMessageClick();
    };
    $scope.linkClick = function(url) {
      shell.openExternal(url);
      return false;
    };
    $scope.toTrusted = function(htmlCode) {
      return $sce.trustAsHtml(htmlCode);
    };
    $scope._saveStates = function() {
      appConfig.save({
        rooms: $scope.openedRooms,
        members: $scope.openedMembers,
        isRoom: $scope.activeRoomProperty,
        active: $scope._activeMessageParam
      });
    };
    $scope._loadStates = function() {
      appConfig.load(function(config) {
        Rooms.openedItems = config.rooms;
        Members.openedItems = config.members;
        if (config.isRoom) {
          $scope._loadRoom(config.active);
        } else {
          $scope._loadMember(config.active);
        }
      });
    };
    $scope._redrawHookEvent = function() {
      $scope._redraw();
      setTimeout($scope._redrawHookEvent, 30000);
    };
    $scope._redrawHookEvent();
    $scope._loadStates();
  });
<commit_msg>fix can't close member message<commit_after>'use strict';

var shell = require('shell');
var remote = require('remote');
var appConfig = remote.require('./lib/app-config');

/**
 * @ngdoc function
 * @name hipslackApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the hipslackApp
 */
angular.module('hipslackApp')
  .controller('MainCtrl', function ($scope, $http, $modal, $location, $sce, config, Messages, Rooms, Members) {
    $scope.openedRooms = [];
    $scope.isLoading = false;
    $scope._activeMessageParam = null;
    $scope.roomsClick = function() {
      var roomsModal = $modal.open({
        animation: true,
        size: 'lg',
        templateUrl: 'roomsModal.html',
        controller: 'RoomsModalCtrl'
      });
      roomsModal.result.then(function (selectedItem){
        $scope.roomClick(selectedItem);
      });
    };
    $scope.roomClick = function(room) {
      $scope._loadRoom(room, function() {
        $scope._saveStates();
      });
    };
    $scope._loadRoom = function(room, callback) {
      $scope.isLoading = true;
      $scope._activeMessageParam = room;
      Rooms.open(room, function() {
        Members.setActive(null);
        $scope.activeRoomProperty = Rooms.activeRoomProperty;
        $scope._update();
        if (callback !== undefined) {
          callback();
        }
      });
    };
    $scope.membersClick = function() {
      var directMessagesModal = $modal.open({
        animation: true,
        size: 'lg',
        templateUrl: 'directMessagesModal.html',
        controller: 'DirectMessagesModalCtrl'
      });
      directMessagesModal.result.then(function (selectedItem){
        $scope.memberClick(selectedItem);
      });
    };
    $scope.memberClick = function(member) {
      $scope._loadMember(member, function() {
        $scope._saveStates();
      });
    };
    $scope._loadMember = function(member, callback) {
      $scope.isLoading = true;
      $scope._activeMessageParam = member;
      Members.open(member, function() {
        Rooms.setActive(null);
        $scope.activeRoomProperty = null;
        $scope._update();
        if (callback !== undefined) {
          callback();
        }
      });
    };
    $scope._redraw = function() {
      if ($scope._activeMessageParam === null) {
        return;
      }
      if ($scope.activeRoomProperty) {
        $scope._loadRoom($scope._activeMessageParam);
      } else {
        $scope._loadMember($scope._activeMessageParam);
      }
    };
    $scope._update = function() {
      $scope.groupMessages = Messages.messages;
      $scope.openedRooms = Rooms.openedItems;
      $scope.openedMembers = Members.openedItems;
      var last = Messages.getLast();
      if (last) {
        $location.hash('message-' + last.id);
      }
      $scope.isLoading = false;
    };
    $scope.closeRoom = function(room) {
      Rooms.close(room);
      $scope.openedRooms = Rooms.openedItems;
    };
    $scope.closeMember = function(member) {
      Members.close(member);
      $scope.openedMembers = Members.openedItems;
    };
    $scope.sendMessageClick = function() {
      var getUrl = function () {
        if ($scope.activeRoomProperty) {
          var roomId = Rooms.getActiveId();
          return config.backend + '/v2/room/' + roomId +  '/message';
        } else {
          var roomId2 = Members.getActiveId();
          return config.backend + '/v2/user/' + roomId2 +  '/message';
        }
      };
      var uri = getUrl();
      $http({
        method: 'POST',
        url: uri,
        data: { message: $scope.inputText },
        headers: { 'Authorization': 'Bearer ' + config.authkey }
      }).success(function() {
        $scope.inputText = "";
        $scope._redraw();
      });
    };
    $scope.messageBoxKeyDown = function() {
      $scope.sendMessageClick();
    };
    $scope.linkClick = function(url) {
      shell.openExternal(url);
      return false;
    };
    $scope.toTrusted = function(htmlCode) {
      return $sce.trustAsHtml(htmlCode);
    };
    $scope._saveStates = function() {
      appConfig.save({
        rooms: $scope.openedRooms,
        members: $scope.openedMembers,
        isRoom: $scope.activeRoomProperty,
        active: $scope._activeMessageParam
      });
    };
    $scope._loadStates = function() {
      appConfig.load(function(config) {
        Rooms.openedItems = config.rooms;
        Members.openedItems = config.members;
        if (config.isRoom) {
          $scope._loadRoom(config.active);
        } else {
          $scope._loadMember(config.active);
        }
      });
    };
    $scope._redrawHookEvent = function() {
      $scope._redraw();
      setTimeout($scope._redrawHookEvent, 30000);
    };
    $scope._redrawHookEvent();
    $scope._loadStates();
  });
<|endoftext|>


<commit_before>/* global app */

/**
 * Main App Controller -- Manage all emails visible in the list
 */

app.controller('MainCtrl', [
  '$scope', '$rootScope', '$http', 'Email', '$route', '$location',
  function($scope, $rootScope, $http, Email, $route, $location) {

    $scope.items = [];
    $scope.configOpen = false;
    $scope.currentItemId = null;
    $scope.autoShow = false;

    // Load all emails
    var loadData = function() {
      $scope.items = Email.query();
    };

    $rootScope.$on('Refresh', function(e, d) {
      loadData();
    });

    $rootScope.$on('$routeChangeSuccess', function( e, route ) {
      if ( route.params ) {
        $scope.currentItemId = route.params.itemId;
      }
    });

    var refreshTimeout = null;
    $rootScope.$on('newMail', function(e, newEmail) {

      //update model
      $scope.items.push(newEmail);

      //update DOM at most 5 times per second
      if (!refreshTimeout) {
        refreshTimeout = setTimeout(function() {
          refreshTimeout = null;
          if ( $scope.autoShow === true ) {
            $location.path('/email/' + newEmail.id );
          }
          $scope.$apply();
        }, 200);
      }

    });

    // Click event handlers
    $scope.markRead = function(email) {
      email.read = true;
    };

    $scope.showConfig = function(){
      $scope.configOpen = !$scope.configOpen;
    };

    $scope.toggleAutoShow = function() {
      $scope.autoShow = !$scope.autoShow;
    };

    // Initialize the view
    loadData();

    $http({method: 'GET', url: 'config'})
      .success(function(data){
        $rootScope.config = data;
        $scope.config = data;
      });

  }
]);

/**
 * Navigation Controller
 */

app.controller('NavCtrl', [
  '$scope', '$rootScope', '$location', 'Email',
  function($scope, $rootScope, $location, Email) {

    $scope.refreshList = function() {
      $rootScope.$emit('Refresh');
    };

    $scope.deleteAll = function() {

      Email.delete({ id: 'all' }, function(email) {
        $rootScope.$emit('Refresh');
        $location.path('/');
      });

    };

  }
]);
<commit_msg>fix jslint error - trailing whitespace on line 43<commit_after>/* global app */

/**
 * Main App Controller -- Manage all emails visible in the list
 */

app.controller('MainCtrl', [
  '$scope', '$rootScope', '$http', 'Email', '$route', '$location',
  function($scope, $rootScope, $http, Email, $route, $location) {

    $scope.items = [];
    $scope.configOpen = false;
    $scope.currentItemId = null;
    $scope.autoShow = false;

    // Load all emails
    var loadData = function() {
      $scope.items = Email.query();
    };

    $rootScope.$on('Refresh', function(e, d) {
      loadData();
    });

    $rootScope.$on('$routeChangeSuccess', function( e, route ) {
      if ( route.params ) {
        $scope.currentItemId = route.params.itemId;
      }
    });

    var refreshTimeout = null;
    $rootScope.$on('newMail', function(e, newEmail) {

      //update model
      $scope.items.push(newEmail);

      //update DOM at most 5 times per second
      if (!refreshTimeout) {
        refreshTimeout = setTimeout(function() {
          refreshTimeout = null;
          if ( $scope.autoShow === true ) {
            $location.path('/email/' + newEmail.id );
          }
          $scope.$apply();
        }, 200);
      }

    });

    // Click event handlers
    $scope.markRead = function(email) {
      email.read = true;
    };

    $scope.showConfig = function(){
      $scope.configOpen = !$scope.configOpen;
    };

    $scope.toggleAutoShow = function() {
      $scope.autoShow = !$scope.autoShow;
    };

    // Initialize the view
    loadData();

    $http({method: 'GET', url: 'config'})
      .success(function(data){
        $rootScope.config = data;
        $scope.config = data;
      });

  }
]);

/**
 * Navigation Controller
 */

app.controller('NavCtrl', [
  '$scope', '$rootScope', '$location', 'Email',
  function($scope, $rootScope, $location, Email) {

    $scope.refreshList = function() {
      $rootScope.$emit('Refresh');
    };

    $scope.deleteAll = function() {

      Email.delete({ id: 'all' }, function(email) {
        $rootScope.$emit('Refresh');
        $location.path('/');
      });

    };

  }
]);
<|endoftext|>


<commit_before>'use strict';

var controllers = {};

var MainCtrl = function ($scope, socket) {
  var init = 0;
  var $container = $('#holder');
  $scope.$on('$viewContentLoaded', function() {
    $( function() {
      $container.packery();
    });
  });

    $scope.awesomeThings = [
      'HTML5 Boilerplate',
      'AngularJS',
      'Karma'
    ];
    $scope.thing = "Fuck";
    socket.on('count', function(data) {
		//$scope.socketnumber = data.hello;
  		$scope.socketnumber = data.number;
  	});
    socket.on('alert', function(data) {
      console.log(data);
    });
    socket.on('photo', function(data) {

    var items = "";
    var $items = $( items );
    $container.prepend( $items );
    //$container.packery( 'appended', img );

    //$('.holder').prepended(element);
    //$scope.socketnumber = data.hello;
    });
};

leanMeanApp.controller(controllers);<commit_msg>init56<commit_after>'use strict';

var controllers = {};

var MainCtrl = function ($scope, socket) {
  var init = 0;
  var $container = $('#holder');
  $scope.$on('$viewContentLoaded', function() {
    $( function() {
      //$container.packery();
    });
  });

    $scope.awesomeThings = [
      'HTML5 Boilerplate',
      'AngularJS',
      'Karma'
    ];
    $scope.thing = "Fuck";
    socket.on('count', function(data) {
		//$scope.socketnumber = data.hello;
  		$scope.socketnumber = data.number;
  	});
    socket.on('alert', function(data) {
      console.log(data);
    });
    socket.on('photo', function(data) {

    var items = "";
    var $items = $( items );
    $container.prepend( $items ).fadeIn('slow');
    //$container.prepend( $items ).packery( 'prepended', $items );
    });
};

leanMeanApp.controller(controllers);<|endoftext|>


<commit_before>'use strict';

angular.module('scoreWebsiteApp')
    .controller('MainCtrl', function ($rootScope) {

        // App labels
        $rootScope.messages = {
            // nav bar
            navGettingStartedTitle: 'Getting Started',
            navUseCasesTitle: 'Use Cases',
            navAboutTitle: 'About Us',
            //navContactUsTitle: 'Contact Us',
            navDocumentationTitle: 'Documentation',

            // header
            headerMainTitle: 'Process-based, lightweight, Multi-Lingual open-source orchestration engine',
            headerDescription: 'score is a generic java-based open-source orchestration engine which is process-based, ' +
                'embeddable, lightweight, scalable and multi-lingual',
            headerStartNow: 'Start Now',

            // footer
            footerPrivacy: 'Privacy Policy',
            footerTerms: 'Terms os Use',
            footerCopyrightAgent: 'Copyright Agent',
            footerLegal: 'Legal',
            footerContactUs: 'Contact Us',
            footerContribute: 'Contribute',

            // bullets
            mainBulletsProcessBasedTitle: 'Process based',
            mainBulletsMultiLingualTitle: 'Multi-lingual',
            mainBulletsLightweightTitle: 'Lightweight',
            mainBulletsProcessBasedDesc: 'The score language ("slang") is a simple and intuitive language to describe workflows in a re-usable fashion that can run using both the score library or the score command-line.',
            mainBulletsMultiLingualDesc: 'Designed to support multiple compilers that can generate low level execution instructions, score serves as an orchestration platform for potentially any process language out there.',
            mainBulletsLightweightDesc: 'Small footprint, out of the box content and an easy-to-embed approach makes score the perfect choice as the  workflow orchestration solution in your application.',
            mainBulletsReadMore: 'Read More',

            // contact us
            contactUsHeader: 'You\'d like to reach out to us? Drop us a message!',
            contactSuccess: 'Your message was sent successfully. Thanks!',
            contactFailure: 'Please fill out all the fields in the form.',
            contactSendButton: 'Send Message',
            contactPlaceholderName: 'Your Name',
            contactPlaceholderEmail: 'Your Email',
            contactPlaceholderSubject: 'Subject',
            contactPlaceholderMessage: 'Your Message',

            // about us
            aboutUsWhoWeAreText: 'The Eclipse Foundation™ project \'score\' was contributed to the open source community by the HP Software engineers to create a collaborative effort by the community ti create the best orchestration technology.',

            // use cases
            useCasesTitle: 'Use Cases',
            useCasesITTitle: 'IT Process Automation',
            useCasesCloudTitle: 'Cloud Orchestration',
            useCasesAppDeploymentTitle: 'Application Deployment',
            useCasesDevOpsTitle: 'DevOps',
            useCasesITDesc: 'Disaster Recovery',
            useCasesCloudDesc: 'OpenStack Health Check',
            useCasesAppDeploymentDesc: 'Link Docker Container',
            useCasesDevOpsDesc: 'CI \\ CD',

            // getting started
            downloadCliHeader: 'Download and use score command-line',
            downloadCliDownloadLink: 'Download and see how',
            embedScoreHeader: 'Embed score in your application',
            embedScoreLink: 'Press to see how',
            orText: 'or',
            // -- download and install sli
            detailedDownloadCliHeader: 'Download score command-line',
            detailedDownloadCliText: 'Download and Unzip score command-line',
            detailedDownloadLatest: 'Download latest version',
            detailedDownloadOldVersions: 'Download old versions',
            detailedSlangCliHeader: 'Use slang',
            detailedSlangCliText: 'Write a flow with slang',
            detailedUseCliHeader: 'Start score command-line',
            detailedUseCliText: 'Open your console and execute score cli',
            detailedTriggerFlowHeader: 'Trigger flow',
            detailedTriggerFlowText: 'Trigger your slang written flow from score command-line',
            detailedCliHeader: 'console',
            detailedCliPrefix: '$',
            detailedCliClear: 'Clear',
            detailedCliOpenScore: 'java -jar score-cli.jar^1000\nHi I\'m score!!\n>',
            detailedCliTriggerFlow: 'score trigger\n^1200the weather in San Fransisco is: Hot\n$',
            // -- embed score
            detailedEmbedPomHeader: 'Score dependencies',
            detailedEmbedPomText: 'Add score dependencies to your pom.xml',
            detailedEmbedSpringHeader: 'Spring configuration',
            detailedEmbedSpringText: 'Add some score configuration to your Spring application context xml',
            detailedEmbedScoreApiHeader: 'Use score API',
            detailedEmbedScoreApiText: 'Call score APIs from your Java application (Trigger example)',
            detailedEmbedScoreApiMore: 'Press here for more score APIs',
            detailedEmbedScoreCompileHeader: 'Compile',
            detailedEmbedScoreCompileText: 'Compile your application and create an executable jar using maven',
            detailedEmbedCompileCli: 'mvn clean install^1000\n[INFO] Scanning for projects...\n ......\n[INFO] BUILD SUCCESS\n$',
            detailedEmbedScoreRunHeader: 'Run',
            detailedEmbedScoreRunText: 'Run your application from command line',
            detailedEmbedRunCli: 'cd /dev/score-app/target\n$ java -jar sample-app.jar\n^1000Checking flow status...^1200\nFinished^1000\nthe weather in San Fransisco is: Hot\n$'
        };

        $rootScope.sections = [
            { id: 'gettingStarted', title: $rootScope.messages.navGettingStartedTitle  },
            { id: 'useCases', title: $rootScope.messages.navUseCasesTitle },
            { id: 'about', title: $rootScope.messages.navAboutTitle },
            { id: 'documentation', title: $rootScope.messages.navDocumentationTitle  }
//            { id: 'contactUs', title: $rootScope.messages.navContactUsTitle  }
        ];

        $rootScope.year = new Date().getFullYear();
    });<commit_msg>Fixed typo<commit_after>'use strict';

angular.module('scoreWebsiteApp')
    .controller('MainCtrl', function ($rootScope) {

        // App labels
        $rootScope.messages = {
            // nav bar
            navGettingStartedTitle: 'Getting Started',
            navUseCasesTitle: 'Use Cases',
            navAboutTitle: 'About Us',
            //navContactUsTitle: 'Contact Us',
            navDocumentationTitle: 'Documentation',

            // header
            headerMainTitle: 'Process-based, lightweight, Multi-Lingual open-source orchestration engine',
            headerDescription: 'score is a generic java-based open-source orchestration engine which is process-based, ' +
                'embeddable, lightweight, scalable and multi-lingual',
            headerStartNow: 'Start Now',

            // footer
            footerPrivacy: 'Privacy Policy',
            footerTerms: 'Terms os Use',
            footerCopyrightAgent: 'Copyright Agent',
            footerLegal: 'Legal',
            footerContactUs: 'Contact Us',
            footerContribute: 'Contribute',

            // bullets
            mainBulletsProcessBasedTitle: 'Process based',
            mainBulletsMultiLingualTitle: 'Multi-lingual',
            mainBulletsLightweightTitle: 'Lightweight',
            mainBulletsProcessBasedDesc: 'The score language ("slang") is a simple and intuitive language to describe workflows in a re-usable fashion that can run using both the score library or the score command-line.',
            mainBulletsMultiLingualDesc: 'Designed to support multiple compilers that can generate low level execution instructions, score serves as an orchestration platform for potentially any process language out there.',
            mainBulletsLightweightDesc: 'Small footprint, out of the box content and an easy-to-embed approach makes score the perfect choice as the  workflow orchestration solution in your application.',
            mainBulletsReadMore: 'Read More',

            // contact us
            contactUsHeader: 'You\'d like to reach out to us? Drop us a message!',
            contactSuccess: 'Your message was sent successfully. Thanks!',
            contactFailure: 'Please fill out all the fields in the form.',
            contactSendButton: 'Send Message',
            contactPlaceholderName: 'Your Name',
            contactPlaceholderEmail: 'Your Email',
            contactPlaceholderSubject: 'Subject',
            contactPlaceholderMessage: 'Your Message',

            // about us
            aboutUsWhoWeAreText: 'The Eclipse Foundation™ project \'score\' was contributed to the open source community by the HP Software engineers to create a collaborative effort by the community it create the best orchestration technology.',

            // use cases
            useCasesTitle: 'Use Cases',
            useCasesITTitle: 'IT Process Automation',
            useCasesCloudTitle: 'Cloud Orchestration',
            useCasesAppDeploymentTitle: 'Application Deployment',
            useCasesDevOpsTitle: 'DevOps',
            useCasesITDesc: 'Disaster Recovery',
            useCasesCloudDesc: 'OpenStack Health Check',
            useCasesAppDeploymentDesc: 'Link Docker Container',
            useCasesDevOpsDesc: 'CI \\ CD',

            // getting started
            downloadCliHeader: 'Download and use score command-line',
            downloadCliDownloadLink: 'Download and see how',
            embedScoreHeader: 'Embed score in your application',
            embedScoreLink: 'Press to see how',
            orText: 'or',
            // -- download and install sli
            detailedDownloadCliHeader: 'Download score command-line',
            detailedDownloadCliText: 'Download and Unzip score command-line',
            detailedDownloadLatest: 'Download latest version',
            detailedDownloadOldVersions: 'Download old versions',
            detailedSlangCliHeader: 'Use slang',
            detailedSlangCliText: 'Write a flow with slang',
            detailedUseCliHeader: 'Start score command-line',
            detailedUseCliText: 'Open your console and execute score cli',
            detailedTriggerFlowHeader: 'Trigger flow',
            detailedTriggerFlowText: 'Trigger your slang written flow from score command-line',
            detailedCliHeader: 'console',
            detailedCliPrefix: '$',
            detailedCliClear: 'Clear',
            detailedCliOpenScore: 'java -jar score-cli.jar^1000\nHi I\'m score!!\n>',
            detailedCliTriggerFlow: 'score trigger\n^1200the weather in San Fransisco is: Hot\n$',
            // -- embed score
            detailedEmbedPomHeader: 'Score dependencies',
            detailedEmbedPomText: 'Add score dependencies to your pom.xml',
            detailedEmbedSpringHeader: 'Spring configuration',
            detailedEmbedSpringText: 'Add some score configuration to your Spring application context xml',
            detailedEmbedScoreApiHeader: 'Use score API',
            detailedEmbedScoreApiText: 'Call score APIs from your Java application (Trigger example)',
            detailedEmbedScoreApiMore: 'Press here for more score APIs',
            detailedEmbedScoreCompileHeader: 'Compile',
            detailedEmbedScoreCompileText: 'Compile your application and create an executable jar using maven',
            detailedEmbedCompileCli: 'mvn clean install^1000\n[INFO] Scanning for projects...\n ......\n[INFO] BUILD SUCCESS\n$',
            detailedEmbedScoreRunHeader: 'Run',
            detailedEmbedScoreRunText: 'Run your application from command line',
            detailedEmbedRunCli: 'cd /dev/score-app/target\n$ java -jar sample-app.jar\n^1000Checking flow status...^1200\nFinished^1000\nthe weather in San Fransisco is: Hot\n$'
        };

        $rootScope.sections = [
            { id: 'gettingStarted', title: $rootScope.messages.navGettingStartedTitle  },
            { id: 'useCases', title: $rootScope.messages.navUseCasesTitle },
            { id: 'about', title: $rootScope.messages.navAboutTitle },
            { id: 'documentation', title: $rootScope.messages.navDocumentationTitle  }
//            { id: 'contactUs', title: $rootScope.messages.navContactUsTitle  }
        ];

        $rootScope.year = new Date().getFullYear();
    });
<|endoftext|>