Employee Time Log using Bootstrap, AngularJS and WCF Service
Hi Guys,
This time I made Employee Time Logging application for an organisation using Bootstrap, AngularJS and WCF Services. This is a simple application which consumes (GET,POST) JSON enabled WCF Services using Angular JS. Hope you like it.
I used a login screen to allow the employees to login directly using there Domain Username and Password. Then I used localStorage module to store the user account info.
var appmodule = angular.module('EmployeeApp', ['ngRoute', 'ngAnimate', 'smart-table', 'LocalStorageModule', 'angular-loading-bar',
'ui.bootstrap.datetimepicker']);
appmodule.controller('IndexController', ["$scope", "$location", "authService", IndexController]);
appmodule.controller('LoginController', ["$scope", "$location", "authService", LoginController]);
appmodule.controller('TimeLogController', ["$scope", "$http", "authService","$filter", TimeLogController])
.directive('newTimeLog', function () {
return {
templateUrl: 'Views/Partials/new-time-log.html'
};
});
appmodule.run(['authService', function (authService) {
authService.fillAuthData();
}]);
appmodule.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/myTimeLogs', {
templateUrl: 'Views/Partials/MyTimeLogs.html',
controller: 'IndexController',
controllerAs: 'index'
})
.when('/login', {
templateUrl: 'Views/Partials/Login.html',
controller: 'LoginController',
controllerAs: 'login'
})
.otherwise({
redirectTo: '/login'
});;
$locationProvider.html5Mode(true);
}]);
function IndexController($scope, $location, authService) {
var scope = $scope;
scope.logOut = function () {
authService.logOut();
$location.path('/login');
}
scope.authentication = authService.authentication;
}
function LoginController($scope, $location, authService) {
var scope = $scope;
scope.message = '';
scope.login = function (loginData) {
authService.login(loginData).then(function (response) {
if (JSON.parse(response)) {
$location.path('/myTimeLogs');
}
else {
scope.message = 'Login UnSuccessful';
}
},
function (err) {
scope.message = err;
});
}
scope.authentication = authService.authentication;
}
function TimeLogController($scope, $http, authService, $filter) {
var scope = $scope;
scope.collection = [];
scope.message = '';
scope.alertClass = 'alert-danger';
scope.rowCollection = [];
scope.CurrentLog = [];
scope.StartTime = '';
scope.EndTime = '';
scope.authentication = authService.authentication;
scope.SaveLog = function (log) {
log.StartTime = getWCFJsonDate(log.StartTime);
log.EndTime = getWCFJsonDate(log.EndTime);
log.CreatedBy = scope.authentication.userName;
$http.post('/Services/EmployeeService.svc/SaveLog', log).success(function (response) {
if (JSON.parse(response)) {
getAllMyTimeLogs(scope, $http, scope.authentication.userName);
//scope.Reset();
scope.alertClass = 'alert-success';
scope.message = 'Saved Successfully!';
}
}).error(function (err, status) {
scope.message = err;
});
}
scope.Reset = function () {
var responsePromise = $http.get("/Services/EmployeeService.svc/GetLogById?id=2");
responsePromise.success(function (data, status, headers, config) {
scope.CurrentLog = clone(data[0]);
scope.message = '';
scope.StartTime = '';
scope.EndTime = '';
scope.CurrentLog.Duration = 0;
scope.alertClass = 'alert-danger';
});
responsePromise.error(function (data, status, headers, config) {
scope.alertClass = 'alert-danger';
scope.message = data;
});
}
scope.GetTotal = function (log) {
var total = 0.0;
for (var i = 0; i < scope.collection.length; i++) {
console.log(getDate(log["CreatedOn"]).toDateString() + '==' +
getDate(scope.collection[i]["CreatedOn"]).toDateString());
if (getDate(scope.collection[i]["CreatedOn"]).toDateString() ==
getDate(log["CreatedOn"]).toDateString()) {
total = total + parseFloat(scope.collection[i]["Duration"]);
}
}
return "width:" + parseInt((parseFloat(log["Duration"]) / total) * 100) +"%";
}
scope.Reset();
scope.Refresh = function () {
getAllMyTimeLogs(scope, $http, scope.authentication.userName);
}
scope.Refresh();
}
function getAllMyTimeLogs(thisscope, http, userName) {
var responsePromise = http.get("/Services/EmployeeService.svc/GetAllMyTimeLogs?userName=" + userName);
responsePromise.success(function (data, status, headers, config) {
thisscope.rowCollection = data;
thisscope.collection = data;
thisscope.displayedCollection = [].concat(thisscope.rowCollection);
thisscope.itemsByPage = 10;
});
responsePromise.error(function (data, status, headers, config) {
alert("AJAX failed!");
});
}
function clone(obj) {
if (obj == null || typeof (obj) != 'object')
return obj;
var temp = obj.constructor(); // changed
return temp;
}
function getWCFJsonDate(date)
{
return '/Date(' + new Date(date).getTime() + '+0300)/';
}
function getDate(dateTo)
{
var dt = new Date();
dt.setTime(dateTo.substring(6, dateTo.indexOf('+')));
return dt;
}
'use strict';
var app = angular.module('EmployeeApp');
app.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
var serviceBase = '/Services/EmployeeService.svc/';
var authServiceFactory = {};
var _authentication = {
isAuth: false,
userName: ""
};
var _login = function (loginData) {
var success = false;
var deferred = $q.defer();
$http.post(serviceBase + 'Login', loginData).success(function (response) {
if (JSON.parse(response)) {
localStorageService.set('authorizationData', { userName: loginData.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
}
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
var _logOut = function () {
localStorageService.remove('authorizationData');
_authentication.isAuth = false;
_authentication.userName = "";
};
var _fillAuthData = function () {
var authData = localStorageService.get('authorizationData');
if (authData) {
_authentication.isAuth = true;
_authentication.userName = authData.userName;
}
};
authServiceFactory.login = _login;
authServiceFactory.logOut = _logOut;
authServiceFactory.fillAuthData = _fillAuthData;
authServiceFactory.authentication = _authentication;
return authServiceFactory;
}]);
3) Open the EmployeeService,svc,cs and paste this code
using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace EmployeeTimeLog.Services
{
[Serializable]
[DataContract]
public class LoginData
{
[DataMember]
public string userName { get; set; }
[DataMember]
public string password { get; set; }
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmployeeService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select EmployeeService.svc or EmployeeService.svc.cs at the Solution Explorer and start debugging.
public class EmployeeService : IEmployeeService
{
[OperationBehavior]
public bool Login(LoginData login)
{
bool valid = true;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
valid = context.ValidateCredentials(login.userName, login.password);
}
return valid;
}
[OperationBehavior]
public List<EP_TimeLog> GetAllMyTimeLogs(string userName)
{
using (EmployeePortalDataContext context = new EmployeePortalDataContext())
{
var temp = (from r in context.EP_TimeLogs
where r.CreatedBy.Trim().ToLower() == userName.Trim().ToLower()
select r);
return temp.ToList();
}
}
[OperationBehavior]
public List<EP_TimeLog> GetLogById(long id)
{
using (EmployeePortalDataContext context = new EmployeePortalDataContext())
{
var temp = (from r in context.EP_TimeLogs where r.ID == id select r);
return temp.ToList();
}
}
[OperationBehavior]
public bool SaveLog(EP_TimeLog log)
{
bool valid = false;
using (EmployeePortalDataContext context = new EmployeePortalDataContext())
{
log.EditedBy = log.CreatedBy;
log.EditedOn = log.CreatedOn = DateTime.Now;
context.EP_TimeLogs.InsertOnSubmit(log);
context.SubmitChanges();
valid = true;
}
return valid;
}
}
}
4) Open the IEmployeeService,cs and paste this code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace EmployeeTimeLog.Services
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IEmployeeService" in both code and config file together.
[ServiceContract]
public interface IEmployeeService
{
[OperationContract]
[WebInvoke(UriTemplate = "/Login",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")]
bool Login(LoginData login);
[OperationContract]
[WebGet(UriTemplate = "/GetAllMyTimeLogs?userName={userName}",
ResponseFormat = WebMessageFormat.Json)]
List<EP_TimeLog> GetAllMyTimeLogs(string userName);
[OperationContract]
[WebInvoke(UriTemplate = "/SaveLog",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")]
bool SaveLog(EP_TimeLog log);
[OperationContract]
[WebGet(UriTemplate = "/GetLogById?id={id}",
ResponseFormat = WebMessageFormat.Json)]
List<EP_TimeLog> GetLogById(long id);
}
}
<form role="form" ng-controller="LoginController">
<div class="panel panel-primary">
<div class="panel-heading">
<img src="../../Images/logo.png" /></div>
<div class="panel-body">
<input type="text" class="form-control" placeholder="Username" data-ng-model="loginData.userName" required autofocus>
<input type="password" class="form-control" placeholder="Password" data-ng-model="loginData.password" required>
<button class="btn btn-primary" type="submit" data-ng-click="login(loginData)">Login</button>
<div data-ng-hide="message == ''" class="alert alert-danger">
{{message}}
</div>
</div>
</div>
</form>
6) Open Views -> Partials -> MyTimeLogs.html and paste following
<div class="container" ng-controller="TimeLogController">
<div class="panel panel-primary">
<div class="panel-heading">
<h1 >My Time Logs</h1>
</div>
<div class="panel-body">
<div class="pull-right"><a data-toggle="modal" data-target="#myModal" ng-click="Reset()" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span> Add</a>
<a class="btn btn-success" ng-click="Refresh()"><span class="glyphicon glyphicon-refresh"></span> Refresh</a>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover" st-table="displayedCollection" st-safe-src="rowCollection" width="100%" >
<thead>
<tr>
<th colspan="7">
<div class="input-group pull-right" style="max-width:470px;">
<input st-search="" placeholder="Search" class="input-sm form-control" type="search">
</div>
</th>
</tr>
<tr>
<th>
Name
</th>
<th>
Description
</th>
<th>
Start Time
</th>
<th>
End Time
</th>
<th>
Duration (Mins)
</th>
<th>
Percentage
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="log in displayedCollection | orderBy:CreatedOn:true">
<td>{{ log.Name }}</td>
<td>{{ log.Description }}</td>
<td>{{ log.StartTime.substring(6, log.StartTime.indexOf('+')) | date:'EEEE, dd MMM yyyy HH:mm:ss ' }}</td>
<td>{{ log.EndTime.substring(6, log.EndTime.indexOf('+')) | date:'EEEE, dd MMM yyyy HH:mm:ss ' }}</td>
<td>{{ log.Duration }}</td>
<td>
<div class="progress progress-striped" style="width:80px" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Total Percentage of work for the day!" >
<div class="progress-bar progress-bar-success" style="{{ GetTotal(log) }}"></div>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="7" >
<div st-pagination="" class="pull-right" st-items-by-page="itemsByPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">New Time Log</h4>
</div>
<div class="modal-body">
<div ng-controller="TimeLogController">
<div new-time-log></div>
</div>
</div>
</div>
</div>
</div>
</div>
7) Open Views -> Partials -> new-time-log.html and paste following
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Employee Time Log</title>
<meta name="generator" content="Bootply" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link rel="icon"
type="image/png" href="Images/favicon.png" />
<script src="js/angular.min.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/angular-local-storage.min.js"></script>
<link href="css/loading-bar.css" rel="stylesheet" />
<script src="js/loading-bar.js"></script>
<script src="js/angular-animate.js"></script>
<script src="js/moment.js"></script>
<script src="js/datetimepicker.js"></script>
<script src="js/app.js"></script>
<link href="css/datetimepicker.css" rel="stylesheet" />
<script src="js/authService.js"></script>
<script src="js/smart-table.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="css/styles.css" rel="stylesheet">
<link href="css/loading-bar.css" rel="stylesheet" />
</head>
<body ng-app="EmployeeApp" >
<div class="navbar navbar-inverse" ng-controller="IndexController">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-inverse-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Employee Time Log</a>
</div>
<div class="navbar-collapse collapse navbar-inverse-collapse">
<ul class="nav navbar-nav navbar-right">
<li data-ng-hide="!authentication.isAuth"><a href="/myTimeLogs"><span class="glyphicon glyphicon-th-list"></span> My Time Logs</a></li>
<li data-ng-hide="!authentication.isAuth" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-user"></span> Welcome {{authentication.userName}} <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a ng-click="logOut()"><span class="glyphicon glyphicon-off"></span> Log out</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!--main-->
<div class="container" id="main">
<div class="view-animate-container">
<div ng-view class="view-animate"></div>
</div>
</div>
<!-- script references -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
</html>
Login Page.
Page is made to work in both mobile and pc browsers using bootstrap.
Before you Start,
1) Any version of Visual Studio
Step One : The Solution
First create a Web Application as following.
Step Two : Code and Styles
Since this is a Website I will not include all the code here. I will include only the AngularJS code.
1) Open js -> app.js and paste the following code
'ui.bootstrap.datetimepicker']);
appmodule.controller('IndexController', ["$scope", "$location", "authService", IndexController]);
appmodule.controller('LoginController', ["$scope", "$location", "authService", LoginController]);
appmodule.controller('TimeLogController', ["$scope", "$http", "authService","$filter", TimeLogController])
.directive('newTimeLog', function () {
return {
templateUrl: 'Views/Partials/new-time-log.html'
};
});
appmodule.run(['authService', function (authService) {
authService.fillAuthData();
}]);
appmodule.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/myTimeLogs', {
templateUrl: 'Views/Partials/MyTimeLogs.html',
controller: 'IndexController',
controllerAs: 'index'
})
.when('/login', {
templateUrl: 'Views/Partials/Login.html',
controller: 'LoginController',
controllerAs: 'login'
})
.otherwise({
redirectTo: '/login'
});;
$locationProvider.html5Mode(true);
}]);
function IndexController($scope, $location, authService) {
var scope = $scope;
scope.logOut = function () {
authService.logOut();
$location.path('/login');
}
scope.authentication = authService.authentication;
}
function LoginController($scope, $location, authService) {
var scope = $scope;
scope.message = '';
scope.login = function (loginData) {
authService.login(loginData).then(function (response) {
if (JSON.parse(response)) {
$location.path('/myTimeLogs');
}
else {
scope.message = 'Login UnSuccessful';
}
},
function (err) {
scope.message = err;
});
}
scope.authentication = authService.authentication;
}
function TimeLogController($scope, $http, authService, $filter) {
var scope = $scope;
scope.collection = [];
scope.message = '';
scope.alertClass = 'alert-danger';
scope.rowCollection = [];
scope.CurrentLog = [];
scope.StartTime = '';
scope.EndTime = '';
scope.authentication = authService.authentication;
scope.SaveLog = function (log) {
log.StartTime = getWCFJsonDate(log.StartTime);
log.EndTime = getWCFJsonDate(log.EndTime);
log.CreatedBy = scope.authentication.userName;
$http.post('/Services/EmployeeService.svc/SaveLog', log).success(function (response) {
if (JSON.parse(response)) {
getAllMyTimeLogs(scope, $http, scope.authentication.userName);
//scope.Reset();
scope.alertClass = 'alert-success';
scope.message = 'Saved Successfully!';
}
}).error(function (err, status) {
scope.message = err;
});
}
scope.Reset = function () {
var responsePromise = $http.get("/Services/EmployeeService.svc/GetLogById?id=2");
responsePromise.success(function (data, status, headers, config) {
scope.CurrentLog = clone(data[0]);
scope.message = '';
scope.StartTime = '';
scope.EndTime = '';
scope.CurrentLog.Duration = 0;
scope.alertClass = 'alert-danger';
});
responsePromise.error(function (data, status, headers, config) {
scope.alertClass = 'alert-danger';
scope.message = data;
});
}
scope.GetTotal = function (log) {
var total = 0.0;
for (var i = 0; i < scope.collection.length; i++) {
console.log(getDate(log["CreatedOn"]).toDateString() + '==' +
getDate(scope.collection[i]["CreatedOn"]).toDateString());
if (getDate(scope.collection[i]["CreatedOn"]).toDateString() ==
getDate(log["CreatedOn"]).toDateString()) {
total = total + parseFloat(scope.collection[i]["Duration"]);
}
}
return "width:" + parseInt((parseFloat(log["Duration"]) / total) * 100) +"%";
}
scope.Reset();
scope.Refresh = function () {
getAllMyTimeLogs(scope, $http, scope.authentication.userName);
}
scope.Refresh();
}
function getAllMyTimeLogs(thisscope, http, userName) {
var responsePromise = http.get("/Services/EmployeeService.svc/GetAllMyTimeLogs?userName=" + userName);
responsePromise.success(function (data, status, headers, config) {
thisscope.rowCollection = data;
thisscope.collection = data;
thisscope.displayedCollection = [].concat(thisscope.rowCollection);
thisscope.itemsByPage = 10;
});
responsePromise.error(function (data, status, headers, config) {
alert("AJAX failed!");
});
}
function clone(obj) {
if (obj == null || typeof (obj) != 'object')
return obj;
var temp = obj.constructor(); // changed
return temp;
}
function getWCFJsonDate(date)
{
return '/Date(' + new Date(date).getTime() + '+0300)/';
}
function getDate(dateTo)
{
var dt = new Date();
dt.setTime(dateTo.substring(6, dateTo.indexOf('+')));
return dt;
}
2) Open js -> authService.js and paste the following code
var app = angular.module('EmployeeApp');
app.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
var serviceBase = '/Services/EmployeeService.svc/';
var authServiceFactory = {};
var _authentication = {
isAuth: false,
userName: ""
};
var _login = function (loginData) {
var success = false;
var deferred = $q.defer();
$http.post(serviceBase + 'Login', loginData).success(function (response) {
if (JSON.parse(response)) {
localStorageService.set('authorizationData', { userName: loginData.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
}
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
var _logOut = function () {
localStorageService.remove('authorizationData');
_authentication.isAuth = false;
_authentication.userName = "";
};
var _fillAuthData = function () {
var authData = localStorageService.get('authorizationData');
if (authData) {
_authentication.isAuth = true;
_authentication.userName = authData.userName;
}
};
authServiceFactory.login = _login;
authServiceFactory.logOut = _logOut;
authServiceFactory.fillAuthData = _fillAuthData;
authServiceFactory.authentication = _authentication;
return authServiceFactory;
}]);
3) Open the EmployeeService,svc,cs and paste this code
using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace EmployeeTimeLog.Services
{
[Serializable]
[DataContract]
public class LoginData
{
[DataMember]
public string userName { get; set; }
[DataMember]
public string password { get; set; }
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmployeeService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select EmployeeService.svc or EmployeeService.svc.cs at the Solution Explorer and start debugging.
public class EmployeeService : IEmployeeService
{
[OperationBehavior]
public bool Login(LoginData login)
{
bool valid = true;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
valid = context.ValidateCredentials(login.userName, login.password);
}
return valid;
}
[OperationBehavior]
public List<EP_TimeLog> GetAllMyTimeLogs(string userName)
{
using (EmployeePortalDataContext context = new EmployeePortalDataContext())
{
var temp = (from r in context.EP_TimeLogs
where r.CreatedBy.Trim().ToLower() == userName.Trim().ToLower()
select r);
return temp.ToList();
}
}
[OperationBehavior]
public List<EP_TimeLog> GetLogById(long id)
{
using (EmployeePortalDataContext context = new EmployeePortalDataContext())
{
var temp = (from r in context.EP_TimeLogs where r.ID == id select r);
return temp.ToList();
}
}
[OperationBehavior]
public bool SaveLog(EP_TimeLog log)
{
bool valid = false;
using (EmployeePortalDataContext context = new EmployeePortalDataContext())
{
log.EditedBy = log.CreatedBy;
log.EditedOn = log.CreatedOn = DateTime.Now;
context.EP_TimeLogs.InsertOnSubmit(log);
context.SubmitChanges();
valid = true;
}
return valid;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace EmployeeTimeLog.Services
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IEmployeeService" in both code and config file together.
[ServiceContract]
public interface IEmployeeService
{
[OperationContract]
[WebInvoke(UriTemplate = "/Login",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")]
bool Login(LoginData login);
[OperationContract]
[WebGet(UriTemplate = "/GetAllMyTimeLogs?userName={userName}",
ResponseFormat = WebMessageFormat.Json)]
List<EP_TimeLog> GetAllMyTimeLogs(string userName);
[OperationContract]
[WebInvoke(UriTemplate = "/SaveLog",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")]
bool SaveLog(EP_TimeLog log);
[OperationContract]
[WebGet(UriTemplate = "/GetLogById?id={id}",
ResponseFormat = WebMessageFormat.Json)]
List<EP_TimeLog> GetLogById(long id);
}
}
5) Open Views -> Partials -> Login.html and paste following
<form role="form" ng-controller="LoginController">
<div class="panel panel-primary">
<div class="panel-heading">
<img src="../../Images/logo.png" /></div>
<div class="panel-body">
<input type="text" class="form-control" placeholder="Username" data-ng-model="loginData.userName" required autofocus>
<input type="password" class="form-control" placeholder="Password" data-ng-model="loginData.password" required>
<button class="btn btn-primary" type="submit" data-ng-click="login(loginData)">Login</button>
<div data-ng-hide="message == ''" class="alert alert-danger">
{{message}}
</div>
</div>
</div>
</form>
6) Open Views -> Partials -> MyTimeLogs.html and paste following
<div class="container" ng-controller="TimeLogController">
<div class="panel panel-primary">
<div class="panel-heading">
<h1 >My Time Logs</h1>
</div>
<div class="panel-body">
<div class="pull-right"><a data-toggle="modal" data-target="#myModal" ng-click="Reset()" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span> Add</a>
<a class="btn btn-success" ng-click="Refresh()"><span class="glyphicon glyphicon-refresh"></span> Refresh</a>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover" st-table="displayedCollection" st-safe-src="rowCollection" width="100%" >
<thead>
<tr>
<th colspan="7">
<div class="input-group pull-right" style="max-width:470px;">
<input st-search="" placeholder="Search" class="input-sm form-control" type="search">
</div>
</th>
</tr>
<tr>
<th>
Name
</th>
<th>
Description
</th>
<th>
Start Time
</th>
<th>
End Time
</th>
<th>
Duration (Mins)
</th>
<th>
Percentage
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="log in displayedCollection | orderBy:CreatedOn:true">
<td>{{ log.Name }}</td>
<td>{{ log.Description }}</td>
<td>{{ log.StartTime.substring(6, log.StartTime.indexOf('+')) | date:'EEEE, dd MMM yyyy HH:mm:ss ' }}</td>
<td>{{ log.EndTime.substring(6, log.EndTime.indexOf('+')) | date:'EEEE, dd MMM yyyy HH:mm:ss ' }}</td>
<td>{{ log.Duration }}</td>
<td>
<div class="progress progress-striped" style="width:80px" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Total Percentage of work for the day!" >
<div class="progress-bar progress-bar-success" style="{{ GetTotal(log) }}"></div>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="7" >
<div st-pagination="" class="pull-right" st-items-by-page="itemsByPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">New Time Log</h4>
</div>
<div class="modal-body">
<div ng-controller="TimeLogController">
<div new-time-log></div>
</div>
</div>
</div>
</div>
</div>
</div>
7) Open Views -> Partials -> new-time-log.html and paste following
<form name="LogForm" ng-submit="LogForm.$valid && SaveLog(CurrentLog)" novalidate>
<div >
<div class="panel panel-primary">
<div class="panel-body">
<div class="form-group">
<label>Name </label>
<input type="text" class="form-control" rows="3" ng-model="CurrentLog.Name" maxlength="250" required></input>
</div>
<div class="form-group">
<label>Description</label>
<textarea class="form-control" ng-model="CurrentLog.Description" maxlength="2000" required> </textarea>
</div>
<div class="form-group">
<label>Start Time</label>
<span> {{ CurrentLog.StartTime = (StartTime | date:'yyyy-MM-dd HH:mm:ss')}}</span>
<div class="dropdown">
<a class="dropdown-toggle" id="dropdown1" role="button" data-toggle="dropdown" data-target="#" href="#">Click here to Set Start Time</a>
<ul class="dropdown-menu" role="menu">
<datetimepicker data-ng-model="StartTime" data-datetimepicker-config="{ dropdownSelector: '#dropdown1' }"/>
</ul>
</div>
</div>
<div class="form-group">
<label>End Time</label>
<span> {{ CurrentLog.EndTime = (EndTime | date:'yyyy-MM-dd HH:mm:ss')}}</span>
<div class="dropdown">
<a class="dropdown-toggle" id="dropdown2" role="button" data-toggle="dropdown" data-target="#" href="#">Click here to Set Start Time</a>
<ul class="dropdown-menu" role="menu">
<datetimepicker data-ng-model="EndTime" data-datetimepicker-config="{ dropdownSelector: '#dropdown2' }"/>
</ul>
</div>
</div>
<div>
<div data-ng-hide="CurrentLog.Duration > 0" class="alert alert-danger">
<strong>Invalid</strong> Start Time and End Time are invalid!
</div>
</div>
<div class="form-group">
<label>Duration</label><br />
<span>
{{ CurrentLog.Duration = (EndTime - StartTime)/60000 }} Min(s)
</span>
</div>
<div data-ng-hide="message == ''" class="alert " ng-class="alertClass">
{{message}}
</div>
<div class="pull-right">
<button type="submit" class="btn btn-primary" ><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
<button type="reset" class="btn btn-primary" ng-click="Reset()" ><span class="glyphicon glyphicon-remove"></span> Reset</button>
</div>
</div>
</div>
</form>
8) Open Views -> Partials -> index.html and paste following
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Employee Time Log</title>
<meta name="generator" content="Bootply" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link rel="icon"
type="image/png" href="Images/favicon.png" />
<script src="js/angular.min.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/angular-local-storage.min.js"></script>
<link href="css/loading-bar.css" rel="stylesheet" />
<script src="js/loading-bar.js"></script>
<script src="js/angular-animate.js"></script>
<script src="js/moment.js"></script>
<script src="js/datetimepicker.js"></script>
<script src="js/app.js"></script>
<link href="css/datetimepicker.css" rel="stylesheet" />
<script src="js/authService.js"></script>
<script src="js/smart-table.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="css/styles.css" rel="stylesheet">
<link href="css/loading-bar.css" rel="stylesheet" />
</head>
<body ng-app="EmployeeApp" >
<div class="navbar navbar-inverse" ng-controller="IndexController">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-inverse-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Employee Time Log</a>
</div>
<div class="navbar-collapse collapse navbar-inverse-collapse">
<ul class="nav navbar-nav navbar-right">
<li data-ng-hide="!authentication.isAuth"><a href="/myTimeLogs"><span class="glyphicon glyphicon-th-list"></span> My Time Logs</a></li>
<li data-ng-hide="!authentication.isAuth" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-user"></span> Welcome {{authentication.userName}} <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a ng-click="logOut()"><span class="glyphicon glyphicon-off"></span> Log out</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!--main-->
<div class="container" id="main">
<div class="view-animate-container">
<div ng-view class="view-animate"></div>
</div>
</div>
<!-- script references -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
</html>
Comments
Post a Comment