<commit_before>import React, { Component } from 'react'
import { Slider, Modal } from 'react-native'
import {
  Container, Content, Body, View,
  Card, CardItem,
  Form,
  Item, InputGroup, Input, Label, Text,
  Picker, Button, Icon, CheckBox,
  Spinner
} from 'native-base'
import { Grid, Col, Row } from 'react-native-easy-grid'

const ROLE_FETCHER = 'Fetcher'
const fakeFetcher =   { userID: 2, userAlias: 'Epan',  role: ROLE_FETCHER,   objective: 'Pencil' }

export default class TaskForm extends Component {
  static navigationOptions = {
    header: {
      title: 'New Task',
    }
  }
  state = {
    requestModalVisible: false,
    bidStatus: 'PENDING',
    cost: 0,
    tip: 0,
    preferFemale: false
  }

  submitRequest = () => {
    this.props.navigation.navigate('ChatRoom', { receiver: fakeFetcher })
  }

  render = () => (
    <Content>
      <Modal
        animationType="fade"
        transparent={true}
        visible={this.state.requestModalVisible}
      >
        <Container style={{ backgroundColor: 'rgba(52, 52, 52, 0.4)', paddingHorizontal: 50, paddingVertical: 200 }}>
          <Card>
            <CardItem>
              <View style={{flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>{
                this.state.bidStatus === 'PENDING' ?
                  <View style={{ justifyContent: 'center', alignItems: 'center', marginVertical: 70, marginHorizontal: 30 }}>
                    <Text>Waiting for Fetcher response</Text>
                    <Spinner />
                  </View> :
                  <View style={{ justifyContent: 'center', alignItems: 'center', marginVertical: 70, marginHorizontal: 30 }}>
                    <View><Text>Task {this.state.bidStatus} !</Text></View>
                    <Button primary block onPress={() => {
                      this.setState({
                        requestModalVisible: false
                      })
                      this.props.navigation.navigate('ChatRoom', { receiver: fakeFetcher })
                      }}>
                      <Icon name="arrow-forward" />
                    </Button>
                  </View>
              }</View>
            </CardItem>
          </Card>
        </Container>
      </Modal>
        <Card>
          <CardItem>

            <View style={{ alignSelf: 'stretch' }}>
              <Item stackedLabel>
                I need:<Input />
              </Item>
              <Item stackedLabel>
                From:<Input />
              </Item>
              <View style={{ flexDirection: 'row', flex: 1 }}>
                <Item stackedLabel style={{ width: 200 }}>
                  Within:<Input keyboardType="numeric" />
                </Item>
                <View style={{ justifyContent: 'center', alignItems: 'center' }}>
                <Picker
                  iosHeader="Select one"
                  mode="dropdown"
                  selectedValue="key0"
                  onValueChange={() => {}}
                  style={{width: 100}}
                  mode="dropdown"
                >
                  <Picker.Item label="Hour" value="key0" />
                  <Picker.Item label="Day" value="key1" />
                </Picker>
                </View>
              </View>
              <View style={{ marginVertical: 10 }}>
                Cost:
                <Input keyboardType="numeric" defaultValue={this.state.cost} onChange={({nativeEvent}) => this.setState({ cost: nativeEvent.text })} />
              </View>
              <View style={{ marginVertical: 10 }}>
                Tip: {this.state.tip}
                <Input keyboardType="numeric" defaultValue={this.state.tip} onChange={({nativeEvent}) => this.setState({ tip: nativeEvent.text })} />
              </View>
              <View style={{ marginVertical: 10 }}>
                 {this.state.tip}
                <CheckBox checked={this.state.preferFemale} onPress={() => this.setState({ preferFemale: !this.state.preferFemale })} />
              </View>
              <Item stackedLabel>
                Additional information
                <Input />
              </Item>
              <Button primary block style={{ marginTop: 30 }} onPress={() => this.submitRequest()}>
                <Text>Request!</Text>
              </Button>
            </View>

          </CardItem>
        </Card>
      </Content>
  )
}
<commit_msg>adjust task form<commit_after>import React, { Component } from 'react'
import { Slider, Modal, TouchableOpacity } from 'react-native'
import {
  Container, Content, Body, View,
  Card, CardItem,
  Form,
  Item, InputGroup, Input, Label, Text, ListItem,
  Picker, Button, Icon, CheckBox,
  Spinner
} from 'native-base'
import { Grid, Col, Row } from 'react-native-easy-grid'

const ROLE_FETCHER = 'Fetcher'
const fakeFetcher =   { userID: 2, userAlias: 'Epan',  role: ROLE_FETCHER,   objective: 'Pencil' }

export default class TaskForm extends Component {
  static navigationOptions = {
    header: {
      title: 'New Task',
    }
  }
  state = {
    requestModalVisible: false,
    bidStatus: 'PENDING',
    cost: 0,
    tip: 0,
    preferFemale: false
  }

  submitRequest = () => {
    this.props.navigation.navigate('ChatRoom', { receiver: fakeFetcher })
  }

  render = () => (
    <Content>
      <Modal
        animationType="fade"
        transparent={true}
        visible={this.state.requestModalVisible}
      >
        <Container style={{ backgroundColor: 'rgba(52, 52, 52, 0.4)', paddingHorizontal: 50, paddingVertical: 200 }}>
          <Card>
            <CardItem>
              <View style={{flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>{
                this.state.bidStatus === 'PENDING' ?
                  <View style={{ justifyContent: 'center', alignItems: 'center', marginVertical: 70, marginHorizontal: 30 }}>
                    <Text>Waiting for Fetcher response</Text>
                    <Spinner />
                  </View> :
                  <View style={{ justifyContent: 'center', alignItems: 'center', marginVertical: 70, marginHorizontal: 30 }}>
                    <View><Text>Task {this.state.bidStatus} !</Text></View>
                    <Button primary block onPress={() => {
                      this.setState({
                        requestModalVisible: false
                      })
                      this.props.navigation.navigate('ChatRoom', { receiver: fakeFetcher })
                      }}>
                      <Icon name="arrow-forward" />
                    </Button>
                  </View>
              }</View>
            </CardItem>
          </Card>
        </Container>
      </Modal>
        <Card>
          <CardItem>

            <View style={{ alignSelf: 'stretch' }}>
              <Item style={{ marginVertical: 10 }}>
                I need:<Input />
              </Item>
              <Item style={{ marginVertical: 10 }}>
                From:<Input />
              </Item>
              <View style={{ flexDirection: 'row', flex: 1, marginVertical: 10 }}>
                <Item style={{ width: 200 }}>
                  Within:<Input keyboardType="numeric" />
                </Item>
                <View style={{ justifyContent: 'center', alignItems: 'center' }}>
                <Picker
                  iosHeader="Select one"
                  mode="dropdown"
                  selectedValue="key0"
                  onValueChange={() => {}}
                  style={{width: 100}}
                  mode="dropdown"
                >
                  <Picker.Item label="Hour" value="key0" />
                  <Picker.Item label="Day" value="key1" />
                </Picker>
                </View>
              </View>
              <Item style={{ marginVertical: 10 }}>
                Cost: $<Input keyboardType="numeric" defaultValue={this.state.cost} onChange={({nativeEvent}) => this.setState({ cost: nativeEvent.text })} />
              </Item>
              <Item style={{ marginVertical: 10 }}>
                Tip: $<Input keyboardType="numeric" defaultValue={this.state.tip} onChange={({nativeEvent}) => this.setState({ tip: nativeEvent.text })} />
              </Item>
              <Item stackedLabel style={{ marginVertical: 10 }}>
                Additional information
                <Input />
              </Item>
              <TouchableOpacity activeOpacity={70} onPress={() => this.setState({ preferFemale: !this.state.preferFemale })}>
              <View style={{ flex: 1, flexDirection: 'row', height: 50, alignItems: 'center' }}>
                <View style={{ height: 20, width: 40 }}><CheckBox checked={this.state.preferFemale} /></View>
                <View><Text>I would prefer a female fetcher</Text></View>
              </View>
              </TouchableOpacity>
              <Button primary block onPress={() => this.submitRequest()}>
                <Text>Request!</Text>
              </Button>
            </View>

          </CardItem>
        </Card>
      </Content>
  )
}
<|endoftext|>


<commit_before>/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
 * text of the license. */
// @require: OpenLayers/Tile.js
/**
* @class
*/
OpenLayers.Tile.WFS = Class.create();
OpenLayers.Tile.WFS.prototype =
  Object.extend( new OpenLayers.Tile(), {

    /** @type Array(OpenLayers.Feature)*/
    features: null,

    /**
    * @constructor
    *
    * @param {OpenLayers.Layer} layer
    * @param {OpenLayers.Pixel} position
    * @param {OpenLayers.Bounds} bounds
    * @param {Array} urls
    * @param {OpenLayers.Size} size
    */
    initialize: function(layer, position, bounds, urls, size) {
        var newArguments = arguments;
        if (arguments.length > 0) {
            newArguments = [layer, position, bounds, null, size];
        }
        OpenLayers.Tile.prototype.initialize.apply(this, newArguments);

        this.urls = urls;
        this.features = new Array();
    },

    /**
     *
     */
    destroy: function() {
        for(var i=0; i < this.features.length; i++) {
            this.features[i].destroy();
        }
        OpenLayers.Tile.prototype.destroy.apply(this, arguments);
    },

    /**
    */
    draw:function() {
        this.loadFeaturesForRegion(this.requestSuccess);
    },

    /** get the full request string from the ds and the tile params
    *     and call the AJAX loadURL().
    *
    *     input are function pointers for what to do on success and failure.
    *
    * @param {function} success
    * @param {function} failure
    */
    loadFeaturesForRegion:function(success, failure) {

        if (!this.loaded) {

            if (this.urls != null) {

                // TODO: Hmmm, this stops multiple loads of the data when a
                //       result isn't immediately retrieved, but it's hacky.
                //       Do it better.
                this.loaded = true;

                for(var i=0; i < this.urls.length; i++) {
                    OpenLayers.loadURL(this.urls[i], null, this,
                                        success, failure);
                }
            }
        }
    },

    /** Return from AJAX request
    *
    * @param {} request
    */
    requestSuccess:function(request) {
        var doc = request.responseXML;

        if (!doc || request.fileType!="XML") {
            doc = OpenLayers.parseXMLString(request.responseText);
        }

        var resultFeatures = doc.getElementsByTagName("featureMember");

    },

    /**
     * @param {Object} results
     */
    addResults: function(results) {

        //clear old featureList
        this.features = new Array();

        for (var i=0; i < results.length; i++) {

            var feature = new this.layer.featureClass(this.layer,
                                                      results[i]);
            this.features.append(feature);
        }

    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Tile.WFS"
  }
);

<commit_msg>now with multiple wfs servers, we do NOT want to clear this list. argh.<commit_after>/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
 * text of the license. */
// @require: OpenLayers/Tile.js
/**
* @class
*/
OpenLayers.Tile.WFS = Class.create();
OpenLayers.Tile.WFS.prototype =
  Object.extend( new OpenLayers.Tile(), {

    /** @type Array(OpenLayers.Feature)*/
    features: null,

    /**
    * @constructor
    *
    * @param {OpenLayers.Layer} layer
    * @param {OpenLayers.Pixel} position
    * @param {OpenLayers.Bounds} bounds
    * @param {Array} urls
    * @param {OpenLayers.Size} size
    */
    initialize: function(layer, position, bounds, urls, size) {
        var newArguments = arguments;
        if (arguments.length > 0) {
            newArguments = [layer, position, bounds, null, size];
        }
        OpenLayers.Tile.prototype.initialize.apply(this, newArguments);

        this.urls = urls;
        this.features = new Array();
    },

    /**
     *
     */
    destroy: function() {
        for(var i=0; i < this.features.length; i++) {
            this.features[i].destroy();
        }
        OpenLayers.Tile.prototype.destroy.apply(this, arguments);
    },

    /**
    */
    draw:function() {
        this.loadFeaturesForRegion(this.requestSuccess);
    },

    /** get the full request string from the ds and the tile params
    *     and call the AJAX loadURL().
    *
    *     input are function pointers for what to do on success and failure.
    *
    * @param {function} success
    * @param {function} failure
    */
    loadFeaturesForRegion:function(success, failure) {

        if (!this.loaded) {

            if (this.urls != null) {

                // TODO: Hmmm, this stops multiple loads of the data when a
                //       result isn't immediately retrieved, but it's hacky.
                //       Do it better.
                this.loaded = true;

                for(var i=0; i < this.urls.length; i++) {
                    OpenLayers.loadURL(this.urls[i], null, this,
                                        success, failure);
                }
            }
        }
    },

    /** Return from AJAX request
    *
    * @param {} request
    */
    requestSuccess:function(request) {
        var doc = request.responseXML;

        if (!doc || request.fileType!="XML") {
            doc = OpenLayers.parseXMLString(request.responseText);
        }

        var resultFeatures = doc.getElementsByTagName("featureMember");

    },

    /**
     * @param {Object} results
     */
    addResults: function(results) {

        for (var i=0; i < results.length; i++) {

            var feature = new this.layer.featureClass(this.layer,
                                                      results[i]);
            this.features.append(feature);
        }

    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Tile.WFS"
  }
);

<|endoftext|>


<commit_before>
load('sugar.js');

load('locales/ca.js');
load('locales/da.js');
load('locales/de.js');
load('locales/es.js');
load('locales/fi.js');
load('locales/fr.js');
load('locales/it.js');
load('locales/ja.js');
load('locales/ko.js');
load('locales/nl.js');
load('locales/pl.js');
load('locales/pt.js');
load('locales/ru.js');
load('locales/sv.js');
load('locales/zh-CN.js');
load('locales/zh-TW.js');

load('test/suite/suite.js');
load('test/suite/log.js');
load('test/suite/helpers/core.js');
load('test/suite/helpers/common.js');
load('test/suite/helpers/array.js');
load('test/suite/helpers/date.js');
load('test/suite/helpers/object.js');

/*
 * 1.7 KNOWN ISSUES:
 *
 * Object(str) produces type "object" but has no defined keys. This breaks a
 * number of tests including Object.isEmpty, Object.size, etc for strings.
 *
 * Additionally Rhino appears to allow overwriting non-writable attributes, so
 * tests that assert on those errors will fail.
 *
 * The function module cannot be used at all as it doesn't have a setTimeout
 * method. A workaround for this can be found here:
 * http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
 *
 * However the test suite still cannot be loaded as Rhino shadows the "global"
 * object which causes sinon to break.
 *
 */

load('test/tests/core.js');
load('test/tests/array.js');
load('test/tests/date.js');
load('test/tests/equals.js');
// load('test/tests/function.js');
load('test/tests/number.js');
load('test/tests/object.js');
load('test/tests/regexp.js');
load('test/tests/string.js');
load('test/tests/enumerable.js');

load('test/tests/range/date.js');
load('test/tests/range/number.js');
load('test/tests/range/string.js');

load('test/tests/locales/ca.js');
load('test/tests/locales/da.js');
load('test/tests/locales/de.js');
load('test/tests/locales/es.js');
load('test/tests/locales/fi.js');
load('test/tests/locales/fr.js');
load('test/tests/locales/it.js');
load('test/tests/locales/ja.js');
load('test/tests/locales/ko.js');
load('test/tests/locales/nl.js');
load('test/tests/locales/pl.js');
load('test/tests/locales/pt.js');
load('test/tests/locales/ru.js');
load('test/tests/locales/sv.js');
load('test/tests/locales/zh-CN.js');
load('test/tests/locales/zh-TW.js');

runTests(logResults, false, 'rhino');
<commit_msg>small rhino test fix<commit_after>
load('sugar.js');

load('locales/ca.js');
load('locales/da.js');
load('locales/de.js');
load('locales/es.js');
load('locales/fi.js');
load('locales/fr.js');
load('locales/it.js');
load('locales/ja.js');
load('locales/ko.js');
load('locales/nl.js');
load('locales/pl.js');
load('locales/pt.js');
load('locales/ru.js');
load('locales/sv.js');
load('locales/zh-CN.js');
load('locales/zh-TW.js');

load('test/suite/suite.js');
load('test/suite/log.js');
load('test/suite/helpers/core.js');
load('test/suite/helpers/common.js');
load('test/suite/helpers/array.js');
load('test/suite/helpers/date.js');
load('test/suite/helpers/object.js');

/*
 * 1.7 KNOWN ISSUES:
 *
 * Object(str) produces type "object" but has no defined keys. This breaks a
 * number of tests including Object.isEmpty, Object.size, etc for strings.
 *
 * Additionally Rhino appears to allow overwriting non-writable attributes, so
 * tests that assert on those errors will fail.
 *
 * The function module cannot be used at all as it doesn't have a setTimeout
 * method. A workaround for this can be found here:
 * http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
 *
 * However the test suite still cannot be loaded as Rhino shadows the "global"
 * object which causes sinon to break.
 *
 */

load('test/tests/core.js');
load('test/tests/array.js');
load('test/tests/date.js');
load('test/tests/equals.js');
// load('test/tests/function.js');
load('test/tests/number.js');
load('test/tests/object.js');
load('test/tests/regexp.js');
load('test/tests/string.js');
load('test/tests/enumerable.js');

load('test/tests/range/date.js');
load('test/tests/range/number.js');
load('test/tests/range/string.js');

load('test/tests/locales/ca.js');
load('test/tests/locales/da.js');
load('test/tests/locales/de.js');
load('test/tests/locales/es.js');
load('test/tests/locales/fi.js');
load('test/tests/locales/fr.js');
load('test/tests/locales/it.js');
load('test/tests/locales/ja.js');
load('test/tests/locales/ko.js');
load('test/tests/locales/nl.js');
load('test/tests/locales/pl.js');
load('test/tests/locales/pt.js');
load('test/tests/locales/ru.js');
load('test/tests/locales/sv.js');
load('test/tests/locales/zh-CN.js');
load('test/tests/locales/zh-TW.js');

runTests(logResults, 'default', 'rhino');
<|endoftext|>


<commit_before>$(document).ready(function () {
	$('#button-reveal').bind('click', function () {
		$('#clock-modal').foundation('reveal', 'open');
	});

	// Do a little background reset when the modal opening starts to avoid
	// flicker.
	$(document).on('open', '[data-reveal]', function () {
		var timerBox = $('#clock-modal');

		SetDisplayText('Ready');

		timerBox.css('background-image', '');
		timerBox.css('background-color', '#FFFFFF');
	});

	// Hack modal box and time display fill the screen and be centered.
	$(document).on('opened', '[data-reveal]', function () {
		ToggleButton('resume', false);
		ToggleButton('pause', false);
		ToggleButton('reset', true);
		ToggleButton('start', true);

		ResetTimer();
	});

	$('#clock-modal').bind('reveal:closed', function () {
		window.clearTimeout(timerId);
	});

	$('#button-start').bind('click', function () {
		StartTimer();
	});

	$('#button-pause').bind('click', function () {
		PauseTimer();
	});

	$('#button-resume').bind('click', function () {
		ResumeTimer();
	});

	$('#button-reset').bind('click', function () {
		ResetTimer();
	});

	// Wire up Trello functionality
	var onAuthorize = function () {
		updateLoggedIn();
		$("#output").empty();

		Trello.members.get("me", function (member) {
			$("#fullName").text(member.fullName);

			var $cards = $("<div>")
				 .text("Loading Cards...")
				 .appendTo("#output");

			// Output a list of all of the cards that the member
			// is assigned to
			Trello.get("members/me/cards", function (cards) {
				$cards.empty();
				$("<div>").text("Click a card to add a sticker to it").appendTo($cards);

				$.each(cards, function (ix, card) {
					$("<a>")
						.addClass("card")
						.text(card.name)
						.appendTo($cards)
						.click(function ()
						{
							// Offset stickers by 20 pixels to properly see amount.
							var stickerCount = 0;
							Trello.get("cards/" + card.id + "/stickers", function(stickers) {
								stickerCount = stickers.length;
								alert(stickers.length);
							});

							var stickerOffSet = 20 * stickerCount;
							Trello.post("cards/" + card.id + "/stickers", { image: "clock", top: 0, left: stickerOffSet, zIndex: 1 });
						});
				});
			});
		});
	};

	var updateLoggedIn = function () {
		var isLoggedIn = Trello.authorized();
		$("#loggedout").toggle(!isLoggedIn);
		$("#loggedin").toggle(isLoggedIn);
	};

	var logout = function () {
		Trello.deauthorize();
		updateLoggedIn();
	};

	Trello.authorize({
		interactive: false,
		success: onAuthorize
	});

	$("#connectLink")
	.click(function () {
		Trello.authorize({
			type: "popup",
			name: "Trellodoro",
			success: onAuthorize,
			scope: { write: true, read: true }
		});
	});

	$("#disconnect").click(logout);
});<commit_msg>Alert update<commit_after>$(document).ready(function () {
	$('#button-reveal').bind('click', function () {
		$('#clock-modal').foundation('reveal', 'open');
	});

	// Do a little background reset when the modal opening starts to avoid
	// flicker.
	$(document).on('open', '[data-reveal]', function () {
		var timerBox = $('#clock-modal');

		SetDisplayText('Ready');

		timerBox.css('background-image', '');
		timerBox.css('background-color', '#FFFFFF');
	});

	// Hack modal box and time display fill the screen and be centered.
	$(document).on('opened', '[data-reveal]', function () {
		ToggleButton('resume', false);
		ToggleButton('pause', false);
		ToggleButton('reset', true);
		ToggleButton('start', true);

		ResetTimer();
	});

	$('#clock-modal').bind('reveal:closed', function () {
		window.clearTimeout(timerId);
	});

	$('#button-start').bind('click', function () {
		StartTimer();
	});

	$('#button-pause').bind('click', function () {
		PauseTimer();
	});

	$('#button-resume').bind('click', function () {
		ResumeTimer();
	});

	$('#button-reset').bind('click', function () {
		ResetTimer();
	});

	// Wire up Trello functionality
	var onAuthorize = function () {
		updateLoggedIn();
		$("#output").empty();

		Trello.members.get("me", function (member) {
			$("#fullName").text(member.fullName);

			var $cards = $("<div>")
				 .text("Loading Cards...")
				 .appendTo("#output");

			// Output a list of all of the cards that the member
			// is assigned to
			Trello.get("members/me/cards", function (cards) {
				$cards.empty();
				$("<div>").text("Click a card to add a sticker to it").appendTo($cards);

				$.each(cards, function (ix, card) {
					$("<a>")
						.addClass("card")
						.text(card.name)
						.appendTo($cards)
						.click(function ()
						{
							// Offset stickers by 20 pixels to properly see amount.
							var stickerCount = 0;
							Trello.get("cards/" + card.id + "/stickers", function(stickers) {
								stickerCount = stickers.length;
								alert("Length: " + stickers.length);
							});

							alert("Count: " + stickerCount);
							var stickerOffSet = 20 * stickerCount;
							Trello.post("cards/" + card.id + "/stickers", { image: "clock", top: 0, left: stickerOffSet, zIndex: 1 });
						});
				});
			});
		});
	};

	var updateLoggedIn = function () {
		var isLoggedIn = Trello.authorized();
		$("#loggedout").toggle(!isLoggedIn);
		$("#loggedin").toggle(isLoggedIn);
	};

	var logout = function () {
		Trello.deauthorize();
		updateLoggedIn();
	};

	Trello.authorize({
		interactive: false,
		success: onAuthorize
	});

	$("#connectLink")
	.click(function () {
		Trello.authorize({
			type: "popup",
			name: "Trellodoro",
			success: onAuthorize,
			scope: { write: true, read: true }
		});
	});

	$("#disconnect").click(logout);
});<|endoftext|>


<commit_before>'use strict';

// article api

var
    _ = require('lodash'),
    api = require('../api'),
    db = require('../db'),
    cache = require('../cache'),
    images = require('./_images'),
    helper = require('../helper'),
    constants = require('../constants'),
    search = require('../search/search'),
    json_schema = require('../json_schema');

var
    settingApi = require('./settingApi'),
    categoryApi = require('./categoryApi'),
    attachmentApi = require('./attachmentApi');

var
    User = db.user,
    Article = db.article,
    Category = db.category,
    Text = db.text,
    warp = db.warp,
    next_id = db.next_id;

function indexArticle(r) {
    process.nextTick(function () {
        search.engine.index({
            type: 'article',
            id: r.id,
            tags: r.tags,
            name: r.name,
            description: r.description,
            content: helper.html2text(helper.md2html(r.content)),
            created_at: r.publish_at,
            updated_at: r.updated_at,
            url: '/article/' + r.id,
            upvotes: 0
        });
    });
}

function unindexArticle(r) {
    process.nextTick(function () {
        search.engine.unindex({
            id: r.id
        });
    });
}

function* $getRecentArticles(max) {
    var now = Date.now();
    return yield Article.$findAll({
        where: 'publish_at<?',
        order: 'publish_at desc',
        params: [now],
        offset: 0,
        limit: max
    });
}

function* $getAllArticles(page) {
    page.total = yield Article.$findNumber('count(id)');
    if (page.isEmpty) {
        return [];
    }
    return yield Article.$findAll({
        offset: page.offset,
        limit: page.limit,
        order: 'publish_at desc'
    });
}

function* $getArticles(page) {
    var now = Date.now();
    page.total = yield Article.$findNumber({
        select: 'count(id)',
        where: 'publish_at<?',
        params: [now]
    });
    if (page.isEmpty) {
        return [];
    }
    return yield Article.$findAll({
        offset: page.offset,
        limit: page.limit,
        order: 'publish_at desc'
    });
}

function* $getArticlesByCategory(categoryId, page) {
    var now = Date.now();
    page.total = yield Article.$findNumber({
        select: 'count(id)',
        where: 'publish_at<? and category_id=?',
        params: [now, categoryId]
    });
    if (page.isEmpty) {
        return [];
    }
    return yield Article.$findAll({
        order: 'publish_at desc',
        where: 'publish_at<? and category_id=?',
        params: [now, categoryId],
        offset: page.offset,
        limit: page.limit
    });
}

function* $getArticle(id, includeContent) {
    var
        text,
        article = yield Article.$find(id);
    if (article === null) {
        throw api.notFound('Article');
    }
    if (includeContent) {
        text = yield Text.$find(article.content_id);
        if (text === null) {
            throw api.notFound('Text');
        }
        article.content = text.value;
    }
    return article;
}

function toRssDate(dt) {
    return new Date(dt).toGMTString();
}

function* $getFeed(domain) {
    var
        i, text, article, url,
        articles = yield $getRecentArticles(20),
        last_publish_at = articles.length === 0 ? 0 : articles[0].publish_at,
        website = yield $settingApi.$getSettingsByDefaults('website', settingApi.defaultSettings.website),
        rss = [],
        rss_footer = '</channel></rss>';
    rss.push('<?xml version="1.0"?>\n');
    rss.push('<rss version="2.0"><channel><title><![CDATA[');
    rss.push(website.name);
    rss.push(']]></title><link>http://');
    rss.push(domain);
    rss.push('/</link><description><![CDATA[');
    rss.push(website.description);
    rss.push(']]></description><lastBuildDate>');
    rss.push(toRssDate(last_publish_at));
    rss.push('</lastBuildDate><generator>iTranswarp.js</generator><ttl>3600</ttl>');

    if (articles.length === 0) {
        rss.push(rss_footer);
    }
    else {
        for (i=0; i<articles.length; i++) {
            article = articles[i];
            text = yield Text.$find(article.content_id);
            url = 'http://' + domain + '/article/' + article.id;
            rss.push('<item><title><![CDATA[');
            rss.push(article.name);
            rss.push(']]></title><link>');
            rss.push(url);
            rss.push('</link><guid>');
            rss.push(url);
            rss.push('</guid><author><![CDATA[');
            rss.push(article.user_name);
            rss.push(']]></author><pubDate>');
            rss.push(toRssDate(article.publish_at));
            rss.push('</pubDate><description><![CDATA[');
            rss.push(helper.md2html(text.value, true));
            rss.push(']]></description></item>');
        }
        rss.push(rss_footer);
    }
    return rss.join('');
}

var RE_TIMESTAMP = /^\-?[0-9]{1,13}$/;

module.exports = {

    $getRecentArticles: $getRecentArticles,

    $getArticlesByCategory: $getArticlesByCategory,

    $getAllArticles: $getAllArticles,

    $getArticles: $getArticles,

    $getArticle: $getArticle,

    'GET /feed': function* () {
        var
            rss,
            gf = function* () {
                return yield $getFeed(this.request.host);
            };
        rss = yield cache.$get('cached_rss', gf);
        this.set('Cache-Control', 'max-age: 3600');
        this.type = 'application/rss+xml';
        this.body = rss;
    },

    'GET /api/articles/:id': function* (id) {
        /**
         * Get article.
         *
         * @name Get Article
         * @param {string} id: Id of the article.
         * @param {string} [format]: Return html if format is 'html', default to '' (raw).
         * @return {object} Article object.
         * @error {resource:notfound} Article was not found by id.
         */
        var article = yield $getArticle(id, true);
        if (article.publish_at > Date.now() && (this.request.user===null || this.request.user.role > constants.role.CONTRIBUTOR)) {
            throw api.notFound('Article');
        }
        if (this.request.query.format === 'html') {
            article.content = helper.md2html(article.content, true);
        }
        this.body = article;
    },

    'GET /api/articles': function* () {
        /**
         * Get articles by page.
         *
         * @name Get Articles
         * @param {number} [page=1]: The page number, starts from 1.
         * @return {object} Article objects and page information.
         */
        helper.checkPermission(this.request, constants.role.CONTRIBUTOR);
        var
            page = helper.getPage(this.request),
            articles = yield $getAllArticles(page);
        this.body = {
            page: page,
            articles: articles
        };
    },

    'POST /api/articles': function* () {
        /**
         * Create a new article.
         *
         * @name Create Article
         * @param {string} category_id: Id of the category that article belongs to.
         * @param {string} name: Name of the article.
         * @param {string} description: Description of the article.
         * @param {string} content: Content of the article.
         * @param {string} [tags]: Tags of the article, seperated by ','.
         * @param {string} [publish_at]: Publish time of the article with format 'yyyy-MM-dd HH:mm:ss', default to current time.
         * @param {image} [image]: Base64 encoded image to upload as cover image.
         * @return {object} The created article object.
         * @error {parameter:invalid} If some parameter is invalid.
         * @error {permission:denied} If current user has no permission.
         */
        helper.checkPermission(this.request, constants.role.EDITOR);
        var
            text,
            article,
            attachment,
            article_id,
            content_id,
            data = this.request.body;
        json_schema.validate('createArticle', data);
        // check category id:
        yield categoryApi.$getCategory(data.category_id);

        attachment = yield attachmentApi.$createAttachment(
            this.request.user.id,
            data.name.trim(),
            data.description.trim(),
            new Buffer(data.image, 'base64'),
            null,
            true);

        content_id = next_id();
        article_id = next_id();

        text = yield Text.$create({
            id: content_id,
            ref_id: article_id,
            value: data.content
        });

        article = yield Article.$create({
            id: article_id,
            user_id: this.request.user.id,
            user_name: this.request.user.name,
            category_id: data.category_id,
            cover_id: attachment.id,
            content_id: content_id,
            name: data.name.trim(),
            description: data.description.trim(),
            tags: helper.formatTags(data.tags),
            publish_at: (data.publish_at === undefined ? Date.now() : data.publish_at)
        });

        article.content = data.content;
        indexArticle(article);

        this.body = article;
    },

    'POST /api/articles/:id': function* (id) {
        /**
         * Update an exist article.
         *
         * @name Update Article
         * @param {string} id: Id of the article.
         * @param {string} [category_id]: Id of the category that article belongs to.
         * @param {string} [name]: Name of the article.
         * @param {string} [description]: Description of the article.
         * @param {string} [content]: Content of the article.
         * @param {string} [tags]: Tags of the article, seperated by ','.
         * @param {string} [publish_at]: Publish time of the article with format 'yyyy-MM-dd HH:mm:ss'.
         * @return {object} The updated article object.
         * @error {resource:notfound} Article was not found by id.
         * @error {parameter:invalid} If some parameter is invalid.
         * @error {permission:denied} If current user has no permission.
         */
        helper.checkPermission(this.request, constants.role.EDITOR);
        var
            user = this.request.user,
            article,
            props = [],
            text,
            attachment,
            data = this.request.body;
        json_schema.validate('updateArticle', data);

        article = yield $getArticle(id);
        if (user.role !== constants.role.ADMIN && user.id !== article.user_id) {
            throw api.notAllowed('Permission denied.');
        }
        if (data.category_id) {
            yield categoryApi.$getCategory(data.category_id);
            article.category_id = data.category_id;
            props.push('category_id');
        }
        if (data.name) {
            article.name = data.name.trim();
            props.push('name');
        }
        if (data.description) {
            article.description = data.description.trim();
            props.push('description');
        }
        if (data.tags) {
            article.tags = helper.formatTags(data.tags);
            props.push('tags');
        }
        if (data.publish_at !== undefined) {
            article.publish_at = data.publish_at;
            props.push('publish_at');
        }
        if (data.image) {
            // check image:
            attachment = yield attachmentApi.$createAttachment(
                user.id,
                article.name,
                article.description,
                new Buffer(data.image, 'base64'),
                null,
                true);
            article.cover_id = attachment.id;
            props.push('cover_id');
        }
        if (data.content) {
            text = yield Text.$create({
                ref_id: article.id,
                value: data.content
            });
            article.content_id = text.id;
            article.content = data.content;
            props.push('content_id');
        }
        if (props.length > 0) {
            props.push('updated_at');
            props.push('version');
            yield article.$update(props);
        }
        if (!article.content) {
            text = yield Text.$find(article.content_id);
            article.content = text.value;
        }
        this.body = article;
    },

    'POST /api/articles/:id/delete': function* (id) {
        /**
         * Delete an article.
         *
         * @name Delete Article
         * @param {string} id: Id of the article.
         * @return {object} Object contains deleted id.
         * @error {resource:notfound} Article not found by id.
         * @error {permission:denied} If current user has no permission.
         */
        helper.checkPermission(this.request, constants.role.EDITOR);
        var
            user = this.request.user,
            article = yield $getArticle(id);
        if (user.role !== constants.role.ADMIN && user.id !== article.user_id) {
            throw api.notAllowed('Permission denied.');
        }
        yield article.$destroy();
        yield warp.$update('delete from texts where ref_id=?', [id]);
        this.body = {
            id: id
        };
    }
};
<commit_msg>fix rss output<commit_after>'use strict';

// article api

var
    _ = require('lodash'),
    api = require('../api'),
    db = require('../db'),
    cache = require('../cache'),
    images = require('./_images'),
    helper = require('../helper'),
    constants = require('../constants'),
    search = require('../search/search'),
    json_schema = require('../json_schema');

var
    settingApi = require('./settingApi'),
    categoryApi = require('./categoryApi'),
    attachmentApi = require('./attachmentApi');

var
    User = db.user,
    Article = db.article,
    Category = db.category,
    Text = db.text,
    warp = db.warp,
    next_id = db.next_id;

function indexArticle(r) {
    process.nextTick(function () {
        search.engine.index({
            type: 'article',
            id: r.id,
            tags: r.tags,
            name: r.name,
            description: r.description,
            content: helper.html2text(helper.md2html(r.content)),
            created_at: r.publish_at,
            updated_at: r.updated_at,
            url: '/article/' + r.id,
            upvotes: 0
        });
    });
}

function unindexArticle(r) {
    process.nextTick(function () {
        search.engine.unindex({
            id: r.id
        });
    });
}

function* $getRecentArticles(max) {
    var now = Date.now();
    return yield Article.$findAll({
        where: 'publish_at<?',
        order: 'publish_at desc',
        params: [now],
        offset: 0,
        limit: max
    });
}

function* $getAllArticles(page) {
    page.total = yield Article.$findNumber('count(id)');
    if (page.isEmpty) {
        return [];
    }
    return yield Article.$findAll({
        offset: page.offset,
        limit: page.limit,
        order: 'publish_at desc'
    });
}

function* $getArticles(page) {
    var now = Date.now();
    page.total = yield Article.$findNumber({
        select: 'count(id)',
        where: 'publish_at<?',
        params: [now]
    });
    if (page.isEmpty) {
        return [];
    }
    return yield Article.$findAll({
        offset: page.offset,
        limit: page.limit,
        order: 'publish_at desc'
    });
}

function* $getArticlesByCategory(categoryId, page) {
    var now = Date.now();
    page.total = yield Article.$findNumber({
        select: 'count(id)',
        where: 'publish_at<? and category_id=?',
        params: [now, categoryId]
    });
    if (page.isEmpty) {
        return [];
    }
    return yield Article.$findAll({
        order: 'publish_at desc',
        where: 'publish_at<? and category_id=?',
        params: [now, categoryId],
        offset: page.offset,
        limit: page.limit
    });
}

function* $getArticle(id, includeContent) {
    var
        text,
        article = yield Article.$find(id);
    if (article === null) {
        throw api.notFound('Article');
    }
    if (includeContent) {
        text = yield Text.$find(article.content_id);
        if (text === null) {
            throw api.notFound('Text');
        }
        article.content = text.value;
    }
    return article;
}

function toRssDate(dt) {
    return new Date(dt).toGMTString();
}

function* $getFeed(domain) {
    var
        i, text, article, url,
        articles = yield $getRecentArticles(20),
        last_publish_at = articles.length === 0 ? 0 : articles[0].publish_at,
        website = yield settingApi.$getWebsiteSettings(),
        rss = [],
        rss_footer = '</channel></rss>';
    rss.push('<?xml version="1.0"?>\n');
    rss.push('<rss version="2.0"><channel><title><![CDATA[');
    rss.push(website.name);
    rss.push(']]></title><link>http://');
    rss.push(domain);
    rss.push('/</link><description><![CDATA[');
    rss.push(website.description);
    rss.push(']]></description><lastBuildDate>');
    rss.push(toRssDate(last_publish_at));
    rss.push('</lastBuildDate><generator>iTranswarp.js</generator><ttl>3600</ttl>');

    if (articles.length === 0) {
        rss.push(rss_footer);
    }
    else {
        for (i=0; i<articles.length; i++) {
            article = articles[i];
            text = yield Text.$find(article.content_id);
            url = 'http://' + domain + '/article/' + article.id;
            rss.push('<item><title><![CDATA[');
            rss.push(article.name);
            rss.push(']]></title><link>');
            rss.push(url);
            rss.push('</link><guid>');
            rss.push(url);
            rss.push('</guid><author><![CDATA[');
            rss.push(article.user_name);
            rss.push(']]></author><pubDate>');
            rss.push(toRssDate(article.publish_at));
            rss.push('</pubDate><description><![CDATA[');
            rss.push(helper.md2html(text.value, true));
            rss.push(']]></description></item>');
        }
        rss.push(rss_footer);
    }
    return rss.join('');
}

var RE_TIMESTAMP = /^\-?[0-9]{1,13}$/;

module.exports = {

    $getRecentArticles: $getRecentArticles,

    $getArticlesByCategory: $getArticlesByCategory,

    $getAllArticles: $getAllArticles,

    $getArticles: $getArticles,

    $getArticle: $getArticle,

    'GET /feed': function* () {
        var
            rss,
            host = this.request.host,
            gf = function* () {
                return yield $getFeed(host);
            };
        rss = yield cache.$get('cached_rss', gf);
        this.set('Cache-Control', 'max-age: 3600');
        this.type = 'text/xml';
        this.body = rss;
    },

    'GET /api/articles/:id': function* (id) {
        /**
         * Get article.
         *
         * @name Get Article
         * @param {string} id: Id of the article.
         * @param {string} [format]: Return html if format is 'html', default to '' (raw).
         * @return {object} Article object.
         * @error {resource:notfound} Article was not found by id.
         */
        var article = yield $getArticle(id, true);
        if (article.publish_at > Date.now() && (this.request.user===null || this.request.user.role > constants.role.CONTRIBUTOR)) {
            throw api.notFound('Article');
        }
        if (this.request.query.format === 'html') {
            article.content = helper.md2html(article.content, true);
        }
        this.body = article;
    },

    'GET /api/articles': function* () {
        /**
         * Get articles by page.
         *
         * @name Get Articles
         * @param {number} [page=1]: The page number, starts from 1.
         * @return {object} Article objects and page information.
         */
        helper.checkPermission(this.request, constants.role.CONTRIBUTOR);
        var
            page = helper.getPage(this.request),
            articles = yield $getAllArticles(page);
        this.body = {
            page: page,
            articles: articles
        };
    },

    'POST /api/articles': function* () {
        /**
         * Create a new article.
         *
         * @name Create Article
         * @param {string} category_id: Id of the category that article belongs to.
         * @param {string} name: Name of the article.
         * @param {string} description: Description of the article.
         * @param {string} content: Content of the article.
         * @param {string} [tags]: Tags of the article, seperated by ','.
         * @param {string} [publish_at]: Publish time of the article with format 'yyyy-MM-dd HH:mm:ss', default to current time.
         * @param {image} [image]: Base64 encoded image to upload as cover image.
         * @return {object} The created article object.
         * @error {parameter:invalid} If some parameter is invalid.
         * @error {permission:denied} If current user has no permission.
         */
        helper.checkPermission(this.request, constants.role.EDITOR);
        var
            text,
            article,
            attachment,
            article_id,
            content_id,
            data = this.request.body;
        json_schema.validate('createArticle', data);
        // check category id:
        yield categoryApi.$getCategory(data.category_id);

        attachment = yield attachmentApi.$createAttachment(
            this.request.user.id,
            data.name.trim(),
            data.description.trim(),
            new Buffer(data.image, 'base64'),
            null,
            true);

        content_id = next_id();
        article_id = next_id();

        text = yield Text.$create({
            id: content_id,
            ref_id: article_id,
            value: data.content
        });

        article = yield Article.$create({
            id: article_id,
            user_id: this.request.user.id,
            user_name: this.request.user.name,
            category_id: data.category_id,
            cover_id: attachment.id,
            content_id: content_id,
            name: data.name.trim(),
            description: data.description.trim(),
            tags: helper.formatTags(data.tags),
            publish_at: (data.publish_at === undefined ? Date.now() : data.publish_at)
        });

        article.content = data.content;
        indexArticle(article);

        this.body = article;
    },

    'POST /api/articles/:id': function* (id) {
        /**
         * Update an exist article.
         *
         * @name Update Article
         * @param {string} id: Id of the article.
         * @param {string} [category_id]: Id of the category that article belongs to.
         * @param {string} [name]: Name of the article.
         * @param {string} [description]: Description of the article.
         * @param {string} [content]: Content of the article.
         * @param {string} [tags]: Tags of the article, seperated by ','.
         * @param {string} [publish_at]: Publish time of the article with format 'yyyy-MM-dd HH:mm:ss'.
         * @return {object} The updated article object.
         * @error {resource:notfound} Article was not found by id.
         * @error {parameter:invalid} If some parameter is invalid.
         * @error {permission:denied} If current user has no permission.
         */
        helper.checkPermission(this.request, constants.role.EDITOR);
        var
            user = this.request.user,
            article,
            props = [],
            text,
            attachment,
            data = this.request.body;
        json_schema.validate('updateArticle', data);

        article = yield $getArticle(id);
        if (user.role !== constants.role.ADMIN && user.id !== article.user_id) {
            throw api.notAllowed('Permission denied.');
        }
        if (data.category_id) {
            yield categoryApi.$getCategory(data.category_id);
            article.category_id = data.category_id;
            props.push('category_id');
        }
        if (data.name) {
            article.name = data.name.trim();
            props.push('name');
        }
        if (data.description) {
            article.description = data.description.trim();
            props.push('description');
        }
        if (data.tags) {
            article.tags = helper.formatTags(data.tags);
            props.push('tags');
        }
        if (data.publish_at !== undefined) {
            article.publish_at = data.publish_at;
            props.push('publish_at');
        }
        if (data.image) {
            // check image:
            attachment = yield attachmentApi.$createAttachment(
                user.id,
                article.name,
                article.description,
                new Buffer(data.image, 'base64'),
                null,
                true);
            article.cover_id = attachment.id;
            props.push('cover_id');
        }
        if (data.content) {
            text = yield Text.$create({
                ref_id: article.id,
                value: data.content
            });
            article.content_id = text.id;
            article.content = data.content;
            props.push('content_id');
        }
        if (props.length > 0) {
            props.push('updated_at');
            props.push('version');
            yield article.$update(props);
        }
        if (!article.content) {
            text = yield Text.$find(article.content_id);
            article.content = text.value;
        }
        this.body = article;
    },

    'POST /api/articles/:id/delete': function* (id) {
        /**
         * Delete an article.
         *
         * @name Delete Article
         * @param {string} id: Id of the article.
         * @return {object} Object contains deleted id.
         * @error {resource:notfound} Article not found by id.
         * @error {permission:denied} If current user has no permission.
         */
        helper.checkPermission(this.request, constants.role.EDITOR);
        var
            user = this.request.user,
            article = yield $getArticle(id);
        if (user.role !== constants.role.ADMIN && user.id !== article.user_id) {
            throw api.notAllowed('Permission denied.');
        }
        yield article.$destroy();
        yield warp.$update('delete from texts where ref_id=?', [id]);
        this.body = {
            id: id
        };
    }
};
<|endoftext|>


<commit_before>const dataSelection = '.c-data-selection';
const homepage = '.c-homepage';
const notification = '.c-panel--warning';
const table = '.c-table';

describe('parcel-ownership (eigendommen) module', () => {
  describe('user should be able to navigate to the parcel-ownership from the homepage', () => {
    it.skip('should open the parcel-ownership page', () => { // TODO reactivate when feature switch is enable
      // go to the homepage
      cy.visit('/');
      // the homepage should be visible
      cy.get(homepage).should('exist').and('be.visible');
      // check if the link is in the dom and visible
      cy.get('#homepage-address-block').should('exist').and('be.visible');
      // the data-selection should not exist yet
      cy.get(dataSelection).should('not.exist');
      // click on the link to go to navigate to the page
      cy.get('.homepage-block__link').contains('Kadaster-tabel').click();
      // the homepage should not be visible anymore
      cy.get(homepage).should('not.be.visible');
      // the data selection should exist
      cy.get(dataSelection).should('exist').and('be.visible');
      // the title should contain Kadastrale objecten met zakelijk rechthebbenden
      cy.get('h1').contains('Kadastrale objecten met zakelijk rechthebbenden').should('exist').and('be.visible');
    });
  });

  describe('not authenticated', () => {
    beforeEach(() => {
      // go to the homepage
      cy.visit('/');
      // click on the link to go navigate to the page
      cy.get('.homepage-block__link').contains('Kadaster-tabel').click();
    });

    describe.skip('user should not be able to view the kadaster data', () => {
      it('should show a notification that the user must authenticate', () => {
        // a warning notification should be shown that the user must authenticate
        cy.get(notification).should('exist').and('be.visible');
      });

      it('should not show the table with results', () => {
        // the table with results should not exist
        cy.get(table).should('not.exist').and('not.be.visible');
      });
    });
  });

  describe('authenticated', () => {
    before(() => {
      cy.login();
    });

    after(() => {
      cy.logout();
    });

    beforeEach(() => {
      cy.server();
      cy.route('/dataselectie/brk/*').as('getDataselectieBrk');
      cy.route('/bag/nummeraanduiding/*').as('getNummeraanduiding');
      cy.route('/brk/object-expand/*').as('getBrkObjectExpand');
      cy.route('/brk/object/*').as('getBrkObject');
    });

    describe('user should be able to view the eigendommen', () => {
      describe.skip('should navigate from the homepage', () => {
        beforeEach(() => {
          // go to the homepage
          cy.visit('/');
          // click on the link to go to the eigendommen
          cy.get('.homepage-block__link').contains('Kadaster-tabel').click();

          cy.wait('@getDataselectieBrk');
          cy.scrollTo('top');
        });

        it('should not show a notification', () => {
          // a warning notification should not exist
          cy.get(notification).should('not.exist').and('not.be.visible');
        });

        it('should show the table with results', () => {
          // the table with results should exist
          cy.get(table).should('exist').and('be.visible');
        });
      });
    });

    describe('user should be able to navigate to the eigendommen detail view', () => {
      it('should open the correct detail view', () => {
        const route = '/#?dsd=brk&dsp=1&dsv=TABLE&dsf=eigenaar_type::Appartementseigenaar:stadsdeel_naam::Centrum:eigenaar_cat::Woningbouwcorporaties:ggw_naam::Centrum-Oost&mpb=topografie&mpz=8&mpv=52.3547489:4.9036586';

        cy.visit(route);
        cy.wait('@getDataselectieBrk');
        cy.scrollTo('top');

        cy.get('.c-table__content-row:first-child').click();

        cy.wait('@getBrkObjectExpand');
        cy.get('.qa-detail').should('exist').and('be.visible');
      });
    });

    describe('user should be able to add a filter', () => {
      it('should add the filter to the active filters and filter the results', () => {
        const route = '/#?dsd=brk&dsp=1&dsv=TABLE&dsf=eigenaar_type::Appartementseigenaar:stadsdeel_naam::Centrum:eigenaar_cat::Woningbouwcorporaties:ggw_naam::Centrum-Oost&mpb=topografie&mpz=8&mpv=52.3547489:4.9036587';

        cy.visit(route);
        cy.wait('@getDataselectieBrk');
        cy.scrollTo('top');

        // get the first category
        cy.get('.qa-available-filters')
          .find('.c-data-selection-available-filters__category')
          .first()
          .then((group) => {
            // get the innerText of the nested h2
            const category = group[0].children[0].innerText;
            // get the innerText of the first nested li
            const selectedFilter = 'Amstelveldbuurt';
            cy.get('.c-data-selection-available-filters__item')
              .find('.qa-option-label')
              .contains(selectedFilter)
              .should('exist').and('be.visible');

            cy.get('.c-data-selection-available-filters__item')
              .find('.qa-option-label')
              .contains(selectedFilter)
              .click({ force: true });

            cy.wait('@getDataselectieBrk');
            cy.scrollTo('top');

            // the filter should be added to the active filters (stadsdeel)
            cy.get('.c-data-selection-active-filters__listitem')
              .find('span')
              .contains(selectedFilter)
              .should('exist').and('be.visible');

            // get the position of the category in the th's of the table
            cy.get('th.c-table__header-field').each((th, index) => {
              // if the position is equal to the category
              if (th[0].innerText === category) {
                // get al the content the td's with the same position as the categoryGroup they all
                // should contain the same value as the `selectedFilter`
                cy.get('.c-table__content-row')
                  .find(`td:nth-child(${index + 1})`)
                  .contains(selectedFilter)
                  .should('exist').and('be.visible');
              }
            });
          });
      });
    });

    describe('user should be able to view a parcel in the leaflet map', () => {
      it('should open the detail view with a leaflet map and a cursor', () => {
        const route = '/#?dte=brk%2Fobject%2FNL.KAD.OnroerendeZaak.11430433270000%2F&mpb=topografie&mpz=13&mpv=52.3675111:4.9375494';

        // open the detail
        cy.visit(route);

        cy.wait('@getNummeraanduiding');
        cy.wait('@getBrkObjectExpand');
        cy.wait('@getBrkObject');

        // the cursor should be rendered inside the leaflet map
        cy.get('.leaflet-interactive').should('exist').and('be.visible');
      });
    });
  });
});
<commit_msg>All disabled E2E tests marked<commit_after>const dataSelection = '.c-data-selection';
const homepage = '.c-homepage';
const notification = '.c-panel--warning';
const table = '.c-table';

describe('parcel-ownership (eigendommen) module', () => {
  describe('user should be able to navigate to the parcel-ownership from the homepage', () => {
    it.skip('should open the parcel-ownership page', () => { // TODO reactivate when feature switch is removed
      // go to the homepage
      cy.visit('/');
      // the homepage should be visible
      cy.get(homepage).should('exist').and('be.visible');
      // check if the link is in the dom and visible
      cy.get('#homepage-address-block').should('exist').and('be.visible');
      // the data-selection should not exist yet
      cy.get(dataSelection).should('not.exist');
      // click on the link to go to navigate to the page
      cy.get('.homepage-block__link').contains('Kadaster-tabel').click();
      // the homepage should not be visible anymore
      cy.get(homepage).should('not.be.visible');
      // the data selection should exist
      cy.get(dataSelection).should('exist').and('be.visible');
      // the title should contain Kadastrale objecten met zakelijk rechthebbenden
      cy.get('h1').contains('Kadastrale objecten met zakelijk rechthebbenden').should('exist').and('be.visible');
    });
  });

  describe('not authenticated', () => {
    beforeEach(() => {
      // go to the homepage
      cy.visit('/');
      // click on the link to go navigate to the page
      cy.get('.homepage-block__link').contains('Kadaster-tabel').click();
    });

    describe.skip('user should not be able to view the kadaster data', () => { // TODO reactivate when feature switch is removed
      it('should show a notification that the user must authenticate', () => {
        // a warning notification should be shown that the user must authenticate
        cy.get(notification).should('exist').and('be.visible');
      });

      it('should not show the table with results', () => {
        // the table with results should not exist
        cy.get(table).should('not.exist').and('not.be.visible');
      });
    });
  });

  describe('authenticated', () => {
    before(() => {
      cy.login();
    });

    after(() => {
      cy.logout();
    });

    beforeEach(() => {
      cy.server();
      cy.route('/dataselectie/brk/*').as('getDataselectieBrk');
      cy.route('/bag/nummeraanduiding/*').as('getNummeraanduiding');
      cy.route('/brk/object-expand/*').as('getBrkObjectExpand');
      cy.route('/brk/object/*').as('getBrkObject');
    });

    describe('user should be able to view the eigendommen', () => {
      describe.skip('should navigate from the homepage', () => { // TODO reactivate when feature switch is removed
        beforeEach(() => {
          // go to the homepage
          cy.visit('/');
          // click on the link to go to the eigendommen
          cy.get('.homepage-block__link').contains('Kadaster-tabel').click();

          cy.wait('@getDataselectieBrk');
          cy.scrollTo('top');
        });

        it('should not show a notification', () => {
          // a warning notification should not exist
          cy.get(notification).should('not.exist').and('not.be.visible');
        });

        it('should show the table with results', () => {
          // the table with results should exist
          cy.get(table).should('exist').and('be.visible');
        });
      });
    });

    describe('user should be able to navigate to the eigendommen detail view', () => {
      it('should open the correct detail view', () => {
        const route = '/#?dsd=brk&dsp=1&dsv=TABLE&dsf=eigenaar_type::Appartementseigenaar:stadsdeel_naam::Centrum:eigenaar_cat::Woningbouwcorporaties:ggw_naam::Centrum-Oost&mpb=topografie&mpz=8&mpv=52.3547489:4.9036586';

        cy.visit(route);
        cy.wait('@getDataselectieBrk');
        cy.scrollTo('top');

        cy.get('.c-table__content-row:first-child').click();

        cy.wait('@getBrkObjectExpand');
        cy.get('.qa-detail').should('exist').and('be.visible');
      });
    });

    describe('user should be able to add a filter', () => {
      it('should add the filter to the active filters and filter the results', () => {
        const route = '/#?dsd=brk&dsp=1&dsv=TABLE&dsf=eigenaar_type::Appartementseigenaar:stadsdeel_naam::Centrum:eigenaar_cat::Woningbouwcorporaties:ggw_naam::Centrum-Oost&mpb=topografie&mpz=8&mpv=52.3547489:4.9036587';

        cy.visit(route);
        cy.wait('@getDataselectieBrk');
        cy.scrollTo('top');

        // get the first category
        cy.get('.qa-available-filters')
          .find('.c-data-selection-available-filters__category')
          .first()
          .then((group) => {
            // get the innerText of the nested h2
            const category = group[0].children[0].innerText;
            // get the innerText of the first nested li
            const selectedFilter = 'Amstelveldbuurt';
            cy.get('.c-data-selection-available-filters__item')
              .find('.qa-option-label')
              .contains(selectedFilter)
              .should('exist').and('be.visible');

            cy.get('.c-data-selection-available-filters__item')
              .find('.qa-option-label')
              .contains(selectedFilter)
              .click({ force: true });

            cy.wait('@getDataselectieBrk');
            cy.scrollTo('top');

            // the filter should be added to the active filters (stadsdeel)
            cy.get('.c-data-selection-active-filters__listitem')
              .find('span')
              .contains(selectedFilter)
              .should('exist').and('be.visible');

            // get the position of the category in the th's of the table
            cy.get('th.c-table__header-field').each((th, index) => {
              // if the position is equal to the category
              if (th[0].innerText === category) {
                // get al the content the td's with the same position as the categoryGroup they all
                // should contain the same value as the `selectedFilter`
                cy.get('.c-table__content-row')
                  .find(`td:nth-child(${index + 1})`)
                  .contains(selectedFilter)
                  .should('exist').and('be.visible');
              }
            });
          });
      });
    });

    describe('user should be able to view a parcel in the leaflet map', () => {
      it('should open the detail view with a leaflet map and a cursor', () => {
        const route = '/#?dte=brk%2Fobject%2FNL.KAD.OnroerendeZaak.11430433270000%2F&mpb=topografie&mpz=13&mpv=52.3675111:4.9375494';

        // open the detail
        cy.visit(route);

        cy.wait('@getNummeraanduiding');
        cy.wait('@getBrkObjectExpand');
        cy.wait('@getBrkObject');

        // the cursor should be rendered inside the leaflet map
        cy.get('.leaflet-interactive').should('exist').and('be.visible');
      });
    });
  });
});
<|endoftext|>


<commit_before>import {
  ruleTester,
  warningFreeBasics,
} from "../../../testUtils"
import rule, { ruleName, messages } from ".."

const testRule = ruleTester(rule, ruleName)

testRule([
  "rgba",
  "scale",
  "linear-gradient",
], tr => {
  warningFreeBasics(tr)
  tr.ok("a { color: pink; }")
  tr.ok("a { transform: rotate(7deg) }")
  tr.ok("a { background: -webkit-radial-gradient(red, green, blue); }")

  tr.notOk("a { transform: scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 16,
  })
  tr.notOk("a { transform : scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 17,
  })
  tr.notOk("a\n{ transform: scale(1); }", {
    message: messages.rejected("scale"),
    line: 2,
    column: 14,
  })
  tr.notOk("a { transform:    scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 19,
  })
  tr.notOk("  a { transform: scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 18,
  })
  tr.notOk("a { color: rgba(0, 0, 0, 0) }", {
    message: messages.rejected("rgba"),
    line: 1,
    column: 12,
  })
  tr.notOk("a { background: red, -moz-linear-gradient(45deg, blue, red); }", {
    message: messages.rejected("-moz-linear-gradient"),
    line: 1,
    column: 22,
  })
})
<commit_msg>Add nested function and nested block tests<commit_after>import {
  ruleTester,
  warningFreeBasics,
} from "../../../testUtils"
import rule, { ruleName, messages } from ".."

const testRule = ruleTester(rule, ruleName)

testRule([
  "rgba",
  "scale",
  "linear-gradient",
], tr => {
  warningFreeBasics(tr)
  tr.ok("a { color: pink; }")
  tr.ok("a { transform: rotate(7deg) }")
  tr.ok("a { background: -webkit-radial-gradient(red, green, blue); }")
  tr.ok("a { color: color(rgb(0, 0, 0) lightness(50%)); }")
  tr.ok("@media (max-width: 10px) { a { color: color(rgb(0, 0, 0) lightness(50%)); } }")

  tr.notOk("a { transform: scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 16,
  })
  tr.notOk("a { transform : scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 17,
  })
  tr.notOk("a\n{ transform: scale(1); }", {
    message: messages.rejected("scale"),
    line: 2,
    column: 14,
  })
  tr.notOk("a { transform:    scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 19,
  })
  tr.notOk("  a { transform: scale(1); }", {
    message: messages.rejected("scale"),
    line: 1,
    column: 18,
  })
  tr.notOk("a { color: rgba(0, 0, 0, 0) }", {
    message: messages.rejected("rgba"),
    line: 1,
    column: 12,
  })
  tr.notOk("a { color: color(rgba(0, 0, 0, 0) lightness(50%)); }", {
    message: messages.rejected("rgba"),
    line: 1,
    column: 18,
  })
  tr.notOk("a { background: red, -moz-linear-gradient(45deg, blue, red); }", {
    message: messages.rejected("-moz-linear-gradient"),
    line: 1,
    column: 22,
  })
  tr.notOk("@media (max-width: 10px) { a { color: color(rgba(0, 0, 0) lightness(50%)); } }", {
    message: messages.rejected("rgba"),
    line: 1,
    column: 45,
  })

})
<|endoftext|>


<commit_before>var dashboardView = Backbone.View.extend({
  el: '#content',
  updateInterval: 1000, // 1 second, constant
  updateFrequency: 5, // the actual update rate (5 s)
  updateCounter: 0,
  arraySize: 99, // how many values will we keep per figure?
  seriesData: {},
  charts: {},
  units: [],
  detailGraph: "userTime",

  initialize: function () {
    var self = this;

    this.initUnits();

    this.collection.fetch({
      success: function() {
        self.calculateSeries();
        self.renderCharts();

        window.setInterval(function() {
          self.updateCounter++;

          if (self.updateCounter < self.updateFrequency) {
            return false;
          }

          self.updateCounter = 0;
          self.collection.fetch({
            success: function() {
              self.calculateSeries();
              self.renderCharts();
            },
            error: function() {
              // need to flush previous values
              self.calculateSeries(true);
              self.renderCharts();
              arangoHelper.arangoError("Lost connection to Database!");
            }
          });

        }, self.updateInterval);
      }
    });
  },

  events: {
    "click .dashboard-dropdown li" : "checkEnabled",
    "click .interval-dropdown li" : "checkInterval",
    "click .db-zoom" : "renderDetailChart",
    "click .db-minimize" : "checkDetailChart",
    "click .db-hide" : "hideChart"
  },

  template: new EJS({url: 'js/templates/dashboardView.ejs'}),

  render: function() {
    var self = this;
    $(this.el).html(this.template.text);

    //Client calculated charts
    self.genCustomCategory("Client calculated charts", "custom", "Customized Charts");
    self.genCustomChart();

    $.each(this.options.description.models[0].attributes.groups, function () {
      $('.thumbnails').append(
        '
' +
        '
' + this.name + '
' +
        '
');
      $('#menuGroups').append(
        '
' + this.name + '
' +
        '

'
      );
    });

    $.each(this.options.description.models[0].attributes.figures, function () {
      self.renderFigure(this);
    });

    $('#every'+self.updateFrequency+'seconds').prop('checked',true);

    if (this.collection.models[0] === undefined) {
      this.collection.fetch({
        success: function() {
          self.calculateSeries();
          self.renderCharts();
        },
        error: function() {
          self.calculateSeries();
          self.renderCharts(flush);
        }
      });
    }
    else {
      self.calculateSeries();
      self.renderCharts();
    }
    return this;
  },
  genCustomCategory: function(description, group, name) {
    this.options.description.models[0].attributes.groups.push({
      "description":description,
      "group":group,
      "name":name
    });
  },
  genCustomChart: function () {
    //totalTime
    var figure = {
      "description" : "userTime + systemTime",
      "group" : "custom",
      "identifier" : "totalTime2",
      "name" : "Total Time (User+System)",
      "type" : "accumulated",
      "units" : "seconds"
    };
    this.options.description.models[0].attributes.figures.push(figure);
    this.renderFigure(figure);
  },

  updateCustomChart: function () {
    //totalTime
    var val1 = this.collection.models[0].attributes.system.userTime;
    var val2 = this.collection.models[0].attributes.system.systemTime;
    var totalTime2Value = val1+val2;
    this.collection.models[0].attributes["custom"] = {"totalTime2":totalTime2Value};
  },

  checkInterval: function (a) {
    this.updateFrequency = a.target.value;
    self.calculateSeries();
    self.renderCharts();
  },

  checkEnabled: function (a) {
    var myId = a.target.id;
    var position = myId.search('Checkbox');
    var preparedId = myId.substring(0, position);
    var toCheck = $(a.target).is(':checked');
    if (toCheck === false) {
      $("#" + preparedId).hide();
    }
    else if (toCheck === true) {
      $("#" + preparedId).show();
    }
  },

  initUnits : function () {
    this.units = [ ];
    var i;
    var scale = 0.0001;

    for (i = 0; i < 12; ++i) {
      this.units.push(scale * 1);
      this.units.push(scale * 2);
      this.units.push(scale * 2.5);
      this.units.push(scale * 4);
      this.units.push(scale * 5);
      scale *= 10;
    }
  },

  getMaxValue : function (identifier) {
    var max = this.seriesData[identifier].max || 1;

    var i = 0, n = this.units.length;
    while (i < n) {
      var unit = this.units[i++];
      if (max > unit) {
        continue;
      }
      if (max == unit) {
        break;
      }
      return unit;
    }

    return max;
  },

  checkDetailChart: function (a) {
    if ($(a.target).hasClass('icon-minus') === true) {
      $('#detailGraph').height(43);
      $('#detailGraphChart').hide();
      $(a.target).removeClass('icon-minus');
      $(a.target).addClass('icon-plus');
    }
    else {
      $('#detailGraphChart').show();
      $('#detailGraph').height(300);
      $(a.target).removeClass('icon-plus');
      $(a.target).addClass('icon-minus');
    }
  },

  hideChart: function (a) {
    var figure = $(a.target).attr("value");
    $('#'+figure+'Checkbox').prop('checked', false);
    $('#'+figure).hide();
  },

  renderDetailChart: function (a) {
    var self = this;
    self.detailGraph = $(a.target).attr("value");
    $.each(this.options.description.models[0].attributes.figures, function () {
      if(this.identifier === self.detailGraph) {
        $('#detailGraphHeader').text(this.name);
        self.calculateSeries();
        self.renderCharts();
        $("html, body").animate({ scrollTop: 0 }, "slow");
        $('#detailGraphChart').show();
        $('#detailGraph').height(300);
        $('#dbHideSwitch').addClass('icon-minus');
        $('#dbHideSwitch').removeClass('icon-plus');
      }
    });
  },

  renderCharts: function () {
    var self = this;
    $('#every'+self.updateFrequency+'seconds').prop('checked',true);

    $.each(self.options.description.models[0].attributes.figures, function () {
      var figure = this;
      var identifier = figure.identifier;
      var chart;

      if (self.charts[identifier] === undefined) {
        chart = self.charts[identifier] = nv.models.lineChart();
        chart.xAxis.axisLabel('').tickFormat(function (d) {
          if (isNaN(d)) {
            return '';
          }

          function pad (value) {
            return (value < 10 ? "0" + String(value) : String(value));
          }

          var date = new Date(d / 10);

          return pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
        });

        var label = figure.units;

        if (figure.units === 'bytes') {
          label = "megabytes";
        }
        chart.yAxis.axisLabel(label);

        nv.addGraph (function () {
          nv.utils.windowResize(function () {
            d3.select('#' + identifier + 'Chart svg').call(chart);
          });

          return chart;
        });
      }
      else {
        chart = self.charts[identifier];
      }

      chart.yDomain([ 0, self.getMaxValue(identifier) ]);

      if (self.detailGraph === undefined) {
        self.detailGraph = "userTime";
      }
      if (self.detailGraph === identifier) {
        d3.select("#detailGraphChart svg")
          .call(chart)
          .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ])
          .transition().duration(500);

      }

      d3.select("#" + identifier + "Chart svg")
        .call(chart)
        .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ])
        .transition().duration(500);
    });
  },

  calculateSeries: function (flush) {
    var self = this;
    self.updateCustomChart();

    var timeStamp = Math.round(new Date() * 10);

    $.each(self.options.description.models[0].attributes.figures, function () {
      var figure = this;
      var identifier = figure.identifier;

      if (self.seriesData[identifier] === undefined) {
        self.seriesData[identifier] = { max: 0, values: [ ] };
      }

      while (self.seriesData[identifier].values.length > self.arraySize) {
        self.seriesData[identifier].values.shift();
      }

      if (flush) {
        self.seriesData[identifier].values.push({ x: timeStamp, y: undefined, value: undefined });
        return;
      }

      var responseValue = self.collection.models[0].attributes[figure.group][identifier];

      if (responseValue !== undefined && responseValue !== null) {
        if (responseValue.sum !== undefined) {
          responseValue = responseValue.sum;
        }
      }

      function sanitize (value, figure) {
        if (value < 0) {
          value = 0;
        }
        else {
          if (figure.units === 'bytes') {
            value /= (1024 * 1024);
          }
          value = Math.round(value * 100) / 100;
        }

        return value;
      }

      var newValue = 0;

      if (figure.type === 'current') {
        newValue = responseValue;
      }
      else {
        var n = self.seriesData[identifier].values.length;

        if (responseValue !== undefined && n > 0) {
          var previous = self.seriesData[identifier].values[n - 1];
          if (previous.value !== undefined) {
            newValue = responseValue - previous.value;
          }
        }
      }

      newValue = sanitize(newValue, figure);
      if (newValue > self.seriesData[identifier].max) {
        self.seriesData[identifier].max = newValue;
      }

      self.seriesData[identifier].values.push({ x: timeStamp, y: newValue, value: responseValue });
    });
  },

  renderFigure: function (figure) {
    $('#' + figure.group).append(
      '
' +
      '

' + figure.name +
      '
'+
      '' +
      '' +
      '' +
      '
' +
      '
<svg class="svgClass"/>
' +
      '
'
    );

    $('#' + figure.group + 'Divider').before(
      '
'+
      '<input type="checkbox" id=' + figure.identifier + 'Checkbox checked>' + figure.name + '
'
    );
    $('.db-info').tooltip({
      placement: "top"
    });
  }

});
<commit_msg>optimized some functions<commit_after>var dashboardView = Backbone.View.extend({
  el: '#content',
  updateInterval: 1000, // 1 second, constant
  updateFrequency: 5, // the actual update rate (5 s)
  updateCounter: 0,
  arraySize: 99, // how many values will we keep per figure?
  seriesData: {},
  charts: {},
  units: [],
  detailGraph: "userTime",

  initialize: function () {
    var self = this;

    this.initUnits();

    this.collection.fetch({
      success: function() {
        self.calculateSeries();
        self.renderCharts();

        window.setInterval(function() {
          self.updateCounter++;

          if (self.updateCounter < self.updateFrequency) {
            return false;
          }

          self.updateCounter = 0;
          self.collection.fetch({
            success: function() {
              self.calculateSeries();
              self.renderCharts();
            },
            error: function() {
              // need to flush previous values
              self.calculateSeries(true);
              self.renderCharts();
              arangoHelper.arangoError("Lost connection to Database!");
            }
          });

        }, self.updateInterval);
      }
    });
  },

  events: {
    "click .dashboard-dropdown li" : "checkEnabled",
    "click .interval-dropdown li" : "checkInterval",
    "click .db-zoom" : "renderDetailChart",
    "click .db-minimize" : "checkDetailChart",
    "click .db-hide" : "hideChart"
  },

  template: new EJS({url: 'js/templates/dashboardView.ejs'}),

  render: function() {
    var self = this;
    $(this.el).html(this.template.text);

    //Client calculated charts
    self.genCustomCategories();
    self.genCustomChartDescription(
      "userTime + systemTime",
      "custom",
      "totalTime2",
      "Total Time (User+System)",
      "accumulated",
      "seconds"
    );

    $.each(this.options.description.models[0].attributes.groups, function () {
      $('.thumbnails').append(
        '
' +
        '
' + this.name + '
' +
        '
');
      $('#menuGroups').append(
        '
' + this.name + '
' +
        '

'
      );
    });

    $.each(this.options.description.models[0].attributes.figures, function () {
      self.renderFigure(this);
    });

    $('#every'+self.updateFrequency+'seconds').prop('checked',true);

    if (this.collection.models[0] === undefined) {
      this.collection.fetch({
        success: function() {
          self.calculateSeries();
          self.renderCharts();
        },
        error: function() {
          self.calculateSeries();
          self.renderCharts(flush);
        }
      });
    }
    else {
      self.calculateSeries();
      self.renderCharts();
    }
    return this;
  },
  //generate function for all custom categories
  genCustomCategories: function () {
    this.genCustomCategory("Client calculated charts", "custom", "Customized Charts");
  },
  //generate a custom category
  genCustomCategory: function(description, group, name) {
    this.options.description.models[0].attributes.groups.push({
      "description":description,
      "group":group,
      "name":name
    });
  },
  //generate a custom description
  genCustomChartDescription: function (description, group, identifier, name, type, units) {
    var figure = {
      "description" : description,
      "group" : group,
      "identifier" : identifier,
      "name" : name,
      "type" : type,
      "units" : units
    };
    this.options.description.models[0].attributes.figures.push(figure);
    this.renderFigure(figure);
  },
  //calculate customized chart value functions here
  updateCustomChartValues: function ( {
    this.totalTime2();
  },

  //custom chart value calculation for totalTime2
  totalTime2: function () {
    var val1 = this.collection.models[0].attributes.system.userTime;
    var val2 = this.collection.models[0].attributes.system.systemTime;
    var totalTime2Value = val1+val2;
    this.collection.models[0].attributes["custom"] = {"totalTime2":totalTime2Value};
  },

  checkInterval: function (a) {
    this.updateFrequency = a.target.value;
    self.calculateSeries();
    self.renderCharts();
  },

  checkEnabled: function (a) {
    var myId = a.target.id;
    var position = myId.search('Checkbox');
    var preparedId = myId.substring(0, position);
    var toCheck = $(a.target).is(':checked');
    if (toCheck === false) {
      $("#" + preparedId).hide();
    }
    else if (toCheck === true) {
      $("#" + preparedId).show();
    }
  },

  initUnits : function () {
    this.units = [ ];
    var i;
    var scale = 0.0001;

    for (i = 0; i < 12; ++i) {
      this.units.push(scale * 1);
      this.units.push(scale * 2);
      this.units.push(scale * 2.5);
      this.units.push(scale * 4);
      this.units.push(scale * 5);
      scale *= 10;
    }
  },

  getMaxValue : function (identifier) {
    var max = this.seriesData[identifier].max || 1;

    var i = 0, n = this.units.length;
    while (i < n) {
      var unit = this.units[i++];
      if (max > unit) {
        continue;
      }
      if (max == unit) {
        break;
      }
      return unit;
    }

    return max;
  },

  checkDetailChart: function (a) {
    if ($(a.target).hasClass('icon-minus') === true) {
      $('#detailGraph').height(43);
      $('#detailGraphChart').hide();
      $(a.target).removeClass('icon-minus');
      $(a.target).addClass('icon-plus');
    }
    else {
      $('#detailGraphChart').show();
      $('#detailGraph').height(300);
      $(a.target).removeClass('icon-plus');
      $(a.target).addClass('icon-minus');
    }
  },

  hideChart: function (a) {
    var figure = $(a.target).attr("value");
    $('#'+figure+'Checkbox').prop('checked', false);
    $('#'+figure).hide();
  },

  renderDetailChart: function (a) {
    var self = this;
    self.detailGraph = $(a.target).attr("value");
    $.each(this.options.description.models[0].attributes.figures, function () {
      if(this.identifier === self.detailGraph) {
        $('#detailGraphHeader').text(this.name);
        self.calculateSeries();
        self.renderCharts();
        $("html, body").animate({ scrollTop: 0 }, "slow");
        $('#detailGraphChart').show();
        $('#detailGraph').height(300);
        $('#dbHideSwitch').addClass('icon-minus');
        $('#dbHideSwitch').removeClass('icon-plus');
      }
    });
  },

  renderCharts: function () {
    var self = this;
    $('#every'+self.updateFrequency+'seconds').prop('checked',true);

    $.each(self.options.description.models[0].attributes.figures, function () {
      var figure = this;
      var identifier = figure.identifier;
      var chart;

      if (self.charts[identifier] === undefined) {
        chart = self.charts[identifier] = nv.models.lineChart();
        chart.xAxis.axisLabel('').tickFormat(function (d) {
          if (isNaN(d)) {
            return '';
          }

          function pad (value) {
            return (value < 10 ? "0" + String(value) : String(value));
          }

          var date = new Date(d / 10);

          return pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
        });

        var label = figure.units;

        if (figure.units === 'bytes') {
          label = "megabytes";
        }
        chart.yAxis.axisLabel(label);

        nv.addGraph (function () {
          nv.utils.windowResize(function () {
            d3.select('#' + identifier + 'Chart svg').call(chart);
          });

          return chart;
        });
      }
      else {
        chart = self.charts[identifier];
      }

      chart.yDomain([ 0, self.getMaxValue(identifier) ]);

      if (self.detailGraph === undefined) {
        self.detailGraph = "userTime";
      }
      if (self.detailGraph === identifier) {
        d3.select("#detailGraphChart svg")
          .call(chart)
          .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ])
          .transition().duration(500);

      }

      d3.select("#" + identifier + "Chart svg")
        .call(chart)
        .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ])
        .transition().duration(500);
    });
  },

  calculateSeries: function (flush) {
    var self = this;
    self.updateCustomChartValues();

    var timeStamp = Math.round(new Date() * 10);

    $.each(self.options.description.models[0].attributes.figures, function () {
      var figure = this;
      var identifier = figure.identifier;

      if (self.seriesData[identifier] === undefined) {
        self.seriesData[identifier] = { max: 0, values: [ ] };
      }

      while (self.seriesData[identifier].values.length > self.arraySize) {
        self.seriesData[identifier].values.shift();
      }

      if (flush) {
        self.seriesData[identifier].values.push({ x: timeStamp, y: undefined, value: undefined });
        return;
      }

      var responseValue = self.collection.models[0].attributes[figure.group][identifier];

      if (responseValue !== undefined && responseValue !== null) {
        if (responseValue.sum !== undefined) {
          responseValue = responseValue.sum;
        }
      }

      function sanitize (value, figure) {
        if (value < 0) {
          value = 0;
        }
        else {
          if (figure.units === 'bytes') {
            value /= (1024 * 1024);
          }
          value = Math.round(value * 100) / 100;
        }

        return value;
      }

      var newValue = 0;

      if (figure.type === 'current') {
        newValue = responseValue;
      }
      else {
        var n = self.seriesData[identifier].values.length;

        if (responseValue !== undefined && n > 0) {
          var previous = self.seriesData[identifier].values[n - 1];
          if (previous.value !== undefined) {
            newValue = responseValue - previous.value;
          }
        }
      }

      newValue = sanitize(newValue, figure);
      if (newValue > self.seriesData[identifier].max) {
        self.seriesData[identifier].max = newValue;
      }

      self.seriesData[identifier].values.push({ x: timeStamp, y: newValue, value: responseValue });
    });
  },

  renderFigure: function (figure) {
    $('#' + figure.group).append(
      '
' +
      '

' + figure.name +
      '
'+
      '' +
      '' +
      '' +
      '
' +
      '
<svg class="svgClass"/>
' +
      '
'
    );

    $('#' + figure.group + 'Divider').before(
      '
'+
      '<input type="checkbox" id=' + figure.identifier + 'Checkbox checked>' + figure.name + '
'
    );
    $('.db-info').tooltip({
      placement: "top"
    });
  }

});
<|endoftext|>