<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {enableIsInputPending} from '../SchedulerFeatureFlags';

// The DOM Scheduler implementation is similar to requestIdleCallback. It
// works by scheduling a requestAnimationFrame, storing the time for the start
// of the frame, then scheduling a postMessage which gets scheduled after paint.
// Within the postMessage handler do as much work as possible until time + frame
// rate. By separating the idle call into a separate event tick we ensure that
// layout, paint and other browser work is counted against the available time.
// The frame rate is dynamically adjusted.

export let requestHostCallback;
export let cancelHostCallback;
export let requestHostTimeout;
export let cancelHostTimeout;
export let shouldYieldToHost;
export let requestPaint;
export let getCurrentTime;
export let forceFrameRate;

const hasNativePerformanceNow =
  typeof performance === 'object' && typeof performance.now === 'function';

// We capture a local reference to any global, in case it gets polyfilled after
// this module is initially evaluated. We want to be using a
// consistent implementation.
const localDate = Date;

// This initialization code may run even on server environments if a component
// just imports ReactDOM (e.g. for findDOMNode). Some environments might not
// have setTimeout or clearTimeout. However, we always expect them to be defined
// on the client. https://github.com/facebook/react/pull/13088
const localSetTimeout =
  typeof setTimeout === 'function' ? setTimeout : undefined;
const localClearTimeout =
  typeof clearTimeout === 'function' ? clearTimeout : undefined;

// We don't expect either of these to necessarily be defined, but we will error
// later if they are missing on the client.
const localRequestAnimationFrame =
  typeof requestAnimationFrame === 'function'
    ? requestAnimationFrame
    : undefined;
const localCancelAnimationFrame =
  typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame : undefined;

// requestAnimationFrame does not run when the tab is in the background. If
// we're backgrounded we prefer for that work to happen so that the page
// continues to load in the background. So we also schedule a 'setTimeout' as
// a fallback.
// TODO: Need a better heuristic for backgrounded work.
const ANIMATION_FRAME_TIMEOUT = 100;
let rAFID;
let rAFTimeoutID;
const requestAnimationFrameWithTimeout = function(callback) {
  // schedule rAF and also a setTimeout
  rAFID = localRequestAnimationFrame(function(timestamp) {
    // cancel the setTimeout
    localClearTimeout(rAFTimeoutID);
    callback(timestamp);
  });
  rAFTimeoutID = localSetTimeout(function() {
    // cancel the requestAnimationFrame
    localCancelAnimationFrame(rAFID);
    callback(getCurrentTime());
  }, ANIMATION_FRAME_TIMEOUT);
};

if (hasNativePerformanceNow) {
  const Performance = performance;
  getCurrentTime = function() {
    return Performance.now();
  };
} else {
  getCurrentTime = function() {
    return localDate.now();
  };
}

if (
  // If Scheduler runs in a non-DOM environment, it falls back to a naive
  // implementation using setTimeout.
  typeof window === 'undefined' ||
  // Check if MessageChannel is supported, too.
  typeof MessageChannel !== 'function'
) {
  // If this accidentally gets imported in a non-browser environment, e.g. JavaScriptCore,
  // fallback to a naive implementation.
  let _callback = null;
  let _timeoutID = null;
  const _flushCallback = function() {
    if (_callback !== null) {
      try {
        const currentTime = getCurrentTime();
        const hasRemainingTime = true;
        _callback(hasRemainingTime, currentTime);
        _callback = null;
      } catch (e) {
        setTimeout(_flushCallback, 0);
        throw e;
      }
    }
  };
  requestHostCallback = function(cb) {
    if (_callback !== null) {
      // Protect against re-entrancy.
      setTimeout(requestHostCallback, 0, cb);
    } else {
      _callback = cb;
      setTimeout(_flushCallback, 0);
    }
  };
  cancelHostCallback = function() {
    _callback = null;
  };
  requestHostTimeout = function(cb, ms) {
    _timeoutID = setTimeout(cb, ms);
  };
  cancelHostTimeout = function() {
    clearTimeout(_timeoutID);
  };
  shouldYieldToHost = function() {
    return false;
  };
  requestPaint = forceFrameRate = function() {};
} else {
  if (typeof console !== 'undefined') {
    // TODO: Remove fb.me link
    if (typeof localRequestAnimationFrame !== 'function') {
      console.error(
        "This browser doesn't support requestAnimationFrame. " +
          'Make sure that you load a ' +
          'polyfill in older browsers. https://fb.me/react-polyfills',
      );
    }
    if (typeof localCancelAnimationFrame !== 'function') {
      console.error(
        "This browser doesn't support cancelAnimationFrame. " +
          'Make sure that you load a ' +
          'polyfill in older browsers. https://fb.me/react-polyfills',
      );
    }
  }

  let scheduledHostCallback = null;
  let isMessageEventScheduled = false;

  let isAnimationFrameScheduled = false;

  let timeoutID = -1;

  let frameDeadline = 0;
  // We start out assuming that we run at 30fps but then the heuristic tracking
  // will adjust this value to a faster fps if we get more frequent animation
  // frames.
  let previousFrameTime = 33;
  let activeFrameTime = 33;
  let fpsLocked = false;

  // TODO: Make this configurable
  // TODO: Adjust this based on priority?
  let maxFrameLength = 150;
  let needsPaint = false;

  if (
    enableIsInputPending &&
    navigator !== undefined &&
    navigator.scheduling !== undefined &&
    navigator.scheduling.isInputPending !== undefined
  ) {
    const scheduling = navigator.scheduling;
    shouldYieldToHost = function() {
      const currentTime = getCurrentTime();
      if (currentTime >= frameDeadline) {
        // There's no time left in the frame. We may want to yield control of
        // the main thread, so the browser can perform high priority tasks. The
        // main ones are painting and user input. If there's a pending paint or
        // a pending input, then we should yield. But if there's neither, then
        // we can yield less often while remaining responsive. We'll eventually
        // yield regardless, since there could be a pending paint that wasn't
        // accompanied by a call to `requestPaint`, or other main thread tasks
        // like network events.
        if (needsPaint || scheduling.isInputPending()) {
          // There is either a pending paint or a pending input.
          return true;
        }
        // There's no pending input. Only yield if we've reached the max
        // frame length.
        return currentTime >= frameDeadline + maxFrameLength;
      } else {
        // There's still time left in the frame.
        return false;
      }
    };

    requestPaint = function() {
      needsPaint = true;
    };
  } else {
    // `isInputPending` is not available. Since we have no way of knowing if
    // there's pending input, always yield at the end of the frame.
    shouldYieldToHost = function() {
      return getCurrentTime() >= frameDeadline;
    };

    // Since we yield every frame regardless, `requestPaint` has no effect.
    requestPaint = function() {};
  }

  forceFrameRate = function(fps) {
    if (fps < 0 || fps > 125) {
      console.error(
        'forceFrameRate takes a positive int between 0 and 125, ' +
          'forcing framerates higher than 125 fps is not unsupported',
      );
      return;
    }
    if (fps > 0) {
      activeFrameTime = Math.floor(1000 / fps);
      fpsLocked = true;
    } else {
      // reset the framerate
      activeFrameTime = 33;
      fpsLocked = false;
    }
  };

  // We use the postMessage trick to defer idle work until after the repaint.
  const channel = new MessageChannel();
  const port = channel.port2;
  channel.port1.onmessage = function(event) {
    isMessageEventScheduled = false;
    if (scheduledHostCallback !== null) {
      const currentTime = getCurrentTime();
      const hasTimeRemaining = frameDeadline - currentTime > 0;
      try {
        const hasMoreWork = scheduledHostCallback(
          hasTimeRemaining,
          currentTime,
        );
        if (hasMoreWork) {
          // Ensure the next frame is scheduled.
          if (!isAnimationFrameScheduled) {
            isAnimationFrameScheduled = true;
            requestAnimationFrameWithTimeout(animationTick);
          }
        } else {
          scheduledHostCallback = null;
        }
      } catch (error) {
        // If a scheduler task throws, exit the current browser task so the
        // error can be observed, and post a new task as soon as possible
        // so we can continue where we left off.
        isMessageEventScheduled = true;
        port.postMessage(undefined);
        throw error;
      }
      // Yielding to the browser will give it a chance to paint, so we can
      // reset this.
      needsPaint = false;
    }
  };

  const animationTick = function(rafTime) {
    if (scheduledHostCallback !== null) {
      // Eagerly schedule the next animation callback at the beginning of the
      // frame. If the scheduler queue is not empty at the end of the frame, it
      // will continue flushing inside that callback. If the queue *is* empty,
      // then it will exit immediately. Posting the callback at the start of the
      // frame ensures it's fired within the earliest possible frame. If we
      // waited until the end of the frame to post the callback, we risk the
      // browser skipping a frame and not firing the callback until the frame
      // after that.
      requestAnimationFrameWithTimeout(animationTick);
    } else {
      // No pending work. Exit.
      isAnimationFrameScheduled = false;
      return;
    }

    let nextFrameTime = rafTime - frameDeadline + activeFrameTime;
    if (
      nextFrameTime < activeFrameTime &&
      previousFrameTime < activeFrameTime &&
      !fpsLocked
    ) {
      if (nextFrameTime < 8) {
        // Defensive coding. We don't support higher frame rates than 120hz.
        // If the calculated frame time gets lower than 8, it is probably a bug.
        nextFrameTime = 8;
      }
      // If one frame goes long, then the next one can be short to catch up.
      // If two frames are short in a row, then that's an indication that we
      // actually have a higher frame rate than what we're currently optimizing.
      // We adjust our heuristic dynamically accordingly. For example, if we're
      // running on 120hz display or 90hz VR display.
      // Take the max of the two in case one of them was an anomaly due to
      // missed frame deadlines.
      activeFrameTime =
        nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
    } else {
      previousFrameTime = nextFrameTime;
    }
    frameDeadline = rafTime + activeFrameTime;
    if (!isMessageEventScheduled) {
      isMessageEventScheduled = true;
      port.postMessage(undefined);
    }
  };

  requestHostCallback = function(callback) {
    if (scheduledHostCallback === null) {
      scheduledHostCallback = callback;
      if (!isAnimationFrameScheduled) {
        // If rAF didn't already schedule one, we need to schedule a frame.
        // TODO: If this rAF doesn't materialize because the browser throttles,
        // we might want to still have setTimeout trigger rIC as a backup to
        // ensure that we keep performing work.
        isAnimationFrameScheduled = true;
        requestAnimationFrameWithTimeout(animationTick);
      }
    }
  };

  cancelHostCallback = function() {
    scheduledHostCallback = null;
    isMessageEventScheduled = false;
  };

  requestHostTimeout = function(callback, ms) {
    timeoutID = localSetTimeout(() => {
      callback(getCurrentTime());
    }, ms);
  };

  cancelHostTimeout = function() {
    localClearTimeout(timeoutID);
    timeoutID = -1;
  };
}
<commit_msg>[Scheduler] Increase max frame length to 300<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {enableIsInputPending} from '../SchedulerFeatureFlags';

// The DOM Scheduler implementation is similar to requestIdleCallback. It
// works by scheduling a requestAnimationFrame, storing the time for the start
// of the frame, then scheduling a postMessage which gets scheduled after paint.
// Within the postMessage handler do as much work as possible until time + frame
// rate. By separating the idle call into a separate event tick we ensure that
// layout, paint and other browser work is counted against the available time.
// The frame rate is dynamically adjusted.

export let requestHostCallback;
export let cancelHostCallback;
export let requestHostTimeout;
export let cancelHostTimeout;
export let shouldYieldToHost;
export let requestPaint;
export let getCurrentTime;
export let forceFrameRate;

const hasNativePerformanceNow =
  typeof performance === 'object' && typeof performance.now === 'function';

// We capture a local reference to any global, in case it gets polyfilled after
// this module is initially evaluated. We want to be using a
// consistent implementation.
const localDate = Date;

// This initialization code may run even on server environments if a component
// just imports ReactDOM (e.g. for findDOMNode). Some environments might not
// have setTimeout or clearTimeout. However, we always expect them to be defined
// on the client. https://github.com/facebook/react/pull/13088
const localSetTimeout =
  typeof setTimeout === 'function' ? setTimeout : undefined;
const localClearTimeout =
  typeof clearTimeout === 'function' ? clearTimeout : undefined;

// We don't expect either of these to necessarily be defined, but we will error
// later if they are missing on the client.
const localRequestAnimationFrame =
  typeof requestAnimationFrame === 'function'
    ? requestAnimationFrame
    : undefined;
const localCancelAnimationFrame =
  typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame : undefined;

// requestAnimationFrame does not run when the tab is in the background. If
// we're backgrounded we prefer for that work to happen so that the page
// continues to load in the background. So we also schedule a 'setTimeout' as
// a fallback.
// TODO: Need a better heuristic for backgrounded work.
const ANIMATION_FRAME_TIMEOUT = 100;
let rAFID;
let rAFTimeoutID;
const requestAnimationFrameWithTimeout = function(callback) {
  // schedule rAF and also a setTimeout
  rAFID = localRequestAnimationFrame(function(timestamp) {
    // cancel the setTimeout
    localClearTimeout(rAFTimeoutID);
    callback(timestamp);
  });
  rAFTimeoutID = localSetTimeout(function() {
    // cancel the requestAnimationFrame
    localCancelAnimationFrame(rAFID);
    callback(getCurrentTime());
  }, ANIMATION_FRAME_TIMEOUT);
};

if (hasNativePerformanceNow) {
  const Performance = performance;
  getCurrentTime = function() {
    return Performance.now();
  };
} else {
  getCurrentTime = function() {
    return localDate.now();
  };
}

if (
  // If Scheduler runs in a non-DOM environment, it falls back to a naive
  // implementation using setTimeout.
  typeof window === 'undefined' ||
  // Check if MessageChannel is supported, too.
  typeof MessageChannel !== 'function'
) {
  // If this accidentally gets imported in a non-browser environment, e.g. JavaScriptCore,
  // fallback to a naive implementation.
  let _callback = null;
  let _timeoutID = null;
  const _flushCallback = function() {
    if (_callback !== null) {
      try {
        const currentTime = getCurrentTime();
        const hasRemainingTime = true;
        _callback(hasRemainingTime, currentTime);
        _callback = null;
      } catch (e) {
        setTimeout(_flushCallback, 0);
        throw e;
      }
    }
  };
  requestHostCallback = function(cb) {
    if (_callback !== null) {
      // Protect against re-entrancy.
      setTimeout(requestHostCallback, 0, cb);
    } else {
      _callback = cb;
      setTimeout(_flushCallback, 0);
    }
  };
  cancelHostCallback = function() {
    _callback = null;
  };
  requestHostTimeout = function(cb, ms) {
    _timeoutID = setTimeout(cb, ms);
  };
  cancelHostTimeout = function() {
    clearTimeout(_timeoutID);
  };
  shouldYieldToHost = function() {
    return false;
  };
  requestPaint = forceFrameRate = function() {};
} else {
  if (typeof console !== 'undefined') {
    // TODO: Remove fb.me link
    if (typeof localRequestAnimationFrame !== 'function') {
      console.error(
        "This browser doesn't support requestAnimationFrame. " +
          'Make sure that you load a ' +
          'polyfill in older browsers. https://fb.me/react-polyfills',
      );
    }
    if (typeof localCancelAnimationFrame !== 'function') {
      console.error(
        "This browser doesn't support cancelAnimationFrame. " +
          'Make sure that you load a ' +
          'polyfill in older browsers. https://fb.me/react-polyfills',
      );
    }
  }

  let scheduledHostCallback = null;
  let isMessageEventScheduled = false;

  let isAnimationFrameScheduled = false;

  let timeoutID = -1;

  let frameDeadline = 0;
  // We start out assuming that we run at 30fps but then the heuristic tracking
  // will adjust this value to a faster fps if we get more frequent animation
  // frames.
  let previousFrameTime = 33;
  let activeFrameTime = 33;
  let fpsLocked = false;

  // TODO: Make this configurable
  // TODO: Adjust this based on priority?
  let maxFrameLength = 300;
  let needsPaint = false;

  if (
    enableIsInputPending &&
    navigator !== undefined &&
    navigator.scheduling !== undefined &&
    navigator.scheduling.isInputPending !== undefined
  ) {
    const scheduling = navigator.scheduling;
    shouldYieldToHost = function() {
      const currentTime = getCurrentTime();
      if (currentTime >= frameDeadline) {
        // There's no time left in the frame. We may want to yield control of
        // the main thread, so the browser can perform high priority tasks. The
        // main ones are painting and user input. If there's a pending paint or
        // a pending input, then we should yield. But if there's neither, then
        // we can yield less often while remaining responsive. We'll eventually
        // yield regardless, since there could be a pending paint that wasn't
        // accompanied by a call to `requestPaint`, or other main thread tasks
        // like network events.
        if (needsPaint || scheduling.isInputPending()) {
          // There is either a pending paint or a pending input.
          return true;
        }
        // There's no pending input. Only yield if we've reached the max
        // frame length.
        return currentTime >= frameDeadline + maxFrameLength;
      } else {
        // There's still time left in the frame.
        return false;
      }
    };

    requestPaint = function() {
      needsPaint = true;
    };
  } else {
    // `isInputPending` is not available. Since we have no way of knowing if
    // there's pending input, always yield at the end of the frame.
    shouldYieldToHost = function() {
      return getCurrentTime() >= frameDeadline;
    };

    // Since we yield every frame regardless, `requestPaint` has no effect.
    requestPaint = function() {};
  }

  forceFrameRate = function(fps) {
    if (fps < 0 || fps > 125) {
      console.error(
        'forceFrameRate takes a positive int between 0 and 125, ' +
          'forcing framerates higher than 125 fps is not unsupported',
      );
      return;
    }
    if (fps > 0) {
      activeFrameTime = Math.floor(1000 / fps);
      fpsLocked = true;
    } else {
      // reset the framerate
      activeFrameTime = 33;
      fpsLocked = false;
    }
  };

  // We use the postMessage trick to defer idle work until after the repaint.
  const channel = new MessageChannel();
  const port = channel.port2;
  channel.port1.onmessage = function(event) {
    isMessageEventScheduled = false;
    if (scheduledHostCallback !== null) {
      const currentTime = getCurrentTime();
      const hasTimeRemaining = frameDeadline - currentTime > 0;
      try {
        const hasMoreWork = scheduledHostCallback(
          hasTimeRemaining,
          currentTime,
        );
        if (hasMoreWork) {
          // Ensure the next frame is scheduled.
          if (!isAnimationFrameScheduled) {
            isAnimationFrameScheduled = true;
            requestAnimationFrameWithTimeout(animationTick);
          }
        } else {
          scheduledHostCallback = null;
        }
      } catch (error) {
        // If a scheduler task throws, exit the current browser task so the
        // error can be observed, and post a new task as soon as possible
        // so we can continue where we left off.
        isMessageEventScheduled = true;
        port.postMessage(undefined);
        throw error;
      }
      // Yielding to the browser will give it a chance to paint, so we can
      // reset this.
      needsPaint = false;
    }
  };

  const animationTick = function(rafTime) {
    if (scheduledHostCallback !== null) {
      // Eagerly schedule the next animation callback at the beginning of the
      // frame. If the scheduler queue is not empty at the end of the frame, it
      // will continue flushing inside that callback. If the queue *is* empty,
      // then it will exit immediately. Posting the callback at the start of the
      // frame ensures it's fired within the earliest possible frame. If we
      // waited until the end of the frame to post the callback, we risk the
      // browser skipping a frame and not firing the callback until the frame
      // after that.
      requestAnimationFrameWithTimeout(animationTick);
    } else {
      // No pending work. Exit.
      isAnimationFrameScheduled = false;
      return;
    }

    let nextFrameTime = rafTime - frameDeadline + activeFrameTime;
    if (
      nextFrameTime < activeFrameTime &&
      previousFrameTime < activeFrameTime &&
      !fpsLocked
    ) {
      if (nextFrameTime < 8) {
        // Defensive coding. We don't support higher frame rates than 120hz.
        // If the calculated frame time gets lower than 8, it is probably a bug.
        nextFrameTime = 8;
      }
      // If one frame goes long, then the next one can be short to catch up.
      // If two frames are short in a row, then that's an indication that we
      // actually have a higher frame rate than what we're currently optimizing.
      // We adjust our heuristic dynamically accordingly. For example, if we're
      // running on 120hz display or 90hz VR display.
      // Take the max of the two in case one of them was an anomaly due to
      // missed frame deadlines.
      activeFrameTime =
        nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
    } else {
      previousFrameTime = nextFrameTime;
    }
    frameDeadline = rafTime + activeFrameTime;
    if (!isMessageEventScheduled) {
      isMessageEventScheduled = true;
      port.postMessage(undefined);
    }
  };

  requestHostCallback = function(callback) {
    if (scheduledHostCallback === null) {
      scheduledHostCallback = callback;
      if (!isAnimationFrameScheduled) {
        // If rAF didn't already schedule one, we need to schedule a frame.
        // TODO: If this rAF doesn't materialize because the browser throttles,
        // we might want to still have setTimeout trigger rIC as a backup to
        // ensure that we keep performing work.
        isAnimationFrameScheduled = true;
        requestAnimationFrameWithTimeout(animationTick);
      }
    }
  };

  cancelHostCallback = function() {
    scheduledHostCallback = null;
    isMessageEventScheduled = false;
  };

  requestHostTimeout = function(callback, ms) {
    timeoutID = localSetTimeout(() => {
      callback(getCurrentTime());
    }, ms);
  };

  cancelHostTimeout = function() {
    localClearTimeout(timeoutID);
    timeoutID = -1;
  };
}
<|endoftext|>


<commit_before>import { Router } from 'express';
import Groups from 'models/groupModel';
import IDCard from 'models/idcardModel';
import PWS from 'models/pwsModel';
import config from 'config/config.json';
import { ensureAPIAuth, ensureAuthOrToken, getAuthToken } from '../utils/helpers';
import { API } from 'Routes';

let api = Router();

api.get(API.GetMembers, async (req, res) => {
		let result = await Groups.GetMembers(req.params.group);
		let members = await PWS.GetMany(result.Payload);
		let verbose = await IDCard.GetManyPhotos(members);
		return res.status(result.Status).json(verbose);
});

// this should have ensureApiAuth, but is buggy atmg
api.get(API.GetToken, (req, res) => {
	console.log("getting token, auth:", req.user, req.session)
	let token = getAuthToken(req);
	console.log("Token Acquired:", token);
	if(token) {
		res.send(200).json({token});
	} else {
		res.send(401).json({token: ""});
	}

});

api.get(API.Logout, (req,res) => {
	console.log("Logging out user");
	req.logout();
	req.session.destroy();
	res.clearCookie('connect.sid', {path:'/'});
	res.sendStatus(200);
});

api.put(API.RegisterMember, ensureAuthOrToken, async (req, res) => {
	let identifier = req.params.identifier;
	let validCard = IDCard.ValidCard(identifier);

	if(validCard){
		identifier = await IDCard.Get(validCard);
		identifier = (await PWS.Get(identifier)).UWNetID;
	}

	let result = await Groups.AddMember(req.params.group, identifier);
	let user = await PWS.Get(identifier);
	user.identifier = identifier;
	user.Base64Image = await IDCard.GetPhoto(user.UWRegID);
	res.status(result.Status).json(user);
});

api.delete(API.RemoveMember, ensureAPIAuth, async (req, res) => {
	let result = await Groups.RemoveMember(req.params.group, req.params.identifier);
	return res.status(result.Status).json(result.Payload);
});

api.get(API.GetSubgroups, ensureAPIAuth, async (req, res) => {
	let result = await Groups.SearchGroups(req.params.group);
	return res.status(result.Status).json(result.Payload);
});

api.delete(API.RemoveSubgroup, ensureAPIAuth, async (req, res) => {
	let result = await Groups.DeleteGroup(req.params.group);
	return res.status(result.Status).json(result.Payload);
});

api.post(API.CreateGroup, ensureAPIAuth, async (req, res) => {
	let result = await Groups.CreateGroup(req.params.group);
	return res.status(result.Status).json(result.Payload);
});

api.get(API.CheckAuth, (req, res) => {
	console.log("Check Auth Session", req.session);

	if(req.isAuthenticated() || process.env.NODE_ENV === 'development') {
		return res.sendStatus(200);
	} else {
		// using 202 because 4xx throws a dumb error in the chrome console,
		// anything but 200 is fine for this use case
		return res.sendStatus(202);
	}
});

api.get(API.Config, (req, res) => {
	let whitelist = ["idcardBaseUrl", "pwsBaseUrl", "photoBaseUrl", "groupsBaseUrl", "groupNameBase"];
	let filteredConfig = Object.keys(config)
			.filter(key => whitelist.includes(key))
			.reduce((obj, key) => {
					obj[key] = config[key];
					return obj;
			}, {});
	res.status(200).json(filteredConfig);
});

api.get(API.CSV, async (req, res) => {
	let members = await Groups.GetMembers(req.params.group);
	let csvWhitelist = ["DisplayName", "UWNetID", "UWRegID"];
	let verboseMembers = await PWS.GetMany(members.Payload, csvWhitelist);
	res.csv(verboseMembers, true);
});

export default api;
<commit_msg>status instead of send<commit_after>import { Router } from 'express';
import Groups from 'models/groupModel';
import IDCard from 'models/idcardModel';
import PWS from 'models/pwsModel';
import config from 'config/config.json';
import { ensureAPIAuth, ensureAuthOrToken, getAuthToken } from '../utils/helpers';
import { API } from 'Routes';

let api = Router();

api.get(API.GetMembers, async (req, res) => {
		let result = await Groups.GetMembers(req.params.group);
		let members = await PWS.GetMany(result.Payload);
		let verbose = await IDCard.GetManyPhotos(members);
		return res.status(result.Status).json(verbose);
});

// this should have ensureApiAuth, but is buggy atmg
api.get(API.GetToken, (req, res) => {
	console.log("getting token, auth:", req.user, req.session)
	let token = getAuthToken(req);
	console.log("Token Acquired:", token);
	if(token) {
		return res.status(200).json({token});
	} else {
		return res.status(401).json({token: ""});
	}

});

api.get(API.Logout, (req,res) => {
	console.log("Logging out user");
	req.logout();
	req.session.destroy();
	res.clearCookie('connect.sid', {path:'/'});
	res.sendStatus(200);
});

api.put(API.RegisterMember, ensureAuthOrToken, async (req, res) => {
	let identifier = req.params.identifier;
	let validCard = IDCard.ValidCard(identifier);

	if(validCard){
		identifier = await IDCard.Get(validCard);
		identifier = (await PWS.Get(identifier)).UWNetID;
	}

	let result = await Groups.AddMember(req.params.group, identifier);
	let user = await PWS.Get(identifier);
	user.identifier = identifier;
	user.Base64Image = await IDCard.GetPhoto(user.UWRegID);
	res.status(result.Status).json(user);
});

api.delete(API.RemoveMember, ensureAPIAuth, async (req, res) => {
	let result = await Groups.RemoveMember(req.params.group, req.params.identifier);
	return res.status(result.Status).json(result.Payload);
});

api.get(API.GetSubgroups, ensureAPIAuth, async (req, res) => {
	let result = await Groups.SearchGroups(req.params.group);
	return res.status(result.Status).json(result.Payload);
});

api.delete(API.RemoveSubgroup, ensureAPIAuth, async (req, res) => {
	let result = await Groups.DeleteGroup(req.params.group);
	return res.status(result.Status).json(result.Payload);
});

api.post(API.CreateGroup, ensureAPIAuth, async (req, res) => {
	let result = await Groups.CreateGroup(req.params.group);
	return res.status(result.Status).json(result.Payload);
});

api.get(API.CheckAuth, (req, res) => {
	console.log("Check Auth Session", req.session);

	if(req.isAuthenticated() || process.env.NODE_ENV === 'development') {
		return res.sendStatus(200);
	} else {
		// using 202 because 4xx throws a dumb error in the chrome console,
		// anything but 200 is fine for this use case
		return res.sendStatus(202);
	}
});

api.get(API.Config, (req, res) => {
	let whitelist = ["idcardBaseUrl", "pwsBaseUrl", "photoBaseUrl", "groupsBaseUrl", "groupNameBase"];
	let filteredConfig = Object.keys(config)
			.filter(key => whitelist.includes(key))
			.reduce((obj, key) => {
					obj[key] = config[key];
					return obj;
			}, {});
	res.status(200).json(filteredConfig);
});

api.get(API.CSV, async (req, res) => {
	let members = await Groups.GetMembers(req.params.group);
	let csvWhitelist = ["DisplayName", "UWNetID", "UWRegID"];
	let verboseMembers = await PWS.GetMany(members.Payload, csvWhitelist);
	res.csv(verboseMembers, true);
});

export default api;
<|endoftext|>


<commit_before>module.exports = function (configuration) {
    return function (name) {
        return require('./' + name)(configuration);
    };
};

module.exports.tables = function (table) {
    return function (name) {
        return require('./tables/' + name)(table);
    };
};
<commit_msg>Added copyright<commit_after>// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
module.exports = function (configuration) {
    return function (name) {
        return require('./' + name)(configuration);
    };
};

module.exports.tables = function (table) {
    return function (name) {
        return require('./tables/' + name)(table);
    };
};
<|endoftext|>


<commit_before>'use strict';

let routes = {
    products: {
        get: 'http://www.beta.battle-comm.net:3000/api/products/',
        getAll: 'http://www.beta.battle-comm.net:3000/api/products',
        create: 'http://www.beta.battle-comm.net:3000/api/products',
        update: 'http://www.beta.battle-comm.net:3000/api/products/',
        remove: 'http://www.beta.battle-comm.net:3000/api/products/'
    },
    orders: {
        get: 'http://www.beta.battle-comm.net:3000/api/orders/',
        getAll: 'http://www.beta.battle-comm.net:3000/api/orders',
        create: 'http://www.beta.battle-comm.net:3000/api/orders',
        update: 'http://www.beta.battle-comm.net:3000/api/orders/',
        remove: 'http://www.beta.battle-comm.net:3000/api/orders/'
    }
};

module.exports = routes;
<commit_msg>updated gitignore<commit_after><|endoftext|>


<commit_before>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2015 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The Destroy component is responsible for destroying a Game Object.
*
* @class
*/
Phaser.Component.Destroy = function () {};

Phaser.Component.Destroy.prototype = {

    /**
    * As a Game Object runs through its destroy method this flag is set to true,
    * and can be checked in any sub-systems or plugins it is being destroyed from.
    * @property {boolean} destroyPhase
    * @readOnly
    */
    destroyPhase: false,

    /**
    * Destroys the Game Object. This removes it from its parent group, destroys the input, event and animation handlers if present
    * and nulls its reference to `game`, freeing it up for garbage collection.
    *
    * If this Game Object has the Events component it will also dispatch the `onDestroy` event.
    *
    * @method
    * @param {boolean} [destroyChildren=true] - Should every child of this object have its destroy method called as well?
    */
    destroy: function(destroyChildren) {

        if (this.game === null || this.destroyPhase) { return; }

        if (typeof destroyChildren === 'undefined') { destroyChildren = true; }

        this.destroyPhase = true;

        if (this.events)
        {
            this.events.onDestroy$dispatch(this);
        }

        if (this.parent)
        {
            if (this.parent instanceof Phaser.Group)
            {
                this.parent.remove(this);
            }
            else
            {
                this.parent.removeChild(this);
            }
        }

        if (this.input)
        {
            this.input.destroy();
        }

        if (this.animations)
        {
            this.animations.destroy();
        }

        if (this.body)
        {
            this.body.destroy();
        }

        if (this.events)
        {
            this.events.destroy();
        }

        var i = this.children.length;

        if (destroyChildren)
        {
            while (i--)
            {
                this.children[i].destroy(destroyChildren);
            }
        }
        else
        {
            while (i--)
            {
                this.removeChild(this.children[i]);
            }
        }

        if (this._crop)
        {
            this._crop = null;
        }

        if (this._frame)
        {
            this._frame = null;
        }

        if (Phaser.Video && this.key instanceof Phaser.Video)
        {
            this.key.onChangeSource.remove(this.resizeFrame, this);
        }

        this.alive = false;
        this.exists = false;
        this.visible = false;

        this.filters = null;
        this.mask = null;
        this.game = null;

        //  In case Pixi is still going to try and render it even though destroyed
        this.renderable = false;

        //  Pixi level DisplayObject destroy
        this.transformCallback = null;
        this.transformCallbackContext = null;
        this.hitArea = null;
        this.parent = null;
        this.stage = null;
        this.worldTransform = null;
        this.filterArea = null;
        this._bounds = null;
        this._currentBounds = null;
        this._mask = null;

        this._destroyCachedSprite();

        this.destroyPhase = false;

    }

};
<commit_msg>Updated Destroy component to deal with BitmapText glyphs pool.<commit_after>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2015 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The Destroy component is responsible for destroying a Game Object.
*
* @class
*/
Phaser.Component.Destroy = function () {};

Phaser.Component.Destroy.prototype = {

    /**
    * As a Game Object runs through its destroy method this flag is set to true,
    * and can be checked in any sub-systems or plugins it is being destroyed from.
    * @property {boolean} destroyPhase
    * @readOnly
    */
    destroyPhase: false,

    /**
    * Destroys the Game Object. This removes it from its parent group, destroys the input, event and animation handlers if present
    * and nulls its reference to `game`, freeing it up for garbage collection.
    *
    * If this Game Object has the Events component it will also dispatch the `onDestroy` event.
    *
    * @method
    * @param {boolean} [destroyChildren=true] - Should every child of this object have its destroy method called as well?
    */
    destroy: function(destroyChildren) {

        if (this.game === null || this.destroyPhase) { return; }

        if (typeof destroyChildren === 'undefined') { destroyChildren = true; }

        this.destroyPhase = true;

        if (this.events)
        {
            this.events.onDestroy$dispatch(this);
        }

        if (this.parent)
        {
            if (this.parent instanceof Phaser.Group)
            {
                this.parent.remove(this);
            }
            else
            {
                this.parent.removeChild(this);
            }
        }

        if (this.input)
        {
            this.input.destroy();
        }

        if (this.animations)
        {
            this.animations.destroy();
        }

        if (this.body)
        {
            this.body.destroy();
        }

        if (this.events)
        {
            this.events.destroy();
        }

        var i = this.children.length;

        if (destroyChildren)
        {
            while (i--)
            {
                this.children[i].destroy(destroyChildren);
            }
        }
        else
        {
            while (i--)
            {
                this.removeChild(this.children[i]);
            }
        }

        if (this._crop)
        {
            this._crop = null;
        }

        if (this._frame)
        {
            this._frame = null;
        }

        if (Phaser.Video && this.key instanceof Phaser.Video)
        {
            this.key.onChangeSource.remove(this.resizeFrame, this);
        }

        if (Phaser.BitmapText && this._glyphs)
        {
            this._glyphs = [];
        }

        this.alive = false;
        this.exists = false;
        this.visible = false;

        this.filters = null;
        this.mask = null;
        this.game = null;

        //  In case Pixi is still going to try and render it even though destroyed
        this.renderable = false;

        //  Pixi level DisplayObject destroy
        this.transformCallback = null;
        this.transformCallbackContext = null;
        this.hitArea = null;
        this.parent = null;
        this.stage = null;
        this.worldTransform = null;
        this.filterArea = null;
        this._bounds = null;
        this._currentBounds = null;
        this._mask = null;

        this._destroyCachedSprite();

        this.destroyPhase = false;

    }

};
<|endoftext|>


<commit_before>(function (module) {
    mifosX.controllers = _.extend(module, {
        NavigationController: function (scope, resourceFactory) {

            scope.offices = [];
            scope.isCollapsed = false;
            scope.officerCollapsed = true;
            scope.groupCollapsed = true;
            scope.centerCollapsed = true;
            scope.clientCollapsed = true;
            resourceFactory.officeResource.get({officeId: 1}, function (data) {
                scope.office = data;
                scope.officeName = data.name;
            });
            resourceFactory.officeResource.getAllOffices(function (data) {
                scope.offices = data;
            });

            scope.collapseOthers = function () {
                scope.filterText = '';
                scope.isCollapsed = !scope.isCollapsed;
                if (scope.isCollapsed == false) {
                    scope.officerCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.centerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseOfficerOthers = function () {
                scope.filterText = '';
                scope.officerCollapsed = !scope.officerCollapsed;
                if (scope.officerCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.centerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseCenterOthers = function () {
                scope.filterText = '';
                scope.centerCollapsed = !scope.centerCollapsed;
                if (scope.centerCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.officerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseGroupOthers = function () {
                scope.filterText = '';
                scope.groupCollapsed = !scope.groupCollapsed;
                if (scope.groupCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.centerCollapsed = true;
                    scope.officerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseClientOthers = function () {
                scope.filterText = '';
                scope.clientCollapsed = !scope.clientCollapsed;
                if (scope.clientCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.officerCollapsed = true;
                    scope.centerCollapsed = true;
                }
            };

            scope.officeSelected = function (officeId, office) {
                scope.officeName = office;
                scope.selectedOffice = officeId;
                scope.filterText = '';
                scope.staffs = '';
                scope.staff = '';
                scope.group = '';
                scope.center = '';
                scope.client = '';
                scope.centers = '';
                scope.clients = '';
                scope.groups = '';
                scope.groupsOrCenters = '';
                scope.isCollapsed = true;
                scope.officerCollapsed = false;
                scope.centerCollapsed = true;
                scope.clientCollapsed = true;
                scope.groupCollapsed = true;
                scope.loanOfficer = '';
                scope.centerName = '';
                scope.groupName = '';
                scope.clientName = '';
                if (scope.staff == '' && scope.group == '' && scope.center == '' && scope.client == '') {
                    resourceFactory.officeResource.get({officeId: officeId}, function (data) {
                        scope.office = data;
                    });
                    resourceFactory.employeeResource.getAllEmployees({'officeId': officeId}, function (data) {
                        scope.staffs = data;
                    });
                }
            };

            scope.staffSelected = function (staffId, staffName) {
                scope.office = '';
                scope.group = '';
                scope.client = '';
                scope.filterText = '';
                scope.center = '';
                scope.centerName = '';
                scope.groupName = '';
                scope.clientName = '';
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = false;
                scope.clientCollapsed = true;
                scope.groupCollapsed = true;
                scope.clients = '';
                scope.groups = '';
                if (scope.office == '' && scope.group == '' && scope.center == '' && scope.client == '') {
                    resourceFactory.employeeResource.get({staffId: staffId}, function (data) {
                        scope.staff = data;
                    });
                    scope.loanOfficer = staffName;
                    scope.selectedStaff = staffId;
                    resourceFactory.runReportsResource.get({reportSource: 'GroupNamesByStaff', 'R_staffId': staffId, genericResultSet: 'false'}, function (data) {
                        scope.centers = data;
                    });
                }
            };
            scope.centerSelected = function (centerId, centerName) {
                scope.office = '';
                scope.staff = '';
                scope.client = '';
                scope.group = '';
                scope.filterText = '';
                scope.groupName = '';
                scope.clientName = '';
                scope.clients = '';
                scope.centerName = centerName;
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = true;
                scope.clientCollapsed = true;
                scope.groupCollapsed = false;
                if (scope.office == '' && scope.group == '' && scope.staff == '' && scope.client == '') {
                    resourceFactory.centerResource.get({centerId: centerId, associations: 'groupMembers'}, function (data) {
                        scope.groups = data.groupMembers;
                        scope.center = data;
                    });
                    resourceFactory.centerAccountResource.get({centerId: centerId}, function (data) {
                        scope.centerAccounts = data;
                    });
                }
            };
            scope.groupSelected = function (groupId, groupName) {
                scope.office = '';
                scope.filterText = '';
                scope.staff = '';
                scope.center = '';
                scope.client = '';
                scope.clientName = '';
                scope.groupName = groupName;
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = true;
                scope.clientCollapsed = false;
                scope.groupCollapsed = true;
                if (scope.office == '' && scope.center == '' && scope.staff == '' && scope.client == '') {
                    resourceFactory.groupResource.get({groupId: groupId, associations: 'all'}, function (data) {
                        scope.group = data;
                        scope.clients = data.clientMembers;
                    });
                    resourceFactory.groupAccountResource.get({groupId: groupId}, function (data) {
                        scope.groupAccounts = data;
                    });
                }
            };
            scope.clientSelected = function (clientId, clientName) {
                scope.office = '';
                scope.filterText = '';
                scope.staff = '';
                scope.center = '';
                scope.group = '';
                scope.clientName = clientName;
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = true;
                scope.clientCollapsed = false;
                scope.groupCollapsed = true;
                if (scope.office == '' && scope.center == '' && scope.staff == '' && scope.group == '') {
                    resourceFactory.clientResource.get({clientId: clientId}, function (data) {
                        scope.client = data;
                    });
                    resourceFactory.clientAccountResource.get({clientId: clientId}, function (data) {
                        scope.clientAccounts = data;
                    });
                }
            };
        }
    });
    mifosX.ng.application.controller('NavigationController', ['$scope', 'ResourceFactory', mifosX.controllers.NavigationController]).run(function ($log) {
        $log.info("NavigationController initialized");
    });
}(mifosX.controllers || {}));
<commit_msg>Access to summary from nav<commit_after>(function (module) {
    mifosX.controllers = _.extend(module, {
        NavigationController: function (scope, resourceFactory) {

            scope.offices = [];
            scope.isCollapsed = false;
            scope.officerCollapsed = true;
            scope.groupCollapsed = true;
            scope.centerCollapsed = true;
            scope.clientCollapsed = true;
            resourceFactory.officeResource.get({officeId: 1}, function (data) {
                scope.office = data;
                scope.officeName = data.name;
            });
            resourceFactory.officeResource.getAllOffices(function (data) {
                scope.offices = data;
            });

            scope.collapseOthers = function () {
                scope.filterText = '';
                scope.isCollapsed = !scope.isCollapsed;
                if (scope.isCollapsed == false) {
                    scope.officerCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.centerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseOfficerOthers = function () {
                scope.filterText = '';
                scope.officerCollapsed = !scope.officerCollapsed;
                if (scope.officerCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.centerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseCenterOthers = function () {
                scope.filterText = '';
                scope.centerCollapsed = !scope.centerCollapsed;
                if (scope.centerCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.officerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseGroupOthers = function () {
                scope.filterText = '';
                scope.groupCollapsed = !scope.groupCollapsed;
                if (scope.groupCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.centerCollapsed = true;
                    scope.officerCollapsed = true;
                    scope.clientCollapsed = true;
                }
            };
            scope.collapseClientOthers = function () {
                scope.filterText = '';
                scope.clientCollapsed = !scope.clientCollapsed;
                if (scope.clientCollapsed == false) {
                    scope.isCollapsed = true;
                    scope.groupCollapsed = true;
                    scope.officerCollapsed = true;
                    scope.centerCollapsed = true;
                }
            };

            scope.officeSelected = function (officeId, office) {
                scope.officeName = office;
                scope.selectedOffice = officeId;
                scope.filterText = '';
                scope.staffs = '';
                scope.staff = '';
                scope.group = '';
                scope.center = '';
                scope.client = '';
                scope.centers = '';
                scope.clients = '';
                scope.groups = '';
                scope.groupsOrCenters = '';
                scope.isCollapsed = true;
                scope.officerCollapsed = false;
                scope.centerCollapsed = true;
                scope.clientCollapsed = true;
                scope.groupCollapsed = true;
                scope.loanOfficer = '';
                scope.centerName = '';
                scope.groupName = '';
                scope.clientName = '';
                if (scope.staff == '' && scope.group == '' && scope.center == '' && scope.client == '') {
                    resourceFactory.officeResource.get({officeId: officeId}, function (data) {
                        scope.office = data;
                    });
                    resourceFactory.employeeResource.getAllEmployees({'officeId': officeId}, function (data) {
                        scope.staffs = data;
                    });
                }
            };

            scope.staffSelected = function (staffId, staffName) {
                scope.office = '';
                scope.group = '';
                scope.client = '';
                scope.filterText = '';
                scope.center = '';
                scope.centerName = '';
                scope.groupName = '';
                scope.clientName = '';
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = false;
                scope.clientCollapsed = true;
                scope.groupCollapsed = true;
                scope.clients = '';
                scope.groups = '';
                if (scope.office == '' && scope.group == '' && scope.center == '' && scope.client == '') {
                    resourceFactory.employeeResource.get({staffId: staffId}, function (data) {
                        scope.staff = data;
                    });
                    scope.loanOfficer = staffName;
                    scope.selectedStaff = staffId;
                    resourceFactory.runReportsResource.get({reportSource: 'GroupNamesByStaff', 'R_staffId': staffId, genericResultSet: 'false'}, function (data) {
                        scope.centers = data;
                    });
                }
            };
            scope.centerSelected = function (centerId, centerName) {
                scope.office = '';
                scope.staff = '';
                scope.client = '';
                scope.group = '';
                scope.filterText = '';
                scope.groupName = '';
                scope.clientName = '';
                scope.clients = '';
                scope.centerName = centerName;
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = true;
                scope.clientCollapsed = true;
                scope.groupCollapsed = false;
                if (scope.office == '' && scope.group == '' && scope.staff == '' && scope.client == '') {
                    resourceFactory.centerResource.get({centerId: centerId, associations: 'groupMembers'}, function (data) {
                        scope.groups = data.groupMembers;
                        scope.center = data;
                    });
                    resourceFactory.centerAccountResource.get({centerId: centerId}, function (data) {
                        scope.centerAccounts = data;
                    });
                    resourceFactory.runReportsResource.get({reportSource: 'GroupSummaryCounts', genericResultSet: 'false', R_groupId: centerId}, function (data) {
                        scope.summary = data[0];
                    });
                }
            };
            scope.groupSelected = function (groupId, groupName) {
                scope.office = '';
                scope.filterText = '';
                scope.staff = '';
                scope.center = '';
                scope.client = '';
                scope.clientName = '';
                scope.groupName = groupName;
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = true;
                scope.clientCollapsed = false;
                scope.groupCollapsed = true;
                if (scope.office == '' && scope.center == '' && scope.staff == '' && scope.client == '') {
                    resourceFactory.groupResource.get({groupId: groupId, associations: 'all'}, function (data) {
                        scope.group = data;
                        scope.clients = data.clientMembers;
                    });
                    resourceFactory.groupAccountResource.get({groupId: groupId}, function (data) {
                        scope.groupAccounts = data;
                    });
                }
            };
            scope.clientSelected = function (clientId, clientName) {
                scope.office = '';
                scope.filterText = '';
                scope.staff = '';
                scope.center = '';
                scope.group = '';
                scope.clientName = clientName;
                scope.isCollapsed = true;
                scope.officerCollapsed = true;
                scope.centerCollapsed = true;
                scope.clientCollapsed = false;
                scope.groupCollapsed = true;
                if (scope.office == '' && scope.center == '' && scope.staff == '' && scope.group == '') {
                    resourceFactory.clientResource.get({clientId: clientId}, function (data) {
                        scope.client = data;
                    });
                    resourceFactory.clientAccountResource.get({clientId: clientId}, function (data) {
                        scope.clientAccounts = data;
                    });
                }
            };
        }
    });
    mifosX.ng.application.controller('NavigationController', ['$scope', 'ResourceFactory', mifosX.controllers.NavigationController]).run(function ($log) {
        $log.info("NavigationController initialized");
    });
}(mifosX.controllers || {}));
<|endoftext|>


<commit_before>/**
 * ufAlerts plugin.  Fetches and renders alerts from the UF alert stream.
 *
 * jQuery plugin template adapted from https://gist.github.com/Air-Craft/1300890
 *
 * === USAGE ===
 *
 * ufAlerts can be initialized on any container element as follows:
 *
 * $("#myDiv").ufAlerts(options);
 *
 * `options` is an object containing any of the following parameters:
 * @param {string} url The absolute URL from which to fetch flash alerts.
 * @param {bool} scrollToTop Whether to automatically scroll back to the top of the page after rendering alerts.
 * @param {string} alertMessageClass The CSS class(es) to be applied to each alert message.
 * @param {string} alertTemplateId The CSS id(es) for the Handlebar alert template.
 * @param {bool} agglomerate Set to true to render all alerts together, applying styling for the highest-priority alert being rendered.
 *
 * == EVENTS ==
 *
 * uf-form triggers the following events:
 *
 * `fetch.ufAlerts`: triggered when the alerts have been successfully fetched from the server.
 * `render.ufAlerts`: triggered when all alerts have been rendered and the call to render() has completed.
 *
 * == METHODS ==
 *
 * `fetch()`: gets messages from the server.
 * `push(type, message)`: adds a message of a specified type (danger, warning, info, success) to the internal collection of alerts.
 * `clear()`: removes all messages from the internal collection.
 * `render()`: renders the collection of alerts to the container.
 *
 * UserFrosting https://www.userfrosting.com
 * @author Alexander Weissman https://alexanderweissman.com
 */

// if (!window.L) { window.L = function () { console.log(arguments);} } // optional EZ quick logging for debugging

(function( $ )
{
    /**
     * The plugin namespace, ie for $('.selector').ufAlerts(options)
     *
     * Also the id for storing the object state via $('.selector').data()
     */
    var PLUGIN_NS = 'ufAlerts';

    var Plugin = function ( target, options )
    {
        this.$T = $(target);

        /** #### OPTIONS #### */
        this.options= $.extend(
            true,               // deep extend
            {
                url                : site.uri.public + "/alerts",
                scrollToTop        : true,
                agglomerate        : false,
                alertMessageClass  : "uf-alert-message",
                alertTemplateId    : "uf-alert-template",
                DEBUG: false
            },
            options
        );

        this._alertMessageTemplateHtml = $("#" + this.options.alertTemplateId).html();

        this._alertTypePriorities = {
            "danger" : 3,
            "warning": 2,
            "success": 1,
            "info"   : 0
        };

        this._alertTypeIcon = {
            "danger" : "fa-ban",
            "warning": "fa-warning",
            "success": "fa-check",
            "info"   : "fa-info"
        };

        this._init( target, options );

        return this;
    }

    /** #### INITIALISER #### */
    Plugin.prototype._init = function ( target, options )
    {
        var base = this;
        var $el = $(target);

        base.messages = [];

        base._newMessagesPromise = $.Deferred();

        return base.$T;
    };

    /**
     * Clear all messages from the current uf-alerts collection.
     *
     */
    Plugin.prototype.clear = function ()
    {
        var base = this;

        // See http://stackoverflow.com/a/1232046/2970321
        base.messages.length = 0;

        // Also, turn off all alert styling in agglomerate container
        if (base.options.agglomerate) {

            base.$T.toggleClass("alert", false)
                .toggleClass("alert-info", false)
                .toggleClass("alert-success", false)
                .toggleClass("alert-warning", false)
                .toggleClass("alert-danger", false);
        }

        return base.$T;
    };

    Plugin.prototype.destroy = function () {
        var base = this;
        var $el = base.$T;

        // Delete the plugin object
        base.delete;

        // Unbind any bound events
        $el.off('.ufAlerts');

        // Remove plugin name from data-* attribute
        $el.removeData(PLUGIN_NS);
    };

    /**
     * Fetches messages from the alert stream
     *
     */
    Plugin.prototype.fetch = function ()
    {
        var base = this;

        // Set a promise, so that any chained calls after fetch can wait until the messages have been retrieved
        base._newMessagesPromise = $.getJSON( base.options.url )
        .done(function ( data ) {
            if (data) {
                base.messages = $.merge(base.messages, data);
            }

            base.$T.trigger("fetch.ufAlerts");
        }).fail(function ( data ) {
            base.$T.trigger('error.ufAlerts');
            if ((typeof site !== "undefined") && site.debug.ajax && data.responseText) {
                document.write(data.responseText);
                document.close();
            } else {
                if (base.options.DEBUG) {
                    console.log("Error (" + data.status + "): " + data.responseText );
                }
            }
        });

        return base.$T;
    };

    /**
     * Push a given message to the current uf-alerts collection.
     *
     */
    Plugin.prototype.push = function (type, message)
    {
        var base = this;

        base.messages.push({
            "type"   : type,
            "message": message
        });

        return base.$T;
    };

    /**
     * Renders the messages.
     *
     */
    Plugin.prototype.render = function ()
    {
        var base = this;

        $.when(base._newMessagesPromise).then( function () {

            // Display alerts
            var alertHtml = "";

            // If agglomeration is enabled, set the container to the highest priority message type
            if (base.messages.length && base.options.agglomerate) {

                var alertMessageTemplate = Handlebars.compile(base._alertMessageTemplateHtml, {noEscape: true});

                var message = "
";
                var alertContainerType = "info";

                jQuery.each(base.messages, function(alert_idx, alert) {
                    if (base._alertTypePriorities[alert["type"]] > base._alertTypePriorities[alertContainerType]) {
                        alertContainerType = alert["type"];
                    }
                });

                var aggTemplate = Handlebars.compile("
{{ message }}
");
                jQuery.each(base.messages, function(alert_idx, alert) {
                    message += aggTemplate(alert);
                });

                message += "
";

                // Render alert
                alertHtml += alertMessageTemplate({
                    "type": alertContainerType,
                    "message": message,
                    "icon": base._alertTypeIcon[alertContainerType]
                });

            } else {

                var alertMessageTemplate = Handlebars.compile(base._alertMessageTemplateHtml, {noEscape: true});

                jQuery.each(base.messages, function(alert_idx, alert) {

                    // Inject icon
                    alert["icon"] = base._alertTypeIcon[alert["type"]];

                    // Render alert
                    alertHtml += alertMessageTemplate(alert);
                });
            }

            base.$T.html(alertHtml);

            // Scroll back to top of page
            if (base.options.scrollToTop) {
                $("html, body").animate({
                    scrollTop: 0
                }, "fast");
            }

            base.$T.trigger("render.ufAlerts");

            return base.$T;
        });
    };

    /** #### PRIVATE METHODS #### */

    /**
     * EZ Logging/Warning (technically private but saving an '_' is worth it imo)
     */
    Plugin.prototype.DLOG = function ()
    {
        if (!this.DEBUG) return;
        for (var i in arguments) {
            console.log( PLUGIN_NS + ': ', arguments[i] );
        }
    }
    Plugin.prototype.DWARN = function ()
    {
        this.DEBUG && console.warn( arguments );
    }

/*###################################################################################
 * JQUERY HOOK
 ###################################################################################*/

    /**
     * Generic jQuery plugin instantiation method call logic
     *
     * Method options are stored via jQuery's data() method in the relevant element(s)
     * Notice, myActionMethod mustn't start with an underscore (_) as this is used to
     * indicate private methods on the PLUGIN class.
     */
    $.fn[ PLUGIN_NS ] = function( methodOrOptions )
    {
        if (!$(this).length) {
            return $(this);
        }
        var instance = $(this).data(PLUGIN_NS);

        // CASE: action method (public method on PLUGIN class)
        if ( instance
                && methodOrOptions.indexOf('_') != 0
                && instance[ methodOrOptions ]
                && typeof( instance[ methodOrOptions ] ) == 'function' ) {

            return instance[ methodOrOptions ]( Array.prototype.slice.call( arguments, 1 ) );

        // CASE: argument is options object or empty = initialise
        } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {

            instance = new Plugin( $(this), methodOrOptions );    // ok to overwrite if this is a re-init
            $(this).data( PLUGIN_NS, instance );
            return $(this);

        // CASE: method called before init
        } else if ( !instance ) {
            $.error( 'Plugin must be initialised before using method: ' + methodOrOptions );

        // CASE: invalid method
        } else if ( methodOrOptions.indexOf('_') == 0 ) {
            $.error( 'Method ' +  methodOrOptions + ' is private!' );
        } else {
            $.error( 'Method ' +  methodOrOptions + ' does not exist.' );
        }
    };
})(jQuery);
<commit_msg>ufAlerts now scroll to alert location, if and only if alerts are output.<commit_after>/**
 * ufAlerts plugin.  Fetches and renders alerts from the UF alert stream.
 *
 * jQuery plugin template adapted from https://gist.github.com/Air-Craft/1300890
 *
 * === USAGE ===
 *
 * ufAlerts can be initialized on any container element as follows:
 *
 * $("#myDiv").ufAlerts(options);
 *
 * `options` is an object containing any of the following parameters:
 * @param {string} url The absolute URL from which to fetch flash alerts.
 * @param {bool} scrollToTop Whether to automatically scroll back to the top of the page after rendering alerts.
 * @param {string} alertMessageClass The CSS class(es) to be applied to each alert message.
 * @param {string} alertTemplateId The CSS id(es) for the Handlebar alert template.
 * @param {bool} agglomerate Set to true to render all alerts together, applying styling for the highest-priority alert being rendered.
 *
 * == EVENTS ==
 *
 * uf-form triggers the following events:
 *
 * `fetch.ufAlerts`: triggered when the alerts have been successfully fetched from the server.
 * `render.ufAlerts`: triggered when all alerts have been rendered and the call to render() has completed.
 *
 * == METHODS ==
 *
 * `fetch()`: gets messages from the server.
 * `push(type, message)`: adds a message of a specified type (danger, warning, info, success) to the internal collection of alerts.
 * `clear()`: removes all messages from the internal collection.
 * `render()`: renders the collection of alerts to the container.
 *
 * UserFrosting https://www.userfrosting.com
 * @author Alexander Weissman https://alexanderweissman.com
 */

// if (!window.L) { window.L = function () { console.log(arguments);} } // optional EZ quick logging for debugging

(function( $ )
{
    /**
     * The plugin namespace, ie for $('.selector').ufAlerts(options)
     *
     * Also the id for storing the object state via $('.selector').data()
     */
    var PLUGIN_NS = 'ufAlerts';

    var Plugin = function ( target, options )
    {
        this.$T = $(target);

        /** #### OPTIONS #### */
        this.options= $.extend(
            true,               // deep extend
            {
                url                : site.uri.public + "/alerts",
                scrollToTop        : true,
                agglomerate        : false,
                alertMessageClass  : "uf-alert-message",
                alertTemplateId    : "uf-alert-template",
                DEBUG: false
            },
            options
        );

        this._alertMessageTemplateHtml = $("#" + this.options.alertTemplateId).html();

        this._alertTypePriorities = {
            "danger" : 3,
            "warning": 2,
            "success": 1,
            "info"   : 0
        };

        this._alertTypeIcon = {
            "danger" : "fa-ban",
            "warning": "fa-warning",
            "success": "fa-check",
            "info"   : "fa-info"
        };

        this._init( target, options );

        return this;
    }

    /** #### INITIALISER #### */
    Plugin.prototype._init = function ( target, options )
    {
        var base = this;
        var $el = $(target);

        base.messages = [];

        base._newMessagesPromise = $.Deferred();

        return base.$T;
    };

    /**
     * Clear all messages from the current uf-alerts collection.
     *
     */
    Plugin.prototype.clear = function ()
    {
        var base = this;

        // See http://stackoverflow.com/a/1232046/2970321
        base.messages.length = 0;

        // Also, turn off all alert styling in agglomerate container
        if (base.options.agglomerate) {

            base.$T.toggleClass("alert", false)
                .toggleClass("alert-info", false)
                .toggleClass("alert-success", false)
                .toggleClass("alert-warning", false)
                .toggleClass("alert-danger", false);
        }

        return base.$T;
    };

    Plugin.prototype.destroy = function () {
        var base = this;
        var $el = base.$T;

        // Delete the plugin object
        base.delete;

        // Unbind any bound events
        $el.off('.ufAlerts');

        // Remove plugin name from data-* attribute
        $el.removeData(PLUGIN_NS);
    };

    /**
     * Fetches messages from the alert stream
     *
     */
    Plugin.prototype.fetch = function ()
    {
        var base = this;

        // Set a promise, so that any chained calls after fetch can wait until the messages have been retrieved
        base._newMessagesPromise = $.getJSON( base.options.url )
        .done(function ( data ) {
            if (data) {
                base.messages = $.merge(base.messages, data);
            }

            base.$T.trigger("fetch.ufAlerts");
        }).fail(function ( data ) {
            base.$T.trigger('error.ufAlerts');
            if ((typeof site !== "undefined") && site.debug.ajax && data.responseText) {
                document.write(data.responseText);
                document.close();
            } else {
                if (base.options.DEBUG) {
                    console.log("Error (" + data.status + "): " + data.responseText );
                }
            }
        });

        return base.$T;
    };

    /**
     * Push a given message to the current uf-alerts collection.
     *
     */
    Plugin.prototype.push = function (type, message)
    {
        var base = this;

        base.messages.push({
            "type"   : type,
            "message": message
        });

        return base.$T;
    };

    /**
     * Renders the messages.
     *
     */
    Plugin.prototype.render = function ()
    {
        var base = this;

        $.when(base._newMessagesPromise).then( function () {

            // Display alerts
            var alertHtml = "";

            // If agglomeration is enabled, set the container to the highest priority message type
            if (base.messages.length && base.options.agglomerate) {

                var alertMessageTemplate = Handlebars.compile(base._alertMessageTemplateHtml, {noEscape: true});

                var message = "
";
                var alertContainerType = "info";

                jQuery.each(base.messages, function(alert_idx, alert) {
                    if (base._alertTypePriorities[alert["type"]] > base._alertTypePriorities[alertContainerType]) {
                        alertContainerType = alert["type"];
                    }
                });

                var aggTemplate = Handlebars.compile("
{{ message }}
");
                jQuery.each(base.messages, function(alert_idx, alert) {
                    message += aggTemplate(alert);
                });

                message += "
";

                // Render alert
                alertHtml += alertMessageTemplate({
                    "type": alertContainerType,
                    "message": message,
                    "icon": base._alertTypeIcon[alertContainerType]
                });

            } else {

                var alertMessageTemplate = Handlebars.compile(base._alertMessageTemplateHtml, {noEscape: true});

                jQuery.each(base.messages, function(alert_idx, alert) {

                    // Inject icon
                    alert["icon"] = base._alertTypeIcon[alert["type"]];

                    // Render alert
                    alertHtml += alertMessageTemplate(alert);
                });
            }

            base.$T.html(alertHtml);

            // Scroll to alert location if new alerts output
            if (base.options.scrollToTop && alertHtml != "") {
                $("html, body").animate({
                    scrollTop: base.$T.offset().top
                }, "fast");
            }

            base.$T.trigger("render.ufAlerts");

            return base.$T;
        });
    };

    /** #### PRIVATE METHODS #### */

    /**
     * EZ Logging/Warning (technically private but saving an '_' is worth it imo)
     */
    Plugin.prototype.DLOG = function ()
    {
        if (!this.DEBUG) return;
        for (var i in arguments) {
            console.log( PLUGIN_NS + ': ', arguments[i] );
        }
    }
    Plugin.prototype.DWARN = function ()
    {
        this.DEBUG && console.warn( arguments );
    }

/*###################################################################################
 * JQUERY HOOK
 ###################################################################################*/

    /**
     * Generic jQuery plugin instantiation method call logic
     *
     * Method options are stored via jQuery's data() method in the relevant element(s)
     * Notice, myActionMethod mustn't start with an underscore (_) as this is used to
     * indicate private methods on the PLUGIN class.
     */
    $.fn[ PLUGIN_NS ] = function( methodOrOptions )
    {
        if (!$(this).length) {
            return $(this);
        }
        var instance = $(this).data(PLUGIN_NS);

        // CASE: action method (public method on PLUGIN class)
        if ( instance
                && methodOrOptions.indexOf('_') != 0
                && instance[ methodOrOptions ]
                && typeof( instance[ methodOrOptions ] ) == 'function' ) {

            return instance[ methodOrOptions ]( Array.prototype.slice.call( arguments, 1 ) );

        // CASE: argument is options object or empty = initialise
        } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {

            instance = new Plugin( $(this), methodOrOptions );    // ok to overwrite if this is a re-init
            $(this).data( PLUGIN_NS, instance );
            return $(this);

        // CASE: method called before init
        } else if ( !instance ) {
            $.error( 'Plugin must be initialised before using method: ' + methodOrOptions );

        // CASE: invalid method
        } else if ( methodOrOptions.indexOf('_') == 0 ) {
            $.error( 'Method ' +  methodOrOptions + ' is private!' );
        } else {
            $.error( 'Method ' +  methodOrOptions + ' does not exist.' );
        }
    };
})(jQuery);
<|endoftext|>


<commit_before>Vps.Form.ComboBox = Ext.extend(Ext.form.ComboBox,
{
    initComponent : function()
    {
        this.addEvents({
            changevalue : true
        });
        if(!this.store) {
            throw "no store set";
        }

        //store klonen (um nicht this.initalConfig.store zu ändern)
        var store = {};
        for (var i in this.store) {
            store[i] = this.store[i];
        }
        delete this.store;
        if (store.data) {
            store = Ext.applyIf(store, {
                fields: ['id', 'name'],
                id: 'id'
            });
            this.store = new Ext.data.SimpleStore(store);
            this.mode = 'local';
        } else {
            if (store.reader) {
                if (store.reader.type && Ext.data[store.reader.type]) {
                    var readerType = Ext.data[store.reader.type];
                    delete store.reader.type;
                } else if (store.reader.type) {
                    try {
                        var readerType = eval(store.reader.type);
                    } catch(e) {
                        throw "invalid readerType: "+store.reader.type;
                    }
                    delete store.reader.type;
                } else {
                    var readerType = Ext.data.JsonReader;
                }
                if (!store.reader.rows) throw "no rows defined, required if reader doesn't this through meta data";
                var rows = store.reader.rows;
                delete store.reader.rows;
                var reader = new readerType(store.reader, rows);
            } else {
                var reader = new Ext.data.JsonReader(); //reader thisuriert sich autom. durch meta-daten
            }
            if (store.proxy) {
                if (store.proxy.type && Ext.data[store.proxy.type]) {
                    var proxyType = Ext.data[store.proxy.type];
                    delete store.proxy.type;
                } else if (store.proxy.type) {
                    try {
                        var proxyType = eval(store.proxy.type);
                    } catch(e) {
                        throw "invalid proxyType: "+store.proxy.type;
                    }
                    delete store.proxy.type;
                } else {
                    var proxyType = Ext.data.HttpProxy;
                }
                var proxy = new proxyType(store.proxy);
            } else if (store.data) {
                var proxy = new Ext.data.MemoryProxy(store.data);
            } else {
                var proxy = new Ext.data.HttpProxy(store);
            }
            if (store.type && Ext.data[store.type]) {
                this.store = new Ext.data[store.type]({
                    proxy: proxy,
                    reader: reader
                });
            } else if (store.type) {
                try {
                    var storeType = eval(store.type)
                } catch(e) {
                    throw "invalid storeType: "+store.type;
                }
                this.store = new storeType({
                    proxy: proxy,
                    reader: reader
                });
            } else {
                this.store = new Ext.data.Store({
                    proxy: proxy,
                    reader: reader
                });
            }
        }

        Ext.applyIf(this, {
            displayField: 'name',
            valueField: 'id'
        });

        if (this.addDialog) {
            var d = Vps.Auto.Form.Window;
            if (this.addDialog.type) {
                try {
                    d = eval(this.addDialog.type);
                } catch (e) {
                    throw new Error("Invalid addDialog \'"+this.addDialog.type+"': "+e);
                }
            }
            this.addDialog = new d(this.addDialog);
            this.addDialog.on('datachange', function(result) {
                if (result.data.addedId) {
                    //neuen Eintrag auswählen
                    this.setValue(result.data.addedId);
                }
            }, this);
        }

        this.store.on('load', function() {
            this.addNoSelection();
        }, this);
        if (this.store.recordType) {
            this.addNoSelection();
        }
        if (this.showNoSelection) {
            this.allowBlank = false;
        }

        Vps.Form.ComboBox.superclass.initComponent.call(this);
    },
    addNoSelection : function() {
        if (this.showNoSelection && this.store.find('id', '') == -1) {
            var data = {};
            data[this.displayField] = '(no selection)';
            data[this.valueField] = null;
            this.store.insert(0, new this.store.recordType(data));
        }
    },
    setValue : function(v)
    {
        if (v == '') v = null;
        if (this.store.proxy && this.valueField && this.mode == 'remote') {
            //wenn proxy vorhanden können daten nachgeladen werden
            //also loading anzeigen (siehe setValue)
            this.valueNotFoundText = this.loadingText;
        } else {
            this.valueNotFoundText = '';
        }
        Vps.Form.ComboBox.superclass.setValue.apply(this, arguments);
        if (this.valueField
                && !this.findRecord(this.valueField, v) //record nicht gefunden
                && this.mode == 'remote'
                && this.store.proxy //proxy vorhanden (dh. daten können nachgeladen werden)
                ) {
            this.store.baseParams[this.queryParam] = v;
            this.store.load({
                params: this.getParams(v),
                callback: function(r, options, success) {
                    if (success && this.findRecord(this.valueField, this.value)) {
                        this.setValue(this.value);
                    }
                },
                scope: this
            });
        }
        this.fireEvent('changevalue', this.value);
    },
    onRender : function(ct, position)
    {
        Vps.Form.ComboBox.superclass.onRender.call(this, ct, position);
        if (this.addDialog) {
            var c = this.el.up('div.x-form-field-wrap').insertSibling({style: 'float: right'}, 'before');
            var button = new Ext.Button({
                renderTo: c,
                text: this.addDialog.text || 'add new entry',
                handler: function() {
                    this.addDialog.showAdd();
                },
                scope: this
            });
        }
    }
});
Ext.reg('combobox', Vps.Form.ComboBox);
<commit_msg>wenn nichts ausgewählt auch nichts laden<commit_after>Vps.Form.ComboBox = Ext.extend(Ext.form.ComboBox,
{
    initComponent : function()
    {
        this.addEvents({
            changevalue : true
        });
        if(!this.store) {
            throw "no store set";
        }

        //store klonen (um nicht this.initalConfig.store zu ändern)
        var store = {};
        for (var i in this.store) {
            store[i] = this.store[i];
        }
        delete this.store;
        if (store.data) {
            store = Ext.applyIf(store, {
                fields: ['id', 'name'],
                id: 'id'
            });
            this.store = new Ext.data.SimpleStore(store);
            this.mode = 'local';
        } else {
            if (store.reader) {
                if (store.reader.type && Ext.data[store.reader.type]) {
                    var readerType = Ext.data[store.reader.type];
                    delete store.reader.type;
                } else if (store.reader.type) {
                    try {
                        var readerType = eval(store.reader.type);
                    } catch(e) {
                        throw "invalid readerType: "+store.reader.type;
                    }
                    delete store.reader.type;
                } else {
                    var readerType = Ext.data.JsonReader;
                }
                if (!store.reader.rows) throw "no rows defined, required if reader doesn't this through meta data";
                var rows = store.reader.rows;
                delete store.reader.rows;
                var reader = new readerType(store.reader, rows);
            } else {
                var reader = new Ext.data.JsonReader(); //reader thisuriert sich autom. durch meta-daten
            }
            if (store.proxy) {
                if (store.proxy.type && Ext.data[store.proxy.type]) {
                    var proxyType = Ext.data[store.proxy.type];
                    delete store.proxy.type;
                } else if (store.proxy.type) {
                    try {
                        var proxyType = eval(store.proxy.type);
                    } catch(e) {
                        throw "invalid proxyType: "+store.proxy.type;
                    }
                    delete store.proxy.type;
                } else {
                    var proxyType = Ext.data.HttpProxy;
                }
                var proxy = new proxyType(store.proxy);
            } else if (store.data) {
                var proxy = new Ext.data.MemoryProxy(store.data);
            } else {
                var proxy = new Ext.data.HttpProxy(store);
            }
            if (store.type && Ext.data[store.type]) {
                this.store = new Ext.data[store.type]({
                    proxy: proxy,
                    reader: reader
                });
            } else if (store.type) {
                try {
                    var storeType = eval(store.type)
                } catch(e) {
                    throw "invalid storeType: "+store.type;
                }
                this.store = new storeType({
                    proxy: proxy,
                    reader: reader
                });
            } else {
                this.store = new Ext.data.Store({
                    proxy: proxy,
                    reader: reader
                });
            }
        }

        Ext.applyIf(this, {
            displayField: 'name',
            valueField: 'id'
        });

        if (this.addDialog) {
            var d = Vps.Auto.Form.Window;
            if (this.addDialog.type) {
                try {
                    d = eval(this.addDialog.type);
                } catch (e) {
                    throw new Error("Invalid addDialog \'"+this.addDialog.type+"': "+e);
                }
            }
            this.addDialog = new d(this.addDialog);
            this.addDialog.on('datachange', function(result) {
                if (result.data.addedId) {
                    //neuen Eintrag auswählen
                    this.setValue(result.data.addedId);
                }
            }, this);
        }

        this.store.on('load', function() {
            this.addNoSelection();
        }, this);
        if (this.store.recordType) {
            this.addNoSelection();
        }
        if (this.showNoSelection) {
            this.allowBlank = false;
        }

        Vps.Form.ComboBox.superclass.initComponent.call(this);
    },
    addNoSelection : function() {
        if (this.showNoSelection && this.store.find('id', '') == -1) {
            var data = {};
            data[this.displayField] = '(no selection)';
            data[this.valueField] = null;
            this.store.insert(0, new this.store.recordType(data));
        }
    },
    setValue : function(v)
    {
        if (v == '') v = null;
        if (v && this.store.proxy && this.valueField && this.mode == 'remote') {
            //wenn proxy vorhanden können daten nachgeladen werden
            //also loading anzeigen (siehe setValue)
            this.valueNotFoundText = this.loadingText;
        } else {
            this.valueNotFoundText = '';
        }
        Vps.Form.ComboBox.superclass.setValue.apply(this, arguments);
        if (v && this.valueField
                && !this.findRecord(this.valueField, v) //record nicht gefunden
                && this.mode == 'remote'
                && this.store.proxy //proxy vorhanden (dh. daten können nachgeladen werden)
                ) {
            this.store.baseParams[this.queryParam] = v;
            this.store.load({
                params: this.getParams(v),
                callback: function(r, options, success) {
                    if (success && this.findRecord(this.valueField, this.value)) {
                        this.setValue(this.value);
                    }
                },
                scope: this
            });
        }
        this.fireEvent('changevalue', this.value);
    },
    onRender : function(ct, position)
    {
        Vps.Form.ComboBox.superclass.onRender.call(this, ct, position);
        if (this.addDialog) {
            var c = this.el.up('div.x-form-field-wrap').insertSibling({style: 'float: right'}, 'before');
            var button = new Ext.Button({
                renderTo: c,
                text: this.addDialog.text || 'add new entry',
                handler: function() {
                    this.addDialog.showAdd();
                },
                scope: this
            });
        }
    }
});
Ext.reg('combobox', Vps.Form.ComboBox);
<|endoftext|>