<commit_before>/**
 * Drag-to-sort class
 *
 * Builds on the Drag class by allowing you to sort the elements amongst themselves.
 */
Garnish.DragSort = Garnish.Drag.extend({

	// Properties
	// =========================================================================

	$heightedContainer: null,
	$insertion: null,
	insertionVisible: false,
	startDraggeeIndex: null,
	closestItem: null,

	// Public methods
	// =========================================================================

	/**
	 * Constructor
	 *
	 * @param mixed  items    Elements that should be draggable right away. (Can be skipped.)
	 * @param object settings Any settings that should override the defaults.
	 */
	init: function(items, settings)
	{
		// Param mapping
		if (!settings && $.isPlainObject(items))
		{
			// (settings)
			settings = items;
			items = null;
		}

		settings = $.extend({}, Garnish.DragSort.defaults, settings);
		this.base(items, settings);
	},

	/**
	 * Creates the insertion element.
	 */
	createInsertion: function()
	{
		if (this.settings.insertion)
		{
			if (typeof this.settings.insertion == 'function')
			{
				return $(this.settings.insertion(this.$draggee));
			}
			else
			{
				return $(this.settings.insertion);
			}
		}
	},

	/**
	 * Returns the helper’s target X position
	 */
	getHelperTargetX: function()
	{
		if (this.settings.magnetStrength != 1)
		{
			this.getHelperTargetX._draggeeOffsetX = this.$draggee.offset().left - this.targetItemMouseOffsetX;
			return this.getHelperTargetX._draggeeOffsetX + ((this.mouseX - this.getHelperTargetX._draggeeOffsetX) / this.settings.magnetStrength);
		}
		else
		{
			return this.mouseX;
		}
	},

	/**
	 * Returns the helper’s target Y position
	 */
	getHelperTargetY: function()
	{
		if (this.settings.magnetStrength != 1)
		{
			this.getHelperTargetY._draggeeOffsetY = this.$draggee.offset().top - this.targetItemMouseOffsetY;
			return this.getHelperTargetY._draggeeOffsetY + ((this.mouseY - this.getHelperTargetY._draggeeOffsetY) / this.settings.magnetStrength);
		}
		else
		{
			return this.mouseY;
		}
	},

	// Events
	// -------------------------------------------------------------------------

	/**
	 * On Drag Start
	 */
	onDragStart: function()
	{
		this.base();

		this.$insertion = this.createInsertion();
		this._placeInsertionWithDraggee();

		this.closestItem = null;
		this._recordPositions();

		//  Get the closest container that has a height
		if (this.settings.container)
		{
			this.$heightedContainer = $(this.settings.container);

			while (! this.$heightedContainer.height())
			{
				this.$heightedContainer = this.$heightedContainer.parent();
			}
		}

		this.startDraggeeIndex = $.inArray(this.$draggee[0], this.$items);
	},

	/**
	 * On Drag
	 */
	onDrag: function()
	{
		// If there's a container set, make sure that we're hovering over it
		if (this.$heightedContainer && !Garnish.hitTest(this.mouseX, this.mouseY, this.$heightedContainer))
		{
			if (this.closestItem)
			{
				this.closestItem = null;
				this._removeInsertion();
			}
		}
		else
		{
			// Is there a new closest item?
			if (
				this.closestItem !== (this.closestItem = this._getClosestItem()) &&
				this.closestItem !== null
			)
			{
				this._updateInsertion();
			}
		}

		this.base();
	},

	/**
	 * On Drag Stop
	 */
	onDragStop: function()
	{
		this._removeInsertion();

		// Return the helpers to the draggees
		this.returnHelpersToDraggees();

		this.base();

		// Has the item actually moved?
		this.$items = $().add(this.$items);
		var newDraggeeIndex = $.inArray(this.$draggee[0], this.$items);

		if (this.startDraggeeIndex != newDraggeeIndex)
		{
			this.onSortChange();
		}
	},

	/**
	 * On Insertion Point Change event
	 */
	onInsertionPointChange: function()
	{
		Garnish.requestAnimationFrame($.proxy(function()
		{
			this.trigger('insertionPointChange');
			this.settings.onInsertionPointChange();
		}, this));
	},

	/**
	 * On Sort Change event
	 */
	onSortChange: function()
	{
		Garnish.requestAnimationFrame($.proxy(function()
		{
			this.trigger('sortChange');
			this.settings.onSortChange();
		}, this));
	},

	// Private methods
	// =========================================================================

	/**
	 * Sets the item midpoints up front so we don't have to keep checking on every mouse move
	 */
	_recordPositions: function()
	{
		for (this._recordPositions._i = 0; this._recordPositions._i < this.totalOtherItems; this._recordPositions._i++)
		{
			this._recordPosition($(this.otherItems[this._recordPositions._i]));
		}

		if (!this.settings.removeDraggee)
		{
			this._recordPosition(this.$draggee);
		}
		else if (this.insertionVisible)
		{
			this._recordPosition(this.$insertion);
		}
	},

	/**
	 * Set the midpoint on an item.
	 */
	_recordPosition: function($item)
	{
		$item.data('offset', $item.offset());
		$item.data('midpointX', $item.data('offset').left + $item.outerWidth() / 2);
		$item.data('midpointY', $item.data('offset').top + $item.outerHeight() / 2);
	},

	/**
	 * Returns the closest item to the cursor.
	 */
	_getClosestItem: function()
	{
		this._getClosestItem._closestItem = null;

		if (!this.settings.removeDraggee)
		{
			this._testForClosestItem(this.$draggee[0]);
		}
		else if (this.insertionVisible)
		{
			this._testForClosestItem(this.$insertion[0]);
		}

		for (this._getClosestItem._i = 0; this._getClosestItem._i < this.totalOtherItems; this._getClosestItem._i++)
		{
			this._testForClosestItem(this.otherItems[this._getClosestItem._i]);
		}

		// Ignore if it's the draggee or insertion
		if (
			this._getClosestItem._closestItem != this.$draggee[0] &&
			(!this.insertionVisible || this._getClosestItem._closestItem != this.$insertion[0])
		)
		{
			return this._getClosestItem._closestItem;
		}
		else
		{
			return null;
		}
	},

	_testForClosestItem: function(item)
	{
		this._testForClosestItem._$item = $(item);

		this._testForClosestItem._mouseDiff = Garnish.getDist(
			this._testForClosestItem._$item.data('midpointX'),
			this._testForClosestItem._$item.data('midpointY'),
			this.draggeeVirtualMidpointX,
			this.draggeeVirtualMidpointY
		);

		if (
			this._getClosestItem._closestItem === null ||
			this._testForClosestItem._mouseDiff < this._getClosestItem._closestItemMouseDiff
		)
		{
			this._getClosestItem._closestItem          = this._testForClosestItem._$item[0];
			this._getClosestItem._closestItemMouseDiff = this._testForClosestItem._mouseDiff;
		}
	},

	/**
	 * Updates the position of the insertion point.
	 */
	_updateInsertion: function()
	{
		if (this.closestItem)
		{
			// Going down?
			if (this.$draggee.index() < $(this.closestItem).index())
			{
				this.$draggee.insertAfter(this.closestItem);
			}
			else
			{
				this.$draggee.insertBefore(this.closestItem);
			}

			this._placeInsertionWithDraggee();
		}

		// Now that things have shifted around we need to set the new midpoints
		this._recordPositions();

		this.onInsertionPointChange();
	},

	_placeInsertionWithDraggee: function()
	{
		if (this.$insertion)
		{
			this.$insertion.insertBefore(this.$draggee.first());
			this.insertionVisible = true;
		}
	},

	/**
	 * Removes the insertion, if it's visible.
	 */
	_removeInsertion: function()
	{
		if (this.insertionVisible)
		{
			this.$insertion.remove();
			this.insertionVisible = false;
		}
	}
},

// Static Properties
// =============================================================================

{
	defaults: {
		container: null,
		insertion: null,
		magnetStrength: 1,
		onInsertionPointChange: $.noop,
		onSortChange: $.noop
	}
});
<commit_msg>mouseDiff => mouseDist<commit_after>/**
 * Drag-to-sort class
 *
 * Builds on the Drag class by allowing you to sort the elements amongst themselves.
 */
Garnish.DragSort = Garnish.Drag.extend({

	// Properties
	// =========================================================================

	$heightedContainer: null,
	$insertion: null,
	insertionVisible: false,
	startDraggeeIndex: null,
	closestItem: null,

	// Public methods
	// =========================================================================

	/**
	 * Constructor
	 *
	 * @param mixed  items    Elements that should be draggable right away. (Can be skipped.)
	 * @param object settings Any settings that should override the defaults.
	 */
	init: function(items, settings)
	{
		// Param mapping
		if (!settings && $.isPlainObject(items))
		{
			// (settings)
			settings = items;
			items = null;
		}

		settings = $.extend({}, Garnish.DragSort.defaults, settings);
		this.base(items, settings);
	},

	/**
	 * Creates the insertion element.
	 */
	createInsertion: function()
	{
		if (this.settings.insertion)
		{
			if (typeof this.settings.insertion == 'function')
			{
				return $(this.settings.insertion(this.$draggee));
			}
			else
			{
				return $(this.settings.insertion);
			}
		}
	},

	/**
	 * Returns the helper’s target X position
	 */
	getHelperTargetX: function()
	{
		if (this.settings.magnetStrength != 1)
		{
			this.getHelperTargetX._draggeeOffsetX = this.$draggee.offset().left - this.targetItemMouseOffsetX;
			return this.getHelperTargetX._draggeeOffsetX + ((this.mouseX - this.getHelperTargetX._draggeeOffsetX) / this.settings.magnetStrength);
		}
		else
		{
			return this.mouseX;
		}
	},

	/**
	 * Returns the helper’s target Y position
	 */
	getHelperTargetY: function()
	{
		if (this.settings.magnetStrength != 1)
		{
			this.getHelperTargetY._draggeeOffsetY = this.$draggee.offset().top - this.targetItemMouseOffsetY;
			return this.getHelperTargetY._draggeeOffsetY + ((this.mouseY - this.getHelperTargetY._draggeeOffsetY) / this.settings.magnetStrength);
		}
		else
		{
			return this.mouseY;
		}
	},

	// Events
	// -------------------------------------------------------------------------

	/**
	 * On Drag Start
	 */
	onDragStart: function()
	{
		this.base();

		this.$insertion = this.createInsertion();
		this._placeInsertionWithDraggee();

		this.closestItem = null;
		this._recordPositions();

		//  Get the closest container that has a height
		if (this.settings.container)
		{
			this.$heightedContainer = $(this.settings.container);

			while (! this.$heightedContainer.height())
			{
				this.$heightedContainer = this.$heightedContainer.parent();
			}
		}

		this.startDraggeeIndex = $.inArray(this.$draggee[0], this.$items);
	},

	/**
	 * On Drag
	 */
	onDrag: function()
	{
		// If there's a container set, make sure that we're hovering over it
		if (this.$heightedContainer && !Garnish.hitTest(this.mouseX, this.mouseY, this.$heightedContainer))
		{
			if (this.closestItem)
			{
				this.closestItem = null;
				this._removeInsertion();
			}
		}
		else
		{
			// Is there a new closest item?
			if (
				this.closestItem !== (this.closestItem = this._getClosestItem()) &&
				this.closestItem !== null
			)
			{
				this._updateInsertion();
			}
		}

		this.base();
	},

	/**
	 * On Drag Stop
	 */
	onDragStop: function()
	{
		this._removeInsertion();

		// Return the helpers to the draggees
		this.returnHelpersToDraggees();

		this.base();

		// Has the item actually moved?
		this.$items = $().add(this.$items);
		var newDraggeeIndex = $.inArray(this.$draggee[0], this.$items);

		if (this.startDraggeeIndex != newDraggeeIndex)
		{
			this.onSortChange();
		}
	},

	/**
	 * On Insertion Point Change event
	 */
	onInsertionPointChange: function()
	{
		Garnish.requestAnimationFrame($.proxy(function()
		{
			this.trigger('insertionPointChange');
			this.settings.onInsertionPointChange();
		}, this));
	},

	/**
	 * On Sort Change event
	 */
	onSortChange: function()
	{
		Garnish.requestAnimationFrame($.proxy(function()
		{
			this.trigger('sortChange');
			this.settings.onSortChange();
		}, this));
	},

	// Private methods
	// =========================================================================

	/**
	 * Sets the item midpoints up front so we don't have to keep checking on every mouse move
	 */
	_recordPositions: function()
	{
		for (this._recordPositions._i = 0; this._recordPositions._i < this.totalOtherItems; this._recordPositions._i++)
		{
			this._recordPosition($(this.otherItems[this._recordPositions._i]));
		}

		if (!this.settings.removeDraggee)
		{
			this._recordPosition(this.$draggee);
		}
		else if (this.insertionVisible)
		{
			this._recordPosition(this.$insertion);
		}
	},

	/**
	 * Set the midpoint on an item.
	 */
	_recordPosition: function($item)
	{
		$item.data('offset', $item.offset());
		$item.data('midpointX', $item.data('offset').left + $item.outerWidth() / 2);
		$item.data('midpointY', $item.data('offset').top + $item.outerHeight() / 2);
	},

	/**
	 * Returns the closest item to the cursor.
	 */
	_getClosestItem: function()
	{
		this._getClosestItem._closestItem = null;

		if (!this.settings.removeDraggee)
		{
			this._testForClosestItem(this.$draggee[0]);
		}
		else if (this.insertionVisible)
		{
			this._testForClosestItem(this.$insertion[0]);
		}

		for (this._getClosestItem._i = 0; this._getClosestItem._i < this.totalOtherItems; this._getClosestItem._i++)
		{
			this._testForClosestItem(this.otherItems[this._getClosestItem._i]);
		}

		// Ignore if it's the draggee or insertion
		if (
			this._getClosestItem._closestItem != this.$draggee[0] &&
			(!this.insertionVisible || this._getClosestItem._closestItem != this.$insertion[0])
		)
		{
			return this._getClosestItem._closestItem;
		}
		else
		{
			return null;
		}
	},

	_testForClosestItem: function(item)
	{
		this._testForClosestItem._$item = $(item);

		this._testForClosestItem._mouseDist = Garnish.getDist(
			this._testForClosestItem._$item.data('midpointX'),
			this._testForClosestItem._$item.data('midpointY'),
			this.draggeeVirtualMidpointX,
			this.draggeeVirtualMidpointY
		);

		if (
			this._getClosestItem._closestItem === null ||
			this._testForClosestItem._mouseDist < this._getClosestItem._closestItemMouseDist
		)
		{
			this._getClosestItem._closestItem          = this._testForClosestItem._$item[0];
			this._getClosestItem._closestItemMouseDist = this._testForClosestItem._mouseDist;
		}
	},

	/**
	 * Updates the position of the insertion point.
	 */
	_updateInsertion: function()
	{
		if (this.closestItem)
		{
			// Going down?
			if (this.$draggee.index() < $(this.closestItem).index())
			{
				this.$draggee.insertAfter(this.closestItem);
			}
			else
			{
				this.$draggee.insertBefore(this.closestItem);
			}

			this._placeInsertionWithDraggee();
		}

		// Now that things have shifted around we need to set the new midpoints
		this._recordPositions();

		this.onInsertionPointChange();
	},

	_placeInsertionWithDraggee: function()
	{
		if (this.$insertion)
		{
			this.$insertion.insertBefore(this.$draggee.first());
			this.insertionVisible = true;
		}
	},

	/**
	 * Removes the insertion, if it's visible.
	 */
	_removeInsertion: function()
	{
		if (this.insertionVisible)
		{
			this.$insertion.remove();
			this.insertionVisible = false;
		}
	}
},

// Static Properties
// =============================================================================

{
	defaults: {
		container: null,
		insertion: null,
		magnetStrength: 1,
		onInsertionPointChange: $.noop,
		onSortChange: $.noop
	}
});
<|endoftext|>


<commit_before>import { Trans } from "@lingui/macro";
import mixin from "reactjs-mixin";
import { Link } from "react-router";
/* eslint-disable no-unused-vars */
import React from "react";
/* eslint-enable no-unused-vars */
import { StoreMixin } from "mesosphere-shared-reactjs";

import AlertPanel from "../../components/AlertPanel";
import AlertPanelHeader from "../../components/AlertPanelHeader";
import Breadcrumb from "../../components/Breadcrumb";
import BreadcrumbTextContent from "../../components/BreadcrumbTextContent";
import FilterBar from "../../components/FilterBar";
import FilterHeadline from "../../components/FilterHeadline";
import FilterInputText from "../../components/FilterInputText";
import Loader from "../../components/Loader";
import Page from "../../components/Page";
import RequestErrorMsg from "../../components/RequestErrorMsg";
import VirtualNetworksStore from "../../stores/VirtualNetworksStore";
import VirtualNetworksTable from "./VirtualNetworksTable";

const NetworksBreadcrumbs = () => {
  const crumbs = [
    <Breadcrumb key={0} title="Networks">
      <BreadcrumbTextContent>
        <Link to="/networking/networks">
          <Trans render="span">Networks</Trans>
        </Link>
      </BreadcrumbTextContent>
    </Breadcrumb>
  ];

  return <Page.Header.Breadcrumbs iconID="networking" breadcrumbs={crumbs} />;
};

const METHODS_TO_BIND = [
  "handleSearchStringChange",
  "onVirtualNetworksStoreError",
  "onVirtualNetworksStoreSuccess",
  "resetFilter"
];

class VirtualNetworksTabContent extends mixin(StoreMixin) {
  constructor() {
    super(...arguments);

    this.state = {
      receivedVirtualNetworks: false,
      searchString: "",
      errorCount: 0
    };

    this.store_listeners = [
      {
        name: "virtualNetworks",
        events: ["success", "error"],
        suppressUpdate: true
      }
    ];

    METHODS_TO_BIND.forEach(method => {
      this[method] = this[method].bind(this);
    });
  }

  handleSearchStringChange(searchString = "") {
    this.setState({ searchString });
  }

  onVirtualNetworksStoreError() {
    const errorCount = this.state.errorCount + 1;
    this.setState({ errorCount });
  }

  onVirtualNetworksStoreSuccess() {
    this.setState({ receivedVirtualNetworks: true, errorCount: 0 });
  }

  isLoading() {
    return !this.state.receivedVirtualNetworks;
  }

  resetFilter() {
    this.setState({ searchString: "" });
  }

  getEmptyScreen() {
    return (
      <AlertPanel>
        <AlertPanelHeader>
          <Trans render="span">No virtual networks detected</Trans>
        </AlertPanelHeader>
        <Trans render="p" className="flush">
          There a currently no other virtual networks found on your datacenter.
          Virtual networks are configured during setup of your DC/OS cluster.
        </Trans>
      </AlertPanel>
    );
  }

  getErrorScreen() {
    return <RequestErrorMsg />;
  }

  getFilteredOverlayList(overlayList, searchString = "") {
    if (searchString === "") {
      return overlayList;
    }

    return overlayList.filterItems(function(overlay) {
      return (
        (overlay.getName() && overlay.getName().includes(searchString)) ||
        (overlay.getSubnet() && overlay.getSubnet().includes(searchString)) ||
        (overlay.getSubnet6() && overlay.getSubnet6().includes(searchString))
      );
    });
  }

  getLoadingScreen() {
    return <Loader />;
  }

  getContent() {
    const { errorCount, searchString } = this.state;
    if (errorCount >= 3) {
      return this.getErrorScreen();
    }

    if (this.isLoading()) {
      return this.getLoadingScreen();
    }

    const overlayList = VirtualNetworksStore.getOverlays();
    const filteredOverlayList = this.getFilteredOverlayList(
      overlayList,
      searchString
    );
    if (filteredOverlayList.length === 0) {
      return this.getEmptyScreen();
    }

    return (

        <FilterHeadline
          onReset={this.resetFilter}
          name="Network"
          currentLength={filteredOverlayList.getItems().length}
          totalLength={overlayList.getItems().length}
        />
        <FilterBar>
          <FilterInputText
            searchString={searchString}
            handleFilterChange={this.handleSearchStringChange}
          />
        </FilterBar>
        <VirtualNetworksTable overlays={filteredOverlayList} />

    );
  }

  render() {
    return (
      <Page>
        <Page.Header breadcrumbs={<NetworksBreadcrumbs />} />
        {this.getContent()}
        {this.props.children}
      </Page>
    );
  }
}

VirtualNetworksTabContent.routeConfig = {
  label: "Networks",
  matches: /^\/networking\/networks/
};

module.exports = VirtualNetworksTabContent;
<commit_msg>feat(VirtualNetworksTab): handle marked and pretranslated strings<commit_after>import { Trans, t } from "@lingui/macro";
import { withI18n } from "@lingui/react";
import mixin from "reactjs-mixin";
import { Link } from "react-router";
/* eslint-disable no-unused-vars */
import React from "react";
/* eslint-enable no-unused-vars */
import { StoreMixin } from "mesosphere-shared-reactjs";

import AlertPanel from "../../components/AlertPanel";
import AlertPanelHeader from "../../components/AlertPanelHeader";
import Breadcrumb from "../../components/Breadcrumb";
import BreadcrumbTextContent from "../../components/BreadcrumbTextContent";
import FilterBar from "../../components/FilterBar";
import FilterHeadline from "../../components/FilterHeadline";
import FilterInputText from "../../components/FilterInputText";
import Loader from "../../components/Loader";
import Page from "../../components/Page";
import RequestErrorMsg from "../../components/RequestErrorMsg";
import VirtualNetworksStore from "../../stores/VirtualNetworksStore";
import VirtualNetworksTable from "./VirtualNetworksTable";

const NetworksBreadcrumbs = () => {
  const crumbs = [
    <Breadcrumb key={0} title="Networks">
      <BreadcrumbTextContent>
        <Trans render={<Link to="/networking/networks" />}>Networks</Trans>
      </BreadcrumbTextContent>
    </Breadcrumb>
  ];

  return <Page.Header.Breadcrumbs iconID="networking" breadcrumbs={crumbs} />;
};

const METHODS_TO_BIND = [
  "handleSearchStringChange",
  "onVirtualNetworksStoreError",
  "onVirtualNetworksStoreSuccess",
  "resetFilter"
];

class VirtualNetworksTabContent extends mixin(StoreMixin) {
  constructor() {
    super(...arguments);

    this.state = {
      receivedVirtualNetworks: false,
      searchString: "",
      errorCount: 0
    };

    this.store_listeners = [
      {
        name: "virtualNetworks",
        events: ["success", "error"],
        suppressUpdate: true
      }
    ];

    METHODS_TO_BIND.forEach(method => {
      this[method] = this[method].bind(this);
    });
  }

  handleSearchStringChange(searchString = "") {
    this.setState({ searchString });
  }

  onVirtualNetworksStoreError() {
    const errorCount = this.state.errorCount + 1;
    this.setState({ errorCount });
  }

  onVirtualNetworksStoreSuccess() {
    this.setState({ receivedVirtualNetworks: true, errorCount: 0 });
  }

  isLoading() {
    return !this.state.receivedVirtualNetworks;
  }

  resetFilter() {
    this.setState({ searchString: "" });
  }

  getEmptyScreen() {
    return (
      <AlertPanel>
        <AlertPanelHeader>
          <Trans render="span">No virtual networks detected</Trans>
        </AlertPanelHeader>
        <Trans render="p" className="flush">
          There a currently no other virtual networks found on your datacenter.
          Virtual networks are configured during setup of your DC/OS cluster.
        </Trans>
      </AlertPanel>
    );
  }

  getErrorScreen() {
    return <RequestErrorMsg />;
  }

  getFilteredOverlayList(overlayList, searchString = "") {
    if (searchString === "") {
      return overlayList;
    }

    return overlayList.filterItems(function(overlay) {
      return (
        (overlay.getName() && overlay.getName().includes(searchString)) ||
        (overlay.getSubnet() && overlay.getSubnet().includes(searchString)) ||
        (overlay.getSubnet6() && overlay.getSubnet6().includes(searchString))
      );
    });
  }

  getLoadingScreen() {
    return <Loader />;
  }

  getContent() {
    const { errorCount, searchString } = this.state;
    if (errorCount >= 3) {
      return this.getErrorScreen();
    }

    if (this.isLoading()) {
      return this.getLoadingScreen();
    }

    const overlayList = VirtualNetworksStore.getOverlays();
    const filteredOverlayList = this.getFilteredOverlayList(
      overlayList,
      searchString
    );
    if (filteredOverlayList.length === 0) {
      return this.getEmptyScreen();
    }

    return (

        {/* L10NTODO: Pluralize
        We should pluralize FilterHeadline name here using lingui macro instead of
        doing it manually in FilterHeadline */}
        <FilterHeadline
          onReset={this.resetFilter}
          name={this.props.i18n._(t`Network`)}
          currentLength={filteredOverlayList.getItems().length}
          totalLength={overlayList.getItems().length}
        />
        <FilterBar>
          <FilterInputText
            searchString={searchString}
            handleFilterChange={this.handleSearchStringChange}
          />
        </FilterBar>
        <VirtualNetworksTable overlays={filteredOverlayList} />

    );
  }

  render() {
    return (
      <Page>
        <Page.Header breadcrumbs={<NetworksBreadcrumbs />} />
        {this.getContent()}
        {this.props.children}
      </Page>
    );
  }
}

VirtualNetworksTabContent.routeConfig = {
  label: "Networks",
  matches: /^\/networking\/networks/
};

module.exports = withI18n()(VirtualNetworksTabContent);
<|endoftext|>


<commit_before>import { timeout, calcInterval, getFormattedDate, getCookie } from "../../utils/common"
import BLOCKCHAIN_INFO from "../../../../env"
import { multiplyOfTwoNumber } from "../../utils/converter"
import { LIMIT_ORDER_CONFIG } from "../../services/constants";
import _ from "lodash";

const MAX_REQUEST_TIMEOUT = 3000

const keyMapping = {
    "id": "id",
    "src": "source",
    "dst": "dest",
    "src_amount": "src_amount",
    "min_rate": "min_rate",
    "addr": "user_address",
    "nonce": "nonce",
    "fee": "fee",
    "status": "status",
    "created_at": "created_at",
    "updated_at": "updated_at",
    "tx_hash": "tx_hash",
    "msg": "msg"
}

function validateOrder(order) {
    if (typeof order.fee !== "number" || typeof order.src_amount !== "number" || typeof order.min_rate !== "number"
    || typeof order.created_at !== "number" || typeof order.updated_at !== "number") return false;
    if (order.fee < 0 || order.fee > 0.5) return false;

    return true;
}

function filterOrder(result) {
    var orderList = []
    var fields = result.fields
    var orders = result.orders
    for (var i = 0; i < orders.length; i++) {
        var order = {}
        for (var j = 0; j < fields.length; j++) {
            var field = keyMapping[fields[j]] ? keyMapping[fields[j]] : fields[j]
            order[field] = orders[i][j]
        }
        if (validateOrder(order)) {
            orderList.push(order)
        }
    }
    const results = orderList.map(item => {
        return {
            ...item,
            user_address: item.user_address.toLowerCase()
        }
    });
    return results;
}

export function getOrders() {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch('/api/orders'))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    var orderList = filterOrder(result)
                    resolve(orderList)
                } else {
                    rejected(new Error("Cannot get orders"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot get user orders: ${err.toString}`))
            })
    })
}

export function submitOrder(order) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch('/api/orders', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(order)
        }))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    var fields = result.fields
                    var order = result.order
                    var orderObj = {}
                    for (var j = 0; j < fields.length; j++) {
                        var field = keyMapping[fields[j]] ? keyMapping[fields[j]] : fields[j]
                        orderObj[field] = order[j]
                    }
                    resolve(orderObj)
                } else {
                    rejected(result.message)
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot submit order: ${err.toString()}`))
            })
    })
}

export function cancelOrder(order) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(`/api/orders/${order.id}/cancel`, {
            method: 'PUT',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            }
        }))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    resolve(result.cancelled)
                } else {
                    rejected(new Error("Cannot cancel order"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot cancel order: ${err.toString()}`))
            })
    })
}

export function getNonce(userAddr, source, dest) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(`/api/orders/nonce?addr=${userAddr}&src=${source}&dst=${dest}`))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    resolve(result.nonce)
                } else {
                    rejected(new Error("Cannot get nonce"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot get user nonce: ${err.toString()}`))
            })
    })
}

export function getFee(userAddr, src, dest, src_amount, dst_amount) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(`/api/orders/fee?user_addr=${userAddr}&src=${src}&dst=${dest}&src_amount=${src_amount}&dst_amount=${dst_amount}`))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                  if (validateGetFeeResult(result)) {
                    resolve(result);
                  } else {
                    rejected("There is something wrong with rate API")
                  }
                } else {
                    rejected(result.message)
                }

            })
            .catch((err) => {
                rejected(new Error(`Cannot get user fee: ${err.toString()}`))
            })
    })
}

function validateGetFeeResult(result) {
  let nonDiscountFee = result.non_discounted_fee;
  let fee = result.fee;
  let discountPercent = result.discount_percent;

  if (typeof nonDiscountFee !== 'number' || typeof fee !== 'number' || typeof discountPercent !== 'number' || fee > nonDiscountFee) {
    return false
  }

  return true
}

export function getOrdersByIdArr(idArr) {
    return new Promise((resolve, rejected) => {
        if (idArr.length === 0) {
            resolve([])
            return
        }

        if (idArr.length > 50) {
            getOrders()
            .then(response => {
                const filterArr = response.filter(item => {
                    return idArr.indexOf(item) !== -1;
                });
                resolve(filterArr)
            })
            .catch(err => {
                rejected(new Error(`Cannot get user orders: ${err.toString()}`));
            })
        } else {
            // get path
            var path = "/api/orders?"
            for (var i = 0; i < idArr.length; i++) {
                if (i === 0) {
                    path += "ids[]=" + idArr[i]
                } else {
                    path += "&ids[]=" + idArr[i]
                }

            }
            timeout(MAX_REQUEST_TIMEOUT, fetch(path))
                .then((response) => {
                    return response.json()
                }).then((result) => {
                    if (result.success) {
                        var orderList = filterOrder(result)
                        resolve(orderList)
                    } else {
                        rejected(new Error("Cannot get orders by ids"));
                    }
                })
                .catch((err) => {
                    rejected(new Error(`Cannot get user orders: ${err.toString()}`))
                })
        }
    })
}

export function isEligibleAddress(addr) {
    return new Promise((resolve, reject) => {
        var path = `/api/orders/eligible_address?user_addr=${addr}`;
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then((response) => {
                return response.json();
            })
            .then((result) => {
                if (result.success) {
                    const { eligible_address } = result;
                    resolve(eligible_address ? true : false);
                } else {
                    reject(new Error("Cannot validate eligible address"));
                }
            }).catch((err) => {
                reject(new Error(`Cannot check eligible address: ${err.toString()}`));
            });
    });
}

export function getUserStats() {
    return new Promise((resolve, reject) => {
        const path = "/api/orders/user_stats";
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then(response => {
                return response.json();
            }).then(result => {
                if (result.success) {
                    const pairs = result.pairs.map(item => item.replace("/", "-"));  // pair array

                    resolve({
                        pairs,
                        addresses: result.addresses,
                        orderStats: result.order_stats
                    });
                } else {
                    reject(new Error("Not authenticated"));
                }
            }).catch(err => {
                reject(new Error(`Cannot get user stats: ${err.toString()}`));
            });
    })
}

export function getPendingBalances(address) {
    return new Promise((resolve, reject) => {
        const path = `/api/orders/pending_balances?user_addr=${address}`;
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then(response => {
                return response.json();
            }).then(result => {
                if (result.success) {
                    resolve(result);
                } else {
                    reject(new Error("Cannot get pending balance"));
                }
            }).catch(err => {
                reject(new Error(`Cannot get pending balance: ${err.toString()}`));
            });
    });
}

export function getRelatedOrders(sourceToken, destToken, minRate, address) {
    return new Promise((resolve, reject) => {
        const path = `/api/orders/related_orders?src=${sourceToken}&dst=${destToken}&min_rate=${minRate}&user_addr=${address}`;
        timeout(MAX_REQUEST_TIMEOUT, fetch(path)).then(response => {
            return response.json();
        }).then(result => {
            if (result.success) {
                const orders = filterOrder(result);
                resolve(orders);
            } else {
                reject(new Error("Cannot get related orders"));
            }
        }).catch(err => {
            reject(new Error(`Cannot get related orders: ${err.toString()}`));
        })
    })
}

function sortOrders(orders) {
    const results = _.sortBy(orders, item => {
        if (item.status === LIMIT_ORDER_CONFIG.status.IN_PROGRESS) {
            return 0;
        } else if (item.status === LIMIT_ORDER_CONFIG.status.OPEN) {
            return 1;
        } else {
            return 2;
        }
    }, ["asc"]);

    return results;
}

export function getOrdersByFilter(address = null, pair = null, status = null, time = null, dateSort = "desc", pageIndex = 1, pageSize = LIMIT_ORDER_CONFIG.pageSize) {
    let path = `/api/orders?page_index=${pageIndex}&page_size=${pageSize}`;

    if (address) {
        const params = address.reduce((sum, item) => {
            return sum + `&user_address[]=${item}`;
        }, "");
        path += params;
    }

    if (pair) {
        const params = pair.reduce((sum, item) => {
            const pairParam = item.replace("-", "_");
            return sum + `&pairs[]=${pairParam}`;
        }, "");
        path += params;
    }

    if (status) {
        const params = status.reduce((sum, item) => {
            return sum + `&status[]=${item}`;
        }, "");
        path += params;
    }

    if (time) {
        const second = calcInterval(time);
        path += `&from=${second}`;
    }

    if (dateSort) {
        path += `&sort=${dateSort}`;
    }

    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    const orderList = filterOrder(result);
                    resolve({
                        orders: orderList,
                        itemsCount: result.paging_info.items_count,
                        pageCount: result.paging_info.page_count,
                        pageIndex: result.paging_info.page_index,
                        pageSize: result.paging_info.page_size
                    });
                } else {
                    rejected(new Error("Cannot get orders by filter"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot get user orders: ${err.toString()}`))
            })
    })
}

export function getModeLimitOrder() {
    const totalOrders = getCookie("order_count");
    return totalOrders <= LIMIT_ORDER_CONFIG.pageSize ? "client" : "server";
}
<commit_msg>Remove query by time<commit_after>import { timeout, calcInterval, getFormattedDate, getCookie } from "../../utils/common"
import BLOCKCHAIN_INFO from "../../../../env"
import { multiplyOfTwoNumber } from "../../utils/converter"
import { LIMIT_ORDER_CONFIG } from "../../services/constants";
import _ from "lodash";

const MAX_REQUEST_TIMEOUT = 3000

const keyMapping = {
    "id": "id",
    "src": "source",
    "dst": "dest",
    "src_amount": "src_amount",
    "min_rate": "min_rate",
    "addr": "user_address",
    "nonce": "nonce",
    "fee": "fee",
    "status": "status",
    "created_at": "created_at",
    "updated_at": "updated_at",
    "tx_hash": "tx_hash",
    "msg": "msg"
}

function validateOrder(order) {
    if (typeof order.fee !== "number" || typeof order.src_amount !== "number" || typeof order.min_rate !== "number"
    || typeof order.created_at !== "number" || typeof order.updated_at !== "number") return false;
    if (order.fee < 0 || order.fee > 0.5) return false;

    return true;
}

function filterOrder(result) {
    var orderList = []
    var fields = result.fields
    var orders = result.orders
    for (var i = 0; i < orders.length; i++) {
        var order = {}
        for (var j = 0; j < fields.length; j++) {
            var field = keyMapping[fields[j]] ? keyMapping[fields[j]] : fields[j]
            order[field] = orders[i][j]
        }
        if (validateOrder(order)) {
            orderList.push(order)
        }
    }
    const results = orderList.map(item => {
        return {
            ...item,
            user_address: item.user_address.toLowerCase()
        }
    });
    return results;
}

export function getOrders() {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch('/api/orders'))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    var orderList = filterOrder(result)
                    resolve(orderList)
                } else {
                    rejected(new Error("Cannot get orders"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot get user orders: ${err.toString}`))
            })
    })
}

export function submitOrder(order) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch('/api/orders', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(order)
        }))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    var fields = result.fields
                    var order = result.order
                    var orderObj = {}
                    for (var j = 0; j < fields.length; j++) {
                        var field = keyMapping[fields[j]] ? keyMapping[fields[j]] : fields[j]
                        orderObj[field] = order[j]
                    }
                    resolve(orderObj)
                } else {
                    rejected(result.message)
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot submit order: ${err.toString()}`))
            })
    })
}

export function cancelOrder(order) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(`/api/orders/${order.id}/cancel`, {
            method: 'PUT',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            }
        }))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    resolve(result.cancelled)
                } else {
                    rejected(new Error("Cannot cancel order"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot cancel order: ${err.toString()}`))
            })
    })
}

export function getNonce(userAddr, source, dest) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(`/api/orders/nonce?addr=${userAddr}&src=${source}&dst=${dest}`))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    resolve(result.nonce)
                } else {
                    rejected(new Error("Cannot get nonce"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot get user nonce: ${err.toString()}`))
            })
    })
}

export function getFee(userAddr, src, dest, src_amount, dst_amount) {
    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(`/api/orders/fee?user_addr=${userAddr}&src=${src}&dst=${dest}&src_amount=${src_amount}&dst_amount=${dst_amount}`))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                  if (validateGetFeeResult(result)) {
                    resolve(result);
                  } else {
                    rejected("There is something wrong with rate API")
                  }
                } else {
                    rejected(result.message)
                }

            })
            .catch((err) => {
                rejected(new Error(`Cannot get user fee: ${err.toString()}`))
            })
    })
}

function validateGetFeeResult(result) {
  let nonDiscountFee = result.non_discounted_fee;
  let fee = result.fee;
  let discountPercent = result.discount_percent;

  if (typeof nonDiscountFee !== 'number' || typeof fee !== 'number' || typeof discountPercent !== 'number' || fee > nonDiscountFee) {
    return false
  }

  return true
}

export function getOrdersByIdArr(idArr) {
    return new Promise((resolve, rejected) => {
        if (idArr.length === 0) {
            resolve([])
            return
        }

        if (idArr.length > 50) {
            getOrders()
            .then(response => {
                const filterArr = response.filter(item => {
                    return idArr.indexOf(item) !== -1;
                });
                resolve(filterArr)
            })
            .catch(err => {
                rejected(new Error(`Cannot get user orders: ${err.toString()}`));
            })
        } else {
            // get path
            var path = "/api/orders?"
            for (var i = 0; i < idArr.length; i++) {
                if (i === 0) {
                    path += "ids[]=" + idArr[i]
                } else {
                    path += "&ids[]=" + idArr[i]
                }

            }
            timeout(MAX_REQUEST_TIMEOUT, fetch(path))
                .then((response) => {
                    return response.json()
                }).then((result) => {
                    if (result.success) {
                        var orderList = filterOrder(result)
                        resolve(orderList)
                    } else {
                        rejected(new Error("Cannot get orders by ids"));
                    }
                })
                .catch((err) => {
                    rejected(new Error(`Cannot get user orders: ${err.toString()}`))
                })
        }
    })
}

export function isEligibleAddress(addr) {
    return new Promise((resolve, reject) => {
        var path = `/api/orders/eligible_address?user_addr=${addr}`;
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then((response) => {
                return response.json();
            })
            .then((result) => {
                if (result.success) {
                    const { eligible_address } = result;
                    resolve(eligible_address ? true : false);
                } else {
                    reject(new Error("Cannot validate eligible address"));
                }
            }).catch((err) => {
                reject(new Error(`Cannot check eligible address: ${err.toString()}`));
            });
    });
}

export function getUserStats() {
    return new Promise((resolve, reject) => {
        const path = "/api/orders/user_stats";
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then(response => {
                return response.json();
            }).then(result => {
                if (result.success) {
                    const pairs = result.pairs.map(item => item.replace("/", "-"));  // pair array

                    resolve({
                        pairs,
                        addresses: result.addresses,
                        orderStats: result.order_stats
                    });
                } else {
                    reject(new Error("Not authenticated"));
                }
            }).catch(err => {
                reject(new Error(`Cannot get user stats: ${err.toString()}`));
            });
    })
}

export function getPendingBalances(address) {
    return new Promise((resolve, reject) => {
        const path = `/api/orders/pending_balances?user_addr=${address}`;
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then(response => {
                return response.json();
            }).then(result => {
                if (result.success) {
                    resolve(result);
                } else {
                    reject(new Error("Cannot get pending balance"));
                }
            }).catch(err => {
                reject(new Error(`Cannot get pending balance: ${err.toString()}`));
            });
    });
}

export function getRelatedOrders(sourceToken, destToken, minRate, address) {
    return new Promise((resolve, reject) => {
        const path = `/api/orders/related_orders?src=${sourceToken}&dst=${destToken}&min_rate=${minRate}&user_addr=${address}`;
        timeout(MAX_REQUEST_TIMEOUT, fetch(path)).then(response => {
            return response.json();
        }).then(result => {
            if (result.success) {
                const orders = filterOrder(result);
                resolve(orders);
            } else {
                reject(new Error("Cannot get related orders"));
            }
        }).catch(err => {
            reject(new Error(`Cannot get related orders: ${err.toString()}`));
        })
    })
}

function sortOrders(orders) {
    const results = _.sortBy(orders, item => {
        if (item.status === LIMIT_ORDER_CONFIG.status.IN_PROGRESS) {
            return 0;
        } else if (item.status === LIMIT_ORDER_CONFIG.status.OPEN) {
            return 1;
        } else {
            return 2;
        }
    }, ["asc"]);

    return results;
}

export function getOrdersByFilter(address = null, pair = null, status = null, time = null, dateSort = "desc", pageIndex = 1, pageSize = LIMIT_ORDER_CONFIG.pageSize) {
    let path = `/api/orders?page_index=${pageIndex}&page_size=${pageSize}`;

    if (address) {
        const params = address.reduce((sum, item) => {
            return sum + `&user_address[]=${item}`;
        }, "");
        path += params;
    }

    if (pair) {
        const params = pair.reduce((sum, item) => {
            const pairParam = item.replace("-", "_");
            return sum + `&pairs[]=${pairParam}`;
        }, "");
        path += params;
    }

    if (status) {
        const params = status.reduce((sum, item) => {
            return sum + `&status[]=${item}`;
        }, "");
        path += params;
    }

    // if (time) {
    //     const second = calcInterval(time);
    //     path += `&from=${second}`;
    // }

    if (dateSort) {
        path += `&sort=${dateSort}`;
    }

    return new Promise((resolve, rejected) => {
        timeout(MAX_REQUEST_TIMEOUT, fetch(path))
            .then((response) => {
                return response.json()
            }).then((result) => {
                if (result.success) {
                    const orderList = filterOrder(result);
                    resolve({
                        orders: orderList,
                        itemsCount: result.paging_info.items_count,
                        pageCount: result.paging_info.page_count,
                        pageIndex: result.paging_info.page_index,
                        pageSize: result.paging_info.page_size
                    });
                } else {
                    rejected(new Error("Cannot get orders by filter"));
                }
            })
            .catch((err) => {
                rejected(new Error(`Cannot get user orders: ${err.toString()}`))
            })
    })
}

export function getModeLimitOrder() {
    const totalOrders = getCookie("order_count");
    return totalOrders <= LIMIT_ORDER_CONFIG.pageSize ? "client" : "server";
}
<|endoftext|>


<commit_before>'use strict';

angular
	.module('groups', [])
	.controller('GroupEditController', ['$scope', '$state', '$modal', 'Authentication', 'NgTableParams',  '_', 'ProjectGroupModel', 'project', 'group', 'mode', function GroupEditController($scope, $state, $modal, Authentication, NgTableParams,  _, ProjectGroupModel, project, group, mode) {
		$scope.project = project;
		$scope.authentication = Authentication;
		$scope.mode = mode;
		// disable the delete button if user doesn't have permission to delete
		$scope.canDelete = $scope.mode === 'edit' && group.userCan.delete;

		var self = this;
		self.group = group;
		self.group.project = $scope.project._id;

		$scope.members = angular.copy(self.group.members) || [];
		$scope.existingRecipients = [];
		$scope.tableParams = new NgTableParams ({count:10}, {dataset: $scope.members});

		var populateGroup = function() {
			self.group.members = angular.copy($scope.members);
		};

		$scope.originalData = JSON.stringify(self.group); // used to capture unsaved changes when we leave this route/screen
		$scope.allowTransition = false;

		var $locationChangeStartUnbind = $scope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
			// no check
			if (mode !== 'detail' && !$scope.allowTransition) {

				populateGroup();
				// do the check...
				if ($scope.originalData !== JSON.stringify(self.group)) {
					// something changed...
					// do NOT allow the state change yet.
					event.preventDefault();

					$modal.open({
						animation: true,
						templateUrl: 'modules/vcs/client/views/vc-modal-confirm-cancel.html',
						controller: function($scope, $state, $modalInstance) {
							var self = this;
							self.ok = function() {
								$modalInstance.close();
							};
							self.cancel = function() {
								$modalInstance.dismiss('cancel');
							};
						},
						controllerAs: 'self',
						scope: $scope,
						size: 'lg'
					}).result.then(function (res) {
						$scope.allowTransition = true;
						$state.go(toState);
					}, function (err) {
						// cancelled...
					});

				} else {
					//DO NOTHING THERE IS NO CHANGES IN THE FORM
					//console.log('data NOT changed, let my data go!');
				}
			}
		});

		$scope.$on('$destroy', function () {
			window.onbeforeunload = null;
			$locationChangeStartUnbind();
		});

		var goToList = function() {
			$state.transitionTo('p.group.list', {projectid: $scope.project.code}, {
				reload: true, inherit: false, notify: true
			});
		};

		var reloadEdit = function() {
			// want to reload this screen, do not catch unsaved changes (we are probably in the middle of saving).
			$scope.allowTransition = true;
			$state.reload();
		};

		var goToEdit = function(model) {
			// want to reload this screen, do not catch unsaved changes (we are probably in the middle of saving).
			$scope.allowTransition = true;
			$state.transitionTo('p.group.edit', {projectid: $scope.project.code, groupId: model._id }, {
				reload: true, inherit: false, notify: true
			});
		};

		var goNowhere = function() {
			// do nothing...
		};

		$scope.$watch(function(scope) { return scope.existingRecipients; },
			function(data) {
				if (data && data.length > 0) {
					_.forEach(data, function(user) {
						var item =  _.find($scope.members, function(o) { return o.email === user.email; });
						if (!item) {
							$scope.members.push(user);
						}
					});
					$scope.existingRecipients = [];
					$scope.tableParams = new NgTableParams ({count:10}, {dataset: $scope.members});
				}
			}
		);

		$scope.removeMember = function(email) {
			var item =  _.find($scope.members, function(o) { return o.email === email; });
			if (item) {
				_.remove($scope.members, function(o) { return o.email === email; });
				$scope.tableParams = new NgTableParams ({count:10}, {dataset: $scope.members});
			}
		};

		$scope.showError = function(msg, errorList, transitionCallback, title) {
			var modalDocView = $modal.open({
				animation: true,
				templateUrl: 'modules/vcs/client/views/vc-modal-error.html',
				controller: function($scope, $state, $modalInstance, _) {
					var self = this;
					self.title = title || 'An error has occurred';
					self.msg = msg;
					self.errors = errorList;
					self.ok = function() {
						$modalInstance.close();
					};
					self.cancel = function() {
						$modalInstance.dismiss('cancel');
					};
				},
				controllerAs: 'self',
				scope: $scope,
				size: 'md',
				windowClass: 'modal-alert',
				backdropClass: 'modal-alert-backdrop'
			});
			// do not care how this modal is closed, just go to the desired location...
			modalDocView.result.then(function (res) {transitionCallback(); }, function (err) { transitionCallback(); });
		};

		$scope.showSuccess = function(msg, transitionCallback, title) {
			var modalDocView = $modal.open({
				animation: true,
				templateUrl: 'modules/vcs/client/views/vc-modal-success.html',
				controller: function($scope, $state, $modalInstance, _) {
					var self = this;
					self.title = title || 'Success';
					self.msg = msg;
					self.ok = function() {
						$modalInstance.close();
					};
					self.cancel = function() {
						$modalInstance.dismiss('cancel');
					};
				},
				controllerAs: 'self',
				scope: $scope,
				size: 'md',
				windowClass: 'modal-alert',
				backdropClass: 'modal-alert-backdrop'
			});
			// do not care how this modal is closed, just go to the desired location...
			modalDocView.result.then(function (res) {transitionCallback(); }, function (err) { transitionCallback(); });
		};

		$scope.save = function(isValid) {
			if (!isValid) {
				$scope.$broadcast('show-errors-check-validity', 'mainForm');
				$scope.$broadcast('show-errors-check-validity', 'detailsForm');
				$scope.$broadcast('show-errors-check-validity', 'recipientsForm');
				return false;
			}

			populateGroup();

			if (mode === 'create') {
				ProjectGroupModel.add(self.group)
					.then (function (res) {
						$scope.showSuccess('"'+ self.group.name +'"' + ' was saved successfully', goToEdit(res), 'Save Successful');
					})
					.catch (function (err) {
						$scope.showError('"'+ self.group.name +'"' + ' was not saved.', [], goNowhere, 'Save Error');
					});

			} else {
				ProjectGroupModel.save(self.group)
					.then (function (res) {
						$scope.showSuccess('"'+ self.group.name +'"' + ' was saved successfully', reloadEdit, 'Save Successful');
					})
					.catch (function (err) {
						$scope.showError('"'+ self.group.name +'"' + ' was not saved.', [], reloadEdit, 'Save Error');
					});
			}

		};

		$scope.delete = function(model) {
			var modalDocView = $modal.open({
				animation: true,
				templateUrl: 'modules/invitations/client/views/confirm-delete.html',
				controller: function($scope, $state, $modalInstance, ProjectGroupModel, _) {
					var self = this;
					self.group = model;
					self.message = "Are you sure you want to delete '" + model.name + "' from this project?";
					self.ok = function() {
						$modalInstance.close(model);
					};
					self.cancel = function() {
						$modalInstance.dismiss('cancel');
					};
				},
				controllerAs: 'self',
				scope: $scope,
				size: 'md'
			});
			modalDocView.result.then(function (res) {
				ProjectGroupModel.deleteId(model._id)
					.then(function(res) {
						// deleted show the message, and go to list...
						$scope.allowTransition = true;
						$scope.showSuccess('"'+ model.name +'"' + ' was deleted successfully from this project.', goToList, 'Delete Success');
					})
					.catch(function(res) {
						// could have errors from a delete check...
						$scope.showError('"'+ model.name +'"' + ' was not deleted.', [], reloadEdit, 'Delete Error');
					});
			}, function () {
				//console.log('delete modalDocView error');
			});
		};

		$scope.cancel = function() {
			goToList();
		};

	}]);

<commit_msg>ESM-595: Implement a partial so that on create() the function will called with the correct parameters.<commit_after>'use strict';

angular
	.module('groups', [])
	.controller('GroupEditController', ['$scope', '$state', '$modal', 'Authentication', 'NgTableParams',  '_', 'ProjectGroupModel', 'project', 'group', 'mode', function GroupEditController($scope, $state, $modal, Authentication, NgTableParams,  _, ProjectGroupModel, project, group, mode) {
		$scope.project = project;
		$scope.authentication = Authentication;
		$scope.mode = mode;
		// disable the delete button if user doesn't have permission to delete
		$scope.canDelete = $scope.mode === 'edit' && group.userCan.delete;

		var self = this;
		self.group = group;
		self.group.project = $scope.project._id;

		$scope.members = angular.copy(self.group.members) || [];
		$scope.existingRecipients = [];
		$scope.tableParams = new NgTableParams ({count:10}, {dataset: $scope.members});

		var populateGroup = function() {
			self.group.members = angular.copy($scope.members);
		};

		$scope.originalData = JSON.stringify(self.group); // used to capture unsaved changes when we leave this route/screen
		$scope.allowTransition = false;

		var $locationChangeStartUnbind = $scope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
			// no check
			if (mode !== 'detail' && !$scope.allowTransition) {

				populateGroup();
				// do the check...
				if ($scope.originalData !== JSON.stringify(self.group)) {
					// something changed...
					// do NOT allow the state change yet.
					event.preventDefault();

					$modal.open({
						animation: true,
						templateUrl: 'modules/vcs/client/views/vc-modal-confirm-cancel.html',
						controller: function($scope, $state, $modalInstance) {
							var self = this;
							self.ok = function() {
								$modalInstance.close();
							};
							self.cancel = function() {
								$modalInstance.dismiss('cancel');
							};
						},
						controllerAs: 'self',
						scope: $scope,
						size: 'lg'
					}).result.then(function (res) {
						$scope.allowTransition = true;
						$state.go(toState);
					}, function (err) {
						// cancelled...
					});

				} else {
					//DO NOTHING THERE IS NO CHANGES IN THE FORM
					//console.log('data NOT changed, let my data go!');
				}
			}
		});

		$scope.$on('$destroy', function () {
			window.onbeforeunload = null;
			$locationChangeStartUnbind();
		});

		var partial = function partial(func /*, 0..n args */) {
			var args = Array.prototype.slice.call(arguments, 1);
			return function() {
				var allArguments = args.concat(Array.prototype.slice.call(arguments));
				return func.apply(this, allArguments);
			};
		};

		var goToList = function() {
			$state.transitionTo('p.group.list', {projectid: $scope.project.code}, {
				reload: true, inherit: false, notify: true
			});
		};

		var reloadEdit = function() {
			// want to reload this screen, do not catch unsaved changes (we are probably in the middle of saving).
			$scope.allowTransition = true;
			$state.reload();
		};

		var goToEdit = function(model) {
			// want to reload this screen, do not catch unsaved changes (we are probably in the middle of saving).
			$scope.allowTransition = true;
			$state.transitionTo('p.group.edit', {projectid: $scope.project.code, groupId: model._id }, {
				reload: true, inherit: false, notify: true
			});
		};

		var goNowhere = function() {
			// do nothing...
		};

		$scope.$watch(function(scope) { return scope.existingRecipients; },
			function(data) {
				if (data && data.length > 0) {
					_.forEach(data, function(user) {
						var item =  _.find($scope.members, function(o) { return o.email === user.email; });
						if (!item) {
							$scope.members.push(user);
						}
					});
					$scope.existingRecipients = [];
					$scope.tableParams = new NgTableParams ({count:10}, {dataset: $scope.members});
				}
			}
		);

		$scope.removeMember = function(email) {
			var item =  _.find($scope.members, function(o) { return o.email === email; });
			if (item) {
				_.remove($scope.members, function(o) { return o.email === email; });
				$scope.tableParams = new NgTableParams ({count:10}, {dataset: $scope.members});
			}
		};

		$scope.showError = function(msg, errorList, transitionCallback, title) {
			var modalDocView = $modal.open({
				animation: true,
				templateUrl: 'modules/vcs/client/views/vc-modal-error.html',
				controller: function($scope, $state, $modalInstance, _) {
					var self = this;
					self.title = title || 'An error has occurred';
					self.msg = msg;
					self.errors = errorList;
					self.ok = function() {
						$modalInstance.close();
					};
					self.cancel = function() {
						$modalInstance.dismiss('cancel');
					};
				},
				controllerAs: 'self',
				scope: $scope,
				size: 'md',
				windowClass: 'modal-alert',
				backdropClass: 'modal-alert-backdrop'
			});
			// do not care how this modal is closed, just go to the desired location...
			modalDocView.result.then(function (res) {transitionCallback(); }, function (err) { transitionCallback(); });
		};

		$scope.showSuccess = function(msg, transitionCallback, title) {
			var modalDocView = $modal.open({
				animation: true,
				templateUrl: 'modules/vcs/client/views/vc-modal-success.html',
				controller: function($scope, $state, $modalInstance, _) {
					var self = this;
					self.title = title || 'Success';
					self.msg = msg;
					self.ok = function() {
						$modalInstance.close();
					};
					self.cancel = function() {
						$modalInstance.dismiss('cancel');
					};
				},
				controllerAs: 'self',
				scope: $scope,
				size: 'md',
				windowClass: 'modal-alert',
				backdropClass: 'modal-alert-backdrop'
			});
			// do not care how this modal is closed, just go to the desired location...
			modalDocView.result.then(function (res) {
				transitionCallback();
			}, function (err) {
				transitionCallback();
			});
		};

		$scope.save = function(isValid) {
			if (!isValid) {
				$scope.$broadcast('show-errors-check-validity', 'mainForm');
				$scope.$broadcast('show-errors-check-validity', 'detailsForm');
				$scope.$broadcast('show-errors-check-validity', 'recipientsForm');
				return false;
			}

			populateGroup();

			if (mode === 'create') {
				ProjectGroupModel.add(self.group)
					.then (function (res) {
						var editFn = partial(goToEdit, res);
						$scope.showSuccess('"'+ self.group.name +'"' + ' was saved successfully', editFn, 'Save Successful');
					})
					.catch (function (err) {
						$scope.showError('"'+ self.group.name +'"' + ' was not saved.', [], goNowhere, 'Save Error');
					});

			} else {
				ProjectGroupModel.save(self.group)
					.then (function (res) {
						$scope.showSuccess('"'+ self.group.name +'"' + ' was saved successfully', reloadEdit, 'Save Successful');
					})
					.catch (function (err) {
						$scope.showError('"'+ self.group.name +'"' + ' was not saved.', [], reloadEdit, 'Save Error');
					});
			}

		};

		$scope.delete = function(model) {
			var modalDocView = $modal.open({
				animation: true,
				templateUrl: 'modules/invitations/client/views/confirm-delete.html',
				controller: function($scope, $state, $modalInstance, ProjectGroupModel, _) {
					var self = this;
					self.group = model;
					self.message = "Are you sure you want to delete '" + model.name + "' from this project?";
					self.ok = function() {
						$modalInstance.close(model);
					};
					self.cancel = function() {
						$modalInstance.dismiss('cancel');
					};
				},
				controllerAs: 'self',
				scope: $scope,
				size: 'md'
			});
			modalDocView.result.then(function (res) {
				ProjectGroupModel.deleteId(model._id)
					.then(function(res) {
						// deleted show the message, and go to list...
						$scope.allowTransition = true;
						$scope.showSuccess('"'+ model.name +'"' + ' was deleted successfully from this project.', goToList, 'Delete Success');
					})
					.catch(function(res) {
						// could have errors from a delete check...
						$scope.showError('"'+ model.name +'"' + ' was not deleted.', [], reloadEdit, 'Delete Error');
					});
			}, function () {
				//console.log('delete modalDocView error');
			});
		};

		$scope.cancel = function() {
			goToList();
		};

	}]);

<|endoftext|>


<commit_before>define(['angular', 'underscore'], function (angular) {
  'use strict';
  return angular.module('app.controllers', []).controller('AppCtrl', [
    '$scope', '$location', function($scope, $location) {
      $scope.isSpecificPage = function() {
        var path;
        path = $location.path();
        return _.contains(['/404', '/pages/500', '/pages/login', '/pages/signin', '/pages/signin1', '/pages/signin2', '/pages/signup', '/pages/signup1', '/pages/signup2', '/pages/lock-screen'], path);
      };
      return $scope.main = {
        brand: 'project HEDWIG',
        name: 'Jane Doe'
      };
    }
  ]).controller('NavCtrl', [
    '$scope', 'taskStorage', 'filterFilter', function($scope, taskStorage, filterFilter) {
      var tasks;
      tasks = $scope.tasks = taskStorage.get();
      $scope.taskRemainingCount = filterFilter(tasks, {
        completed: false
      }).length;
      return $scope.$on('taskRemaining:changed', function(event, count) {
        return $scope.taskRemainingCount = count;
      });
    }
  ]).controller('DashboardCtrl', [
    '$scope', function($scope) {
      $scope.comboChartData = [['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua New Guinea', 'Rwanda', 'Average'], ['2014/05', 165, 938, 522, 998, 450, 614.6], ['2014/06', 135, 1120, 599, 1268, 288, 682], ['2014/07', 157, 1167, 587, 807, 397, 623], ['2014/08', 139, 1110, 615, 968, 215, 609.4], ['2014/09', 136, 691, 629, 1026, 366, 569.6]];
      return $scope.salesData = [['Year', 'Sales', 'Expenses'], ['2010', 1000, 400], ['2011', 1170, 460], ['2012', 660, 1120], ['2013', 1030, 540]];
    }
  ]);

});
<commit_msg>reverted name to ls-seed<commit_after>define(['angular', 'underscore'], function (angular) {
  'use strict';
  return angular.module('app.controllers', []).controller('AppCtrl', [
    '$scope', '$location', function($scope, $location) {
      $scope.isSpecificPage = function() {
        var path;
        path = $location.path();
        return _.contains(['/404', '/pages/500', '/pages/login', '/pages/signin', '/pages/signin1', '/pages/signin2', '/pages/signup', '/pages/signup1', '/pages/signup2', '/pages/lock-screen'], path);
      };
      return $scope.main = {
        brand: 'LS-Seed',
        name: 'Jane Doe'
      };
    }
  ]).controller('NavCtrl', [
    '$scope', 'taskStorage', 'filterFilter', function($scope, taskStorage, filterFilter) {
      var tasks;
      tasks = $scope.tasks = taskStorage.get();
      $scope.taskRemainingCount = filterFilter(tasks, {
        completed: false
      }).length;
      return $scope.$on('taskRemaining:changed', function(event, count) {
        return $scope.taskRemainingCount = count;
      });
    }
  ]).controller('DashboardCtrl', [
    '$scope', function($scope) {
      $scope.comboChartData = [['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua New Guinea', 'Rwanda', 'Average'], ['2014/05', 165, 938, 522, 998, 450, 614.6], ['2014/06', 135, 1120, 599, 1268, 288, 682], ['2014/07', 157, 1167, 587, 807, 397, 623], ['2014/08', 139, 1110, 615, 968, 215, 609.4], ['2014/09', 136, 691, 629, 1026, 366, 569.6]];
      return $scope.salesData = [['Year', 'Sales', 'Expenses'], ['2010', 1000, 400], ['2011', 1170, 460], ['2012', 660, 1120], ['2013', 1030, 540]];
    }
  ]);

});
<|endoftext|>