Add user management

This commit is contained in:
2016-09-23 15:12:46 -04:00
parent 9f50a4635c
commit 0b5dde065a
53 changed files with 1046 additions and 690 deletions
@@ -1,5 +1,6 @@
using System.Web.Mvc; using System.Web.Mvc;
using AutoMapper; using AutoMapper;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Identity; using InventoryTraker.Web.Identity;
using InventoryTraker.Web.Models; using InventoryTraker.Web.Models;
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity;
@@ -0,0 +1,94 @@
using System.Linq;
using System.Threading.Tasks;
using System.Web.Mvc;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using InventoryTraker.Web.Attributes;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Identity;
using InventoryTraker.Web.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security.DataProtection;
namespace InventoryTraker.Web.Controllers
{
public class UserController : ControllerBase
{
private readonly ApplicationUserManager _userManager;
public UserController(ApplicationUserManager userManager)
{
_userManager = userManager;
}
public ActionResult Index()
{
return View();
}
public JsonResult All()
{
var users =
_userManager
.Users
.ProjectTo<UserViewModel>()
.OrderBy(u => u.UserName);
return BetterJson(users);
}
[ActionLog]
[HttpPost]
public async Task<JsonResult> Create(UserEditForm form)
{
if (!ModelState.IsValid)
return GetModelStateErrorListJson();
var user =
new User
{
Email = form.Email,
UserName = form.UserName
};
var identityResult = await _userManager.CreateAsync(user, form.Password);
if (!identityResult.Succeeded)
return GetErrorListJson(identityResult.Errors.ToArray());
return BetterJson(Mapper.Map<UserViewModel>(user));
}
[ActionLog]
[HttpPost]
public async Task<JsonResult> Edit(UserEditForm form)
{
if (!ModelState.IsValid)
return GetModelStateErrorListJson();
var user = _userManager.FindByEmail(form.Email);
user.UserName = form.UserName;
user.Email = form.Email;
if (!string.IsNullOrEmpty(form.Password))
{
var provider = new DpapiDataProtectionProvider("Inventory Traker");
_userManager.UserTokenProvider = new DataProtectorTokenProvider<User>(
provider.Create("EmailConfirmation"));
var resetToken = await _userManager.GeneratePasswordResetTokenAsync(user.Id);
var resetResult = await _userManager.ResetPasswordAsync(user.Id, resetToken, form.Password);
if (!resetResult.Succeeded)
return GetErrorListJson(resetResult.Errors.ToArray());
}
var identityResult = _userManager.Update(user);
if (!identityResult.Succeeded)
return GetErrorListJson(identityResult.Errors.ToArray());
return BetterJson(Mapper.Map<UserViewModel>(user));
}
}
}
@@ -119,6 +119,9 @@ namespace InventoryTraker.Web.Helpers
if (metadata.DataTypeName == "EmailAddress") if (metadata.DataTypeName == "EmailAddress")
input.Attr("type", "email"); input.Attr("type", "email");
if (metadata.DataTypeName == "Password")
input.Attr("type", "password");
if (metadata.ModelType == typeof(DateTime)) if (metadata.ModelType == typeof(DateTime))
{ {
//input.Attr("type", "date"); //input.Attr("type", "date");
+14 -1
View File
@@ -232,6 +232,11 @@
<Content Include="Global.asax" /> <Content Include="Global.asax" />
<Content Include="js\app.js" /> <Content Include="js\app.js" />
<Content Include="js\authentication\LoginController.js" /> <Content Include="js\authentication\LoginController.js" />
<Content Include="js\user\UserCreateDirective.js" />
<Content Include="js\user\UserController.js" />
<Content Include="js\user\UserEditDirective.js" />
<Content Include="js\user\UserListDirective.js" />
<Content Include="js\user\userSvc.js" />
<Content Include="js\inventoryType\InventoryTypeAddDirective.js" /> <Content Include="js\inventoryType\InventoryTypeAddDirective.js" />
<Content Include="js\inventoryType\InventoryTypeListDirective.js" /> <Content Include="js\inventoryType\InventoryTypeListDirective.js" />
<Content Include="js\inventoryType\InventoryTypeEditDirective.js" /> <Content Include="js\inventoryType\InventoryTypeEditDirective.js" />
@@ -263,7 +268,6 @@
<Content Include="js\utility\FormGroupValidationDirective.js" /> <Content Include="js\utility\FormGroupValidationDirective.js" />
<Content Include="js\utility\HideZeroFilter.js" /> <Content Include="js\utility\HideZeroFilter.js" />
<Content Include="js\utility\InputValidationIconsDirective.js" /> <Content Include="js\utility\InputValidationIconsDirective.js" />
<Content Include="js\utility\MvcGridDirective.js" />
<Content Include="js\utility\ParseDateFilter.js" /> <Content Include="js\utility\ParseDateFilter.js" />
<Content Include="Scripts\angular-animate.js" /> <Content Include="Scripts\angular-animate.js" />
<Content Include="Scripts\angular-animate.min.js" /> <Content Include="Scripts\angular-animate.min.js" />
@@ -310,6 +314,9 @@
<Content Include="js\utility\templates\statusMessage.tmpl.cshtml" /> <Content Include="js\utility\templates\statusMessage.tmpl.cshtml" />
<Content Include="js\utility\templates\monthQuery.tmpl.cshtml" /> <Content Include="js\utility\templates\monthQuery.tmpl.cshtml" />
<Content Include="js\report\templates\movementReport.tmpl.cshtml" /> <Content Include="js\report\templates\movementReport.tmpl.cshtml" />
<Content Include="js\user\templates\userCreate.tmpl.cshtml" />
<Content Include="js\user\templates\userEdit.tmpl.cshtml" />
<Content Include="js\user\templates\userList.tmpl.cshtml" />
<None Include="NLog.xsd"> <None Include="NLog.xsd">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>
@@ -335,6 +342,7 @@
<Compile Include="App_Start\FilterConfig.cs" /> <Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="App_Start\RouteConfig.cs" /> <Compile Include="App_Start\RouteConfig.cs" />
<Content Include="js\utility\DownloadService.js" /> <Content Include="js\utility\DownloadService.js" />
<Compile Include="Controllers\UserController.cs" />
<Compile Include="Migrations\SeedData.cs" /> <Compile Include="Migrations\SeedData.cs" />
<Compile Include="App_Start\Startup.cs" /> <Compile Include="App_Start\Startup.cs" />
<Compile Include="App_Start\StructureMapConfig.cs" /> <Compile Include="App_Start\StructureMapConfig.cs" />
@@ -370,6 +378,9 @@
<DependentUpon>201609201242047_Initial.cs</DependentUpon> <DependentUpon>201609201242047_Initial.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Migrations\Configuration.cs" /> <Compile Include="Migrations\Configuration.cs" />
<Compile Include="Models\UserEditForm.cs" />
<Compile Include="Models\UserViewModel.cs" />
<Compile Include="Models\UserCreateForm.cs" />
<Compile Include="Models\DateRangeQuery.cs" /> <Compile Include="Models\DateRangeQuery.cs" />
<Compile Include="Models\DistributionReport.cs" /> <Compile Include="Models\DistributionReport.cs" />
<Compile Include="Models\InventoryDistributeForm.cs" /> <Compile Include="Models\InventoryDistributeForm.cs" />
@@ -418,6 +429,7 @@
<Content Include="Views\InventoryType\Index.cshtml" /> <Content Include="Views\InventoryType\Index.cshtml" />
<Content Include="Views\Report\Distribution.cshtml" /> <Content Include="Views\Report\Distribution.cshtml" />
<Content Include="Views\Report\Movement.cshtml" /> <Content Include="Views\Report\Movement.cshtml" />
<Content Include="Views\User\Index.cshtml" />
<None Include="Web.Debug.config"> <None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</None> </None>
@@ -430,6 +442,7 @@
<DependentUpon>201609201242047_Initial.cs</DependentUpon> <DependentUpon>201609201242047_Initial.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup />
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
@@ -0,0 +1,31 @@
using System.ComponentModel.DataAnnotations;
namespace InventoryTraker.Web.Models
{
public class UserCreateForm
{
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required(ErrorMessage = "Confirm Password is required")]
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
public override string ToString()
{
return $"UserName: {UserName}, email: {Email}";
}
}
}
@@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;
namespace InventoryTraker.Web.Models
{
public class UserEditForm
{
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
public override string ToString()
{
return $"UserName: {UserName}, email: {Email}";
}
}
}
@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Heroic.AutoMapper;
using InventoryTraker.Web.Core;
namespace InventoryTraker.Web.Models
{
public class UserViewModel : IMapFrom<User>
{
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
public string Email { get; set; }
public override string ToString()
{
return $"UserName: {UserName}, email: {Email}";
}
}
}
@@ -4,7 +4,7 @@
<div ng-controller="InventoryListController as vm"> <div ng-controller="InventoryListController as vm">
<h1 class="page-header"> <h1 class="page-header">
<i class="fa fa-cubes"></i> Inventory <i class="fa fa-cubes"></i> @ViewBag.Title
</h1> </h1>
<h4>Current inventory</h4> <h4>Current inventory</h4>
<div class="pull-left"> <div class="pull-left">
@@ -1,12 +1,12 @@
@model dynamic @model dynamic
@{ @{
ViewBag.Title = "Inventory"; ViewBag.Title = "Commodity Types";
} }
<div ng-controller="InventoryTypeController as vm"> <div ng-controller="InventoryTypeController as vm">
<h1 class="page-header"> <h1 class="page-header">
<i class="fa fa-cube"></i> Commodity Types <i class="fa fa-cube"></i> @ViewBag.Title
</h1> </h1>
<div class="pull-left"> <div class="pull-left">
<a class="btn btn-default" href="" ng-click="vm.add()"><i class="fa fa-plus-circle"></i> Add</a> <a class="btn btn-default" href="" ng-click="vm.add()"><i class="fa fa-plus-circle"></i> Add</a>
@@ -10,19 +10,22 @@
<a class="navbar-brand" href="~/">Inventory Traker</a> <a class="navbar-brand" href="~/">Inventory Traker</a>
</div> </div>
<!-- Top Menu Items --> <!-- Top Menu Items -->
<ul class="nav navbar-right top-nav"> <ul class="nav navbar-right top-nav">
<li class="dropdown"> <li>
<a href="" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-user"></i> @User.Identity.Name <b class="caret"></b></a> <a href="@(Html.BuildUrlFromExpression<UserController>(c => c.Index()))"><i class="fa fa-fw fa-users"></i> Users</a>
<ul class="dropdown-menu"> </li>
<li> <li class="dropdown">
<a href="@(Html.BuildUrlFromExpression<ProfileController>(c => c.Index()))"><i class="fa fa-fw fa-user"></i> Profile</a> <a href="" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-user"></i> @User.Identity.Name <b class="caret"></b></a>
</li> <ul class="dropdown-menu">
<li> <li>
<a href="@(Html.BuildUrlFromExpression<AuthenticationController>(c => c.Logout()))"><i class="fa fa-fw fa-power-off"></i> Log Out</a> <a href="@(Html.BuildUrlFromExpression<ProfileController>(c => c.Index()))"><i class="fa fa-fw fa-user"></i> Profile</a>
</li> </li>
</ul> <li>
</li> <a href="@(Html.BuildUrlFromExpression<AuthenticationController>(c => c.Logout()))"><i class="fa fa-fw fa-power-off"></i> Log Out</a>
</ul> </li>
</ul>
</li>
</ul>
<!-- Sidebar Menu Items - These collapse to the responsive navigation menu on small screens --> <!-- Sidebar Menu Items - These collapse to the responsive navigation menu on small screens -->
<div class="collapse navbar-collapse navbar-ex1-collapse"> <div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav side-nav"> <ul class="nav navbar-nav side-nav">
@@ -0,0 +1,16 @@
@model dynamic
@{
ViewBag.Title = "Users";
}
<div ng-controller="UserController as vm">
<h1 class="page-header">
<i class="fa fa-users"></i> @ViewBag.Title
</h1>
<div class="pull-left">
<a class="btn btn-default" href="" ng-click="vm.create()"><i class="fa fa-plus-circle"></i> Create</a>
</div>
<user-list users="vm.users"></user-list>
</div>
@@ -1,30 +1,28 @@
(function () { (function () {
'use strict'; 'use strict';
window.app.controller('LoginController', LoginController); window.app.controller('LoginController',
function($window, $http) {
LoginController.$inject = ['$window', '$http']; var vm = this;
function LoginController($window, $http) {
var vm = this;
vm.errorMessage = null;
vm.loggingIn = false;
vm.login = login;
function login() {
vm.loggingIn = true;
vm.errorMessage = null; vm.errorMessage = null;
vm.loggingIn = false;
vm.login = login;
$http.post("/Authentication/Login", { emailAddress: vm.emailAddress, password: vm.password }) function login() {
.success(function() {
$window.location.href = "/"; vm.loggingIn = true;
}) vm.errorMessage = null;
.error(function(data) {
vm.errorMessage = "There was a problem logging in: " + data; $http.post("/Authentication/Login", { emailAddress: vm.emailAddress, password: vm.password })
}) .success(function() {
.finally(function() { $window.location.href = "/";
vm.loggingIn = false; })
}); .error(function(data) {
} vm.errorMessage = "There was a problem logging in: " + data;
} })
.finally(function() {
vm.loggingIn = false;
});
}
});
})(); })();
@@ -1,15 +1,14 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('inventoryAdd', inventoryAdd); window.app.directive('inventoryAdd',
function() {
function inventoryAdd() { return {
return { templateUrl: '/inventory/template/inventoryAdd.tmpl.cshtml',
templateUrl: '/inventory/template/inventoryAdd.tmpl.cshtml', controller: controller,
controller: controller, controllerAs: 'vm'
controllerAs: 'vm' }
} });
}
controller.$inject = ['$scope', 'inventorySvc', 'inventoryTypeSvc']; controller.$inject = ['$scope', 'inventorySvc', 'inventoryTypeSvc'];
@@ -1,15 +1,14 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('inventoryDistribute', inventoryDistribute); window.app.directive('inventoryDistribute',
function() {
function inventoryDistribute() { return {
return { templateUrl: '/inventory/template/inventoryDistribute.tmpl.cshtml',
templateUrl: '/inventory/template/inventoryDistribute.tmpl.cshtml', controller: controller,
controller: controller, controllerAs: 'vm'
controllerAs: 'vm' }
} });
}
controller.$inject = ['$scope', 'inventorySvc']; controller.$inject = ['$scope', 'inventorySvc'];
function controller($scope, inventorySvc) { function controller($scope, inventorySvc) {
@@ -1,18 +1,17 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('editInventory', editInventory); window.app.directive('editInventory',
function() {
function editInventory() { return {
return { scope: {
scope: { inventory: "="
inventory: "=" },
}, templateUrl: '/inventory/template/inventoryEdit.tmpl.cshtml',
templateUrl: '/inventory/template/inventoryEdit.tmpl.cshtml', controller: controller,
controller: controller, controllerAs: 'vm'
controllerAs: 'vm' }
} });
}
controller.$inject = ['$scope', '$uibModal', 'inventorySvc', 'transactionSvc']; controller.$inject = ['$scope', '$uibModal', 'inventorySvc', 'transactionSvc'];
function controller($scope, $uibModal, inventorySvc, transactionSvc) { function controller($scope, $uibModal, inventorySvc, transactionSvc) {
@@ -1,33 +1,29 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.controller('InventoryListController', InventoryListController); window.app.controller('InventoryListController',
function($uibModal, inventorySvc, downloadSvc) {
var vm = this;
InventoryListController.$inject = ['$uibModal', 'inventorySvc', 'downloadSvc']; vm.inventories = inventorySvc.inventories;
function InventoryListController($uibModal, inventorySvc, downloadSvc) {
var vm = this;
vm.add = add; vm.add = function() {
vm.distribute = distribute; $uibModal.open({
vm.inventories = inventorySvc.inventories; template: '<inventory-add />',
backdrop: 'static'
function add() { });
$uibModal.open({ };
template: '<inventory-add />',
backdrop: 'static'
});
}
function distribute() { vm.distribute = function() {
$uibModal.open({ $uibModal.open({
template: '<inventory-distribute />', template: '<inventory-distribute />',
backdrop: 'static' backdrop: 'static'
}); });
} };
vm.export = function () { vm.export = function() {
inventorySvc.exportInventory() inventorySvc.exportInventory()
.success(downloadSvc.success); .success(downloadSvc.success);
} };
} });
})(); })();
@@ -1,15 +1,15 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('inventoryList', inventoryList); window.app.directive('inventoryList',
function inventoryList() { function () {
return { return {
scope: {"inventories" : "="}, scope: {"inventories" : "="},
templateUrl: '/inventory/template/inventoryList.tmpl.cshtml', templateUrl: '/inventory/template/inventoryList.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope', '$uibModal']; controller.$inject = ['$scope', '$uibModal'];
function controller($scope, $uibModal) { function controller($scope, $uibModal) {
@@ -1,16 +1,15 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('inventoryInfo', inventoryInfo); window.app.directive('inventoryInfo',
function() {
function inventoryInfo() { return {
return { scope: { "inventory": "=" },
scope: { "inventory": "=" }, templateUrl: '/inventory/template/inventoryInfo.tmpl.cshtml',
templateUrl: '/inventory/template/inventoryInfo.tmpl.cshtml', controller: controller,
controller: controller, controllerAs: 'vm'
controllerAs: 'vm' }
} });
}
controller.$inject = ['$scope']; controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
@@ -1,16 +1,15 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('inventoryRemove', inventoryRemove); window.app.directive('inventoryRemove',
function() {
function inventoryRemove() { return {
return { scope: { "inventory": "=" },
scope: { "inventory": "=" }, templateUrl: '/inventory/template/inventoryRemove.tmpl.cshtml',
templateUrl: '/inventory/template/inventoryRemove.tmpl.cshtml', controller: controller,
controller: controller, controllerAs: 'vm'
controllerAs: 'vm' }
} });
}
controller.$inject = ['$scope', 'inventorySvc']; controller.$inject = ['$scope', 'inventorySvc'];
function controller($scope, inventorySvc) { function controller($scope, inventorySvc) {
@@ -1,87 +1,85 @@
(function() { (function() {
window.app.factory('inventorySvc', inventorySvc); window.app.factory('inventorySvc',
function($http, $filter) {
var inventories = [];
inventorySvc.$inject = ['$http', '$filter']; loadInventories();
function inventorySvc($http, $filter) {
var inventories = [];
loadInventories(); var svc = {
add: add,
distribute: distribute,
update: update,
remove: remove,
inventories: inventories,
get: get,
refresh: refresh,
find: find,
exportInventory: exportInventory
};
var svc = { return svc;
add: add,
distribute: distribute,
update: update,
remove: remove,
inventories: inventories,
get: get,
refresh: refresh,
find: find,
exportInventory: exportInventory
};
return svc; function loadInventories() {
$http.post('/Inventory/All')
function loadInventories() { .success(function(data) {
$http.post('/Inventory/All') angular.copy(data, inventories);
.success(function(data) {
angular.copy(data, inventories);
});
}
function exportInventory() {
return $http.post('/Inventory/Export', {}, { responseType: 'arraybuffer' });
}
function add(inventory) {
return $http.post('/Inventory/Add', inventory)
.success(function(inventory) {
inventories.unshift(inventory);
});
}
function distribute(distribution) {
return $http.post('/Inventory/Distribute', distribution)
.success(function (data) {
angular.copy(data, inventories);
});
}
function update(existingInventory, updatedInventory) {
return $http.post('/Inventory/Update', updatedInventory)
.success(function(inventory) {
angular.extend(existingInventory, inventory);
});
}
// remove quantity from this inventory
function remove(removeForm) {
var existingInventory = get(removeForm.inventoryId);
return $http.post('/Inventory/Remove', removeForm)
.success(function(data) {
angular.copy(data, existingInventory);
});
}
function get(id) {
var results = $filter('filter')(inventories, { id: id });
if (results.length > 0)
return results[0];
return null;
}
// refresh this inventory from the server
function refresh(id) {
var existingInventory = get(id);
if (existingInventory) {
find(id)
.success(function(inventory) {
angular.copy(inventory, existingInventory);
}); });
} }
}
function find(id) { function exportInventory() {
return $http.post('/Inventory/Find', { id: id }); return $http.post('/Inventory/Export', {}, { responseType: 'arraybuffer' });
} }
}
function add(inventory) {
return $http.post('/Inventory/Add', inventory)
.success(function(inventory) {
inventories.unshift(inventory);
});
}
function distribute(distribution) {
return $http.post('/Inventory/Distribute', distribution)
.success(function(data) {
angular.copy(data, inventories);
});
}
function update(existingInventory, updatedInventory) {
return $http.post('/Inventory/Update', updatedInventory)
.success(function(inventory) {
angular.extend(existingInventory, inventory);
});
}
// remove quantity from this inventory
function remove(removeForm) {
var existingInventory = get(removeForm.inventoryId);
return $http.post('/Inventory/Remove', removeForm)
.success(function(data) {
angular.copy(data, existingInventory);
});
}
function get(id) {
var results = $filter('filter')(inventories, { id: id });
if (results.length > 0)
return results[0];
return null;
}
// refresh this inventory from the server
function refresh(id) {
var existingInventory = get(id);
if (existingInventory) {
find(id)
.success(function(inventory) {
angular.copy(inventory, existingInventory);
});
}
}
function find(id) {
return $http.post('/Inventory/Find', { id: id });
}
});
})(); })();
@@ -1,17 +1,15 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('inventoryTypeAdd', inventoryTypeAdd); window.app.directive("inventoryTypeAdd",
function() {
return {
templateUrl: "/inventoryType/template/inventoryTypeAdd.tmpl.cshtml",
controller: controller,
controllerAs: "vm"
};
});
function inventoryTypeAdd() {
return {
templateUrl: '/inventoryType/template/inventoryTypeAdd.tmpl.cshtml',
controller: controller,
controllerAs: 'vm'
}
}
controller.$inject = ['$scope', 'inventoryTypeSvc'];
function controller($scope, inventoryTypeSvc){ function controller($scope, inventoryTypeSvc){
var vm = this; var vm = this;
@@ -1,33 +1,22 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.controller('InventoryTypeController', InventoryTypeController); window.app.controller('InventoryTypeController',
function($uibModal, inventoryTypeSvc, downloadSvc) {
var vm = this;
InventoryTypeController.$inject = ['$uibModal', 'inventoryTypeSvc', 'downloadSvc']; vm.inventoryTypes = inventoryTypeSvc.inventoryTypes;
function InventoryTypeController($uibModal, inventoryTypeSvc, downloadSvc) {
var vm = this;
vm.add = add; vm.add = function() {
vm.edit = edit; $uibModal.open({
vm.inventoryTypes = inventoryTypeSvc.inventoryTypes; template: '<inventory-type-add />',
backdrop: 'static'
});
}
function add() { vm.export = function() {
$uibModal.open({ inventoryTypeSvc.exportInventoryTypes()
template: '<inventory-type-add />', .success(downloadSvc.success);
backdrop: 'static' }
}); });
}
function edit() {
$uibModal.open({
template: '<inventory-type-edit />',
backdrop: 'static'
});
}
vm.export = function () {
inventoryTypeSvc.exportInventoryTypes()
.success(downloadSvc.success);
}
}
})(); })();
@@ -1,20 +1,18 @@
(function() { (function() {
"use strict"; "use strict";
window.app.directive('editInventoryType', editInventory); window.app.directive('editInventoryType',
function() {
return {
scope: {
inventoryType: "="
},
templateUrl: '/inventoryType/template/inventoryTypeEdit.tmpl.cshtml',
controller: controller,
controllerAs: 'vm'
}
});
function editInventory() {
return {
scope: {
inventoryType: "="
},
templateUrl: '/inventoryType/template/inventoryTypeEdit.tmpl.cshtml',
controller: controller,
controllerAs: 'vm'
}
}
controller.$inject = ['$scope', 'inventoryTypeSvc'];
function controller($scope, inventoryTypeSvc) { function controller($scope, inventoryTypeSvc) {
var vm = this; var vm = this;
vm.inventoryType = angular.copy($scope.inventoryType); vm.inventoryType = angular.copy($scope.inventoryType);
@@ -1,28 +1,26 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('inventoryTypeList', inventoryTypeList); window.app.directive('inventoryTypeList',
function inventoryTypeList() { function() {
return { return {
scope: { "inventoryTypes": "=" }, scope: { "inventoryTypes": "=" },
templateUrl: '/inventoryType/template/inventoryTypeList.tmpl.cshtml', templateUrl: '/inventoryType/template/inventoryTypeList.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope', '$uibModal'];
function controller($scope, $uibModal) { function controller($scope, $uibModal) {
var vm = this; var vm = this;
vm.inventoryTypes = $scope.inventoryTypes; vm.inventoryTypes = $scope.inventoryTypes;
vm.edit = edit;
function edit(inventoryType) { vm.edit = function(inventoryType) {
$uibModal.open({ $uibModal.open({
template: '<edit-inventory-type inventory-type="inventoryType" />', template: '<edit-inventory-type inventory-type="inventoryType" />',
scope: angular.extend($scope.$new(true), { inventoryType: inventoryType }) scope: angular.extend($scope.$new(true), { inventoryType: inventoryType })
}); });
} };
} }
})(); })();
@@ -1,44 +1,42 @@
(function () { (function () {
window.app.factory('inventoryTypeSvc', inventoryTypeSvc); window.app.factory('inventoryTypeSvc',
function($http) {
var inventoryTypes = [];
inventoryTypeSvc.$inject = ['$http']; loadInventoryTypes();
function inventoryTypeSvc($http) {
var inventoryTypes = [];
loadInventoryTypes(); var svc = {
add: add,
update: update,
inventoryTypes: inventoryTypes,
exportInventoryTypes: exportInventoryTypes
};
var svc = { return svc;
add: add,
update: update,
inventoryTypes: inventoryTypes,
exportInventoryTypes: exportInventoryTypes
};
return svc; function loadInventoryTypes() {
$http.post('/InventoryType/All')
.success(function(data) {
inventoryTypes.addRange(data);
});
}
function loadInventoryTypes() { function exportInventoryTypes() {
$http.post('/InventoryType/All') return $http.post('/InventoryType/Export', {}, { responseType: 'arraybuffer' });
.success(function (data) { }
inventoryTypes.addRange(data);
});
}
function exportInventoryTypes() { function add(inventoryType) {
return $http.post('/InventoryType/Export', {}, { responseType: 'arraybuffer' }); return $http.post('/InventoryType/Add', inventoryType)
} .success(function(inventoryType) {
inventoryTypes.unshift(inventoryType);
});
}
function add(inventoryType) { function update(existingInventoryType, updatedInventoryType) {
return $http.post('/InventoryType/Add', inventoryType) return $http.post('/InventoryType/Update', updatedInventoryType)
.success(function (inventoryType) { .success(function(inventoryType) {
inventoryTypes.unshift(inventoryType); angular.extend(existingInventoryType, inventoryType);
}); });
} }
});
function update(existingInventoryType, updatedInventoryType) {
return $http.post('/InventoryType/Update', updatedInventoryType)
.success(function (inventoryType) {
angular.extend(existingInventoryType, inventoryType);
});
}
}
})(); })();
@@ -1,30 +1,28 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.controller('EditProfileController', EditProfileController); window.app.controller('EditProfileController',
function($http, editProfileConfig, model) {
var vm = this;
EditProfileController.$inject = ['$http', 'editProfileConfig', 'model']; vm.profile = model;
function EditProfileController($http, editProfileConfig, model) { vm.save = save;
var vm = this;
vm.profile = model; function save() {
vm.save = save; vm.saving = true;
vm.errorMessage = null;
vm.success = false;
function save() { $http.post(editProfileConfig.saveUrl, vm.profile)
vm.saving = true; .success(function() {
vm.errorMessage = null; vm.success = true;
vm.success = false; })
.error(function(msg) {
$http.post(editProfileConfig.saveUrl, vm.profile) vm.errorMessage = msg;
.success(function() { })
vm.success = true; .finally(function() {
}) vm.saving = false;
.error(function(msg) { });
vm.errorMessage = msg; }
}) });
.finally(function() {
vm.saving = false;
});
}
}
})(); })();
@@ -1,17 +1,15 @@
(function () { (function () {
'use strict'; 'use strict';
window.app.controller('DistributionReportController', DistributionReportController); window.app.controller('DistributionReportController',
function($scope, reportSvc, downloadSvc) {
DistributionReportController.$inject = ['$scope', 'reportSvc', 'downloadSvc']; var vm = this;
function DistributionReportController($scope, reportSvc, downloadSvc) { vm.loadData = reportSvc.loadDistributionReport;
var vm = this; vm.query = reportSvc.distributionQuery;
vm.loadData = reportSvc.loadDistributionReport; vm.distributionData = reportSvc.distributionData;
vm.query = reportSvc.distributionQuery; vm.export = function(params) {
vm.distributionData = reportSvc.distributionData; reportSvc.exportDistributionReport(params)
vm.export = function (params) { .success(downloadSvc.success);
reportSvc.exportDistributionReport(params) }
.success(downloadSvc.success); });
}
}
})(); })();
@@ -1,17 +1,16 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('distributionReport', distributionReport); window.app.directive('distributionReport',
function distributionReport() { function () {
return { return {
scope: {distributionData: "="}, scope: {distributionData: "="},
templateUrl: '/report/template/distributionReport.tmpl.cshtml', templateUrl: '/report/template/distributionReport.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
var vm = this; var vm = this;
vm.distributionData = $scope.distributionData; vm.distributionData = $scope.distributionData;
@@ -1,16 +1,14 @@
(function () { (function () {
'use strict'; 'use strict';
window.app.controller('MovementReportController', MovementReportController); window.app.controller('MovementReportController',
function($scope, reportSvc, downloadSvc) {
MovementReportController.$inject = ['$scope', 'reportSvc', 'downloadSvc']; var vm = this;
function MovementReportController($scope, reportSvc, downloadSvc) { vm.loadData = reportSvc.loadMovementData;
var vm = this; vm.movementData = reportSvc.movementData;
vm.loadData = reportSvc.loadMovementData; vm.export = function(month) {
vm.movementData = reportSvc.movementData; reportSvc.exportMovementData({ month: month })
vm.export = function(month) { .success(downloadSvc.success);
reportSvc.exportMovementData({month: month}) }
.success(downloadSvc.success); });
}
}
})(); })();
@@ -1,17 +1,16 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('movementReport', movementReport); window.app.directive('movementReport',
function movementReport() { function() {
return { return {
scope: { movementData: "=" }, scope: { movementData: "=" },
templateUrl: '/report/template/movementReport.tmpl.cshtml', templateUrl: '/report/template/movementReport.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope', '$uibModal', 'inventorySvc'];
function controller($scope, $uibModal, inventorySvc) { function controller($scope, $uibModal, inventorySvc) {
var vm = this; var vm = this;
vm.movementData = $scope.movementData; vm.movementData = $scope.movementData;
+35 -37
View File
@@ -1,45 +1,43 @@
(function () { (function () {
window.app.factory('reportSvc', reportSvc); window.app.factory('reportSvc',
function($http) {
var distributionData = [];
var distributionQuery = {};
var movementData = {};
reportSvc.$inject = ['$http']; var svc = {
function reportSvc($http) { distributionData: distributionData,
var distributionData = []; distributionQuery: distributionQuery,
var distributionQuery = {}; loadDistributionReport: loadDistributionReport,
var movementData = {}; exportDistributionReport: exportDistributionReport,
movementData: movementData,
loadMovementData: loadMovementData,
exportMovementData: exportMovementData
};
var svc = { return svc;
distributionData: distributionData,
distributionQuery: distributionQuery,
loadDistributionReport: loadDistributionReport,
exportDistributionReport: exportDistributionReport,
movementData: movementData,
loadMovementData: loadMovementData,
exportMovementData: exportMovementData
};
return svc; function loadDistributionReport(query) {
return $http.post('/Report/Distribution', query)
.success(function(data) {
distributionQuery = angular.copy(query, distributionQuery);
angular.copy(data, distributionData);
});
}
function loadDistributionReport(query) { function exportDistributionReport(query) {
return $http.post('/Report/Distribution', query) return $http.post('/Report/DistributionExcel', query, { responseType: 'arraybuffer' });
.success(function (data) { }
distributionQuery = angular.copy(query, distributionQuery);
angular.copy(data, distributionData);
});
}
function exportDistributionReport(query) { function loadMovementData(query) {
return $http.post('/Report/DistributionExcel', query, { responseType: 'arraybuffer' }); return $http.post('/Report/Movement', query)
} .success(function(data) {
angular.copy(data, movementData);
});
}
function loadMovementData(query) { function exportMovementData(query) {
return $http.post('/Report/Movement', query) return $http.post('/Report/MovementExcel', query, { responseType: 'arraybuffer' });
.success(function (data) { }
angular.copy(data, movementData); });
});
}
function exportMovementData(query) {
return $http.post('/Report/MovementExcel', query, { responseType: 'arraybuffer' });
}
}
})(); })();
@@ -1,82 +1,81 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.controller('TransactionController', TransactionController); window.app.controller('TransactionController',
function($scope, $uibModal, transactionSvc, inventorySvc, uiGridConstants) {
var vm = this;
TransactionController.$inject = ['$scope', '$uibModal', 'transactionSvc', 'inventorySvc', 'uiGridConstants']; var paginationOptions = {
function TransactionController($scope, $uibModal, transactionSvc, inventorySvc, uiGridConstants) { pageNumber: 1,
var vm = this; pageSize: 20,
pageSizes: [20, 50, 100],
sort: null
};
var paginationOptions = { vm.gridOptions = {
pageNumber: 1, enablePaginationControls: true,
pageSize: 20, paginationPageSize: paginationOptions.pageSize,
pageSizes: [20,50,100], paginationPageSizes: paginationOptions.pageSizes,
sort: null useExternalPagination: true,
}; enableSorting: false,
columnDefs: [
vm.gridOptions = { {
enablePaginationControls: true, field: 'name',
paginationPageSize: paginationOptions.pageSize, cellTooltip: function(row) {
paginationPageSizes: paginationOptions.pageSizes, return row.entity.name + "\r" + row.entity.unitsPerCase + " / " + row.entity.containerType;
useExternalPagination: true, },
enableSorting: false, cellTemplate: '<div class="ui-grid-cell-contents" ' +
columnDefs: [ 'title="{{row.entity.name}}' +
{ '\r{{row.entity.unitsPerCase}} / {{row.entity.containerType}}' +
field: 'name', '\rExp Date: {{row.entity.expirationDate | date:\'shortDate\'}}' +
cellTooltip: function(row) { '\rAdd Date: {{row.entity.addedDate | date:\'shortDate\'}}">' +
return row.entity.name + "\r" + row.entity.unitsPerCase + " / " + row.entity.containerType; '<a href="" ng-click="grid.appScope.editInventory(row.entity.inventoryId)"><i class="fa fa-edit"></i></a> ' +
'{{row.entity.name}}</div>',
width: "20%"
}, },
cellTemplate: '<div class="ui-grid-cell-contents" ' + { field: 'transactionType', name: 'Type', width: "10%" },
'title="{{row.entity.name}}' + { field: 'destination', cellTooltip: true, width: "10%" },
'\r{{row.entity.unitsPerCase}} / {{row.entity.containerType}}' + { field: 'memo', cellTooltip: true, width: "15%" },
'\rExp Date: {{row.entity.expirationDate | date:\'shortDate\'}}' + { field: 'transactionDate', name: 'Transaction Date', cellFilter: "date:'shortDate'", width: "10%" },
'\rAdd Date: {{row.entity.addedDate | date:\'shortDate\'}}">' + { field: 'previousQuantity', name: 'Prev Qty', width: "10%", enableSorting: false },
'<a href="" ng-click="grid.appScope.editInventory(row.entity.inventoryId)"><i class="fa fa-edit"></i></a> ' + { field: 'addedQuantity', name: 'Add Qty', width: "10%", enableSorting: false, cellFilter: "hideZero" },
'{{row.entity.name}}</div>', { field: 'removedQuantity', name: 'Remove Qty', width: "10%", enableSorting: false, cellFilter: "hideZero" },
width: "20%" { field: 'currentQuantity', name: 'Current Qty', width: "10%", enableSorting: false }
}, ],
{ field: 'transactionType', name: 'Type', width: "10%" }, onRegisterApi: function(gridApi) {
{ field: 'destination', cellTooltip: true, width: "10%" }, vm.gridApi = gridApi;
{ field: 'memo', cellTooltip: true, width: "15%" }, vm.gridApi.pagination
{ field: 'transactionDate', name: 'Transaction Date', cellFilter: "date:'shortDate'", width: "10%" }, .on.paginationChanged($scope,
{ field: 'previousQuantity', name: 'Prev Qty', width: "10%", enableSorting: false }, function(pageNumber, pageSize) {
{ field: 'addedQuantity', name: 'Add Qty', width: "10%", enableSorting: false, cellFilter: "hideZero" }, paginationOptions.pageNumber = pageNumber;
{ field: 'removedQuantity', name: 'Remove Qty', width: "10%", enableSorting: false, cellFilter: "hideZero" }, paginationOptions.pageSize = pageSize;
{ field: 'currentQuantity', name: 'Current Qty', width: "10%", enableSorting: false } updateData();
], });
onRegisterApi: function(gridApi) { }
vm.gridApi = gridApi; };
vm.gridApi.pagination
.on.paginationChanged($scope, function(pageNumber, pageSize) { function updateData() {
paginationOptions.pageNumber = pageNumber; transactionSvc
paginationOptions.pageSize = pageSize; .filterByPage(paginationOptions.pageNumber, paginationOptions.pageSize)
updateData(); .success(function(data) {
vm.gridOptions.data = data.transactions;
vm.gridOptions.totalItems = data.totalItems;
}); });
} }
};
function updateData() { updateData();
transactionSvc
.filterByPage(paginationOptions.pageNumber, paginationOptions.pageSize)
.success(function (data) {
vm.gridOptions.data = data.transactions;
vm.gridOptions.totalItems = data.totalItems;
});
}
updateData(); $scope.editInventory = function(inventoryId) {
inventorySvc.find(inventoryId)
$scope.editInventory = function (inventoryId) { .success(function(inventory) {
inventorySvc.find(inventoryId) $uibModal.open({
.success(function(inventory) { template: '<edit-inventory inventory="inventory" />',
$uibModal.open({ scope: angular.extend($scope.$new(true), { inventory: inventory })
template: '<edit-inventory inventory="inventory" />', })
scope: angular.extend($scope.$new(true), { inventory: inventory }) .closed.then(function() {
}) updateData();
.closed.then(function() { });
updateData(); });
}); }
}); });
}
}
})(); })();
@@ -1,37 +1,35 @@
(function() { (function() {
window.app.factory('transactionSvc', transactionSvc); window.app.factory('transactionSvc',
function($http, inventorySvc) {
transactionSvc.$inject = ['$http', 'inventorySvc']; var svc = {
function transactionSvc($http, inventorySvc) { filterByPage: filterByPage,
filterByInventoryId: filterByInventoryId,
deleteTransaction: deleteTransaction
};
var svc = { return svc;
filterByPage: filterByPage,
filterByInventoryId: filterByInventoryId,
deleteTransaction: deleteTransaction
};
return svc; function filterByPage(pageNumber, pageSize) {
return getTransactions({ pageNumber: pageNumber, pageSize: pageSize });
function filterByPage(pageNumber, pageSize) { }
return getTransactions({ pageNumber: pageNumber, pageSize: pageSize });
}
function filterByInventoryId(inventoryId) { function filterByInventoryId(inventoryId) {
return getTransactions({ inventoryId: inventoryId }); return getTransactions({ inventoryId: inventoryId });
} }
function getTransactions(params) { function getTransactions(params) {
var url = '/Transaction/Get'; var url = '/Transaction/Get';
return $http.post(url, params) return $http.post(url, params)
.success(function (data) { .success(function(data) {
}); });
} }
function deleteTransaction(transactionId) { function deleteTransaction(transactionId) {
return $http.post('/Transaction/Delete', { transactionId: transactionId }) return $http.post('/Transaction/Delete', { transactionId: transactionId })
.success(function (data) { .success(function(data) {
inventorySvc.refresh(data.inventoryId); inventorySvc.refresh(data.inventoryId);
}); });
} }
} });
})(); })();
@@ -0,0 +1,29 @@
(function() {
'use strict';
window.app.controller('UserController',
function($uibModal, userSvc, downloadSvc) {
var vm = this;
vm.users = userSvc.users;
vm.create = function() {
$uibModal.open({
template: '<user-create />',
backdrop: 'static'
});
}
vm.edit = function() {
$uibModal.open({
template: '<user-edit />',
backdrop: 'static'
});
}
vm.export = function() {
userSvc.exportUsers()
.success(downloadSvc.success);
}
});
})();
@@ -0,0 +1,37 @@
(function() {
"use strict";
window.app.directive('userCreate', function() {
return {
templateUrl: '/user/template/userCreate.tmpl.cshtml',
controller: controller,
controllerAs: 'vm'
}
});
function controller($scope, userSvc){
var vm = this;
vm.saving = false;
vm.user = {};
vm.statusMessage = "Create a user";
vm.errorMessages = [];
vm.create = function() {
vm.statusMessage = null;
vm.saving = true;
userSvc.create(vm.user)
.success(function() {
//Close the modal
$scope.$close();
})
.error(function(data) {
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
})
.finally(function() {
vm.saving = false;
});
};
}
})();
@@ -0,0 +1,42 @@
(function() {
"use strict";
window.app.directive('userEdit', function (){
return {
scope: {
user: "="
},
templateUrl: '/user/template/userEdit.tmpl.cshtml',
controller: controller,
controllerAs: 'vm'
}
});
function controller($scope, userSvc) {
var vm = this;
vm.user = angular.copy($scope.user);
vm.save = save;
vm.saving = false;
vm.userSvc = userSvc;
vm.statusMessage = "Edit this user";
vm.errorMessages = [];
function save() {
vm.statusMessage = null;
vm.saving = true;
userSvc.edit($scope.user, vm.user)
.success(function () {
//Close the modal
$scope.$parent.$close();
})
.error(function(data) {
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
})
.finally(function() {
vm.saving = false;
});
}
}
})();
@@ -0,0 +1,27 @@
(function() {
'use strict';
window.app.directive('userList', function () {
return {
scope: { "users": "=" },
templateUrl: '/user/template/userList.tmpl.cshtml',
controller: controller,
controllerAs: 'vm'
}
});
controller.$inject = ['$scope', '$uibModal'];
function controller($scope, $uibModal) {
var vm = this;
vm.users = $scope.users;
vm.edit = edit;
function edit(user) {
$uibModal.open({
template: '<user-edit user="user" />',
scope: angular.extend($scope.$new(true), { user: user })
});
}
}
})();
@@ -0,0 +1,27 @@
@using InventoryTraker.Web.Helpers
@model InventoryTraker.Web.Models.UserEditForm
<form novalidate
name="vm.form"
ng-submit="vm.form.$valid && vm.create()">
<fieldset ng-disabled="vm.saving">
<div class="modal-header">
<h3 class="modal-title"><i class="fa fa-user"></i> Create User</h3>
</div>
<div class="modal-body">
<status-message message="vm.statusMessage"></status-message>
<error-list errors="vm.errorMessages"></error-list>
@Html.Angular().FormForModel("vm.user")
</div>
<div class="modal-footer">
<button class="btn btn-success">Create</button>
<button type="button" class="btn" ng-click="$dismiss()">Cancel</button>
</div>
</fieldset>
</form>
@@ -0,0 +1,27 @@
@using InventoryTraker.Web.Helpers
@model InventoryTraker.Web.Models.UserEditForm
<form novalidate
name="vm.form"
ng-submit="vm.form.$valid && vm.save()">
<fieldset ng-disabled="vm.saving">
<div class="modal-header">
<h3 class="modal-title"><i class="fa fa-user"></i> Edit User</h3>
</div>
<div class="modal-body">
<status-message message="vm.statusMessage"></status-message>
<error-list errors="vm.errorMessages"></error-list>
@Html.Angular().FormForModel("vm.user")
</div>
<div class="modal-footer">
<button class="btn btn-success">Save</button>
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
</div>
</fieldset>
</form>
@@ -0,0 +1,16 @@
<table class="table table-striped">
<thead>
<tr>
<th class="control-column"></th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in vm.users | orderBy:'name'">
<td><a href="" ng-click="vm.edit(user)"><i class="fa fa-edit"></i></a></td>
<td>{{user.userName}}</td>
<td>{{user.email}}</td>
</tr>
</tbody>
</table>
+42
View File
@@ -0,0 +1,42 @@
(function () {
window.app.factory('userSvc',
function($http) {
var users = [];
loadUsers();
var svc = {
create: create,
edit: edit,
users: users,
exportusers: exportusers
};
return svc;
function loadUsers() {
$http.post('/User/All')
.success(function(data) {
users.addRange(data);
});
}
function exportusers() {
return $http.post('/User/Export', {}, { responseType: 'arraybuffer' });
}
function create(user) {
return $http.post('/User/Create', user)
.success(function(user) {
users.unshift(user);
});
}
function edit(existingUser, editedUser) {
return $http.post('/User/Edit', editedUser)
.success(function(user) {
angular.copy(user, existingUser);
});
}
});
})();
@@ -13,7 +13,6 @@
} }
} }
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
var vm = this; var vm = this;
vm.query = {}; vm.query = {};
@@ -1,17 +1,15 @@
(function () { (function () {
window.app.factory('downloadSvc', downloadSvc); window.app.factory('downloadSvc',
function($http) {
downloadSvc.$inject = ['$http']; var svc = {
function downloadSvc($http) { success: function(data, status, headers, config) {
var file = new Blob([data], { type: headers('Content-Type') });
var match = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(headers('Content-Disposition'));
saveAs(file, match[1]);
}
};
var svc = { return svc;
success: function (data, status, headers, config) { });
var file = new Blob([data], { type: headers('Content-Type') });
var match = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(headers('Content-Disposition'));
saveAs(file, match[1]);
}
};
return svc;
}
})(); })();
+12 -13
View File
@@ -1,20 +1,19 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('errorList', errorList); window.app.directive('errorList',
function errorList() { function() {
return { return {
scope: { scope: {
errors: "=", errors: "=",
editMsg: "=" editMsg: "="
}, },
templateUrl: '/utility/template/errorList.tmpl.cshtml', templateUrl: '/utility/template/errorList.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
var vm = this; var vm = this;
vm.errors = $scope.errors; vm.errors = $scope.errors;
@@ -1,30 +1,28 @@
(function () { (function () {
'use strict'; 'use strict';
window.app.directive('formGroupValidation', formGroupValidation); window.app.directive('formGroupValidation',
function() {
function formGroupValidation() { return {
return { require: '^form',
require: '^form', replace: true,
replace: true, transclude: true,
transclude: true, template:
template: '<div class="has-feedback" ng-class="vm.getValidationClass()">' +
'<div class="has-feedback" ng-class="vm.getValidationClass()">' + '<ng-transclude></ng-transclude>' +
'<ng-transclude></ng-transclude>' + //'<input-validation-icons field="vm.field"></input-validation-icons>' +
//'<input-validation-icons field="vm.field"></input-validation-icons>' + '</div>',
'</div>', scope: {
scope: { field: '@formGroupValidation'
field: '@formGroupValidation' },
}, controller: controller,
controller: controller, controllerAs: 'vm',
controllerAs: 'vm', link: function(scope, element, attrs, formCtrl) {
link: function (scope, element, attrs, formCtrl) { scope.form = formCtrl;
scope.form = formCtrl; }
} }
} });
}
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
var vm = this; var vm = this;
@@ -1,12 +1,11 @@
(function() { (function() {
window.app.filter('formatCases', formatCases); window.app.filter('formatCases',
function() {
return function(qty) {
if (qty === '' || !isFinite(qty))
return '';
function formatCases() { return '(' + qty + ' cs)';
return function (qty) { }
if (qty === '' || !isFinite(qty)) });
return '';
return '(' + qty + ' cs)';
}
}
})(); })();
@@ -1,10 +1,9 @@
(function () { (function () {
window.app.filter('hideZero', hideZero); window.app.filter('hideZero',
function() {
return function(input) {
function hideZero() { return input > 0 ? input : "";
return function (input) { }
});
return input > 0 ? input : '';
}
}
})(); })();
@@ -1,28 +1,26 @@
(function () { (function () {
'use strict'; 'use strict';
window.app.directive('inputValidationIcons', inputValidationIcons); window.app.directive('inputValidationIcons',
function() {
function inputValidationIcons() { return {
return { require: '^form',
require: '^form', scope: {
scope: { field: '='
field: '=' },
}, template:
template: '<span ng-show="vm.canBeValidated() && vm.isValid()" ' +
'<span ng-show="vm.canBeValidated() && vm.isValid()" ' + 'class="fa fa-2x fa-check-square form-control-feedback"></span>' +
'class="fa fa-2x fa-check-square form-control-feedback"></span>' + '<span ng-show="vm.canBeValidated() && !vm.isValid()" ' +
'<span ng-show="vm.canBeValidated() && !vm.isValid()" ' + 'class="fa fa-2x fa-exclamation-triangle form-control-feedback"></span>',
'class="fa fa-2x fa-exclamation-triangle form-control-feedback"></span>', controller: controller,
controller: controller, controllerAs: 'vm',
controllerAs: 'vm', link: function(scope, element, attrs, formCtrl) {
link: function (scope, element, attrs, formCtrl) { scope.form = formCtrl;
scope.form = formCtrl; }
} }
} });
}
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
var vm = this; var vm = this;
@@ -1,35 +1,34 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('monthQuery', monthQuery); window.app.directive('monthQuery',
function monthQuery() { function() {
return { return {
scope: { scope: {
queryFn: '=' queryFn: '='
}, },
templateUrl: '/utility/template/monthQuery.tmpl.cshtml', templateUrl: '/utility/template/monthQuery.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
var vm = this; var vm = this;
vm.query = {}; vm.query = {};
vm.submitting = false; vm.submitting = false;
vm.errorMessages = []; vm.errorMessages = [];
vm.submit = submit; vm.submit =
function() {
function submit() { vm.submitting = true;
vm.submitting = true; $scope.queryFn({ month: vm.query })
$scope.queryFn({ month: vm.query }) .error(function(data) {
.error(function (data) { vm.errorMessages
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages); = angular.copy(data.errorMessages, vm.errorMessages);
}) })
.finally(function () { .finally(function() {
vm.submitting = false; vm.submitting = false;
}); });
} };
} }
})(); })();
@@ -1,46 +0,0 @@
(function () {
window.app.directive('mvcGrid', mvcGrid);
function mvcGrid() {
return {
scope: {
gridDataUrl: '@',
title: '@',
columns: '@?'
},
template:
'<div>' +
'<h4><i class="fa fa-pie-chart fa-fw"></i> {{vm.title}}</h4>' +
'<div>' +
'<p ng-if="vm.loading">Loading...</p>' +
'<div ng-if="!vm.loading" ui-grid="vm.gridOptions"></div>' +
'</div>' +
'</div>',
controllerAs: 'vm',
controller: controller
}
}
controller.$inject = ['$scope', '$http'];
function controller($scope, $http) {
var vm = this;
vm.gridOptions = {
enableHorizontalScrollbar: 0
}
vm.loading = true;
vm.title = $scope.title;
if ($scope.columns)
vm.gridOptions.columnDefs = angular.fromJson($scope.columns);
$http.post($scope.gridDataUrl)
.success(function (data) {
vm.gridOptions.data = data;
vm.loading = false;
});
}
})();
@@ -1,11 +1,10 @@
(function() { (function() {
window.app.filter('parseDate', parseDate); window.app.filter("parseDate",
function() {
return function(input) {
if (typeof input != 'string' || input.indexOf("/Date") === -1) return input;
function parseDate() { return new Date(parseInt(input.substr(6)));
return function(input) { }
if (typeof input != 'string' || input.indexOf('/Date') === -1) return input; });
return new Date(parseInt(input.substr(6)));
}
}
})(); })();
+12 -13
View File
@@ -1,20 +1,19 @@
(function() { (function() {
'use strict'; 'use strict';
window.app.directive('statusMessage', statusMessage); window.app.directive('statusMessage',
function statusMessage() { function() {
return { return {
scope: { scope: {
message: "=", message: "=",
severity: "=?" severity: "=?"
}, },
templateUrl: '/utility/template/statusMessage.tmpl.cshtml', templateUrl: '/utility/template/statusMessage.tmpl.cshtml',
controller: controller, controller: controller,
controllerAs: 'vm' controllerAs: 'vm'
} }
} });
controller.$inject = ['$scope'];
function controller($scope) { function controller($scope) {
} }
})(); })();
+8 -9
View File
@@ -1,13 +1,12 @@
(function() { (function() {
window.app.filter('toUnits', toUnits); window.app.filter('toUnits',
function() {
return function(caseQty, unitsPerCase) {
if (caseQty === "" || !isFinite(caseQty) || !isFinite(unitsPerCase))
return "";
function toUnits() { return caseQty * unitsPerCase;
return function (caseQty, unitsPerCase) { }
if (caseQty === '' || !isFinite(caseQty) || !isFinite(unitsPerCase)) });
return '';
return caseQty * unitsPerCase;
}
}
})(); })();