Added source code for Snapshot Debugger lab
This commit is contained in:
Родитель
841234d61c
Коммит
eb8d9485ba
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- File name extension must be .runsettings -->
|
||||
<RunSettings>
|
||||
<DataCollectionRunSettings>
|
||||
<DataCollectors>
|
||||
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<Configuration>
|
||||
<CodeCoverage>
|
||||
<!--
|
||||
Additional paths to search for .pdb (symbol) files. Symbols must be found for modules to be instrumented.
|
||||
If .pdb files are in the same folder as the .dll or .exe files, they are automatically found. Otherwise, specify them here.
|
||||
Note that searching for symbols increases code coverage runtime. So keep this small and local.
|
||||
-->
|
||||
<!--
|
||||
<SymbolSearchPaths>
|
||||
<Path>C:\Users\User\Documents\Visual Studio 2012\Projects\ProjectX\bin\Debug</Path>
|
||||
<Path>\\mybuildshare\builds\ProjectX</Path>
|
||||
</SymbolSearchPaths>
|
||||
-->
|
||||
|
||||
<!--
|
||||
About include/exclude lists:
|
||||
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
|
||||
Each element in the list is a regular expression (ECMAScript syntax). See http://msdn.microsoft.com/library/2k3te2cs.aspx.
|
||||
An item must first match at least one entry in the include list to be included.
|
||||
Included items must then not match any entries in the exclude list to remain included.
|
||||
-->
|
||||
|
||||
<!-- Match assembly file paths: -->
|
||||
<ModulePaths>
|
||||
<Include>
|
||||
</Include>
|
||||
<Exclude>
|
||||
<ModulePath>.*Tests.dll</ModulePath>
|
||||
</Exclude>
|
||||
</ModulePaths>
|
||||
|
||||
<!-- Match fully qualified names of functions: -->
|
||||
<!-- (Use "\." to delimit namespaces in C# or Visual Basic, "::" in C++.) -->
|
||||
<Functions>
|
||||
<Exclude>
|
||||
<ModulePath>.*notification.dll</ModulePath>
|
||||
</Exclude>
|
||||
</Functions>
|
||||
|
||||
<!-- Match attributes on any code element: -->
|
||||
<Attributes>
|
||||
<Exclude>
|
||||
<!-- Don’t forget "Attribute" at the end of the name -->
|
||||
<Attribute>^System.Diagnostics.DebuggerHiddenAttribute$</Attribute>
|
||||
<Attribute>^System.Diagnostics.DebuggerNonUserCodeAttribute$</Attribute>
|
||||
<Attribute>^System.Runtime.CompilerServices.CompilerGeneratedAttribute$</Attribute>
|
||||
<Attribute>^System.CodeDom.Compiler.GeneratedCodeAttribute$</Attribute>
|
||||
<Attribute>^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
|
||||
</Exclude>
|
||||
</Attributes>
|
||||
|
||||
<!-- Match the path of the source files in which each method is defined: -->
|
||||
<Sources>
|
||||
<Exclude>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\App_Start\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Utils\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Infraestructure\\ErrorHandling\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Infraestructure\\Security\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Infraestructure\\Cache\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Infraestructure\\IoC\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Areas\\HelpPage\\.*</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Controllers\\FederationController.cs</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Controllers\\HomeController.cs</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Controllers\\ApiExplorerController.cs</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Controllers\\AccountController.cs</Source>
|
||||
<Source>.*\\MyCompany.Visitors.Web\\Global.asax.cs</Source>
|
||||
</Exclude>
|
||||
</Sources>
|
||||
|
||||
<!-- Match the company name property in the assembly: -->
|
||||
<CompanyNames>
|
||||
<Exclude>
|
||||
<CompanyName>.*microsoft.*</CompanyName>
|
||||
</Exclude>
|
||||
</CompanyNames>
|
||||
|
||||
<!-- Match the public key token of a signed assembly: -->
|
||||
<PublicKeyTokens>
|
||||
<!-- Exclude Visual Studio extensions: -->
|
||||
<Exclude>
|
||||
<PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
|
||||
<PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
|
||||
<PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
|
||||
<PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
|
||||
<PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
|
||||
<PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
|
||||
<PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
|
||||
</Exclude>
|
||||
</PublicKeyTokens>
|
||||
|
||||
|
||||
<!-- We recommend you do not change the following values: -->
|
||||
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
|
||||
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
|
||||
<CollectFromChildProcesses>True</CollectFromChildProcesses>
|
||||
<CollectAspDotNet>False</CollectAspDotNet>
|
||||
|
||||
</CodeCoverage>
|
||||
</Configuration>
|
||||
</DataCollector>
|
||||
</DataCollectors>
|
||||
</DataCollectionRunSettings>
|
||||
</RunSettings>
|
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/Common/MyCompany.Common.CrossCutting.dll
Executable file
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/Common/MyCompany.Common.CrossCutting.dll
Executable file
Двоичный файл не отображается.
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/Common/MyCompany.Common.Notification.dll
Executable file
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/Common/MyCompany.Common.Notification.dll
Executable file
Двоичный файл не отображается.
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/Common/MyCompany.Common.Security.dll
Executable file
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/Common/MyCompany.Common.Security.dll
Executable file
Двоичный файл не отображается.
|
@ -0,0 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
[assembly: AssemblyCompany("MyCompany Visitors")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("MyCompany")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyProduct("MyCompany")]
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Dictionary>
|
||||
<Words>
|
||||
<Recognized>
|
||||
<Word>MyCompany</Word>
|
||||
</Recognized>
|
||||
</Words>
|
||||
<Acronyms>
|
||||
<CasingExceptions>
|
||||
</CasingExceptions>
|
||||
</Acronyms>
|
||||
</Dictionary>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
|
||||
<connectionStrings>
|
||||
<add name="MyCompany.Visitors" providerName="System.Data.SqlClient" connectionString="Server=(localdb)\v11.0;Database=MyCompany.Visitors;Trusted_Connection=true;Integrated Security=True;MultipleActiveResultSets=True" />
|
||||
</connectionStrings>
|
||||
<entityFramework>
|
||||
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
|
||||
<parameters>
|
||||
<parameter value="v11.0" />
|
||||
</parameters>
|
||||
</defaultConnectionFactory>
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
</configuration>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Dictionary>
|
||||
<Words>
|
||||
<Recognized>
|
||||
<Word>MyCompany</Word>
|
||||
</Recognized>
|
||||
</Words>
|
||||
<Acronyms>
|
||||
<CasingExceptions>
|
||||
</CasingExceptions>
|
||||
</Acronyms>
|
||||
</Dictionary>
|
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/MyCompany.Visitors.Data/GlobalSuppressions.cs
Executable file
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/MyCompany.Visitors.Data/GlobalSuppressions.cs
Executable file
Двоичный файл не отображается.
|
@ -0,0 +1,24 @@
|
|||
|
||||
namespace MyCompany.Visitors.Data.Infrastructure.Conventions
|
||||
{
|
||||
using System;
|
||||
using System.Data.Entity.ModelConfiguration.Conventions;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Convention to set all clr date time properties
|
||||
/// to datetime2 sql data type.
|
||||
/// </summary>
|
||||
class CLRDateTimeToSqlDateTime2
|
||||
: Convention
|
||||
{
|
||||
/// <summary>
|
||||
/// CLR Date time to sql datatime convention constuctor
|
||||
/// </summary>
|
||||
public CLRDateTimeToSqlDateTime2()
|
||||
{
|
||||
this.Properties<DateTime>()
|
||||
.Configure(p => p.HasColumnType("datetime2"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
|
||||
namespace MyCompany.Visitors.Data.Infrastructure.Conventions
|
||||
{
|
||||
using System;
|
||||
using System.Data.Entity.ModelConfiguration.Conventions;
|
||||
|
||||
/// <summary>
|
||||
/// Max string length convention
|
||||
/// </summary>
|
||||
class MaxStringLengthConvention
|
||||
:Convention
|
||||
{
|
||||
/// <summary>
|
||||
/// Max string length convention constructor
|
||||
/// </summary>
|
||||
public MaxStringLengthConvention()
|
||||
{
|
||||
this.Properties<String>()
|
||||
.Configure(c => c.HasMaxLength(255));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,494 @@
|
|||
namespace MyCompany.Visitors.Data.Infrastructure.Initializers
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The default initializer for context. You can learn more
|
||||
/// about EF initializers here
|
||||
/// http://msdn.microsoft.com/en-us/library/gg696323(v=VS.103).aspx
|
||||
/// </summary>
|
||||
class MyCompanyContextInitializer :
|
||||
DropCreateDatabaseIfModelChanges<MyCompanyContext>
|
||||
{
|
||||
|
||||
private static readonly Random _randomize = new Random();
|
||||
private static string tenant = ConfigurationManager.AppSettings["ida:Domain"];
|
||||
private string _picturePath = "FakeImages\\{0}.jpg";
|
||||
private string _smallPicturePath = "FakeImages\\{0} - small.jpg";
|
||||
private List<string> _employeeEmails = new List<string>()
|
||||
{
|
||||
String.Format("Andrew.Davis@{0}", tenant),
|
||||
String.Format("Christen.Anderson@{0}", tenant),
|
||||
String.Format("David.Alexander@{0}", tenant),
|
||||
String.Format("Robin.Counts@{0}", tenant),
|
||||
String.Format("Thomas.Andersen@{0}", tenant),
|
||||
String.Format("Josh.Bailey@{0}", tenant),
|
||||
String.Format("Adam.Barr@{0}", tenant),
|
||||
String.Format("Christa.Geller@{0}", tenant),
|
||||
String.Format("Carole.Poland@{0}", tenant),
|
||||
String.Format("Cristina.Potra@{0}", tenant),
|
||||
};
|
||||
private List<string> _employeeNames = new List<string>()
|
||||
{
|
||||
"Andrew Davis",
|
||||
"Christen Anderson",
|
||||
"David Alexander",
|
||||
"Robin Counts",
|
||||
"Thomas Andersen",
|
||||
"Josh Bailey",
|
||||
"Adam Barr",
|
||||
"Christa Geller",
|
||||
"Carole Poland",
|
||||
"Cristina Potra",
|
||||
};
|
||||
|
||||
private List<string> _visitorNames = new List<string>()
|
||||
{
|
||||
"Scott Hunter",
|
||||
"Brian Moore",
|
||||
"Scott Woodgate",
|
||||
"Craig Kitterman",
|
||||
"Violeta Arroyo",
|
||||
"Phil Webb",
|
||||
"Rob Caron",
|
||||
"Matt Mostad",
|
||||
"Adriana Bors",
|
||||
"Beth Massi",
|
||||
"Carlos Zimmermann",
|
||||
"Mitra Azizirad"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Seed
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
protected override void Seed(MyCompanyContext context)
|
||||
{
|
||||
CreateTeamManagers(context);
|
||||
|
||||
CreateEmployees(context, 2);
|
||||
|
||||
CreateTeamManagersNYC(context);
|
||||
CreateEmployeesForNYCTeams(context);
|
||||
|
||||
CreateEmployeePictures(context);
|
||||
|
||||
CreateVisitors(context);
|
||||
CreateVisits(context);
|
||||
CreateQuestions(context);
|
||||
}
|
||||
|
||||
|
||||
private void CreateQuestions(MyCompanyContext context)
|
||||
{
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "Why are software updates necessary?",
|
||||
Answer = "Microsoft is committed to providing its customers with software that has been tested for safety and security. Although no system is completely secure, we use processes, technology, and several specially focused teams to investigate, fix, and learn from security issues to help us meet this goal and to provide guidance to customers on how to help protect their PCs."
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "How can I keep my software up to date?",
|
||||
Answer = "Microsoft offers a range of online services to help you keep your computer up to date. Windows Update finds updates that you might not even be aware of and provides you with the simplest way to install updates that help prevent or fix problems, improve how your computer works, or enhance your computing experience. Visit Windows Update to learn more."
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "How do I find worldwide downloads?",
|
||||
Answer = "Microsoft delivers downloads in more than 118 languages worldwide. The Download Center now combines all English downloads into a single English Download Center. We no longer offer separate downloads for U.S. English, U.K. English, Australian English, or Canadian English."
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "How do I install downloaded software?",
|
||||
Answer = "Before you can use any software that you download, you must install it. For example, if you download a security update but do not install it, the update will not provide any protection for your computer."
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "Can I try Office before I buy?",
|
||||
Answer = "Yes. You can sign up to try Office 365 Home Premium for one month free."
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "What do I get with the Office 365 Home Premium trial? ",
|
||||
Answer = "The Office trial gives you access to all the features of Office 365 Home Premium except the additional. 20 GB of SkyDrive storage. You can install the Office trial alongside your existing version of Office."
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "How do I make sure I always have the latest Office applications?",
|
||||
Answer = "Office 365 customers with an active subscription always get the newest versions of the Office applications when they are available. When we release a new version of Office, you will be notified that you have the option to update your software to the latest version. "
|
||||
});
|
||||
|
||||
context.Questions.Add(new Question()
|
||||
{
|
||||
Text = "Can I install the new Office on my Mac?",
|
||||
Answer = " you have an active Office 365 Home Premium or Office 365 University subscription, and available installs, you can install Office applications including Word, Excel, PowerPoint and Outlook on your Mac. The applications available for Mac users and the version numbers may be different from those available for PC users."
|
||||
});
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
private void CreateTeamManagers(MyCompanyContext context)
|
||||
{
|
||||
int managersCount = 1;
|
||||
|
||||
for (int i = 0; i < managersCount; i++)
|
||||
{
|
||||
int id = i + 1;
|
||||
var name = _employeeNames[i];
|
||||
var split = name.Split(' ');
|
||||
context.Employees.Add(new Employee()
|
||||
{
|
||||
EmployeeId = id,
|
||||
FirstName = split[0],
|
||||
LastName = split[1],
|
||||
Email = _employeeEmails[i],
|
||||
JobTitle = "Team Lead",
|
||||
});
|
||||
|
||||
context.Teams.Add(new Team() { TeamId = id, ManagerId = id });
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
|
||||
private void CreateEmployees(MyCompanyContext context, int employeesCount)
|
||||
{
|
||||
int initialId = context.Employees.Count() + 1;
|
||||
|
||||
int teamOneId = context.Teams.OrderBy(t => t.TeamId).First().TeamId;
|
||||
|
||||
for (int i = initialId; i <= employeesCount; i++)
|
||||
{
|
||||
int index = i - 1;
|
||||
var name = _employeeNames[index];
|
||||
|
||||
var split = name.Split(' ');
|
||||
context.Employees.Add(new Employee()
|
||||
{
|
||||
EmployeeId = i,
|
||||
FirstName = split[0],
|
||||
LastName = split[1],
|
||||
Email = _employeeEmails[index],
|
||||
JobTitle = GetPosition(i),
|
||||
TeamId = teamOneId
|
||||
});
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
private void CreateVisitors(MyCompanyContext context)
|
||||
{
|
||||
int visitorsCount = _visitorNames.Count;
|
||||
int visitorPictureId = 1;
|
||||
string domain;
|
||||
|
||||
string cs = ConfigurationManager.ConnectionStrings["MyCompany.Visitors"].ConnectionString; //QuickStart
|
||||
|
||||
for (int i = 0; i < visitorsCount; i++)
|
||||
{
|
||||
int id = i + 1;
|
||||
var name = _visitorNames[i];
|
||||
var split = name.Split(' ');
|
||||
|
||||
if (!cs.Contains("localdb") && i == 1) //QuickStart - for production db simulate a data error
|
||||
{
|
||||
domain = "#mycompanydemos.com";
|
||||
}
|
||||
else
|
||||
{
|
||||
domain = "@mycompanydemos.com";
|
||||
}
|
||||
|
||||
context.Visitors.Add(new Visitor()
|
||||
{
|
||||
VisitorId = id,
|
||||
FirstName = split[0],
|
||||
LastName = split[1],
|
||||
Email = name.Replace(" ", ".") + domain,
|
||||
Position = GetPosition(i),
|
||||
Company = "Microsoft",
|
||||
CreatedDateTime = DateTime.UtcNow,
|
||||
LastModifiedDateTime = DateTime.UtcNow
|
||||
}
|
||||
);
|
||||
|
||||
string path = string.Format(_smallPicturePath, name);
|
||||
context.VisitorPictures.Add(new VisitorPicture()
|
||||
{
|
||||
VisitorPictureId = visitorPictureId,
|
||||
VisitorId = id,
|
||||
PictureType = PictureType.Small,
|
||||
Content = GetPicture(path)
|
||||
});
|
||||
visitorPictureId++;
|
||||
|
||||
path = string.Format(_picturePath, name);
|
||||
context.VisitorPictures.Add(new VisitorPicture()
|
||||
{
|
||||
VisitorPictureId = visitorPictureId,
|
||||
VisitorId = id,
|
||||
PictureType = PictureType.Big,
|
||||
Content = GetPicture(path)
|
||||
});
|
||||
visitorPictureId++;
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
private void CreateVisits(MyCompanyContext context)
|
||||
{
|
||||
var employeesIds = context.Employees.Select(e => e.EmployeeId).ToList();
|
||||
|
||||
int cesardlId = 101;
|
||||
int jayschId = 102;
|
||||
int orvilleId = 103;
|
||||
int egamma = 104 ;
|
||||
|
||||
List<int> _employeeNYCIds = new List<int>()
|
||||
{
|
||||
cesardlId, jayschId, orvilleId, egamma
|
||||
};
|
||||
|
||||
foreach (var visitor in context.Visitors)
|
||||
{
|
||||
int visits = _randomize.Next(5, 10);
|
||||
|
||||
DateTime visitDate = new DateTime(2017, 05, 17, 12, 0, 0).ToUniversalTime();
|
||||
DateTime launchDt = new DateTime(2017, 05, 10, 19, 0, 0).ToUniversalTime();
|
||||
DateTime createdDateTime = new DateTime(2016, 11, 13);
|
||||
for (int i = 0; i < visits; i++)
|
||||
{
|
||||
int index = _randomize.Next(0, 3);
|
||||
int employeeId = _employeeNYCIds.ElementAt(index);
|
||||
int days = _randomize.Next(-2, 15);
|
||||
int minutes = _randomize.Next(5, 480);
|
||||
|
||||
var visit = new Visit()
|
||||
{
|
||||
CreatedDateTime = DateTime.UtcNow,
|
||||
VisitDateTime = i == 0
|
||||
&& employeeId == cesardlId ? launchDt : visitDate.AddDays(days).AddMinutes(minutes),
|
||||
Comments = string.Empty,
|
||||
EmployeeId = employeeId,
|
||||
VisitorId = visitor.VisitorId,
|
||||
Status = VisitStatus.Pending
|
||||
};
|
||||
|
||||
if (i % 3 == 0)
|
||||
{
|
||||
visit.HasCar = true;
|
||||
visit.Plate = string.Format("B{0}E-6610", visitor.FirstName.Substring(0, 1));
|
||||
}
|
||||
|
||||
context.Visits.Add(visit);
|
||||
}
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
private void CreateEmployeePictures(MyCompanyContext context)
|
||||
{
|
||||
int employeePictureId = 1;
|
||||
|
||||
foreach (var employee in context.Employees)
|
||||
{
|
||||
string employeeName = string.Format("{0} {1}", employee.FirstName, employee.LastName);
|
||||
string path = string.Format(_smallPicturePath, employeeName);
|
||||
context.EmployeePictures.Add(new EmployeePicture()
|
||||
{
|
||||
EmployeePictureId = employeePictureId,
|
||||
EmployeeId = employee.EmployeeId,
|
||||
PictureType = PictureType.Small,
|
||||
Content = GetPicture(path)
|
||||
});
|
||||
employeePictureId++;
|
||||
|
||||
path = string.Format(_picturePath, employeeName);
|
||||
context.EmployeePictures.Add(new EmployeePicture()
|
||||
{
|
||||
EmployeePictureId = employeePictureId,
|
||||
EmployeeId = employee.EmployeeId,
|
||||
PictureType = PictureType.Big,
|
||||
Content = GetPicture(path)
|
||||
});
|
||||
employeePictureId++;
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
private static byte[] GetPicture(string fileName)
|
||||
{
|
||||
string path = new Uri(Assembly.GetAssembly(typeof(MyCompanyContextInitializer)).CodeBase).LocalPath;
|
||||
FileStream fs = new FileStream(Path.Combine(Path.GetDirectoryName(path),
|
||||
fileName), FileMode.Open, FileAccess.Read);
|
||||
|
||||
using (BinaryReader br = new BinaryReader(fs))
|
||||
{
|
||||
return br.ReadBytes((int)fs.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetPosition(int index)
|
||||
{
|
||||
return "Developer Division";
|
||||
}
|
||||
|
||||
private static string GetComments()
|
||||
{
|
||||
List<string> comments = new List<string>() {
|
||||
"Work meeting",
|
||||
"Sprint Planning Meeting",
|
||||
"Analyze the project status",
|
||||
"Personal meeting",
|
||||
"Monthly meeting with partners",
|
||||
"First meeting before starting the project",
|
||||
};
|
||||
|
||||
return comments[_randomize.Next(0, 5)];
|
||||
}
|
||||
|
||||
#region NYC
|
||||
|
||||
private List<string> _employeeEmailsNYC = new List<string>()
|
||||
{
|
||||
// Managers
|
||||
String.Format("cesardl@{0}", tenant),
|
||||
String.Format("Jaysch@{0}", tenant),
|
||||
String.Format("orvillem@{0}", tenant),
|
||||
String.Format("egamma@{0}", tenant),
|
||||
|
||||
// Equipo 1
|
||||
String.Format("bharry@{0}", tenant),
|
||||
String.Format("somase@{0}", tenant),
|
||||
String.Format("scottgu@{0}", tenant),
|
||||
String.Format("nichers@{0}", tenant),
|
||||
|
||||
|
||||
// Equipo 2
|
||||
String.Format("bethma@{0}", tenant),
|
||||
String.Format("epadrino@{0}", tenant),
|
||||
String.Format("seanla@{0}", tenant),
|
||||
String.Format("jnak@{0}", tenant),
|
||||
|
||||
// Equipo 3
|
||||
String.Format("cesardl@{0}", tenant),
|
||||
String.Format("davidcsa@{0}", tenant),
|
||||
String.Format("dmitryly@{0}", tenant),
|
||||
String.Format("briankel@{0}", tenant),
|
||||
|
||||
|
||||
// Equipo 4
|
||||
String.Format("habibh@{0}", tenant),
|
||||
String.Format("Brandon.Bray@{0}", tenant),
|
||||
String.Format("David.Salgado@{0}", tenant),
|
||||
String.Format("ed.blankenship@{0}", tenant),
|
||||
};
|
||||
|
||||
private List<string> _employeeNamesNYC = new List<string>()
|
||||
{
|
||||
"Cesar de_la_Torre",
|
||||
"Jay Schmelzer",
|
||||
"Orville McDonald",
|
||||
"Erich Gamma",
|
||||
"Brian Harry",
|
||||
"S. Somasegar",
|
||||
"Scott Guthrie",
|
||||
"Nicole Herskowitz",
|
||||
"Beth Massi",
|
||||
"Evelyn Padrino",
|
||||
"Sean Laberee",
|
||||
"Jim Nakashima",
|
||||
"Cesar de_la_Torre",
|
||||
"David Carmona",
|
||||
"Dmitry Lyalin",
|
||||
"Brian Keller",
|
||||
"Habib Heydarian",
|
||||
"Brandon Bray",
|
||||
"David Salgado",
|
||||
"Ed Blankenship",
|
||||
};
|
||||
|
||||
int startId = 100;
|
||||
|
||||
void CreateTeamManagersNYC(MyCompanyContext context)
|
||||
{
|
||||
int managersCount = 4;
|
||||
|
||||
for (int i = 0; i < managersCount; i++)
|
||||
{
|
||||
int id = startId + 1 + i;
|
||||
var name = _employeeNamesNYC[i];
|
||||
var split = name.Split(' ');
|
||||
context.Employees.Add(new Employee()
|
||||
{
|
||||
EmployeeId = id,
|
||||
FirstName = split[0],
|
||||
LastName = split[1],
|
||||
Email = _employeeEmailsNYC[i],
|
||||
JobTitle = "Team Lead",
|
||||
});
|
||||
|
||||
context.Teams.Add(new Team() { TeamId = id, ManagerId = id });
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
|
||||
}
|
||||
|
||||
void CreateEmployeesForNYCTeams(MyCompanyContext context)
|
||||
{
|
||||
int teamOneId = context.Teams.OrderBy(t => t.TeamId).Skip(1).First().TeamId; // Cesar de_la_Torre
|
||||
int teamTwoId = context.Teams.OrderBy(t => t.TeamId).Skip(2).First().TeamId; // Jay Schmelzer
|
||||
int teamThreeId = context.Teams.OrderBy(t => t.TeamId).Skip(3).First().TeamId; // Orville McDonald
|
||||
int teamFourId = context.Teams.OrderBy(t => t.TeamId).Skip(4).First().TeamId; // Erich Gamma
|
||||
|
||||
CreateEmployeesNYC(context, teamOneId, 5, 8);
|
||||
CreateEmployeesNYC(context, teamTwoId, 9, 12);
|
||||
CreateEmployeesNYC(context, teamThreeId, 13, 16);
|
||||
CreateEmployeesNYC(context, teamFourId, 17, 20);
|
||||
}
|
||||
|
||||
void CreateEmployeesNYC(MyCompanyContext context, int teamId, int startIndex, int endIndex)
|
||||
{
|
||||
int initialId = 300 * startIndex;
|
||||
for (int i = startIndex; i <= endIndex; i++)
|
||||
{
|
||||
int index = i - 1;
|
||||
var name = _employeeNamesNYC[index];
|
||||
|
||||
var split = name.Split(' ');
|
||||
context.Employees.Add(new Employee()
|
||||
{
|
||||
EmployeeId = initialId,
|
||||
FirstName = split[0],
|
||||
LastName = split[1],
|
||||
Email = _employeeEmailsNYC[index],
|
||||
JobTitle = GetPosition(i),
|
||||
TeamId = teamId,
|
||||
});
|
||||
|
||||
initialId++;
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
namespace MyCompany.Visitors.Data.Infrastructure.Interceptors
|
||||
{
|
||||
using System.Data.Entity.Infrastructure.Interception;
|
||||
|
||||
/// <summary>
|
||||
/// Connection breaker interceptor
|
||||
/// </summary>
|
||||
class ConnectionBreakInterceptor
|
||||
:IDbCommandInterceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Reader executing
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="interceptionContext"></param>
|
||||
public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
|
||||
{
|
||||
//add a error in the command ( 40501:The service is currently busy ) to
|
||||
//test if the execution strategy works correctly! If command logger is setted to console
|
||||
//you can view the retries produced for configured execution strategy
|
||||
command.CommandText = string.Format("{0};{1}", command.CommandText, "RAISERROR(40501,18,1)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Non query executed
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="interceptionContext"></param>
|
||||
public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Non query executing
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="interceptionContext"></param>
|
||||
public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reader executed
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="interceptionContext"></param>
|
||||
public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scalar executed
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="interceptionContext"></param>
|
||||
public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scalar executing
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="interceptionContext"></param>
|
||||
public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
namespace MyCompany.Visitors.Data.Infrastructure.Mapping
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data.Entity.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// The entity type configuration for <see cref="MyCompany.Visitors.Model.Employee"/>
|
||||
/// </summary>
|
||||
class EmployeeEntityTypeConfigurator
|
||||
: EntityTypeConfiguration<Employee>
|
||||
{
|
||||
|
||||
private EmployeeEntityTypeConfigurator()
|
||||
{
|
||||
this.HasKey(e => e.EmployeeId);
|
||||
|
||||
this.Property(e => e.EmployeeId)
|
||||
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
|
||||
|
||||
this.Property(e => e.FirstName)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(e => e.LastName)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(e => e.Email)
|
||||
.IsRequired();
|
||||
|
||||
this.HasOptional(t => t.Team)
|
||||
.WithMany(d => d.Employees)
|
||||
.HasForeignKey(t => t.TeamId)
|
||||
.WillCascadeOnDelete(false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
namespace MyCompany.Visitors.Data.Infrastructure.Mapping
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data.Entity.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// the entity type configuration for <see cref="MyCompany.Visitors.Model.EmployeePicture"/>
|
||||
/// </summary>
|
||||
class EmployeePictureEntityTypeConfiguration
|
||||
:EntityTypeConfiguration<EmployeePicture>
|
||||
{
|
||||
private EmployeePictureEntityTypeConfiguration()
|
||||
{
|
||||
this.HasKey(ep => ep.EmployeePictureId);
|
||||
|
||||
this.Property(ep => ep.EmployeePictureId)
|
||||
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
|
||||
|
||||
this.HasRequired(ep => ep.Employee)
|
||||
.WithMany(e => e.EmployeePictures)
|
||||
.HasForeignKey(e => e.EmployeeId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
namespace MyCompany.Visitors.Data.Infrastructure.Mapping
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data.Entity.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// The entity type configuration for <see cref="MyCompany.Visitors.Model.Team"/>
|
||||
/// </summary>
|
||||
class TeamEntityTypeConfigurator
|
||||
: EntityTypeConfiguration<Team>
|
||||
{
|
||||
private TeamEntityTypeConfigurator()
|
||||
{
|
||||
this.HasKey(t => t.TeamId);
|
||||
|
||||
this.Property(t => t.TeamId)
|
||||
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
|
||||
|
||||
this.HasRequired(t => t.Manager)
|
||||
.WithMany(d => d.ManagedTeams)
|
||||
.HasForeignKey(t => t.ManagerId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
namespace MyCompany.Visitors.Data.Infrastructure.Mapping
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.Data.Entity.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// Visit entity type configuration
|
||||
/// </summary>
|
||||
class VisitEntityTypeConfiguration
|
||||
:EntityTypeConfiguration<Visit>
|
||||
{
|
||||
private VisitEntityTypeConfiguration()
|
||||
{
|
||||
this.HasKey(v => v.VisitId);
|
||||
|
||||
this.Property(v => v.CreatedDateTime)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.VisitDateTime)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.HasCar)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.Status)
|
||||
.IsRequired();
|
||||
|
||||
this.HasRequired(v => v.Employee)
|
||||
.WithMany(e => e.Visits)
|
||||
.HasForeignKey(v => v.EmployeeId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
namespace MyCompany.Visitors.Data.Infrastructure.Mapping
|
||||
{
|
||||
using System.Data.Entity.ModelConfiguration;
|
||||
using MyCompany.Visitors.Model;
|
||||
|
||||
/// <summary>
|
||||
/// The entity type configuration
|
||||
/// </summary>
|
||||
class VisitorEntityTypeConfigurator
|
||||
: EntityTypeConfiguration<Visitor>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public VisitorEntityTypeConfigurator()
|
||||
{
|
||||
this.HasKey(v => v.VisitorId);
|
||||
|
||||
this.Ignore(v => v.LastVisit);
|
||||
|
||||
this.Property(v => v.FirstName)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.LastName)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.Company)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.Email)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.CreatedDateTime)
|
||||
.IsRequired();
|
||||
|
||||
this.Property(v => v.LastModifiedDateTime)
|
||||
.IsRequired();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
namespace MyCompany.Visitors.Data.Infrastructure
|
||||
{
|
||||
using MyCompany.Visitors.Data.Infrastructure.Initializers;
|
||||
using MyCompany.Visitors.Data.Infrastructure.Interceptors;
|
||||
using System.Data.Entity;
|
||||
using System.Data.Entity.SqlServer;
|
||||
|
||||
/// <summary>
|
||||
/// My Company Db configuration
|
||||
/// </summary>
|
||||
public class MyCompanyDbConfiguration
|
||||
: DbConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// My Company Db configuration constuctor
|
||||
/// </summary>
|
||||
public MyCompanyDbConfiguration()
|
||||
{
|
||||
//set the seed initializer
|
||||
SetDatabaseInitializer<MyCompanyContext>(new MyCompanyContextInitializer());
|
||||
|
||||
//Set Sql Azure Strategy ( check common erros in azure,cluster with connection lost and retry operations )
|
||||
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
|
||||
|
||||
//Un-comment next line to test execution strategy!
|
||||
//Interceptor(new ConnectionBreakInterceptor());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MyCompany.Visitors.Data</RootNamespace>
|
||||
<AssemblyName>MyCompany.Visitors.Data</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>bin\Debug\MyCompany.Visitors.Data.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>bin\Release\MyCompany.Visitors.Data.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugCD|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\DebugCD\</OutputPath>
|
||||
<DefineConstants>CODE_ANALYSIS;DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Debug\MyCompany.Visitors.Data.xml</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_LocalDeployment|AnyCPU'">
|
||||
<OutputPath>bin\Release_LocalDeployment\</OutputPath>
|
||||
<DefineConstants>CODE_ANALYSIS;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Release\MyCompany.Visitors.Data.xml</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MyCompany.Common.CrossCutting">
|
||||
<HintPath>..\Common\MyCompany.Common.CrossCutting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<Compile Include="Repositories\EmployeePictureRepository.cs" />
|
||||
<Compile Include="Repositories\EmployeeRepository.cs" />
|
||||
<Compile Include="Repositories\IEmployeePictureRepository.cs" />
|
||||
<Compile Include="Repositories\IEmployeeRepository.cs" />
|
||||
<Compile Include="Infrastructure\Conventions\CLRDateTimeToSqlDateTime2.cs" />
|
||||
<Compile Include="Infrastructure\Conventions\MaxStringLengthConvention.cs" />
|
||||
<Compile Include="Infrastructure\Interceptors\ConnectionBreakInterceptor.cs" />
|
||||
<Compile Include="Infrastructure\Mapping\EmployeePictureEntityTypeConfiguration.cs" />
|
||||
<Compile Include="Infrastructure\Mapping\VisitEntityTypeConfiguration.cs" />
|
||||
<Compile Include="Infrastructure\Initializers\MyCompanyContextInitializer.cs" />
|
||||
<Compile Include="Infrastructure\MyCompanyDbConfiguration.cs" />
|
||||
<Compile Include="Repositories\ITeamRepository.cs" />
|
||||
<Compile Include="Repositories\IVisitorPictureRepository.cs" />
|
||||
<Compile Include="Repositories\IVisitorRepository.cs" />
|
||||
<Compile Include="Repositories\IVisitRepository.cs" />
|
||||
<Compile Include="Infrastructure\Mapping\VisitorsEntityTypeConfigurator.cs" />
|
||||
<Compile Include="Infrastructure\Mapping\EmployeeEntityTypeConfigurator.cs" />
|
||||
<Compile Include="Infrastructure\Mapping\TeamEntityTypeConfigurator.cs" />
|
||||
<Compile Include="MyCompanyContext.cs" />
|
||||
<Compile Include="Properties\CommonAssemblyInfo.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Repositories\TeamRepository.cs" />
|
||||
<Compile Include="Repositories\VisitorPictureRepository.cs" />
|
||||
<Compile Include="Repositories\VisitorRepository.cs" />
|
||||
<Compile Include="Repositories\VisitRepository.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MyCompany.Visitors.Model\MyCompany.Visitors.Model.csproj">
|
||||
<Project>{05a33938-b402-4a82-8446-3a81cb0f5aa1}</Project>
|
||||
<Name>MyCompany.Visitors.Model</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDictionary Include="CustomCodeAnalysisDictionary.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,86 @@
|
|||
namespace MyCompany.Visitors.Data
|
||||
{
|
||||
using MyCompany.Common.CrossCutting;
|
||||
using MyCompany.Visitors.Data.Infrastructure;
|
||||
using MyCompany.Visitors.Data.Infrastructure.Conventions;
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.Data.Entity;
|
||||
|
||||
/// <summary>
|
||||
/// Context to access to MyCompany entities
|
||||
/// </summary>
|
||||
[DbConfigurationType(typeof(MyCompanyDbConfiguration))]
|
||||
public class MyCompanyContext : DbContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public MyCompanyContext()
|
||||
: base("MyCompany.Visitors")
|
||||
{
|
||||
//Database.Log = (s) =>
|
||||
//{
|
||||
// TraceManager.TraceInfo(new string[] { s });
|
||||
//};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when the model for a derived context has been initialized,
|
||||
/// but before the model has been locked down and used to initialize the context
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">The builder that defines the model for the context being created</param>
|
||||
protected override void OnModelCreating(DbModelBuilder modelBuilder)
|
||||
{
|
||||
//add custom conventions
|
||||
modelBuilder.Conventions.Add<CLRDateTimeToSqlDateTime2>();
|
||||
modelBuilder.Conventions.Add<MaxStringLengthConvention>();
|
||||
|
||||
modelBuilder.Entity<Question>()
|
||||
.Property(q => q.Answer).HasMaxLength(1024);
|
||||
|
||||
//Add all entity type configurations defined in "this" assembly. With this
|
||||
//method the boilerplate code to add configurations is removed.
|
||||
modelBuilder.Configurations.AddFromAssembly(typeof(MyCompanyContext).Assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Employee Collection
|
||||
/// </summary>
|
||||
public DbSet<Employee> Employees { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Team Collection
|
||||
/// </summary>
|
||||
public DbSet<Team> Teams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visit Collection
|
||||
/// </summary>
|
||||
public DbSet<Visit> Visits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visitor Collection
|
||||
/// </summary>
|
||||
public DbSet<Visitor> Visitors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Employee Picture Collection
|
||||
/// </summary>
|
||||
public DbSet<EmployeePicture> EmployeePictures { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visitor Picture Collection
|
||||
/// </summary>
|
||||
public DbSet<VisitorPicture> VisitorPictures { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IssuingAuthorityKeys
|
||||
/// </summary>
|
||||
public DbSet<IssuingAuthorityKey> IssuingAuthorityKeys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Question Collection
|
||||
/// </summary>
|
||||
public DbSet<Question> Questions { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MyCompany.Visitors.Data")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a4f1202e-44f2-45a9-a716-5798a237b611")]
|
|
@ -0,0 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
[assembly: AssemblyCompany("MyCompany Visitors")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("MyCompany")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyProduct("MyCompany")]
|
|
@ -0,0 +1,96 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// The employee picture repository implementation
|
||||
/// </summary>
|
||||
public class EmployeePictureRepository : IEmployeePictureRepository
|
||||
{
|
||||
private readonly MyCompanyContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance
|
||||
/// </summary>
|
||||
/// <param name="context">the context dependency</param>
|
||||
public EmployeePictureRepository(MyCompanyContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException("context");
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeePicture"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/></returns>
|
||||
public async Task<int> AddAsync(EmployeePicture employeePicture)
|
||||
{
|
||||
if (employeePicture == null)
|
||||
throw new ArgumentNullException("employeePicture");
|
||||
|
||||
_context.EmployeePictures.Add(employeePicture);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return employeePicture.EmployeePictureId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeePicture"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/></param>
|
||||
public async Task UpdateAsync(EmployeePicture employeePicture)
|
||||
{
|
||||
if (employeePicture == null) throw new ArgumentNullException("employeePicture");
|
||||
|
||||
_context.Entry<EmployeePicture>(employeePicture)
|
||||
.State = System.Data.Entity.EntityState.Modified;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeePictureId"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeePictureRepository"/></param>
|
||||
public async Task DeleteAsync(int employeePictureId)
|
||||
{
|
||||
var picture = _context.EmployeePictures
|
||||
.Find(employeePictureId);
|
||||
|
||||
if (picture != null)
|
||||
{
|
||||
_context.EmployeePictures
|
||||
.Remove(picture);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resource
|
||||
/// </summary>
|
||||
/// <param name="disposing">Dispose managed resources check</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// The employee repository implementation
|
||||
/// </summary>
|
||||
public class EmployeeRepository : IEmployeeRepository
|
||||
{
|
||||
private readonly MyCompanyContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance
|
||||
/// </summary>
|
||||
/// <param name="context">the context dependency</param>
|
||||
public EmployeeRepository(MyCompanyContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException("context");
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeeId"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></returns>
|
||||
public async Task<Employee> GetAsync(int employeeId)
|
||||
{
|
||||
return await _context.Employees.FindAsync(employeeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="email"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></returns>
|
||||
public async Task<Employee> GetByEmailAsync(string email, PictureType pictureType)
|
||||
{
|
||||
var result = await _context.Employees
|
||||
.Include(e => e.ManagedTeams)
|
||||
.Where(e => e.Email == email)
|
||||
.Select(e => new
|
||||
{
|
||||
Employee = e,
|
||||
Pictures = e.EmployeePictures.Where(ep => ep.PictureType == pictureType)
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result.Employee;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></returns>
|
||||
public async Task<IEnumerable<Employee>> GetAllAsync()
|
||||
{
|
||||
return await _context.Employees.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <param name="pageSize"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <param name="pageCount"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></returns>
|
||||
public async Task<IEnumerable<Employee>> GetEmployeesAsync(string filter, PictureType pictureType, int pageSize, int pageCount)
|
||||
{
|
||||
//get filtered and paged employees
|
||||
var filteredEmployees = await _context.Employees
|
||||
.Where(q =>
|
||||
String.IsNullOrEmpty(filter) ||
|
||||
q.FirstName.Contains(filter) ||
|
||||
q.LastName.Contains(filter) ||
|
||||
(q.FirstName + " " + q.LastName).Contains(filter))
|
||||
.OrderBy(q => q.FirstName)
|
||||
.Skip(pageSize * pageCount)
|
||||
.Take(pageSize)
|
||||
.Select(e => new
|
||||
{
|
||||
Employee = e,
|
||||
Pictures = e.EmployeePictures.Where(ep => ep.PictureType == pictureType)
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return filteredEmployees
|
||||
.Select(e => e.Employee);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeeId"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Employee> GetCompleteInfoAsync(int employeeId, PictureType pictureType)
|
||||
{
|
||||
var result = await _context.Employees
|
||||
.Where(e => e.EmployeeId == employeeId)
|
||||
.Select(e => new
|
||||
{
|
||||
Employee = e,
|
||||
Pictures = e.EmployeePictures.Where(ep => ep.PictureType == pictureType)
|
||||
}).SingleOrDefaultAsync();
|
||||
|
||||
return result.Employee;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employee"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></returns>
|
||||
public async Task<int> AddAsync(Employee employee)
|
||||
{
|
||||
if (employee == null)
|
||||
throw new ArgumentNullException("employee");
|
||||
|
||||
_context.Employees.Add(employee);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return employee.EmployeeId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employee"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
public async Task UpdateAsync(Employee employee)
|
||||
{
|
||||
if (employee == null)
|
||||
throw new ArgumentNullException("employee");
|
||||
|
||||
_context.Entry<Employee>(employee)
|
||||
.State = EntityState.Modified;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeeId"><see cref="MyCompany.Visitors.Data.Repositories.IEmployeeRepository"/></param>
|
||||
public async Task DeleteAsync(int employeeId)
|
||||
{
|
||||
var employee = _context.Employees
|
||||
.Find(employeeId);
|
||||
|
||||
if (employee != null)
|
||||
{
|
||||
_context.Employees
|
||||
.Remove(employee);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resource
|
||||
/// </summary>
|
||||
/// <param name="disposing">Dispose managed resources check</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Base contract for employee picture repository
|
||||
/// </summary>
|
||||
public interface IEmployeePictureRepository
|
||||
: IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Add new employee picture
|
||||
/// </summary>
|
||||
/// <param name="employeePicture">employee picture information</param>
|
||||
/// <returns>employeePictureId</returns>
|
||||
Task<int> AddAsync(EmployeePicture employeePicture);
|
||||
|
||||
/// <summary>
|
||||
/// Update employee picture
|
||||
/// </summary>
|
||||
/// <param name="employeePicture">employee picture information</param>
|
||||
Task UpdateAsync(EmployeePicture employeePicture);
|
||||
|
||||
/// <summary>
|
||||
/// Delete employee picture
|
||||
/// </summary>
|
||||
/// <param name="employeePictureId">employee picture to delete</param>
|
||||
Task DeleteAsync(int employeePictureId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Base contract for employee repository
|
||||
/// </summary>
|
||||
public interface IEmployeeRepository
|
||||
: IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Get employee by Id
|
||||
/// </summary>
|
||||
/// <param name="employeeId"></param>
|
||||
/// <returns></returns>
|
||||
Task<Employee> GetAsync(int employeeId);
|
||||
|
||||
/// <summary>
|
||||
/// Get employee by email
|
||||
/// </summary>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="pictureType"></param>
|
||||
/// <returns></returns>
|
||||
Task<Employee> GetByEmailAsync(string email, PictureType pictureType);
|
||||
|
||||
/// <summary>
|
||||
/// Get All employees
|
||||
/// </summary>
|
||||
/// <returns>List of employees</returns>
|
||||
Task<IEnumerable<Employee>> GetAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Get Employees
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
/// <param name="pictureType"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="pageCount"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<Employee>> GetEmployeesAsync(string filter, PictureType pictureType, int pageSize, int pageCount);
|
||||
|
||||
/// <summary>
|
||||
/// Get Employee by Id and Picture Type
|
||||
/// </summary>
|
||||
/// <param name="employeeId">Employee Id</param>
|
||||
/// <param name="pictureType">Picture Type</param>
|
||||
/// <returns></returns>
|
||||
Task<Employee> GetCompleteInfoAsync(int employeeId, PictureType pictureType);
|
||||
|
||||
/// <summary>
|
||||
/// Add new employee
|
||||
/// </summary>
|
||||
/// <param name="employee">employee information</param>
|
||||
/// <returns>commentId</returns>
|
||||
Task<int> AddAsync(Employee employee);
|
||||
|
||||
/// <summary>
|
||||
/// Update employee
|
||||
/// </summary>
|
||||
/// <param name="expense">employee information</param>
|
||||
Task UpdateAsync(Employee expense);
|
||||
|
||||
/// <summary>
|
||||
/// Delete employee
|
||||
/// </summary>
|
||||
/// <param name="employeeId">employee to delete</param>
|
||||
Task DeleteAsync(int employeeId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Base contract for team repository
|
||||
/// </summary>
|
||||
public interface ITeamRepository
|
||||
: IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Get team by Id
|
||||
/// </summary>
|
||||
/// <param name="teamId"></param>
|
||||
/// <returns></returns>
|
||||
Task<Team> GetAsync(int teamId);
|
||||
|
||||
/// <summary>
|
||||
/// Get All teams
|
||||
/// </summary>
|
||||
/// <returns>List of teams</returns>
|
||||
Task<IEnumerable<Team>> GetAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Add new team
|
||||
/// </summary>
|
||||
/// <param name="team">team information</param>
|
||||
/// <returns>teamId</returns>
|
||||
Task<int> AddAsync(Team team);
|
||||
|
||||
/// <summary>
|
||||
/// Update team
|
||||
/// </summary>
|
||||
/// <param name="team">team information</param>
|
||||
Task UpdateAsync(Team team);
|
||||
|
||||
/// <summary>
|
||||
/// Delete team
|
||||
/// </summary>
|
||||
/// <param name="teamId">team to delete</param>
|
||||
Task DeleteAsync(int teamId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Base contract for visits repository
|
||||
/// </summary>
|
||||
public interface IVisitRepository
|
||||
: IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Get visit by Id
|
||||
/// </summary>
|
||||
/// <param name="visitId"></param>
|
||||
/// <returns></returns>
|
||||
Task<Visit> GetAsync(int visitId);
|
||||
|
||||
/// <summary>
|
||||
/// Get All visits
|
||||
/// </summary>
|
||||
/// <returns>List of visits</returns>
|
||||
Task<IEnumerable<Visit>> GetAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Get expense by Id
|
||||
/// </summary>
|
||||
/// <param name="visitId"></param>
|
||||
/// <param name="pictureType">PictureType</param>
|
||||
/// <returns></returns>
|
||||
Task<Visit> GetCompleteInfoAsync(int visitId, PictureType pictureType);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visits.
|
||||
/// If dateFilter is populated, only gets the visits from this day
|
||||
/// </summary>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <param name="pictureType">PictureType</param>
|
||||
/// <param name="pageSize">Size of page</param>
|
||||
/// <param name="pageCount">Size Count</param>
|
||||
/// <param name="dateFilter">Date filter</param>
|
||||
/// <param name="toDate">To date filter</param>
|
||||
/// <returns>List of visits</returns>
|
||||
Task<IEnumerable<Visit>> GetVisitsAsync(string filter, PictureType pictureType, int pageSize, int pageCount, DateTime? dateFilter, DateTime? toDate);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visits from Date
|
||||
/// </summary>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <param name="pictureType">PictureType</param>
|
||||
/// <param name="pageSize">Size of page</param>
|
||||
/// <param name="pageCount">Size Count</param>
|
||||
/// <param name="dateFilter">Date filter</param>
|
||||
/// <returns>List of visits</returns>
|
||||
Task<IEnumerable<Visit>> GetVisitsFromDateAsync(string filter, PictureType pictureType, int pageSize, int pageCount, DateTime dateFilter);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visits
|
||||
/// </summary>
|
||||
/// <param name="employeeEmail">employee Identity</param>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <param name="pictureType">PictureType</param>
|
||||
/// <param name="pageSize">Size of page</param>
|
||||
/// <param name="pageCount">Size Count</param>
|
||||
/// <returns>List of visits</returns>
|
||||
Task<IEnumerable<Visit>> GetUserVisitsAsync(string employeeEmail, string filter, PictureType pictureType, int pageSize, int pageCount);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visit Count
|
||||
/// </summary>
|
||||
/// <param name="dateFilter">Date Filter</param>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <param name="toDate">to date filter</param>
|
||||
/// <returns>Number of visits</returns>
|
||||
Task<int> GetCountAsync(string filter, DateTime? dateFilter, DateTime? toDate);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visit Count from Date
|
||||
/// </summary>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <param name="dateFilter">Date Filter</param>
|
||||
/// <returns>Number of visits from a Date</returns>
|
||||
Task<int> GetCountFromDateAsync(string filter, DateTime dateFilter);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visit Count
|
||||
/// </summary>
|
||||
/// <param name="employeeIdentity">employee Identity</param>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <returns>Number of visits</returns>
|
||||
Task<int> GetUserCountAsync(string employeeIdentity, string filter);
|
||||
|
||||
/// <summary>
|
||||
/// Add new visit
|
||||
/// </summary>
|
||||
/// <param name="visit">visit information</param>
|
||||
/// <returns>visitId</returns>
|
||||
Task<int> AddAsync(Visit visit);
|
||||
|
||||
/// <summary>
|
||||
/// Update visit
|
||||
/// </summary>
|
||||
/// <param name="visit">visit information</param>
|
||||
Task UpdateAsync(Visit visit);
|
||||
|
||||
/// <summary>
|
||||
/// Delete visit
|
||||
/// </summary>
|
||||
/// <param name="visitId">visit to delete</param>
|
||||
Task DeleteAsync(int visitId);
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Base contract for visitorPicture repository
|
||||
/// </summary>
|
||||
public interface IVisitorPictureRepository
|
||||
:IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the specified visitor id.
|
||||
/// </summary>
|
||||
/// <param name="visitorId">The visitor id.</param>
|
||||
/// <param name="pictureType">Type of the picture.</param>
|
||||
/// <returns></returns>
|
||||
Task<VisitorPicture> GetAsync(int visitorId, PictureType pictureType);
|
||||
|
||||
/// <summary>
|
||||
/// Add new visitorPicture
|
||||
/// </summary>
|
||||
/// <param name="visitorPicture">visitorPicture information</param>
|
||||
/// <returns>visitorPictureId</returns>
|
||||
Task<int> AddAsync(VisitorPicture visitorPicture);
|
||||
|
||||
/// <summary>
|
||||
/// Update visitorPicture
|
||||
/// </summary>
|
||||
/// <param name="visitorPicture">visitorPicture information</param>
|
||||
Task UpdateAsync(VisitorPicture visitorPicture);
|
||||
|
||||
/// <summary>
|
||||
/// Adds or update the visitorPicture.
|
||||
/// </summary>
|
||||
/// <param name="visitorId">The visitor id.</param>
|
||||
/// <param name="pictureType">Type of the picture.</param>
|
||||
/// <param name="content">The content.</param>
|
||||
Task AddOrUpdateAsync(int visitorId, PictureType pictureType, byte[] content);
|
||||
|
||||
/// <summary>
|
||||
/// Delete visitorPicture
|
||||
/// </summary>
|
||||
/// <param name="visitorPictureId">visitorPicture to delete</param>
|
||||
Task DeleteAsync(int visitorPictureId);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Base contract for visitor repository
|
||||
/// </summary>
|
||||
public interface IVisitorRepository
|
||||
: IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Get visitor by Id
|
||||
/// </summary>
|
||||
/// <param name="visitorId"></param>
|
||||
/// <returns></returns>
|
||||
Task<Visitor> GetAsync(int visitorId);
|
||||
|
||||
/// <summary>
|
||||
/// Get All visitors
|
||||
/// </summary>
|
||||
/// <returns>List of visitors</returns>
|
||||
Task<IEnumerable<Visitor>> GetAllAsync();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get visitor by Id
|
||||
/// </summary>
|
||||
/// <param name="visitorId"></param>
|
||||
/// <param name="pictureType">PictureType</param>
|
||||
/// <returns>Visitor</returns>
|
||||
Task<Visitor> GetCompleteInfoAsync(int visitorId, PictureType pictureType);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visitors
|
||||
/// </summary>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <param name="pictureType">PictureType</param>
|
||||
/// <param name="pageSize">Size of page</param>
|
||||
/// <param name="pageCount">Size Count</param>
|
||||
/// <returns>List of visitors</returns>
|
||||
Task<IEnumerable<Visitor>> GetVisitorsAsync(string filter, PictureType pictureType, int pageSize, int pageCount);
|
||||
|
||||
/// <summary>
|
||||
/// Get Visitor Count
|
||||
/// </summary>
|
||||
/// <param name="filter">Filter</param>
|
||||
/// <returns>Number of visitors</returns>
|
||||
Task<int> GetCountAsync(string filter);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new visitor
|
||||
/// </summary>
|
||||
/// <param name="visitor">visitor information</param>
|
||||
/// <returns>visitorId</returns>
|
||||
Task<int> AddAsync(Visitor visitor);
|
||||
|
||||
/// <summary>
|
||||
/// Update visitor
|
||||
/// </summary>
|
||||
/// <param name="visitor">visitor information</param>
|
||||
Task UpdateAsync(Visitor visitor);
|
||||
|
||||
/// <summary>
|
||||
/// Delete visitor
|
||||
/// </summary>
|
||||
/// <param name="visitorId">visitor to delete</param>
|
||||
Task DeleteAsync(int visitorId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// The team repository implementation
|
||||
/// </summary>
|
||||
public class TeamRepository : ITeamRepository
|
||||
{
|
||||
private readonly MyCompanyContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance
|
||||
/// </summary>
|
||||
/// <param name="context">the context dependency</param>
|
||||
public TeamRepository(MyCompanyContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException("context");
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="teamId"><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></returns>
|
||||
public async Task<Team> GetAsync(int teamId)
|
||||
{
|
||||
return await _context.Teams.FindAsync(teamId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/>
|
||||
/// </summary>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></returns>
|
||||
public async Task<IEnumerable<Team>> GetAllAsync()
|
||||
{
|
||||
return await _context.Teams
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="team"><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></returns>
|
||||
public async Task<int> AddAsync(Team team)
|
||||
{
|
||||
if (team == null)
|
||||
throw new ArgumentNullException("team");
|
||||
|
||||
_context.Teams
|
||||
.Add(team);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return team.TeamId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="team"><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></param>
|
||||
public async Task UpdateAsync(Team team)
|
||||
{
|
||||
if (team == null)
|
||||
throw new ArgumentNullException("team");
|
||||
|
||||
_context.Entry<Team>(team)
|
||||
.State = EntityState.Modified;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="teamId"><see cref="MyCompany.Visitors.Data.Repositories.ITeamRepository"/></param>
|
||||
public async Task DeleteAsync(int teamId)
|
||||
{
|
||||
var team = await _context.Teams.FindAsync(teamId);
|
||||
|
||||
if (team != null)
|
||||
{
|
||||
_context.Teams
|
||||
.Remove(team);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resource
|
||||
/// </summary>
|
||||
/// <param name="disposing">Dispose managed resources check</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,373 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MyCompany.Visitors.Model;
|
||||
using System.Data.Entity;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// The visit repository implementation
|
||||
/// </summary>
|
||||
public class VisitRepository
|
||||
: IVisitRepository
|
||||
{
|
||||
private readonly MyCompanyContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance
|
||||
/// </summary>
|
||||
/// <param name="context">the context dependency</param>
|
||||
public VisitRepository(MyCompanyContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException("context");
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<Visit> GetAsync(int visitId)
|
||||
{
|
||||
return await _context.Visits
|
||||
.FindAsync(visitId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<IEnumerable<Visit>> GetAllAsync()
|
||||
{
|
||||
return await _context.Visits
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<Visit> GetCompleteInfoAsync(int visitId, PictureType pictureType)
|
||||
{
|
||||
var result = await _context.Visits
|
||||
.Where(q => q.VisitId == visitId)
|
||||
.Select(v => new
|
||||
{
|
||||
Visit = v,
|
||||
Visitor = v.Visitor,
|
||||
VisitorImages = v.Visitor.VisitorPictures.Where(vp => vp.PictureType == pictureType || pictureType == PictureType.All),
|
||||
Employee = v.Employee,
|
||||
EmployeePictures = v.Employee.EmployeePictures.Where(ep => ep.PictureType == pictureType || pictureType == PictureType.All)
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return result.Select(v => BuildVisit(v.Visit))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pageSize"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pageCount"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="dateFilter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="toDate"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<IEnumerable<Visit>> GetVisitsAsync(string filter, PictureType pictureType, int pageSize, int pageCount, DateTime? dateFilter, DateTime? toDate)
|
||||
{
|
||||
DateTime? maxDate = null;
|
||||
|
||||
if (dateFilter != null)
|
||||
{
|
||||
maxDate = toDate ?? dateFilter.Value.Date.AddDays(1);
|
||||
dateFilter = DateTime.SpecifyKind(dateFilter.Value, DateTimeKind.Utc);
|
||||
maxDate = DateTime.SpecifyKind(maxDate.Value, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
var results = await _context.Visits
|
||||
.Where(q => String.IsNullOrEmpty(filter) || q.Comments.Contains(filter) || (q.Visitor.FirstName + " " + q.Visitor.LastName).Contains(filter) || (q.Visitor.Email.Contains(filter)))
|
||||
.Where(q => dateFilter == null || q.VisitDateTime >= dateFilter && q.VisitDateTime < maxDate)
|
||||
.Select(v => new
|
||||
{
|
||||
Visit = v,
|
||||
Visitor = v.Visitor,
|
||||
VisitorImages = v.Visitor.VisitorPictures.Where(vp => vp.PictureType == pictureType || pictureType == PictureType.All),
|
||||
Employee = v.Employee,
|
||||
EmployeePictures = v.Employee.EmployeePictures.Where(ep => ep.PictureType == pictureType || pictureType == PictureType.All)
|
||||
|
||||
})
|
||||
.OrderBy(v => v.Visit.VisitDateTime)
|
||||
.Skip(pageSize * pageCount)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
var x = results.Select(v => BuildVisit(v.Visit)).ToList();
|
||||
return x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pageSize"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pageCount"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="dateFilter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<Visit>> GetVisitsFromDateAsync(string filter, PictureType pictureType, int pageSize, int pageCount, DateTime dateFilter)
|
||||
{
|
||||
dateFilter = DateTime.SpecifyKind(dateFilter, DateTimeKind.Utc);
|
||||
|
||||
var results = await _context.Visits
|
||||
.Where(q => String.IsNullOrEmpty(filter) || q.Comments.Contains(filter) || (q.Visitor.FirstName + " " + q.Visitor.LastName).Contains(filter) || (q.Visitor.Email.Contains(filter)))
|
||||
.Where(q => q.VisitDateTime >= dateFilter)
|
||||
.Select(v => new
|
||||
{
|
||||
Visit = v,
|
||||
Visitor = v.Visitor,
|
||||
VisitorImages = v.Visitor.VisitorPictures.Where(vp => vp.PictureType == pictureType),
|
||||
Employee = v.Employee,
|
||||
EmployeePictures = v.Employee.EmployeePictures.Where(ep => ep.PictureType == pictureType)
|
||||
|
||||
})
|
||||
.OrderBy(v => v.Visit.VisitDateTime)
|
||||
.Skip(pageSize * pageCount)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return results.Select(v => BuildVisit(v.Visit));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeeEmail"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pageSize"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="pageCount"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<IEnumerable<Visit>> GetUserVisitsAsync(string employeeEmail, string filter, PictureType pictureType, int pageSize, int pageCount)
|
||||
{
|
||||
var dateFilter = DateTime.UtcNow.AddHours(-1);
|
||||
|
||||
var result = await _context.Visits
|
||||
.Where(q => q.Employee.Email == employeeEmail
|
||||
&&
|
||||
(String.IsNullOrEmpty(filter) || q.Comments.Contains(filter) || (q.Visitor.FirstName + " " + q.Visitor.LastName).Contains(filter))
|
||||
&&
|
||||
q.VisitDateTime >= dateFilter
|
||||
)
|
||||
.OrderBy(q => q.VisitDateTime)
|
||||
.Select(v => new
|
||||
{
|
||||
Visit = v,
|
||||
Visitor = v.Visitor,
|
||||
VisitorImages = v.Visitor.VisitorPictures.Where(vp => vp.PictureType == pictureType),
|
||||
Employee = v.Employee,
|
||||
EmployeePictures = v.Employee.EmployeePictures.Where(ep => ep.PictureType == pictureType)
|
||||
|
||||
})
|
||||
.Skip(pageSize * pageCount)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
return result.Select(v => BuildVisit(v.Visit));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="dateFilter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="toDate"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<int> GetCountAsync(string filter, DateTime? dateFilter, DateTime? toDate)
|
||||
{
|
||||
DateTime? maxDate = null;
|
||||
if (dateFilter != null)
|
||||
{
|
||||
maxDate = toDate ?? dateFilter.Value.Date.AddDays(1);
|
||||
dateFilter = DateTime.SpecifyKind(dateFilter.Value, DateTimeKind.Utc);
|
||||
maxDate = DateTime.SpecifyKind(maxDate.Value, DateTimeKind.Utc);
|
||||
|
||||
}
|
||||
|
||||
return await _context.Visits
|
||||
.Where(q => String.IsNullOrEmpty(filter) || q.Comments.Contains(filter) || (q.Visitor.FirstName + " " + q.Visitor.LastName).Contains(filter))
|
||||
.Where(q => dateFilter == null || q.VisitDateTime >= dateFilter && q.VisitDateTime < maxDate)
|
||||
.OrderBy(q => q.VisitDateTime)
|
||||
.CountAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="dateFilter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<int> GetCountFromDateAsync(string filter, DateTime dateFilter)
|
||||
{
|
||||
dateFilter = DateTime.SpecifyKind(dateFilter, DateTimeKind.Utc);
|
||||
|
||||
return await _context.Visits
|
||||
.Where(q => String.IsNullOrEmpty(filter) || q.Comments.Contains(filter) || (q.Visitor.FirstName + " " + q.Visitor.LastName).Contains(filter))
|
||||
.Where(q => q.VisitDateTime >= dateFilter)
|
||||
.CountAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="employeeIdentity"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<int> GetUserCountAsync(string employeeIdentity, string filter)
|
||||
{
|
||||
var dateFilter = DateTime.UtcNow.AddHours(-1);
|
||||
|
||||
return await _context.Visits
|
||||
.Where(q =>
|
||||
q.Employee.Email == employeeIdentity
|
||||
&&
|
||||
(String.IsNullOrEmpty(filter) || q.Comments.Contains(filter) || (q.Visitor.FirstName + " " + q.Visitor.LastName).Contains(filter)))
|
||||
.Where(q => q.VisitDateTime >= dateFilter)
|
||||
.OrderBy(q => q.VisitDateTime)
|
||||
.CountAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visit"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></returns>
|
||||
public async Task<int> AddAsync(Visit visit)
|
||||
{
|
||||
visit.CreatedDateTime = DateTime.UtcNow;
|
||||
visit.Status = VisitStatus.Pending;
|
||||
|
||||
_context.Visits.Add(visit);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return visit.VisitId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visit"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
public async Task UpdateAsync(Visit visit)
|
||||
{
|
||||
var visittoUpdate = await _context.Visits.FirstOrDefaultAsync(q => q.VisitId == visit.VisitId);
|
||||
|
||||
_context.Entry<Visit>(visittoUpdate)
|
||||
.CurrentValues
|
||||
.SetValues(visit);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitRepository"/></param>
|
||||
public async Task DeleteAsync(int visitId)
|
||||
{
|
||||
var visit = await _context.Visits.FirstOrDefaultAsync(q => q.VisitId == visitId);
|
||||
if (visit != null)
|
||||
{
|
||||
_context.Visits.Remove(visit);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Visit BuildVisit(Visit visit)
|
||||
{
|
||||
var created = new Visit()
|
||||
{
|
||||
VisitId = visit.VisitId,
|
||||
CreatedDateTime = visit.CreatedDateTime,
|
||||
VisitDateTime = visit.VisitDateTime,
|
||||
Comments = visit.Comments,
|
||||
EmployeeId = visit.EmployeeId,
|
||||
HasCar = visit.HasCar,
|
||||
Plate = visit.Plate,
|
||||
Status = visit.Status,
|
||||
VisitorId = visit.VisitorId,
|
||||
Visitor = new Visitor()
|
||||
{
|
||||
VisitorId = visit.Visitor.VisitorId,
|
||||
FirstName = visit.Visitor.FirstName,
|
||||
LastName = visit.Visitor.LastName,
|
||||
Company = visit.Visitor.Company,
|
||||
Email = visit.Visitor.Email,
|
||||
CreatedDateTime = visit.CreatedDateTime,
|
||||
LastModifiedDateTime = visit.Visitor.LastModifiedDateTime,
|
||||
VisitorPictures = (visit.Visitor.VisitorPictures != null) ?
|
||||
visit.Visitor.VisitorPictures
|
||||
.Select(vp => new VisitorPicture()
|
||||
{
|
||||
PictureType = vp.PictureType,
|
||||
VisitorPictureId = vp.VisitorPictureId,
|
||||
VisitorId = vp.VisitorId,
|
||||
Content = vp.Content
|
||||
}).ToList() : null
|
||||
},
|
||||
Employee = new Employee()
|
||||
{
|
||||
EmployeeId = visit.Employee.EmployeeId,
|
||||
FirstName = visit.Employee.FirstName,
|
||||
LastName = visit.Employee.LastName,
|
||||
JobTitle = visit.Employee.JobTitle,
|
||||
Email = visit.Employee.Email,
|
||||
TeamId = visit.Employee.TeamId,
|
||||
EmployeePictures = (visit.Employee.EmployeePictures != null) ?
|
||||
visit.Employee.EmployeePictures
|
||||
.Select(ep => new EmployeePicture()
|
||||
{
|
||||
Employee = null,
|
||||
PictureType = ep.PictureType,
|
||||
EmployeePictureId = ep.EmployeePictureId,
|
||||
EmployeeId = ep.EmployeeId,
|
||||
Content = ep.Content
|
||||
}).ToList() : null
|
||||
}
|
||||
};
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resource
|
||||
/// </summary>
|
||||
/// <param name="disposing">Dispose managed resources check</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// The visitorPicture repository implementation
|
||||
/// </summary>
|
||||
public class VisitorPictureRepository : IVisitorPictureRepository
|
||||
{
|
||||
private readonly MyCompanyContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance
|
||||
/// </summary>
|
||||
/// <param name="context">the context dependency</param>
|
||||
public VisitorPictureRepository(MyCompanyContext context)
|
||||
{
|
||||
if (context == null) throw new ArgumentNullException("context");
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></returns>
|
||||
public Task<VisitorPicture> GetAsync(int visitorId, PictureType pictureType)
|
||||
{
|
||||
return _context.VisitorPictures
|
||||
.FirstOrDefaultAsync(q => q.VisitorId == visitorId && q.PictureType == pictureType);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorPicture"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></returns>
|
||||
public async Task<int> AddAsync(VisitorPicture visitorPicture)
|
||||
{
|
||||
if (visitorPicture == null) throw new ArgumentNullException("visitorPicture");
|
||||
|
||||
_context.VisitorPictures
|
||||
.Add(visitorPicture);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return visitorPicture.VisitorPictureId;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorPicture"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></param>
|
||||
public async Task UpdateAsync(VisitorPicture visitorPicture)
|
||||
{
|
||||
if (visitorPicture == null) throw new ArgumentNullException("visitorPicture");
|
||||
|
||||
_context.Entry<VisitorPicture>(visitorPicture)
|
||||
.State = EntityState.Modified;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository" />
|
||||
/// </summary>
|
||||
/// <param name="visitorId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository" /></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository" /></param>
|
||||
/// <param name="content"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository" /></param>
|
||||
public async Task AddOrUpdateAsync(int visitorId, PictureType pictureType, byte[] content)
|
||||
{
|
||||
var visitorPicturetoUpdate = await _context.VisitorPictures
|
||||
.FirstOrDefaultAsync(q => q.VisitorId == visitorId && q.PictureType == pictureType);
|
||||
|
||||
if (visitorPicturetoUpdate != null)
|
||||
{
|
||||
visitorPicturetoUpdate.Content = content;
|
||||
}
|
||||
else
|
||||
{
|
||||
_context.VisitorPictures.Add(new VisitorPicture()
|
||||
{
|
||||
VisitorId = visitorId,
|
||||
PictureType = pictureType,
|
||||
Content = content
|
||||
});
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorPictureId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorPictureRepository"/></param>
|
||||
public async Task DeleteAsync(int visitorPictureId)
|
||||
{
|
||||
var visitorPicture = await _context.VisitorPictures
|
||||
.FindAsync(visitorPictureId);
|
||||
|
||||
if (visitorPicture != null)
|
||||
{
|
||||
_context.VisitorPictures
|
||||
.Remove(visitorPicture);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resource
|
||||
/// </summary>
|
||||
/// <param name="disposing">Dispose managed resources check</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
namespace MyCompany.Visitors.Data.Repositories
|
||||
{
|
||||
using MyCompany.Visitors.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// The visitor repository implementation
|
||||
/// </summary>
|
||||
public class VisitorRepository : IVisitorRepository
|
||||
{
|
||||
private readonly MyCompanyContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance
|
||||
/// </summary>
|
||||
/// <param name="context">the context dependency</param>
|
||||
public VisitorRepository(MyCompanyContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException("context");
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></returns>
|
||||
public async Task<Visitor> GetAsync(int visitorId)
|
||||
{
|
||||
return await _context.Visitors
|
||||
.FindAsync(visitorId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></returns>
|
||||
public async Task<IEnumerable<Visitor>> GetAllAsync()
|
||||
{
|
||||
return await _context.Visitors
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></returns>
|
||||
public async Task<Visitor> GetCompleteInfoAsync(int visitorId, PictureType pictureType)
|
||||
{
|
||||
var result = await _context.Visitors
|
||||
.Where(q => q.VisitorId == visitorId)
|
||||
.Select(v => new
|
||||
{
|
||||
Visitor = v,
|
||||
VisitorPictures = v.VisitorPictures.Where(vp => vp.PictureType == pictureType),
|
||||
Visits = v.Visits,
|
||||
VisitsEmployee = v.Visits.Select(ve => ve.Employee),
|
||||
VisitsEmployeePictures = v.Visits.Select(ve => ve.Employee).SelectMany(vee => vee.EmployeePictures.Where(vpe => vpe.PictureType == pictureType))
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return result.Select(v => BuildVisitor(v.Visitor)).FirstOrDefault();;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <param name="pictureType"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <param name="pageSize"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <param name="pageCount"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></returns>
|
||||
public async Task<IEnumerable<Visitor>> GetVisitorsAsync(string filter, PictureType pictureType, int pageSize, int pageCount)
|
||||
{
|
||||
var results = await _context.Visitors
|
||||
.Where(q =>
|
||||
String.IsNullOrEmpty(filter) ||
|
||||
(q.FirstName + " " + q.LastName).Contains(filter) ||
|
||||
q.Company.Contains(filter) ||
|
||||
q.Email.Contains(filter))
|
||||
.Select(v => new
|
||||
{
|
||||
Visitor = v,
|
||||
VisitorPictures = v.VisitorPictures.Where(vp => vp.PictureType == pictureType),
|
||||
Visits = v.Visits,
|
||||
VisitsEmployee = v.Visits.Select(ve => ve.Employee),
|
||||
VisitsEmployeePictures = v.Visits.Select(ve => ve.Employee).SelectMany(vee => vee.EmployeePictures.Where(vpe => vpe.PictureType == pictureType))
|
||||
})
|
||||
.OrderBy(v => v.Visitor.FirstName)
|
||||
.Skip(pageSize * pageCount)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return results.Select(v => BuildVisitor(v.Visitor));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="filter"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></returns>
|
||||
public async Task<int> GetCountAsync(string filter)
|
||||
{
|
||||
return await _context.Visitors.CountAsync(q => String.IsNullOrEmpty(filter) ||
|
||||
q.FirstName.Contains(filter) ||
|
||||
q.LastName.Contains(filter) ||
|
||||
(q.FirstName + " " + q.LastName).Contains(filter) ||
|
||||
q.Company.Contains(filter));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitor"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
/// <returns><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></returns>
|
||||
public async Task<int> AddAsync(Visitor visitor)
|
||||
{
|
||||
visitor.CreatedDateTime = DateTime.UtcNow;
|
||||
visitor.LastModifiedDateTime = DateTime.UtcNow;
|
||||
|
||||
_context.Visitors.Add(visitor);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return visitor.VisitorId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitor"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
public async Task UpdateAsync(Visitor visitor)
|
||||
{
|
||||
visitor.LastModifiedDateTime = DateTime.UtcNow;
|
||||
|
||||
_context.Entry<Visitor>(visitor)
|
||||
.State = EntityState.Modified;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/>
|
||||
/// </summary>
|
||||
/// <param name="visitorId"><see cref="MyCompany.Visitors.Data.Repositories.IVisitorRepository"/></param>
|
||||
public async Task DeleteAsync(int visitorId)
|
||||
{
|
||||
var visitor = await _context.Visitors
|
||||
.FindAsync(visitorId);
|
||||
|
||||
if (visitor != null)
|
||||
{
|
||||
_context.Visitors
|
||||
.Remove(visitor);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private Visitor BuildVisitor(Visitor visitor)
|
||||
{
|
||||
//the idea is remove reference for improve
|
||||
//client work without $ref
|
||||
|
||||
if (!visitor.Email.Contains("@")) //for quickstart
|
||||
{
|
||||
throw new InvalidOperationException("Email validation failed");
|
||||
}
|
||||
|
||||
var created = new Visitor
|
||||
{
|
||||
VisitorId = visitor.VisitorId,
|
||||
FirstName = visitor.FirstName,
|
||||
LastName = visitor.LastName,
|
||||
Company = visitor.Company,
|
||||
Email = visitor.Email,
|
||||
CreatedDateTime = visitor.CreatedDateTime,
|
||||
LastModifiedDateTime = visitor.LastModifiedDateTime,
|
||||
PersonalId = visitor.PersonalId,
|
||||
Position = visitor.Position,
|
||||
VisitorPictures = (visitor.VisitorPictures != null) ? visitor.VisitorPictures.Select(vp => new VisitorPicture()
|
||||
{
|
||||
VisitorPictureId = vp.VisitorPictureId,
|
||||
Content = vp.Content,
|
||||
PictureType = vp.PictureType,
|
||||
VisitorId = vp.VisitorId
|
||||
}).ToList()
|
||||
: null,
|
||||
};
|
||||
|
||||
if (visitor.Visits != null && visitor.Visits.Any())
|
||||
{
|
||||
created.LastVisit = visitor.Visits.Where(x => x.VisitDateTime < DateTime.UtcNow)
|
||||
.OrderByDescending(x => x.VisitDateTime)
|
||||
.Select(BuildVisit)
|
||||
.FirstOrDefault();
|
||||
|
||||
created.Visits = visitor.Visits.Where(x => x.VisitDateTime >= DateTime.UtcNow)
|
||||
.OrderBy(x => x.VisitDateTime)
|
||||
.Take(4)
|
||||
.Select(BuildVisit)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
private Visit BuildVisit(Visit visit)
|
||||
{
|
||||
//the idea is remove reference for improve
|
||||
//client work without $ref
|
||||
var created = new Visit
|
||||
{
|
||||
VisitId = visit.VisitId,
|
||||
VisitDateTime = visit.VisitDateTime,
|
||||
Employee = new Employee()
|
||||
{
|
||||
FirstName = visit.Employee.FirstName,
|
||||
LastName = visit.Employee.LastName,
|
||||
JobTitle = visit.Employee.JobTitle,
|
||||
Email = visit.Employee.Email,
|
||||
EmployeePictures = (visit.Employee.EmployeePictures != null) ? visit.Employee.EmployeePictures.Select(ep => new EmployeePicture()
|
||||
{
|
||||
PictureType = ep.PictureType,
|
||||
EmployeePictureId = ep.EmployeePictureId,
|
||||
EmployeeId = ep.EmployeeId,
|
||||
Content = ep.Content
|
||||
}).ToList() : null
|
||||
}
|
||||
};
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all resource
|
||||
/// </summary>
|
||||
/// <param name="disposing">Dispose managed resources check</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="EntityFramework" version="6.1.0" targetFramework="net451" />
|
||||
</packages>
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// CRM Integration data
|
||||
/// </summary>
|
||||
public class CRMData
|
||||
{
|
||||
/// <summary>
|
||||
/// VisitorId
|
||||
/// </summary>
|
||||
public int VisitorId { get; set; }
|
||||
/// <summary>
|
||||
/// Number of CRMLeads
|
||||
/// </summary>
|
||||
public int CRMLeads { get; set; }
|
||||
/// <summary>
|
||||
/// Name of Account Manager
|
||||
/// </summary>
|
||||
public string CRMAccountManager { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Dictionary>
|
||||
<Words>
|
||||
<Recognized>
|
||||
<Word>MyCompany</Word>
|
||||
</Recognized>
|
||||
</Words>
|
||||
<Acronyms>
|
||||
<CasingExceptions>
|
||||
</CasingExceptions>
|
||||
</Acronyms>
|
||||
</Dictionary>
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
/// <summary>
|
||||
/// Employee entity
|
||||
/// </summary>
|
||||
public class Employee
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of this employee
|
||||
/// </summary>
|
||||
public int EmployeeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// First Name
|
||||
/// </summary>
|
||||
public string FirstName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Last Name
|
||||
/// </summary>
|
||||
public string LastName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Email
|
||||
/// </summary>
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// JobTitle
|
||||
/// </summary>
|
||||
public string JobTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TeamId
|
||||
/// </summary>
|
||||
public int? TeamId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Team
|
||||
/// </summary>
|
||||
public Team Team { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ManagedT eams
|
||||
/// </summary>
|
||||
public ICollection<Team> ManagedTeams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visit
|
||||
/// </summary>
|
||||
public ICollection<Visit> Visits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Employee Pictures
|
||||
/// </summary>
|
||||
public ICollection<EmployeePicture> EmployeePictures { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
/// <summary>
|
||||
/// Employee Picture Entity
|
||||
/// </summary>
|
||||
public class EmployeePicture
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier for entity
|
||||
/// </summary>
|
||||
public int EmployeePictureId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Picture Type
|
||||
/// </summary>
|
||||
public PictureType PictureType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content
|
||||
/// </summary>
|
||||
public byte[] Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// EmployeeId
|
||||
/// </summary>
|
||||
public int EmployeeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Employee
|
||||
/// </summary>
|
||||
public Employee Employee { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// IssuingAuthorityKey
|
||||
/// </summary>
|
||||
public class IssuingAuthorityKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{05A33938-B402-4A82-8446-3A81CB0F5AA1}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MyCompany.Visitors.Model</RootNamespace>
|
||||
<AssemblyName>MyCompany.Visitors.Model</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>bin\Debug\MyCompany.Visitors.Model.xml</DocumentationFile>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>bin\Release\MyCompany.Visitors.Model.xml</DocumentationFile>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugCD|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\DebugCD\</OutputPath>
|
||||
<DefineConstants>CODE_ANALYSIS;DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Debug\MyCompany.Visitors.Model.xml</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_LocalDeployment|AnyCPU'">
|
||||
<OutputPath>bin\Release_LocalDeployment\</OutputPath>
|
||||
<DefineConstants>CODE_ANALYSIS;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Release\MyCompany.Visitors.Model.xml</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CrmData.cs" />
|
||||
<Compile Include="Employee.cs" />
|
||||
<Compile Include="EmployeePicture.cs" />
|
||||
<Compile Include="IssuingAuthorityKey.cs" />
|
||||
<Compile Include="PictureType.cs" />
|
||||
<Compile Include="Properties\CommonAssemblyInfo.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Question.cs" />
|
||||
<Compile Include="Team.cs" />
|
||||
<Compile Include="Visit.cs" />
|
||||
<Compile Include="VisitorPicture.cs" />
|
||||
<Compile Include="Visitor.cs" />
|
||||
<Compile Include="VisitStatus.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDictionary Include="CustomCodeAnalysisDictionary.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Picture Type
|
||||
/// </summary>
|
||||
public enum PictureType
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
/// <summary>
|
||||
/// Small
|
||||
/// </summary>
|
||||
Small = 1,
|
||||
/// <summary>
|
||||
/// Big
|
||||
/// </summary>
|
||||
Big = 2,
|
||||
/// <summary>
|
||||
/// All photos
|
||||
/// </summary>
|
||||
All = 3
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MyCompany.Visitors.Model")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("e19a3ccb-b9a9-4ec4-8f76-f149004ae894")]
|
|
@ -0,0 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
[assembly: AssemblyCompany("MyCompany Visitors")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("MyCompany")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyProduct("MyCompany")]
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Question entity
|
||||
/// </summary>
|
||||
public class Question
|
||||
{
|
||||
/// <summary>
|
||||
/// UniqueId
|
||||
/// </summary>
|
||||
public int QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Question Text
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Answer
|
||||
/// </summary>
|
||||
public string Answer { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
/// <summary>
|
||||
/// Team entity
|
||||
/// </summary>
|
||||
public class Team
|
||||
{
|
||||
/// <summary>
|
||||
/// the unique identifier for team entities
|
||||
/// </summary>
|
||||
public int TeamId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ManagerId
|
||||
/// </summary>
|
||||
public int ManagerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Manager
|
||||
/// </summary>
|
||||
public Employee Manager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Employees
|
||||
/// </summary>
|
||||
public ICollection<Employee> Employees { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Visit entity
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class Visit
|
||||
{
|
||||
/// <summary>
|
||||
/// the unique identifier for this entity
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int VisitId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VisitorId
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int VisitorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// created DateTime
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public DateTime CreatedDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visit DateTime
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public DateTime VisitDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Has car?
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public bool HasCar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Plate
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Plate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Comments
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Comments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visitor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Visitor Visitor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// EmployeeId
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int EmployeeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Employee
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Employee Employee { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visit Status
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public VisitStatus Status { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Visit Status
|
||||
/// </summary>
|
||||
public enum VisitStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
/// <summary>
|
||||
/// Visitor has not arrived yet
|
||||
/// </summary>
|
||||
Pending = 1,
|
||||
/// <summary>
|
||||
/// Visitor has arrived
|
||||
/// </summary>
|
||||
Arrived = 2,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Visit entity
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class Visitor
|
||||
{
|
||||
/// <summary>
|
||||
/// UniqueId
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int VisitorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// First Name
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public string FirstName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Last Name
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public string LastName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PersonalId
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string PersonalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Company
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public string Company { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Email
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Created DateTime
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public DateTime CreatedDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Last Modified DateTime
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public DateTime LastModifiedDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VisitorPictures
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public ICollection<VisitorPicture> VisitorPictures { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last visit.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The last visit.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public Visit LastVisit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Visit
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public ICollection<Visit> Visits { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
namespace MyCompany.Visitors.Model
|
||||
{
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Visitor Picture Entity
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class VisitorPicture
|
||||
{
|
||||
/// <summary>
|
||||
/// UniqueId
|
||||
/// </summary>
|
||||
[Key]
|
||||
[DataMember]
|
||||
public int VisitorPictureId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Picture Type
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public PictureType PictureType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public byte[] Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VisitorId
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int VisitorId { get; set; }
|
||||
/*
|
||||
/// <summary>
|
||||
/// Visitor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Visitor Visitor { get; set; }*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26403.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompany.Visitors.Web", "MyCompany.Visitors.Web\MyCompany.Visitors.Web.csproj", "{A2D2B1B4-A65A-40A1-81B7-2DADA59BB28E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{05A33938-B402-4A82-8446-3A81CB0F5AA1} = {05A33938-B402-4A82-8446-3A81CB0F5AA1}
|
||||
{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359} = {0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompany.Visitors.Data", "MyCompany.Visitors.Data\MyCompany.Visitors.Data.csproj", "{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompany.Visitors.Model", "MyCompany.Visitors.Model\MyCompany.Visitors.Model.csproj", "{05A33938-B402-4A82-8446-3A81CB0F5AA1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Data and Model", "Data and Model", "{CF2DB505-26D8-4FD4-BC16-539491B71A64}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A2D2B1B4-A65A-40A1-81B7-2DADA59BB28E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2D2B1B4-A65A-40A1-81B7-2DADA59BB28E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2D2B1B4-A65A-40A1-81B7-2DADA59BB28E}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2D2B1B4-A65A-40A1-81B7-2DADA59BB28E}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{05A33938-B402-4A82-8446-3A81CB0F5AA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{05A33938-B402-4A82-8446-3A81CB0F5AA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{05A33938-B402-4A82-8446-3A81CB0F5AA1}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{05A33938-B402-4A82-8446-3A81CB0F5AA1}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{0D9AC8C7-B5A6-4DEF-8478-17412E5F2359} = {CF2DB505-26D8-4FD4-BC16-539491B71A64}
|
||||
{05A33938-B402-4A82-8446-3A81CB0F5AA1} = {CF2DB505-26D8-4FD4-BC16-539491B71A64}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,52 @@
|
|||
define(function () {
|
||||
var routes = [{
|
||||
url: 'visitors',
|
||||
moduleId: 'viewmodels/visitors',
|
||||
name: 'Visitors',
|
||||
visible: true
|
||||
},
|
||||
{
|
||||
url: 'visits',
|
||||
moduleId: 'viewmodels/visits',
|
||||
name: 'My Visits',
|
||||
visible: true
|
||||
}];
|
||||
|
||||
var isNoAuth = location.href.toLowerCase().indexOf('noauth') != -1;
|
||||
|
||||
if (isNoAuth) {
|
||||
var hasHash = location.href.toLowerCase().indexOf('noauth#/') != -1;
|
||||
if (!hasHash) {
|
||||
location.href = location.href.toLowerCase().replace('noauth', 'noauth#/');
|
||||
}
|
||||
|
||||
for (var i = 0; i < routes.length; i++) {
|
||||
routes[i].hash = 'noauth#/' + routes[i].url;
|
||||
}
|
||||
}
|
||||
|
||||
var startModule = 'visits',
|
||||
pageSize = 10,
|
||||
dateFormat = 'MM/DD/YYYY',
|
||||
timeFormat = 'hh:mm A',
|
||||
defaultPicture = 'Content/Images/no-photo.jpg',
|
||||
defaultBigPicture = 'Content/Images/no-photo-big.png';
|
||||
|
||||
return {
|
||||
routes: routes,
|
||||
startModule: startModule,
|
||||
pageSize: pageSize,
|
||||
dateFormat: dateFormat,
|
||||
timeFormat: timeFormat,
|
||||
defaultPicture: defaultPicture,
|
||||
defaultBigPicture: defaultBigPicture,
|
||||
isNoAuth: isNoAuth
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
}
|
|
@ -0,0 +1,393 @@
|
|||
/**
|
||||
* almond 0.2.0 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/jrburke/almond for details
|
||||
*/
|
||||
//Going sloppy to avoid 'use strict' string cost, but strict practices should
|
||||
//be followed.
|
||||
/*jslint sloppy: true */
|
||||
/*global setTimeout: false */
|
||||
|
||||
var requirejs, require, define;
|
||||
(function (undef) {
|
||||
var main, req, makeMap, handlers,
|
||||
defined = {},
|
||||
waiting = {},
|
||||
config = {},
|
||||
defining = {},
|
||||
aps = [].slice;
|
||||
|
||||
/**
|
||||
* Given a relative module name, like ./something, normalize it to
|
||||
* a real name that can be mapped to a path.
|
||||
* @param {String} name the relative name
|
||||
* @param {String} baseName a real name that the name arg is relative
|
||||
* to.
|
||||
* @returns {String} normalized name
|
||||
*/
|
||||
function normalize(name, baseName) {
|
||||
var nameParts, nameSegment, mapValue, foundMap,
|
||||
foundI, foundStarMap, starI, i, j, part,
|
||||
baseParts = baseName && baseName.split("/"),
|
||||
map = config.map,
|
||||
starMap = (map && map['*']) || {};
|
||||
|
||||
//Adjust any relative paths.
|
||||
if (name && name.charAt(0) === ".") {
|
||||
//If have a base name, try to normalize against it,
|
||||
//otherwise, assume it is a top-level require that will
|
||||
//be relative to baseUrl in the end.
|
||||
if (baseName) {
|
||||
//Convert baseName to array, and lop off the last part,
|
||||
//so that . matches that "directory" and not name of the baseName's
|
||||
//module. For instance, baseName of "one/two/three", maps to
|
||||
//"one/two/three.js", but we want the directory, "one/two" for
|
||||
//this normalization.
|
||||
baseParts = baseParts.slice(0, baseParts.length - 1);
|
||||
|
||||
name = baseParts.concat(name.split("/"));
|
||||
|
||||
//start trimDots
|
||||
for (i = 0; i < name.length; i += 1) {
|
||||
part = name[i];
|
||||
if (part === ".") {
|
||||
name.splice(i, 1);
|
||||
i -= 1;
|
||||
} else if (part === "..") {
|
||||
if (i === 1 && (name[2] === '..' || name[0] === '..')) {
|
||||
//End of the line. Keep at least one non-dot
|
||||
//path segment at the front so it can be mapped
|
||||
//correctly to disk. Otherwise, there is likely
|
||||
//no path mapping for a path starting with '..'.
|
||||
//This can still fail, but catches the most reasonable
|
||||
//uses of ..
|
||||
break;
|
||||
} else if (i > 0) {
|
||||
name.splice(i - 1, 2);
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
//end trimDots
|
||||
|
||||
name = name.join("/");
|
||||
}
|
||||
}
|
||||
|
||||
//Apply map config if available.
|
||||
if ((baseParts || starMap) && map) {
|
||||
nameParts = name.split('/');
|
||||
|
||||
for (i = nameParts.length; i > 0; i -= 1) {
|
||||
nameSegment = nameParts.slice(0, i).join("/");
|
||||
|
||||
if (baseParts) {
|
||||
//Find the longest baseName segment match in the config.
|
||||
//So, do joins on the biggest to smallest lengths of baseParts.
|
||||
for (j = baseParts.length; j > 0; j -= 1) {
|
||||
mapValue = map[baseParts.slice(0, j).join('/')];
|
||||
|
||||
//baseName segment has config, find if it has one for
|
||||
//this name.
|
||||
if (mapValue) {
|
||||
mapValue = mapValue[nameSegment];
|
||||
if (mapValue) {
|
||||
//Match, update name to the new value.
|
||||
foundMap = mapValue;
|
||||
foundI = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMap) {
|
||||
break;
|
||||
}
|
||||
|
||||
//Check for a star map match, but just hold on to it,
|
||||
//if there is a shorter segment match later in a matching
|
||||
//config, then favor over this star map.
|
||||
if (!foundStarMap && starMap && starMap[nameSegment]) {
|
||||
foundStarMap = starMap[nameSegment];
|
||||
starI = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundMap && foundStarMap) {
|
||||
foundMap = foundStarMap;
|
||||
foundI = starI;
|
||||
}
|
||||
|
||||
if (foundMap) {
|
||||
nameParts.splice(0, foundI, foundMap);
|
||||
name = nameParts.join('/');
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function makeRequire(relName, forceSync) {
|
||||
return function () {
|
||||
//A version of a require function that passes a moduleName
|
||||
//value for items that may need to
|
||||
//look up paths relative to the moduleName
|
||||
return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));
|
||||
};
|
||||
}
|
||||
|
||||
function makeNormalize(relName) {
|
||||
return function (name) {
|
||||
return normalize(name, relName);
|
||||
};
|
||||
}
|
||||
|
||||
function makeLoad(depName) {
|
||||
return function (value) {
|
||||
defined[depName] = value;
|
||||
};
|
||||
}
|
||||
|
||||
function callDep(name) {
|
||||
if (waiting.hasOwnProperty(name)) {
|
||||
var args = waiting[name];
|
||||
delete waiting[name];
|
||||
defining[name] = true;
|
||||
main.apply(undef, args);
|
||||
}
|
||||
|
||||
if (!defined.hasOwnProperty(name) && !defining.hasOwnProperty(name)) {
|
||||
throw new Error('No ' + name);
|
||||
}
|
||||
return defined[name];
|
||||
}
|
||||
|
||||
//Turns a plugin!resource to [plugin, resource]
|
||||
//with the plugin being undefined if the name
|
||||
//did not have a plugin prefix.
|
||||
function splitPrefix(name) {
|
||||
var prefix,
|
||||
index = name ? name.indexOf('!') : -1;
|
||||
if (index > -1) {
|
||||
prefix = name.substring(0, index);
|
||||
name = name.substring(index + 1, name.length);
|
||||
}
|
||||
return [prefix, name];
|
||||
}
|
||||
|
||||
function onResourceLoad(name, defined, deps){
|
||||
if(requirejs.onResourceLoad && name){
|
||||
requirejs.onResourceLoad({defined:defined}, {id:name}, deps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a name map, normalizing the name, and using a plugin
|
||||
* for normalization if necessary. Grabs a ref to plugin
|
||||
* too, as an optimization.
|
||||
*/
|
||||
makeMap = function (name, relName) {
|
||||
var plugin,
|
||||
parts = splitPrefix(name),
|
||||
prefix = parts[0];
|
||||
|
||||
name = parts[1];
|
||||
|
||||
if (prefix) {
|
||||
prefix = normalize(prefix, relName);
|
||||
plugin = callDep(prefix);
|
||||
}
|
||||
|
||||
//Normalize according
|
||||
if (prefix) {
|
||||
if (plugin && plugin.normalize) {
|
||||
name = plugin.normalize(name, makeNormalize(relName));
|
||||
} else {
|
||||
name = normalize(name, relName);
|
||||
}
|
||||
} else {
|
||||
name = normalize(name, relName);
|
||||
parts = splitPrefix(name);
|
||||
prefix = parts[0];
|
||||
name = parts[1];
|
||||
if (prefix) {
|
||||
plugin = callDep(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
//Using ridiculous property names for space reasons
|
||||
return {
|
||||
f: prefix ? prefix + '!' + name : name, //fullName
|
||||
n: name,
|
||||
pr: prefix,
|
||||
p: plugin
|
||||
};
|
||||
};
|
||||
|
||||
function makeConfig(name) {
|
||||
return function () {
|
||||
return (config && config.config && config.config[name]) || {};
|
||||
};
|
||||
}
|
||||
|
||||
handlers = {
|
||||
require: function (name) {
|
||||
return makeRequire(name);
|
||||
},
|
||||
exports: function (name) {
|
||||
var e = defined[name];
|
||||
if (typeof e !== 'undefined') {
|
||||
return e;
|
||||
} else {
|
||||
return (defined[name] = {});
|
||||
}
|
||||
},
|
||||
module: function (name) {
|
||||
return {
|
||||
id: name,
|
||||
uri: '',
|
||||
exports: defined[name],
|
||||
config: makeConfig(name)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
main = function (name, deps, callback, relName) {
|
||||
var cjsModule, depName, ret, map, i,
|
||||
args = [],
|
||||
usingExports;
|
||||
|
||||
//Use name if no relName
|
||||
relName = relName || name;
|
||||
|
||||
//Call the callback to define the module, if necessary.
|
||||
if (typeof callback === 'function') {
|
||||
|
||||
//Pull out the defined dependencies and pass the ordered
|
||||
//values to the callback.
|
||||
//Default to [require, exports, module] if no deps
|
||||
deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
|
||||
for (i = 0; i < deps.length; i += 1) {
|
||||
map = makeMap(deps[i], relName);
|
||||
depName = map.f;
|
||||
|
||||
//Fast path CommonJS standard dependencies.
|
||||
if (depName === "require") {
|
||||
args[i] = handlers.require(name);
|
||||
} else if (depName === "exports") {
|
||||
//CommonJS module spec 1.1
|
||||
args[i] = handlers.exports(name);
|
||||
usingExports = true;
|
||||
} else if (depName === "module") {
|
||||
//CommonJS module spec 1.1
|
||||
cjsModule = args[i] = handlers.module(name);
|
||||
} else if (defined.hasOwnProperty(depName) ||
|
||||
waiting.hasOwnProperty(depName) ||
|
||||
defining.hasOwnProperty(depName)) {
|
||||
args[i] = callDep(depName);
|
||||
} else if (map.p) {
|
||||
map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
|
||||
args[i] = defined[depName];
|
||||
} else {
|
||||
throw new Error(name + ' missing ' + depName);
|
||||
}
|
||||
}
|
||||
|
||||
ret = callback.apply(defined[name], args);
|
||||
|
||||
if (name) {
|
||||
//If setting exports via "module" is in play,
|
||||
//favor that over return value and exports. After that,
|
||||
//favor a non-undefined return value over exports use.
|
||||
if (cjsModule && cjsModule.exports !== undef &&
|
||||
cjsModule.exports !== defined[name]) {
|
||||
defined[name] = cjsModule.exports;
|
||||
} else if (ret !== undef || !usingExports) {
|
||||
//Use the return value from the function.
|
||||
defined[name] = ret;
|
||||
}
|
||||
}
|
||||
} else if (name) {
|
||||
//May just be an object definition for the module. Only
|
||||
//worry about defining if have a module name.
|
||||
defined[name] = callback;
|
||||
}
|
||||
|
||||
onResourceLoad(name, defined, args);
|
||||
};
|
||||
|
||||
requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
|
||||
if (typeof deps === "string") {
|
||||
if (handlers[deps]) {
|
||||
//callback in this case is really relName
|
||||
return handlers[deps](callback);
|
||||
}
|
||||
//Just return the module wanted. In this scenario, the
|
||||
//deps arg is the module name, and second arg (if passed)
|
||||
//is just the relName.
|
||||
//Normalize module name, if it contains . or ..
|
||||
return callDep(makeMap(deps, callback).f);
|
||||
} else if (!deps.splice) {
|
||||
//deps is a config object, not an array.
|
||||
config = deps;
|
||||
if (callback.splice) {
|
||||
//callback is an array, which means it is a dependency list.
|
||||
//Adjust args if there are dependencies
|
||||
deps = callback;
|
||||
callback = relName;
|
||||
relName = null;
|
||||
} else {
|
||||
deps = undef;
|
||||
}
|
||||
}
|
||||
|
||||
//Support require(['a'])
|
||||
callback = callback || function () {};
|
||||
|
||||
//If relName is a function, it is an errback handler,
|
||||
//so remove it.
|
||||
if (typeof relName === 'function') {
|
||||
relName = forceSync;
|
||||
forceSync = alt;
|
||||
}
|
||||
|
||||
//Simulate async callback;
|
||||
if (forceSync) {
|
||||
main(undef, deps, callback, relName);
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
main(undef, deps, callback, relName);
|
||||
}, 15);
|
||||
}
|
||||
|
||||
return req;
|
||||
};
|
||||
|
||||
/**
|
||||
* Just drops the config on the floor, but returns req in case
|
||||
* the config return value is used.
|
||||
*/
|
||||
req.config = function (cfg) {
|
||||
config = cfg;
|
||||
return req;
|
||||
};
|
||||
|
||||
define = function (name, deps, callback) {
|
||||
|
||||
//This module may not have dependencies
|
||||
if (!deps.splice) {
|
||||
//deps is not an array, so probably means
|
||||
//an object literal or factory function for
|
||||
//the value. Adjust args.
|
||||
callback = deps;
|
||||
deps = [];
|
||||
}
|
||||
|
||||
waiting[name] = [name, deps, callback];
|
||||
};
|
||||
|
||||
define.amd = {
|
||||
jQuery: true
|
||||
};
|
||||
}());
|
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/MyCompany.Visitors.Web/App/durandal/amd/optimizer.exe
Executable file
Двоичные данные
Labs/Snapshot Debugging Quick Start/src/MyCompany.Visitors/MyCompany.Visitors.Web/App/durandal/amd/optimizer.exe
Executable file
Двоичный файл не отображается.
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
RequireJS 2.1.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
Available via the MIT or new BSD license.
|
||||
see: http://github.com/jrburke/requirejs for details
|
||||
*/
|
||||
var requirejs,require,define;
|
||||
(function(Y){function H(b){return"[object Function]"===L.call(b)}function I(b){return"[object Array]"===L.call(b)}function x(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function M(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function r(b,c){return da.call(b,c)}function i(b,c){return r(b,c)&&b[c]}function E(b,c){for(var d in b)if(r(b,d)&&c(b[d],d))break}function Q(b,c,d,i){c&&E(c,function(c,h){if(d||!r(b,h))i&&"string"!==typeof c?(b[h]||(b[h]={}),Q(b[h],
|
||||
c,d,i)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function Z(b){if(!b)return b;var c=Y;x(b.split("."),function(b){c=c[b]});return c}function J(b,c,d,i){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=i;d&&(c.originalError=d);return c}function ea(b){function c(a,g,v){var e,n,b,c,d,j,f,h=g&&g.split("/");e=h;var l=m.map,k=l&&l["*"];if(a&&"."===a.charAt(0))if(g){e=i(m.pkgs,g)?h=[g]:h.slice(0,h.length-1);g=a=e.concat(a.split("/"));
|
||||
for(e=0;g[e];e+=1)if(n=g[e],"."===n)g.splice(e,1),e-=1;else if(".."===n)if(1===e&&(".."===g[2]||".."===g[0]))break;else 0<e&&(g.splice(e-1,2),e-=2);e=i(m.pkgs,g=a[0]);a=a.join("/");e&&a===g+"/"+e.main&&(a=g)}else 0===a.indexOf("./")&&(a=a.substring(2));if(v&&(h||k)&&l){g=a.split("/");for(e=g.length;0<e;e-=1){b=g.slice(0,e).join("/");if(h)for(n=h.length;0<n;n-=1)if(v=i(l,h.slice(0,n).join("/")))if(v=i(v,b)){c=v;d=e;break}if(c)break;!j&&(k&&i(k,b))&&(j=i(k,b),f=e)}!c&&j&&(c=j,d=f);c&&(g.splice(0,d,
|
||||
c),a=g.join("/"))}return a}function d(a){z&&x(document.getElementsByTagName("script"),function(g){if(g.getAttribute("data-requiremodule")===a&&g.getAttribute("data-requirecontext")===j.contextName)return g.parentNode.removeChild(g),!0})}function y(a){var g=i(m.paths,a);if(g&&I(g)&&1<g.length)return d(a),g.shift(),j.require.undef(a),j.require([a]),!0}function f(a){var g,b=a?a.indexOf("!"):-1;-1<b&&(g=a.substring(0,b),a=a.substring(b+1,a.length));return[g,a]}function h(a,g,b,e){var n,u,d=null,h=g?g.name:
|
||||
null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(L+=1));a=f(a);d=a[0];a=a[1];d&&(d=c(d,h,e),u=i(p,d));a&&(d?k=u&&u.normalize?u.normalize(a,function(a){return c(a,h,e)}):c(a,h,e):(k=c(a,h,e),a=f(k),d=a[0],k=a[1],b=!0,n=j.nameToUrl(k)));b=d&&!u&&!b?"_unnormalized"+(M+=1):"";return{prefix:d,name:k,parentMap:g,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(d?d+"!"+k:k)+b}}function q(a){var g=a.id,b=i(k,g);b||(b=k[g]=new j.Module(a));return b}function s(a,g,b){var e=a.id,n=i(k,e);if(r(p,e)&&(!n||n.defineEmitComplete))"defined"===
|
||||
g&&b(p[e]);else q(a).on(g,b)}function C(a,g){var b=a.requireModules,e=!1;if(g)g(a);else if(x(b,function(g){if(g=i(k,g))g.error=a,g.events.error&&(e=!0,g.emit("error",a))}),!e)l.onError(a)}function w(){R.length&&(fa.apply(F,[F.length-1,0].concat(R)),R=[])}function A(a,g,b){var e=a.map.id;a.error?a.emit("error",a.error):(g[e]=!0,x(a.depMaps,function(e,c){var d=e.id,h=i(k,d);h&&(!a.depMatched[c]&&!b[d])&&(i(g,d)?(a.defineDep(c,p[d]),a.check()):A(h,g,b))}),b[e]=!0)}function B(){var a,g,b,e,n=(b=1E3*m.waitSeconds)&&
|
||||
j.startTime+b<(new Date).getTime(),c=[],h=[],f=!1,l=!0;if(!T){T=!0;E(k,function(b){a=b.map;g=a.id;if(b.enabled&&(a.isDefine||h.push(b),!b.error))if(!b.inited&&n)y(g)?f=e=!0:(c.push(g),d(g));else if(!b.inited&&(b.fetched&&a.isDefine)&&(f=!0,!a.prefix))return l=!1});if(n&&c.length)return b=J("timeout","Load timeout for modules: "+c,null,c),b.contextName=j.contextName,C(b);l&&x(h,function(a){A(a,{},{})});if((!n||e)&&f)if((z||$)&&!U)U=setTimeout(function(){U=0;B()},50);T=!1}}function D(a){r(p,a[0])||
|
||||
q(h(a[0],null,!0)).init(a[1],a[2])}function G(a){var a=a.currentTarget||a.srcElement,b=j.onScriptLoad;a.detachEvent&&!V?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=j.onScriptError;(!a.detachEvent||V)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function K(){var a;for(w();F.length;){a=F.shift();if(null===a[0])return C(J("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));D(a)}}var T,W,j,N,U,m={waitSeconds:7,
|
||||
baseUrl:"./",paths:{},pkgs:{},shim:{},map:{},config:{}},k={},X={},F=[],p={},S={},L=1,M=1;N={require:function(a){return a.require?a.require:a.require=j.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return m.config&&i(m.config,a.map.id)||{}},exports:p[a.map.id]}}};W=function(a){this.events=i(X,a.id)||{};this.map=a;this.shim=
|
||||
i(m.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};W.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=
|
||||
b)},fetch:function(){if(!this.fetched){this.fetched=!0;j.startTime=(new Date).getTime();var a=this.map;if(this.shim)j.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;S[a]||(S[a]=!0,j.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var e=this.exports,n=this.factory;
|
||||
if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(H(n)){if(this.events.error)try{e=j.execCb(c,n,b,e)}catch(d){a=d}else e=j.execCb(c,n,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=[this.map.id],a.requireType="define",C(this.error=a)}else e=n;this.exports=e;if(this.map.isDefine&&
|
||||
!this.ignore&&(p[c]=e,l.onResourceLoad))l.onResourceLoad(j,this.map,this.depMaps);delete k[c];this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=h(a.prefix);this.depMaps.push(d);s(d,"defined",t(this,function(e){var n,d;d=this.map.name;var v=this.map.parentMap?this.map.parentMap.name:null,f=j.makeRequire(a.parentMap,{enableBuildCallback:!0,
|
||||
skipMap:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,v,!0)})||""),e=h(a.prefix+"!"+d,this.map.parentMap),s(e,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=i(k,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",t(this,function(a){this.emit("error",a)}));d.enable()}}else n=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),n.error=t(this,function(a){this.inited=!0;this.error=
|
||||
a;a.requireModules=[b];E(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&delete k[a.map.id]});C(a)}),n.fromText=t(this,function(e,c){var d=a.name,u=h(d),v=O;c&&(e=c);v&&(O=!1);q(u);r(m.config,b)&&(m.config[d]=m.config[b]);try{l.exec(e)}catch(k){throw Error("fromText eval for "+d+" failed: "+k);}v&&(O=!0);this.depMaps.push(u);j.completeLoad(d);f([d],n)}),e.load(a.name,f,n,m)}));j.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){this.enabling=this.enabled=!0;x(this.depMaps,t(this,function(a,
|
||||
b){var c,e;if("string"===typeof a){a=h(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=i(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;s(a,"defined",t(this,function(a){this.defineDep(b,a);this.check()}));this.errback&&s(a,"error",this.errback)}c=a.id;e=k[c];!r(N,c)&&(e&&!e.enabled)&&j.enable(a,this)}));E(this.pluginMaps,t(this,function(a){var b=i(k,a.id);b&&!b.enabled&&j.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=
|
||||
this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){x(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};j={config:m,contextName:b,registry:k,defined:p,urlFetched:S,defQueue:F,Module:W,makeModuleMap:h,nextTick:l.nextTick,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=m.pkgs,c=m.shim,e={paths:!0,config:!0,map:!0};E(a,function(a,b){e[b]?"map"===b?Q(m[b],a,!0,!0):Q(m[b],a,!0):m[b]=a});a.shim&&(E(a.shim,function(a,
|
||||
b){I(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=j.makeShimExports(a);c[b]=a}),m.shim=c);a.packages&&(x(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,location:a.location||a.name,main:(a.main||"main").replace(ga,"").replace(aa,"")}}),m.pkgs=b);E(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=h(b))});if(a.deps||a.callback)j.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(Y,arguments));
|
||||
return b||a.exports&&Z(a.exports)}},makeRequire:function(a,d){function f(e,c,u){var i,m;d.enableBuildCallback&&(c&&H(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(H(c))return C(J("requireargs","Invalid require call"),u);if(a&&r(N,e))return N[e](k[a.id]);if(l.get)return l.get(j,e,a);i=h(e,a,!1,!0);i=i.id;return!r(p,i)?C(J("notloaded",'Module name "'+i+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[i]}K();j.nextTick(function(){K();m=q(h(null,a));m.skipMap=d.skipMap;
|
||||
m.init(e,c,u,{enabled:!0});B()});return f}d=d||{};Q(f,{isBrowser:z,toUrl:function(b){var d=b.lastIndexOf("."),g=null;-1!==d&&(g=b.substring(d,b.length),b=b.substring(0,d));return j.nameToUrl(c(b,a&&a.id,!0),g)},defined:function(b){return r(p,h(b,a,!1,!0).id)},specified:function(b){b=h(b,a,!1,!0).id;return r(p,b)||r(k,b)}});a||(f.undef=function(b){w();var c=h(b,a,!0),d=i(k,b);delete p[b];delete S[c.url];delete X[b];d&&(d.events.defined&&(X[b]=d.events),delete k[b])});return f},enable:function(a){i(k,
|
||||
a.id)&&q(a).enable()},completeLoad:function(a){var b,c,d=i(m.shim,a)||{},h=d.exports;for(w();F.length;){c=F.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);D(c)}c=i(k,a);if(!b&&!r(p,a)&&c&&!c.inited){if(m.enforceDefine&&(!h||!Z(h)))return y(a)?void 0:C(J("nodefine","No define call for "+a,null,[a]));D([a,d.deps||[],d.exportsFn])}B()},nameToUrl:function(a,b){var c,d,h,f,j,k;if(l.jsExtRegExp.test(a))f=a+(b||"");else{c=m.paths;d=m.pkgs;f=a.split("/");for(j=f.length;0<j;j-=1)if(k=
|
||||
f.slice(0,j).join("/"),h=i(d,k),k=i(c,k)){I(k)&&(k=k[0]);f.splice(0,j,k);break}else if(h){c=a===h.name?h.location+"/"+h.main:h.location;f.splice(0,j,c);break}f=f.join("/");f+=b||(/\?/.test(f)?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":m.baseUrl)+f}return m.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+m.urlArgs):f},load:function(a,b){l.load(j,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ha.test((a.currentTarget||a.srcElement).readyState))P=
|
||||
null,a=G(a),j.completeLoad(a.id)},onScriptError:function(a){var b=G(a);if(!y(b.id))return C(J("scripterror","Script error",a,[b.id]))}};j.require=j.makeRequire();return j}var l,w,A,D,s,G,P,K,ba,ca,ia=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ja=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,aa=/\.js$/,ga=/^\.\//;w=Object.prototype;var L=w.toString,da=w.hasOwnProperty,fa=Array.prototype.splice,z=!!("undefined"!==typeof window&&navigator&&document),$=!z&&"undefined"!==typeof importScripts,ha=z&&
|
||||
"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,V="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),B={},q={},R=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(H(requirejs))return;q=requirejs;requirejs=void 0}"undefined"!==typeof require&&!H(require)&&(q=require,require=void 0);l=requirejs=function(b,c,d,y){var f,h="_";!I(b)&&"string"!==typeof b&&(f=b,I(c)?(b=c,c=d,d=y):b=[]);f&&f.context&&(h=f.context);(y=i(B,h))||(y=B[h]=l.s.newContext(h));
|
||||
f&&y.configure(f);return y.require(b,c,d)};l.config=function(b){return l(b)};l.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=l);l.version="2.1.2";l.jsExtRegExp=/^\/|:|\?|\.js$/;l.isBrowser=z;w=l.s={contexts:B,newContext:ea};l({});x(["toUrl","undef","defined","specified"],function(b){l[b]=function(){var c=B._;return c.require[b].apply(c,arguments)}});if(z&&(A=w.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))A=
|
||||
w.head=D.parentNode;l.onError=function(b){throw b;};l.load=function(b,c,d){var i=b&&b.config||{},f;if(z)return f=i.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),f.type=i.scriptType||"text/javascript",f.charset="utf-8",f.async=!0,f.setAttribute("data-requirecontext",b.contextName),f.setAttribute("data-requiremodule",c),f.attachEvent&&!(f.attachEvent.toString&&0>f.attachEvent.toString().indexOf("[native code"))&&!V?(O=!0,f.attachEvent("onreadystatechange",
|
||||
b.onScriptLoad)):(f.addEventListener("load",b.onScriptLoad,!1),f.addEventListener("error",b.onScriptError,!1)),f.src=d,K=f,D?A.insertBefore(f,D):A.appendChild(f),K=null,f;$&&(importScripts(d),b.completeLoad(c))};z&&M(document.getElementsByTagName("script"),function(b){A||(A=b.parentNode);if(s=b.getAttribute("data-main"))return q.baseUrl||(G=s.split("/"),ba=G.pop(),ca=G.length?G.join("/")+"/":"./",q.baseUrl=ca,s=ba),s=s.replace(aa,""),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var i,
|
||||
f;"string"!==typeof b&&(d=c,c=b,b=null);I(c)||(d=c,c=[]);!c.length&&H(d)&&d.length&&(d.toString().replace(ia,"").replace(ja,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c));if(O){if(!(i=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),i=P;i&&(b||(b=i.getAttribute("data-requiremodule")),f=B[i.getAttribute("data-requirecontext")])}(f?f.defQueue:R).push([b,c,d])};define.amd=
|
||||
{jQuery:!0};l.exec=function(b){return eval(b)};l(q)}})(this);
|
|
@ -0,0 +1,308 @@
|
|||
/**
|
||||
* @license RequireJS text 2.0.3 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/requirejs/text for details
|
||||
*/
|
||||
/*jslint regexp: true */
|
||||
/*global require: false, XMLHttpRequest: false, ActiveXObject: false,
|
||||
define: false, window: false, process: false, Packages: false,
|
||||
java: false, location: false */
|
||||
|
||||
define(['module'], function (module) {
|
||||
'use strict';
|
||||
|
||||
var text, fs,
|
||||
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
|
||||
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
|
||||
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
|
||||
hasLocation = typeof location !== 'undefined' && location.href,
|
||||
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
|
||||
defaultHostName = hasLocation && location.hostname,
|
||||
defaultPort = hasLocation && (location.port || undefined),
|
||||
buildMap = [],
|
||||
masterConfig = (module.config && module.config()) || {};
|
||||
|
||||
text = {
|
||||
version: '2.0.3',
|
||||
|
||||
strip: function (content) {
|
||||
//Strips <?xml ...?> declarations so that external SVG and XML
|
||||
//documents can be added to a document without worry. Also, if the string
|
||||
//is an HTML document, only the part inside the body tag is returned.
|
||||
if (content) {
|
||||
content = content.replace(xmlRegExp, "");
|
||||
var matches = content.match(bodyRegExp);
|
||||
if (matches) {
|
||||
content = matches[1];
|
||||
}
|
||||
} else {
|
||||
content = "";
|
||||
}
|
||||
return content;
|
||||
},
|
||||
|
||||
jsEscape: function (content) {
|
||||
return content.replace(/(['\\])/g, '\\$1')
|
||||
.replace(/[\f]/g, "\\f")
|
||||
.replace(/[\b]/g, "\\b")
|
||||
.replace(/[\n]/g, "\\n")
|
||||
.replace(/[\t]/g, "\\t")
|
||||
.replace(/[\r]/g, "\\r")
|
||||
.replace(/[\u2028]/g, "\\u2028")
|
||||
.replace(/[\u2029]/g, "\\u2029");
|
||||
},
|
||||
|
||||
createXhr: masterConfig.createXhr || function () {
|
||||
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
|
||||
var xhr, i, progId;
|
||||
if (typeof XMLHttpRequest !== "undefined") {
|
||||
return new XMLHttpRequest();
|
||||
} else if (typeof ActiveXObject !== "undefined") {
|
||||
for (i = 0; i < 3; i += 1) {
|
||||
progId = progIds[i];
|
||||
try {
|
||||
xhr = new ActiveXObject(progId);
|
||||
} catch (e) {}
|
||||
|
||||
if (xhr) {
|
||||
progIds = [progId]; // so faster next time
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xhr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a resource name into its component parts. Resource names
|
||||
* look like: module/name.ext!strip, where the !strip part is
|
||||
* optional.
|
||||
* @param {String} name the resource name
|
||||
* @returns {Object} with properties "moduleName", "ext" and "strip"
|
||||
* where strip is a boolean.
|
||||
*/
|
||||
parseName: function (name) {
|
||||
var strip = false, index = name.indexOf("."),
|
||||
modName = name.substring(0, index),
|
||||
ext = name.substring(index + 1, name.length);
|
||||
|
||||
index = ext.indexOf("!");
|
||||
if (index !== -1) {
|
||||
//Pull off the strip arg.
|
||||
strip = ext.substring(index + 1, ext.length);
|
||||
strip = strip === "strip";
|
||||
ext = ext.substring(0, index);
|
||||
}
|
||||
|
||||
return {
|
||||
moduleName: modName,
|
||||
ext: ext,
|
||||
strip: strip
|
||||
};
|
||||
},
|
||||
|
||||
xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
|
||||
|
||||
/**
|
||||
* Is an URL on another domain. Only works for browser use, returns
|
||||
* false in non-browser environments. Only used to know if an
|
||||
* optimized .js version of a text resource should be loaded
|
||||
* instead.
|
||||
* @param {String} url
|
||||
* @returns Boolean
|
||||
*/
|
||||
useXhr: function (url, protocol, hostname, port) {
|
||||
var uProtocol, uHostName, uPort,
|
||||
match = text.xdRegExp.exec(url);
|
||||
if (!match) {
|
||||
return true;
|
||||
}
|
||||
uProtocol = match[2];
|
||||
uHostName = match[3];
|
||||
|
||||
uHostName = uHostName.split(':');
|
||||
uPort = uHostName[1];
|
||||
uHostName = uHostName[0];
|
||||
|
||||
return (!uProtocol || uProtocol === protocol) &&
|
||||
(!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
|
||||
((!uPort && !uHostName) || uPort === port);
|
||||
},
|
||||
|
||||
finishLoad: function (name, strip, content, onLoad) {
|
||||
content = strip ? text.strip(content) : content;
|
||||
if (masterConfig.isBuild) {
|
||||
buildMap[name] = content;
|
||||
}
|
||||
onLoad(content);
|
||||
},
|
||||
|
||||
load: function (name, req, onLoad, config) {
|
||||
//Name has format: some.module.filext!strip
|
||||
//The strip part is optional.
|
||||
//if strip is present, then that means only get the string contents
|
||||
//inside a body tag in an HTML string. For XML/SVG content it means
|
||||
//removing the <?xml ...?> declarations so the content can be inserted
|
||||
//into the current doc without problems.
|
||||
|
||||
// Do not bother with the work if a build and text will
|
||||
// not be inlined.
|
||||
if (config.isBuild && !config.inlineText) {
|
||||
onLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
masterConfig.isBuild = config.isBuild;
|
||||
|
||||
var parsed = text.parseName(name),
|
||||
nonStripName = parsed.moduleName + '.' + parsed.ext,
|
||||
url = req.toUrl(nonStripName),
|
||||
useXhr = (masterConfig.useXhr) ||
|
||||
text.useXhr;
|
||||
|
||||
//Load the text. Use XHR if possible and in a browser.
|
||||
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
|
||||
text.get(url, function (content) {
|
||||
text.finishLoad(name, parsed.strip, content, onLoad);
|
||||
}, function (err) {
|
||||
if (onLoad.error) {
|
||||
onLoad.error(err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//Need to fetch the resource across domains. Assume
|
||||
//the resource has been optimized into a JS module. Fetch
|
||||
//by the module name + extension, but do not include the
|
||||
//!strip part to avoid file system issues.
|
||||
req([nonStripName], function (content) {
|
||||
text.finishLoad(parsed.moduleName + '.' + parsed.ext,
|
||||
parsed.strip, content, onLoad);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
write: function (pluginName, moduleName, write, config) {
|
||||
if (buildMap.hasOwnProperty(moduleName)) {
|
||||
var content = text.jsEscape(buildMap[moduleName]);
|
||||
write.asModule(pluginName + "!" + moduleName,
|
||||
"define(function () { return '" +
|
||||
content +
|
||||
"';});\n");
|
||||
}
|
||||
},
|
||||
|
||||
writeFile: function (pluginName, moduleName, req, write, config) {
|
||||
var parsed = text.parseName(moduleName),
|
||||
nonStripName = parsed.moduleName + '.' + parsed.ext,
|
||||
//Use a '.js' file name so that it indicates it is a
|
||||
//script that can be loaded across domains.
|
||||
fileName = req.toUrl(parsed.moduleName + '.' +
|
||||
parsed.ext) + '.js';
|
||||
|
||||
//Leverage own load() method to load plugin value, but only
|
||||
//write out values that do not have the strip argument,
|
||||
//to avoid any potential issues with ! in file names.
|
||||
text.load(nonStripName, req, function (value) {
|
||||
//Use own write() method to construct full module value.
|
||||
//But need to create shell that translates writeFile's
|
||||
//write() to the right interface.
|
||||
var textWrite = function (contents) {
|
||||
return write(fileName, contents);
|
||||
};
|
||||
textWrite.asModule = function (moduleName, contents) {
|
||||
return write.asModule(moduleName, fileName, contents);
|
||||
};
|
||||
|
||||
text.write(pluginName, nonStripName, textWrite, config);
|
||||
}, config);
|
||||
}
|
||||
};
|
||||
|
||||
if (masterConfig.env === 'node' || (!masterConfig.env &&
|
||||
typeof process !== "undefined" &&
|
||||
process.versions &&
|
||||
!!process.versions.node)) {
|
||||
//Using special require.nodeRequire, something added by r.js.
|
||||
fs = require.nodeRequire('fs');
|
||||
|
||||
text.get = function (url, callback) {
|
||||
var file = fs.readFileSync(url, 'utf8');
|
||||
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
|
||||
if (file.indexOf('\uFEFF') === 0) {
|
||||
file = file.substring(1);
|
||||
}
|
||||
callback(file);
|
||||
};
|
||||
} else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
|
||||
text.createXhr())) {
|
||||
text.get = function (url, callback, errback) {
|
||||
var xhr = text.createXhr();
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
//Allow overrides specified in config
|
||||
if (masterConfig.onXhr) {
|
||||
masterConfig.onXhr(xhr, url);
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function (evt) {
|
||||
var status, err;
|
||||
//Do not explicitly handle errors, those should be
|
||||
//visible via console output in the browser.
|
||||
if (xhr.readyState === 4) {
|
||||
status = xhr.status;
|
||||
if (status > 399 && status < 600) {
|
||||
//An http 4xx or 5xx error. Signal an error.
|
||||
err = new Error(url + ' HTTP status: ' + status);
|
||||
err.xhr = xhr;
|
||||
errback(err);
|
||||
} else {
|
||||
callback(xhr.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
};
|
||||
} else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
|
||||
typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
|
||||
//Why Java, why is this so awkward?
|
||||
text.get = function (url, callback) {
|
||||
var stringBuffer, line,
|
||||
encoding = "utf-8",
|
||||
file = new java.io.File(url),
|
||||
lineSeparator = java.lang.System.getProperty("line.separator"),
|
||||
input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
|
||||
content = '';
|
||||
try {
|
||||
stringBuffer = new java.lang.StringBuffer();
|
||||
line = input.readLine();
|
||||
|
||||
// Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
|
||||
// http://www.unicode.org/faq/utf_bom.html
|
||||
|
||||
// Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
|
||||
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
|
||||
if (line && line.length() && line.charAt(0) === 0xfeff) {
|
||||
// Eat the BOM, since we've already found the encoding on this file,
|
||||
// and we plan to concatenating this buffer with others; the BOM should
|
||||
// only appear at the top of a file.
|
||||
line = line.substring(1);
|
||||
}
|
||||
|
||||
stringBuffer.append(line);
|
||||
|
||||
while ((line = input.readLine()) !== null) {
|
||||
stringBuffer.append(lineSeparator);
|
||||
stringBuffer.append(line);
|
||||
}
|
||||
//Make sure we return a JavaScript string and not a Java string.
|
||||
content = String(stringBuffer.toString()); //String
|
||||
} finally {
|
||||
input.close();
|
||||
}
|
||||
callback(content);
|
||||
};
|
||||
}
|
||||
|
||||
return text;
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
define(['./system', './viewEngine', './composition', './widget', './modalDialog', './events'],
|
||||
function(system, viewEngine, composition, widget, modalDialog, Events) {
|
||||
|
||||
var app = {
|
||||
title: 'Application',
|
||||
showModal: function(obj, activationData, context) {
|
||||
return modalDialog.show(obj, activationData, context);
|
||||
},
|
||||
showMessage: function(message, title, options) {
|
||||
return modalDialog.show('./messageBox', {
|
||||
message: message,
|
||||
title: title || this.title,
|
||||
options: options
|
||||
});
|
||||
},
|
||||
start: function() {
|
||||
var that = this;
|
||||
if (that.title) {
|
||||
document.title = that.title;
|
||||
}
|
||||
|
||||
return system.defer(function (dfd) {
|
||||
$(function() {
|
||||
system.log('Starting Application');
|
||||
dfd.resolve();
|
||||
system.log('Started Application');
|
||||
});
|
||||
}).promise();
|
||||
},
|
||||
setRoot: function(root, transition, applicationHost) {
|
||||
var hostElement, settings = { activate: true, transition: transition };
|
||||
|
||||
if (!applicationHost || typeof applicationHost == "string") {
|
||||
hostElement = document.getElementById(applicationHost || 'applicationHost');
|
||||
} else {
|
||||
hostElement = applicationHost;
|
||||
}
|
||||
|
||||
if (typeof root === 'string') {
|
||||
if (viewEngine.isViewUrl(root)) {
|
||||
settings.view = root;
|
||||
} else {
|
||||
settings.model = root;
|
||||
}
|
||||
} else {
|
||||
settings.model = root;
|
||||
}
|
||||
|
||||
composition.compose(hostElement, settings);
|
||||
},
|
||||
adaptToDevice: function() {
|
||||
document.ontouchmove = function (event) {
|
||||
event.preventDefault();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Events.includeIn(app);
|
||||
|
||||
return app;
|
||||
});
|
|
@ -0,0 +1,294 @@
|
|||
define(['./viewLocator', './viewModelBinder', './viewEngine', './system', './viewModel'],
|
||||
function (viewLocator, viewModelBinder, viewEngine, system, viewModel) {
|
||||
|
||||
var dummyModel = {},
|
||||
activeViewAttributeName = 'data-active-view';
|
||||
|
||||
function shouldPerformActivation(settings) {
|
||||
return settings.model && settings.model.activate
|
||||
&& ((composition.activateDuringComposition && settings.activate == undefined) || settings.activate);
|
||||
}
|
||||
|
||||
function tryActivate(settings, successCallback) {
|
||||
if (shouldPerformActivation(settings)) {
|
||||
viewModel.activator().activateItem(settings.model).then(function (success) {
|
||||
if (success) {
|
||||
successCallback();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
successCallback();
|
||||
}
|
||||
}
|
||||
|
||||
function getHostState(parent) {
|
||||
var elements = [];
|
||||
var state = {
|
||||
childElements: elements,
|
||||
activeView: null
|
||||
};
|
||||
|
||||
var child = ko.virtualElements.firstChild(parent);
|
||||
|
||||
while (child) {
|
||||
if (child.nodeType == 1) {
|
||||
elements.push(child);
|
||||
if (child.getAttribute(activeViewAttributeName)) {
|
||||
state.activeView = child;
|
||||
}
|
||||
}
|
||||
|
||||
child = ko.virtualElements.nextSibling(child);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function afterContentSwitch(parent, newChild, settings) {
|
||||
if (settings.activeView) {
|
||||
settings.activeView.removeAttribute(activeViewAttributeName);
|
||||
}
|
||||
|
||||
if (newChild) {
|
||||
if (settings.model && settings.model.viewAttached) {
|
||||
if (settings.composingNewView || settings.alwaysAttachView) {
|
||||
settings.model.viewAttached(newChild);
|
||||
}
|
||||
}
|
||||
|
||||
newChild.setAttribute(activeViewAttributeName, true);
|
||||
}
|
||||
|
||||
if (settings.afterCompose) {
|
||||
settings.afterCompose(parent, newChild, settings);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldTransition(newChild, settings) {
|
||||
if (typeof settings.transition == 'string') {
|
||||
if (settings.activeView) {
|
||||
if (settings.activeView == newChild) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!newChild) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (settings.skipTransitionOnSameViewId) {
|
||||
var currentViewId = settings.activeView.getAttribute('data-view');
|
||||
var newViewId = newChild.getAttribute('data-view');
|
||||
return currentViewId != newViewId;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var composition = {
|
||||
activateDuringComposition: false,
|
||||
convertTransitionToModuleId: function (name) {
|
||||
return 'durandal/transitions/' + name;
|
||||
},
|
||||
switchContent: function (parent, newChild, settings) {
|
||||
settings.transition = settings.transition || this.defaultTransitionName;
|
||||
|
||||
if (shouldTransition(newChild, settings)) {
|
||||
var transitionModuleId = this.convertTransitionToModuleId(settings.transition);
|
||||
system.acquire(transitionModuleId).then(function (transition) {
|
||||
settings.transition = transition;
|
||||
transition(parent, newChild, settings).then(function () {
|
||||
afterContentSwitch(parent, newChild, settings);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
if (newChild != settings.activeView) {
|
||||
if (settings.cacheViews && settings.activeView) {
|
||||
$(settings.activeView).css('display', 'none');
|
||||
}
|
||||
|
||||
if (!newChild) {
|
||||
if (!settings.cacheViews) {
|
||||
ko.virtualElements.emptyNode(parent);
|
||||
}
|
||||
} else {
|
||||
if (settings.cacheViews) {
|
||||
if (settings.composingNewView) {
|
||||
settings.viewElements.push(newChild);
|
||||
ko.virtualElements.prepend(parent, newChild);
|
||||
} else {
|
||||
$(newChild).css('display', '');
|
||||
}
|
||||
} else {
|
||||
ko.virtualElements.emptyNode(parent);
|
||||
ko.virtualElements.prepend(parent, newChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterContentSwitch(parent, newChild, settings);
|
||||
}
|
||||
},
|
||||
bindAndShow: function (element, view, settings) {
|
||||
if (settings.cacheViews) {
|
||||
settings.composingNewView = (ko.utils.arrayIndexOf(settings.viewElements, view) == -1);
|
||||
} else {
|
||||
settings.composingNewView = true;
|
||||
}
|
||||
|
||||
tryActivate(settings, function () {
|
||||
if (settings.beforeBind) {
|
||||
settings.beforeBind(element, view, settings);
|
||||
}
|
||||
|
||||
if (settings.preserveContext && settings.bindingContext) {
|
||||
if (settings.composingNewView) {
|
||||
viewModelBinder.bindContext(settings.bindingContext, view, settings.model);
|
||||
}
|
||||
} else if (view) {
|
||||
var modelToBind = settings.model || dummyModel;
|
||||
var currentModel = ko.dataFor(view);
|
||||
|
||||
if (currentModel != modelToBind) {
|
||||
if (!settings.composingNewView) {
|
||||
$(view).remove();
|
||||
viewEngine.createView(view.getAttribute('data-view')).then(function(recreatedView) {
|
||||
composition.bindAndShow(element, recreatedView, settings);
|
||||
});
|
||||
return;
|
||||
}
|
||||
viewModelBinder.bind(modelToBind, view);
|
||||
}
|
||||
}
|
||||
|
||||
composition.switchContent(element, view, settings);
|
||||
});
|
||||
},
|
||||
defaultStrategy: function (settings) {
|
||||
return viewLocator.locateViewForObject(settings.model, settings.viewElements);
|
||||
},
|
||||
getSettings: function (valueAccessor, element) {
|
||||
var value = ko.utils.unwrapObservable(valueAccessor()) || {};
|
||||
|
||||
if (typeof value == 'string') {
|
||||
return value;
|
||||
}
|
||||
|
||||
var moduleId = system.getModuleId(value);
|
||||
if (moduleId) {
|
||||
return {
|
||||
model: value
|
||||
};
|
||||
}
|
||||
|
||||
for (var attrName in value) {
|
||||
value[attrName] = ko.utils.unwrapObservable(value[attrName]);
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
executeStrategy: function (element, settings) {
|
||||
settings.strategy(settings).then(function (view) {
|
||||
composition.bindAndShow(element, view, settings);
|
||||
});
|
||||
},
|
||||
inject: function (element, settings) {
|
||||
if (!settings.model) {
|
||||
this.bindAndShow(element, null, settings);
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.view) {
|
||||
viewLocator.locateView(settings.view, settings.area, settings.viewElements).then(function (view) {
|
||||
composition.bindAndShow(element, view, settings);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.view !== undefined && !settings.view) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!settings.strategy) {
|
||||
settings.strategy = this.defaultStrategy;
|
||||
}
|
||||
|
||||
if (typeof settings.strategy == 'string') {
|
||||
system.acquire(settings.strategy).then(function (strategy) {
|
||||
settings.strategy = strategy;
|
||||
composition.executeStrategy(element, settings);
|
||||
});
|
||||
} else {
|
||||
this.executeStrategy(element, settings);
|
||||
}
|
||||
},
|
||||
compose: function (element, settings, bindingContext) {
|
||||
if (typeof settings == 'string') {
|
||||
if (viewEngine.isViewUrl(settings)) {
|
||||
settings = {
|
||||
view: settings
|
||||
};
|
||||
} else {
|
||||
settings = {
|
||||
model: settings
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var moduleId = system.getModuleId(settings);
|
||||
if (moduleId) {
|
||||
settings = {
|
||||
model: settings
|
||||
};
|
||||
}
|
||||
|
||||
var hostState = getHostState(element);
|
||||
|
||||
settings.bindingContext = bindingContext;
|
||||
settings.activeView = hostState.activeView;
|
||||
|
||||
if (settings.cacheViews && !settings.viewElements) {
|
||||
settings.viewElements = hostState.childElements;
|
||||
}
|
||||
|
||||
if (!settings.model) {
|
||||
if (!settings.view) {
|
||||
this.bindAndShow(element, null, settings);
|
||||
} else {
|
||||
settings.area = settings.area || 'partial';
|
||||
settings.preserveContext = true;
|
||||
|
||||
viewLocator.locateView(settings.view, settings.area, settings.viewElements).then(function (view) {
|
||||
composition.bindAndShow(element, view, settings);
|
||||
});
|
||||
}
|
||||
} else if (typeof settings.model == 'string') {
|
||||
system.acquire(settings.model).then(function (module) {
|
||||
if (typeof (module) == 'function') {
|
||||
settings.model = new module(element, settings);
|
||||
} else {
|
||||
settings.model = module;
|
||||
}
|
||||
|
||||
composition.inject(element, settings);
|
||||
});
|
||||
} else {
|
||||
composition.inject(element, settings);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.compose = {
|
||||
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
||||
var settings = composition.getSettings(valueAccessor);
|
||||
composition.compose(element, settings, bindingContext);
|
||||
}
|
||||
};
|
||||
|
||||
ko.virtualElements.allowedBindings.compose = true;
|
||||
|
||||
return composition;
|
||||
});
|
|
@ -0,0 +1,139 @@
|
|||
//heavily borrowed from backbone events, augmented by signals.js, added a little of my own code, cleaned up for better readability
|
||||
define(['./system'], function (system) {
|
||||
var eventSplitter = /\s+/;
|
||||
var Events = function() { };
|
||||
|
||||
var Subscription = function(owner, events) {
|
||||
this.owner = owner;
|
||||
this.events = events;
|
||||
};
|
||||
|
||||
Subscription.prototype.then = function (callback, context) {
|
||||
this.callback = callback || this.callback;
|
||||
this.context = context || this.context;
|
||||
|
||||
if (!this.callback) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.owner.on(this.events, this.callback, this.context);
|
||||
return this;
|
||||
};
|
||||
|
||||
Subscription.prototype.on = Subscription.prototype.then;
|
||||
|
||||
Subscription.prototype.off = function () {
|
||||
this.owner.off(this.events, this.callback, this.context);
|
||||
return this;
|
||||
};
|
||||
|
||||
Events.prototype.on = function(events, callback, context) {
|
||||
var calls, event, list;
|
||||
|
||||
if (!callback) {
|
||||
return new Subscription(this, events);
|
||||
} else {
|
||||
calls = this.callbacks || (this.callbacks = {});
|
||||
events = events.split(eventSplitter);
|
||||
|
||||
while (event = events.shift()) {
|
||||
list = calls[event] || (calls[event] = []);
|
||||
list.push(callback, context);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
Events.prototype.off = function(events, callback, context) {
|
||||
var event, calls, list, i;
|
||||
|
||||
// No events
|
||||
if (!(calls = this.callbacks)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
//removing all
|
||||
if (!(events || callback || context)) {
|
||||
delete this.callbacks;
|
||||
return this;
|
||||
}
|
||||
|
||||
events = events ? events.split(eventSplitter) : system.keys(calls);
|
||||
|
||||
// Loop through the callback list, splicing where appropriate.
|
||||
while (event = events.shift()) {
|
||||
if (!(list = calls[event]) || !(callback || context)) {
|
||||
delete calls[event];
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = list.length - 2; i >= 0; i -= 2) {
|
||||
if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
|
||||
list.splice(i, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Events.prototype.trigger = function(events) {
|
||||
var event, calls, list, i, length, args, all, rest;
|
||||
if (!(calls = this.callbacks)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
rest = [];
|
||||
events = events.split(eventSplitter);
|
||||
for (i = 1, length = arguments.length; i < length; i++) {
|
||||
rest[i - 1] = arguments[i];
|
||||
}
|
||||
|
||||
// For each event, walk through the list of callbacks twice, first to
|
||||
// trigger the event, then to trigger any `"all"` callbacks.
|
||||
while (event = events.shift()) {
|
||||
// Copy callback lists to prevent modification.
|
||||
if (all = calls.all) {
|
||||
all = all.slice();
|
||||
}
|
||||
|
||||
if (list = calls[event]) {
|
||||
list = list.slice();
|
||||
}
|
||||
|
||||
// Execute event callbacks.
|
||||
if (list) {
|
||||
for (i = 0, length = list.length; i < length; i += 2) {
|
||||
list[i].apply(list[i + 1] || this, rest);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute "all" callbacks.
|
||||
if (all) {
|
||||
args = [event].concat(rest);
|
||||
for (i = 0, length = all.length; i < length; i += 2) {
|
||||
all[i].apply(all[i + 1] || this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Events.prototype.proxy = function(events) {
|
||||
var that = this;
|
||||
return (function(arg) {
|
||||
that.trigger(events, arg);
|
||||
});
|
||||
};
|
||||
|
||||
Events.includeIn = function(targetObject) {
|
||||
targetObject.on = Events.prototype.on;
|
||||
targetObject.off = Events.prototype.off;
|
||||
targetObject.trigger = Events.prototype.trigger;
|
||||
targetObject.proxy = Events.prototype.proxy;
|
||||
};
|
||||
|
||||
return Events;
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
define(function() {
|
||||
return {
|
||||
defaultJSONPCallbackParam:'callback',
|
||||
get:function(url, query) {
|
||||
return $.ajax(url, { data: query });
|
||||
},
|
||||
jsonp: function (url, query, callbackParam) {
|
||||
if (url.indexOf('=?') == -1) {
|
||||
callbackParam = callbackParam || this.defaultJSONPCallbackParam;
|
||||
|
||||
if (url.indexOf('?') == -1) {
|
||||
url += '?';
|
||||
} else {
|
||||
url += '&';
|
||||
}
|
||||
|
||||
url += callbackParam + '=?';
|
||||
}
|
||||
|
||||
return $.ajax({
|
||||
url: url,
|
||||
dataType:'jsonp',
|
||||
data:query
|
||||
});
|
||||
},
|
||||
post:function(url, data) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
data: ko.toJSON(data),
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json'
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
<div class="modal-msgBox autoclose">
|
||||
<div class="modal-msgBox-header">
|
||||
<!--<span data-bind="html: title"></span>-->
|
||||
<button class="button-close" data-bind="click: close"></button>
|
||||
</div>
|
||||
<div class="modal-msgBox-body">
|
||||
<p class="msgBox-message" data-bind="html: message"></p>
|
||||
</div>
|
||||
<div class="modal-msgBox-footer" data-bind="foreach: options">
|
||||
<button class="button-primary button-primary-padding"
|
||||
data-bind="click: function () { $parent.selectOption($data); }, html: $data, css: { autofocus: $index() == ($parent.options.length - 1) }"></button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,28 @@
|
|||
define(function() {
|
||||
var MessageBox = function(message, title, options) {
|
||||
this.message = message;
|
||||
this.title = title || MessageBox.defaultTitle;
|
||||
this.options = options || MessageBox.defaultOptions;
|
||||
};
|
||||
|
||||
MessageBox.prototype.selectOption = function (dialogResult) {
|
||||
this.modal.close(dialogResult);
|
||||
};
|
||||
|
||||
MessageBox.prototype.activate = function(config) {
|
||||
if (config) {
|
||||
this.message = config.message;
|
||||
this.title = config.title || MessageBox.defaultTitle;
|
||||
this.options = config.options || MessageBox.defaultOptions;
|
||||
}
|
||||
};
|
||||
|
||||
MessageBox.prototype.close = function() {
|
||||
this.modal.close();
|
||||
};
|
||||
|
||||
MessageBox.defaultTitle = 'Application';
|
||||
MessageBox.defaultOptions = ['Ok'];
|
||||
|
||||
return MessageBox;
|
||||
});
|
|
@ -0,0 +1,166 @@
|
|||
define(['./composition', './system', './viewModel'],
|
||||
function (composition, system, viewModel) {
|
||||
|
||||
var contexts = {},
|
||||
modalCount = 0;
|
||||
|
||||
function ensureModalInstance(objOrModuleId) {
|
||||
return system.defer(function(dfd) {
|
||||
if (typeof objOrModuleId == "string") {
|
||||
system.acquire(objOrModuleId).then(function(module) {
|
||||
if (typeof(module) == 'function') {
|
||||
dfd.resolve(new module());
|
||||
} else {
|
||||
dfd.resolve(module);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dfd.resolve(objOrModuleId);
|
||||
}
|
||||
}).promise();
|
||||
}
|
||||
|
||||
var modalDialog = {
|
||||
currentZIndex: 500,
|
||||
getNextZIndex: function () {
|
||||
return ++this.currentZIndex;
|
||||
},
|
||||
isModalOpen: function() {
|
||||
return modalCount > 0;
|
||||
},
|
||||
getContext: function(name) {
|
||||
return contexts[name || 'default'];
|
||||
},
|
||||
addContext: function(name, modalContext) {
|
||||
modalContext.name = name;
|
||||
contexts[name] = modalContext;
|
||||
|
||||
var helperName = 'show' + name.substr(0, 1).toUpperCase() + name.substr(1);
|
||||
this[helperName] = function (obj, activationData) {
|
||||
return this.show(obj, activationData, name);
|
||||
};
|
||||
},
|
||||
createCompositionSettings: function(obj, modalContext) {
|
||||
var settings = {
|
||||
model:obj,
|
||||
activate:false
|
||||
};
|
||||
|
||||
if (modalContext.afterCompose) {
|
||||
settings.afterCompose = modalContext.afterCompose;
|
||||
}
|
||||
|
||||
return settings;
|
||||
},
|
||||
show: function(obj, activationData, context) {
|
||||
var that = this;
|
||||
var modalContext = contexts[context || 'default'];
|
||||
|
||||
return system.defer(function(dfd) {
|
||||
ensureModalInstance(obj).then(function(instance) {
|
||||
var activator = viewModel.activator();
|
||||
|
||||
activator.activateItem(instance, activationData).then(function (success) {
|
||||
if (success) {
|
||||
var modal = instance.modal = {
|
||||
owner: instance,
|
||||
context: modalContext,
|
||||
activator: activator,
|
||||
close: function () {
|
||||
var args = arguments;
|
||||
activator.deactivateItem(instance, true).then(function (closeSuccess) {
|
||||
if (closeSuccess) {
|
||||
modalCount--;
|
||||
modalContext.removeHost(modal);
|
||||
delete instance.modal;
|
||||
dfd.resolve.apply(dfd, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
modal.settings = that.createCompositionSettings(instance, modalContext);
|
||||
modalContext.addHost(modal);
|
||||
|
||||
modalCount++;
|
||||
composition.compose(modal.host, modal.settings);
|
||||
} else {
|
||||
dfd.resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}).promise();
|
||||
}
|
||||
};
|
||||
|
||||
modalDialog.addContext('default', {
|
||||
blockoutOpacity: .5,
|
||||
removeDelay: 200,
|
||||
addHost: function(modal) {
|
||||
var body = $('body');
|
||||
var blockout = $('<div class="modalBlockout"></div>')
|
||||
.css({ 'z-index': modalDialog.getNextZIndex(), 'opacity': this.blockoutOpacity })
|
||||
.appendTo(body);
|
||||
|
||||
var host = $('<div class="modalHost"></div>')
|
||||
.css({ 'z-index': modalDialog.getNextZIndex() })
|
||||
.appendTo(body);
|
||||
|
||||
modal.host = host.get(0);
|
||||
modal.blockout = blockout.get(0);
|
||||
|
||||
if (!modalDialog.isModalOpen()) {
|
||||
modal.oldBodyMarginRight = $("body").css("margin-right");
|
||||
|
||||
var html = $("html");
|
||||
var oldBodyOuterWidth = body.outerWidth(true);
|
||||
var oldScrollTop = html.scrollTop();
|
||||
$("html").css("overflow-y", "hidden");
|
||||
var newBodyOuterWidth = $("body").outerWidth(true);
|
||||
body.css("margin-right", (newBodyOuterWidth - oldBodyOuterWidth + parseInt(modal.oldBodyMarginRight)) + "px");
|
||||
html.scrollTop(oldScrollTop); // necessary for Firefox
|
||||
$("#simplemodal-overlay").css("width", newBodyOuterWidth + "px");
|
||||
}
|
||||
},
|
||||
removeHost: function(modal) {
|
||||
$(modal.host).css('opacity', 0);
|
||||
$(modal.blockout).css('opacity', 0);
|
||||
|
||||
setTimeout(function() {
|
||||
$(modal.host).remove();
|
||||
$(modal.blockout).remove();
|
||||
}, this.removeDelay);
|
||||
|
||||
if (!modalDialog.isModalOpen()) {
|
||||
var html = $("html");
|
||||
var oldScrollTop = html.scrollTop(); // necessary for Firefox.
|
||||
html.css("overflow-y", "").scrollTop(oldScrollTop);
|
||||
$("body").css("margin-right", modal.oldBodyMarginRight);
|
||||
}
|
||||
},
|
||||
afterCompose: function(parent, newChild, settings) {
|
||||
var $child = $(newChild);
|
||||
var width = $child.width();
|
||||
var height = $child.height();
|
||||
|
||||
$child.css({
|
||||
'margin-top': (-height / 2).toString() + 'px',
|
||||
'margin-left': (-width / 2).toString() + 'px'
|
||||
});
|
||||
|
||||
$(settings.model.modal.host).css('opacity', 1);
|
||||
|
||||
if ($(newChild).hasClass('autoclose')) {
|
||||
$(settings.model.modal.blockout).click(function() {
|
||||
settings.model.modal.close();
|
||||
});
|
||||
}
|
||||
|
||||
$('.autofocus', newChild).each(function() {
|
||||
$(this).focus();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return modalDialog;
|
||||
});
|
|
@ -0,0 +1,386 @@
|
|||
define(['../system', '../viewModel', '../app'], function (system, viewModel, app) {
|
||||
|
||||
//NOTE: Sammy.js is not required by the core of Durandal.
|
||||
//However, this plugin leverages it to enable navigation.
|
||||
|
||||
var routesByPath = {},
|
||||
allRoutes = ko.observableArray([]),
|
||||
visibleRoutes = ko.observableArray([]),
|
||||
ready = ko.observable(false),
|
||||
isNavigating = ko.observable(false),
|
||||
sammy,
|
||||
router,
|
||||
previousRoute,
|
||||
previousModule,
|
||||
cancelling = false,
|
||||
activeItem = viewModel.activator(),
|
||||
activeRoute = ko.observable(),
|
||||
navigationDefaultRoute,
|
||||
queue = [],
|
||||
skipRouteUrl;
|
||||
|
||||
var tryActivateRouter = function () {
|
||||
tryActivateRouter = system.noop;
|
||||
ready(true);
|
||||
router.dfd.resolve();
|
||||
delete router.dfd;
|
||||
};
|
||||
|
||||
activeItem.settings.areSameItem = function (currentItem, newItem, activationData) {
|
||||
return false;
|
||||
};
|
||||
|
||||
function redirect(url) {
|
||||
isNavigating(false);
|
||||
system.log('Redirecting');
|
||||
router.navigateTo(url);
|
||||
}
|
||||
|
||||
function cancelNavigation() {
|
||||
cancelling = true;
|
||||
system.log('Cancelling Navigation');
|
||||
|
||||
if (previousRoute) {
|
||||
sammy.setLocation(previousRoute);
|
||||
}
|
||||
|
||||
cancelling = false;
|
||||
isNavigating(false);
|
||||
|
||||
var routeAttempted = sammy.last_location[1].split('#/')[1];
|
||||
|
||||
if (previousRoute || !routeAttempted) {
|
||||
tryActivateRouter();
|
||||
} else if (routeAttempted != navigationDefaultRoute) {
|
||||
window.location.replace("#/" + navigationDefaultRoute);
|
||||
} else {
|
||||
tryActivateRouter();
|
||||
}
|
||||
}
|
||||
|
||||
function completeNavigation(routeInfo, params, module) {
|
||||
activeRoute(routeInfo);
|
||||
router.onNavigationComplete(routeInfo, params, module);
|
||||
previousModule = module;
|
||||
previousRoute = sammy.last_location[1].replace('/', '');
|
||||
tryActivateRouter();
|
||||
}
|
||||
|
||||
function activateRoute(routeInfo, params, module) {
|
||||
system.log('Activating Route', routeInfo, module, params);
|
||||
|
||||
activeItem.activateItem(module, params).then(function (succeeded) {
|
||||
if (succeeded) {
|
||||
completeNavigation(routeInfo, params, module);
|
||||
} else {
|
||||
cancelNavigation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function shouldStopNavigation() {
|
||||
return cancelling || (sammy.last_location[1].replace('/', '') == previousRoute);
|
||||
}
|
||||
|
||||
function handleGuardedRoute(routeInfo, params, instance) {
|
||||
var resultOrPromise = router.guardRoute(routeInfo, params, instance);
|
||||
if (resultOrPromise) {
|
||||
if (resultOrPromise.then) {
|
||||
resultOrPromise.then(function(result) {
|
||||
if (result) {
|
||||
if (typeof result == 'string') {
|
||||
redirect(result);
|
||||
} else {
|
||||
activateRoute(routeInfo, params, instance);
|
||||
}
|
||||
} else {
|
||||
cancelNavigation();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (typeof resultOrPromise == 'string') {
|
||||
redirect(resultOrPromise);
|
||||
} else {
|
||||
activateRoute(routeInfo, params, instance);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cancelNavigation();
|
||||
}
|
||||
}
|
||||
|
||||
function dequeueRoute() {
|
||||
if (isNavigating()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var next = queue.shift();
|
||||
queue = [];
|
||||
|
||||
if (!next) {
|
||||
return;
|
||||
}
|
||||
|
||||
isNavigating(true);
|
||||
|
||||
system.acquire(next.routeInfo.moduleId).then(function(module) {
|
||||
next.params.routeInfo = next.routeInfo;
|
||||
next.params.router = router;
|
||||
|
||||
var instance = router.getActivatableInstance(next.routeInfo, next.params, module);
|
||||
|
||||
if (router.guardRoute) {
|
||||
handleGuardedRoute(next.routeInfo, next.params, instance);
|
||||
} else {
|
||||
activateRoute(next.routeInfo, next.params, instance);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function queueRoute(routeInfo, params) {
|
||||
queue.unshift({
|
||||
routeInfo: routeInfo,
|
||||
params: params
|
||||
});
|
||||
|
||||
dequeueRoute();
|
||||
}
|
||||
|
||||
function ensureRoute(route, params) {
|
||||
var routeInfo = routesByPath[route];
|
||||
|
||||
if (shouldStopNavigation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!routeInfo) {
|
||||
if (!router.autoConvertRouteToModuleId) {
|
||||
router.handleInvalidRoute(route, params);
|
||||
return;
|
||||
}
|
||||
|
||||
routeInfo = {
|
||||
moduleId: router.autoConvertRouteToModuleId(route, params),
|
||||
name: router.convertRouteToName(route)
|
||||
};
|
||||
}
|
||||
|
||||
queueRoute(routeInfo, params);
|
||||
}
|
||||
|
||||
function handleDefaultRoute() {
|
||||
ensureRoute(navigationDefaultRoute, this.params || {});
|
||||
}
|
||||
|
||||
function handleMappedRoute() {
|
||||
ensureRoute(this.app.last_route.path.toString(), this.params || {});
|
||||
}
|
||||
|
||||
function handleWildCardRoute() {
|
||||
var params = this.params || {}, route;
|
||||
|
||||
if (router.autoConvertRouteToModuleId) {
|
||||
var fragment = this.path.split('#/');
|
||||
|
||||
if (fragment.length == 2) {
|
||||
var parts = fragment[1].split('/');
|
||||
route = parts[0];
|
||||
params.splat = parts.splice(1);
|
||||
ensureRoute(route, params);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
router.handleInvalidRoute(this.app.last_location[1], params);
|
||||
}
|
||||
|
||||
function configureRoute(routeInfo) {
|
||||
router.prepareRouteInfo(routeInfo);
|
||||
|
||||
routesByPath[routeInfo.url.toString()] = routeInfo;
|
||||
allRoutes.push(routeInfo);
|
||||
|
||||
if (routeInfo.visible) {
|
||||
routeInfo.isActive = ko.computed(function () {
|
||||
return ready() && activeItem() && activeItem().__moduleId__ == routeInfo.moduleId;
|
||||
});
|
||||
|
||||
visibleRoutes.push(routeInfo);
|
||||
}
|
||||
|
||||
return routeInfo;
|
||||
}
|
||||
|
||||
return router = {
|
||||
ready: ready,
|
||||
allRoutes: allRoutes,
|
||||
visibleRoutes: visibleRoutes,
|
||||
isNavigating: isNavigating,
|
||||
activeItem: activeItem,
|
||||
activeRoute: activeRoute,
|
||||
afterCompose: function () {
|
||||
setTimeout(function () {
|
||||
isNavigating(false);
|
||||
dequeueRoute();
|
||||
}, 10);
|
||||
},
|
||||
getActivatableInstance: function (routeInfo, params, module) {
|
||||
if (typeof module == 'function') {
|
||||
return new module();
|
||||
} else {
|
||||
return module;
|
||||
}
|
||||
},
|
||||
useConvention: function (rootPath) {
|
||||
rootPath = rootPath == null ? 'viewmodels' : rootPath;
|
||||
if (rootPath) {
|
||||
rootPath += '/';
|
||||
}
|
||||
router.convertRouteToModuleId = function (url) {
|
||||
return rootPath + router.stripParameter(url);
|
||||
};
|
||||
},
|
||||
stripParameter: function (val) {
|
||||
var colonIndex = val.indexOf(':');
|
||||
var length = colonIndex > 0 ? colonIndex - 1 : val.length;
|
||||
return val.substring(0, length);
|
||||
},
|
||||
handleInvalidRoute: function (route, params) {
|
||||
system.log('No Route Found', route, params);
|
||||
},
|
||||
onNavigationComplete: function (routeInfo, params, module) {
|
||||
if (app.title) {
|
||||
document.title = routeInfo.caption + " | " + app.title;
|
||||
} else {
|
||||
document.title = routeInfo.caption;
|
||||
}
|
||||
},
|
||||
navigateBack: function () {
|
||||
window.history.back();
|
||||
},
|
||||
navigateTo: function (url, option) {
|
||||
option = option || 'trigger';
|
||||
|
||||
switch (option.toLowerCase()) {
|
||||
case 'skip':
|
||||
skipRouteUrl = url;
|
||||
sammy.setLocation(url);
|
||||
break;
|
||||
case 'replace':
|
||||
window.location.replace(url);
|
||||
break;
|
||||
default:
|
||||
if (sammy.lookupRoute('get', url)) {
|
||||
sammy.setLocation(url);
|
||||
} else {
|
||||
window.location.href = url;
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
replaceLocation: function (url) {
|
||||
this.navigateTo(url, 'replace');
|
||||
},
|
||||
convertRouteToName: function (route) {
|
||||
var value = router.stripParameter(route);
|
||||
return value.substring(0, 1).toUpperCase() + value.substring(1);
|
||||
},
|
||||
convertRouteToModuleId: function (route) {
|
||||
return router.stripParameter(route);
|
||||
},
|
||||
prepareRouteInfo: function (info) {
|
||||
if (!(info.url instanceof RegExp)) {
|
||||
info.name = info.name || router.convertRouteToName(info.url);
|
||||
info.moduleId = info.moduleId || router.convertRouteToModuleId(info.url);
|
||||
info.hash = info.hash || '#/' + info.url;
|
||||
}
|
||||
|
||||
info.caption = info.caption || info.name;
|
||||
info.settings = info.settings || {};
|
||||
},
|
||||
mapAuto: function (path) {
|
||||
path = path || 'viewmodels';
|
||||
path += '/';
|
||||
|
||||
router.autoConvertRouteToModuleId = function (url, params) {
|
||||
return path + router.stripParameter(url);
|
||||
};
|
||||
},
|
||||
mapNav: function (urlOrConfig, moduleId, name) {
|
||||
if (typeof urlOrConfig == "string") {
|
||||
return this.mapRoute(urlOrConfig, moduleId, name, true);
|
||||
}
|
||||
|
||||
urlOrConfig.visible = true;
|
||||
return configureRoute(urlOrConfig);
|
||||
},
|
||||
mapRoute: function (urlOrConfig, moduleId, name, visible) {
|
||||
if (typeof urlOrConfig == "string") {
|
||||
return configureRoute({
|
||||
url: urlOrConfig,
|
||||
moduleId: moduleId,
|
||||
name: name,
|
||||
visible: visible
|
||||
});
|
||||
} else {
|
||||
return configureRoute(urlOrConfig);
|
||||
}
|
||||
},
|
||||
map: function (routeOrRouteArray) {
|
||||
if (!system.isArray(routeOrRouteArray)) {
|
||||
return configureRoute(routeOrRouteArray);
|
||||
}
|
||||
|
||||
var configured = [];
|
||||
for (var i = 0; i < routeOrRouteArray.length; i++) {
|
||||
configured.push(configureRoute(routeOrRouteArray[i]));
|
||||
}
|
||||
return configured;
|
||||
},
|
||||
activate: function (defaultRoute) {
|
||||
return system.defer(function (dfd) {
|
||||
var processedRoute;
|
||||
|
||||
router.dfd = dfd;
|
||||
navigationDefaultRoute = defaultRoute;
|
||||
|
||||
sammy = Sammy(function (route) {
|
||||
var unwrapped = allRoutes();
|
||||
|
||||
for (var i = 0; i < unwrapped.length; i++) {
|
||||
var current = unwrapped[i];
|
||||
route.get(current.url, handleMappedRoute);
|
||||
processedRoute = this.routes.get[i];
|
||||
routesByPath[processedRoute.path.toString()] = current;
|
||||
}
|
||||
|
||||
route.get('#/', handleDefaultRoute);
|
||||
route.get(/\#\/(.*)/, handleWildCardRoute);
|
||||
});
|
||||
|
||||
sammy._checkFormSubmission = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
sammy.before(null, function(context) {
|
||||
if (!skipRouteUrl) {
|
||||
return true;
|
||||
} else if (context.path === "/" + skipRouteUrl) {
|
||||
skipRouteUrl = null;
|
||||
return false;
|
||||
} else {
|
||||
throw new Error("Expected to skip url '" + skipRouteUrl + "', but found url '" + context.path + "'");
|
||||
}
|
||||
});
|
||||
|
||||
sammy.log = function () {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
args.unshift('Sammy');
|
||||
system.log.apply(system, args);
|
||||
};
|
||||
|
||||
sammy.run('#/');
|
||||
}).promise();
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,165 @@
|
|||
define(['require'], function (require) {
|
||||
var isDebugging = false,
|
||||
nativeKeys = Object.keys,
|
||||
hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||
toString = Object.prototype.toString,
|
||||
system,
|
||||
treatAsIE8 = false;
|
||||
|
||||
//see http://patik.com/blog/complete-cross-browser-console-log/
|
||||
// Tell IE9 to use its built-in console
|
||||
if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log == 'object') {
|
||||
try {
|
||||
['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd']
|
||||
.forEach(function(method) {
|
||||
console[method] = this.call(console[method], console);
|
||||
}, Function.prototype.bind);
|
||||
} catch (ex) {
|
||||
treatAsIE8 = true;
|
||||
}
|
||||
}
|
||||
|
||||
// callback for dojo's loader
|
||||
// note: if you wish to use Durandal with dojo's AMD loader,
|
||||
// currently you must fork the dojo source with the following
|
||||
// dojo/dojo.js, line 1187, the last line of the finishExec() function:
|
||||
// (add) signal("moduleLoaded", [module.result, module.mid]);
|
||||
// an enhancement request has been submitted to dojo to make this
|
||||
// a permanent change. To view the status of this request, visit:
|
||||
// http://bugs.dojotoolkit.org/ticket/16727
|
||||
|
||||
if (require.on) {
|
||||
require.on("moduleLoaded", function (module, mid) {
|
||||
system.setModuleId(module, mid);
|
||||
});
|
||||
}
|
||||
|
||||
// callback for require.js loader
|
||||
if (typeof requirejs !== 'undefined') {
|
||||
requirejs.onResourceLoad = function (context, map, depArray) {
|
||||
system.setModuleId(context.defined[map.id], map.id);
|
||||
};
|
||||
}
|
||||
|
||||
var noop = function() { };
|
||||
|
||||
var log = function() {
|
||||
try {
|
||||
// Modern browsers
|
||||
if (typeof console != 'undefined' && typeof console.log == 'function') {
|
||||
// Opera 11
|
||||
if (window.opera) {
|
||||
var i = 0;
|
||||
while (i < arguments.length) {
|
||||
console.log('Item ' + (i + 1) + ': ' + arguments[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// All other modern browsers
|
||||
else if ((Array.prototype.slice.call(arguments)).length == 1 && typeof Array.prototype.slice.call(arguments)[0] == 'string') {
|
||||
console.log((Array.prototype.slice.call(arguments)).toString());
|
||||
} else {
|
||||
console.log(Array.prototype.slice.call(arguments));
|
||||
}
|
||||
}
|
||||
// IE8
|
||||
else if ((!Function.prototype.bind || treatAsIE8) && typeof console != 'undefined' && typeof console.log == 'object') {
|
||||
Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
|
||||
}
|
||||
|
||||
// IE7 and lower, and other old browsers
|
||||
} catch(ignore) {}
|
||||
};
|
||||
|
||||
system = {
|
||||
version:"1.2.0",
|
||||
noop: noop,
|
||||
getModuleId: function(obj) {
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof obj == 'function') {
|
||||
return obj.prototype.__moduleId__;
|
||||
}
|
||||
|
||||
if (typeof obj == 'string') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return obj.__moduleId__;
|
||||
},
|
||||
setModuleId: function (obj, id) {
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof obj == 'function') {
|
||||
obj.prototype.__moduleId__ = id;
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof obj == 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
obj.__moduleId__ = id;
|
||||
},
|
||||
debug: function(enable) {
|
||||
if (arguments.length == 1) {
|
||||
isDebugging = enable;
|
||||
if (isDebugging) {
|
||||
this.log = log;
|
||||
this.log('Debug mode enabled.');
|
||||
} else {
|
||||
this.log('Debug mode disabled.');
|
||||
this.log = noop;
|
||||
}
|
||||
} else {
|
||||
return isDebugging;
|
||||
}
|
||||
},
|
||||
isArray: function(obj) {
|
||||
return toString.call(obj) === '[object Array]';
|
||||
},
|
||||
log: noop,
|
||||
defer: function(action) {
|
||||
return $.Deferred(action);
|
||||
},
|
||||
guid: function() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
},
|
||||
acquire: function() {
|
||||
var modules = Array.prototype.slice.call(arguments, 0);
|
||||
return this.defer(function(dfd) {
|
||||
require(modules, function() {
|
||||
var args = arguments;
|
||||
setTimeout(function() {
|
||||
dfd.resolve.apply(dfd, args);
|
||||
}, 1);
|
||||
});
|
||||
}).promise();
|
||||
}
|
||||
};
|
||||
|
||||
system.keys = nativeKeys || function(obj) {
|
||||
if (obj !== Object(obj)) {
|
||||
throw new TypeError('Invalid object');
|
||||
}
|
||||
|
||||
var keys = [];
|
||||
|
||||
for (var key in obj) {
|
||||
if (hasOwnProperty.call(obj, key)) {
|
||||
keys[keys.length] = key;
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
};
|
||||
|
||||
return system;
|
||||
});
|
|
@ -0,0 +1,75 @@
|
|||
define(['../system'], function(system) {
|
||||
var fadeOutDuration = 100;
|
||||
|
||||
var entrance = function(parent, newChild, settings) {
|
||||
return system.defer(function(dfd) {
|
||||
function endTransition() {
|
||||
dfd.resolve();
|
||||
}
|
||||
|
||||
function scrollIfNeeded() {
|
||||
if (!settings.keepScrollPosition) {
|
||||
$(document).scrollTop(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!newChild) {
|
||||
scrollIfNeeded();
|
||||
|
||||
if (settings.activeView) {
|
||||
$(settings.activeView).fadeOut(fadeOutDuration, function () {
|
||||
if (!settings.cacheViews) {
|
||||
ko.virtualElements.emptyNode(parent);
|
||||
}
|
||||
endTransition();
|
||||
});
|
||||
} else {
|
||||
if (!settings.cacheViews) {
|
||||
ko.virtualElements.emptyNode(parent);
|
||||
}
|
||||
endTransition();
|
||||
}
|
||||
} else {
|
||||
var $previousView = $(settings.activeView);
|
||||
var duration = settings.duration || 500;
|
||||
|
||||
function startTransition() {
|
||||
scrollIfNeeded();
|
||||
|
||||
if (settings.cacheViews) {
|
||||
if (settings.composingNewView) {
|
||||
ko.virtualElements.prepend(parent, newChild);
|
||||
}
|
||||
} else {
|
||||
ko.virtualElements.emptyNode(parent);
|
||||
ko.virtualElements.prepend(parent, newChild);
|
||||
}
|
||||
|
||||
var startValues = {
|
||||
marginLeft: '20px',
|
||||
marginRight: '-20px',
|
||||
opacity: 0,
|
||||
display: 'block'
|
||||
};
|
||||
|
||||
var endValues = {
|
||||
marginRight: 0,
|
||||
marginLeft: 0,
|
||||
opacity: 1
|
||||
};
|
||||
|
||||
$(newChild).css(startValues);
|
||||
$(newChild).animate(endValues, duration, 'swing', endTransition);
|
||||
}
|
||||
|
||||
if ($previousView.length) {
|
||||
$previousView.fadeOut(fadeOutDuration, startTransition);
|
||||
} else {
|
||||
startTransition();
|
||||
}
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
return entrance;
|
||||
});
|
|
@ -0,0 +1,67 @@
|
|||
define(['./system'], function (system) {
|
||||
var parseMarkupCore;
|
||||
|
||||
if ($.parseHTML) {
|
||||
parseMarkupCore = function(html) {
|
||||
return $.parseHTML(html);
|
||||
};
|
||||
} else {
|
||||
parseMarkupCore = function(html) {
|
||||
return $(html).get();
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
viewExtension: '.html',
|
||||
viewPlugin: 'text',
|
||||
isViewUrl: function (url) {
|
||||
return url.indexOf(this.viewExtension, url.length - this.viewExtension.length) !== -1;
|
||||
},
|
||||
convertViewUrlToViewId: function (url) {
|
||||
return url.substring(0, url.length - this.viewExtension.length);
|
||||
},
|
||||
convertViewIdToRequirePath: function (viewId) {
|
||||
return this.viewPlugin + '!' + viewId + this.viewExtension;
|
||||
},
|
||||
parseMarkup: function (markup) {
|
||||
var allElements = parseMarkupCore(markup);
|
||||
if (allElements.length == 1) {
|
||||
return allElements[0];
|
||||
}
|
||||
|
||||
var withoutCommentsOrEmptyText = [];
|
||||
|
||||
for (var i = 0; i < allElements.length; i++) {
|
||||
var current = allElements[i];
|
||||
if (current.nodeType != 8) {
|
||||
if (current.nodeType == 3) {
|
||||
var result = /\S/.test(current.nodeValue);
|
||||
if (!result) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
withoutCommentsOrEmptyText.push(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (withoutCommentsOrEmptyText.length > 1) {
|
||||
return $(withoutCommentsOrEmptyText).wrapAll('<div class="durandal-wrapper"></div>').parent().get(0);
|
||||
}
|
||||
|
||||
return withoutCommentsOrEmptyText[0];
|
||||
},
|
||||
createView: function(viewId) {
|
||||
var that = this;
|
||||
var requirePath = this.convertViewIdToRequirePath(viewId);
|
||||
|
||||
return system.defer(function(dfd) {
|
||||
system.acquire(requirePath).then(function(markup) {
|
||||
var element = that.parseMarkup(markup);
|
||||
element.setAttribute('data-view', viewId);
|
||||
dfd.resolve(element);
|
||||
});
|
||||
}).promise();
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,103 @@
|
|||
define(['./system', './viewEngine'],
|
||||
function (system, viewEngine) {
|
||||
|
||||
function findInElements(nodes, url) {
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var current = nodes[i];
|
||||
var existingUrl = current.getAttribute('data-view');
|
||||
if (existingUrl == url) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function escape(str) {
|
||||
return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
|
||||
}
|
||||
|
||||
return {
|
||||
useConvention: function(modulesPath, viewsPath, areasPath) {
|
||||
modulesPath = modulesPath || 'viewmodels';
|
||||
viewsPath = viewsPath || 'views';
|
||||
areasPath = areasPath || viewsPath;
|
||||
|
||||
var reg = new RegExp(escape(modulesPath), 'gi');
|
||||
|
||||
this.convertModuleIdToViewId = function (moduleId) {
|
||||
return moduleId.replace(reg, viewsPath);
|
||||
};
|
||||
|
||||
this.translateViewIdToArea = function (viewId, area) {
|
||||
if (!area || area == 'partial') {
|
||||
return areasPath + '/' + viewId;
|
||||
}
|
||||
|
||||
return areasPath + '/' + area + '/' + viewId;
|
||||
};
|
||||
},
|
||||
locateViewForObject: function(obj, elementsToSearch) {
|
||||
var view;
|
||||
|
||||
if (obj.getView) {
|
||||
view = obj.getView();
|
||||
if (view) {
|
||||
return this.locateView(view, null, elementsToSearch);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.viewUrl) {
|
||||
return this.locateView(obj.viewUrl, null, elementsToSearch);
|
||||
}
|
||||
|
||||
var id = system.getModuleId(obj);
|
||||
if (id) {
|
||||
return this.locateView(this.convertModuleIdToViewId(id), null, elementsToSearch);
|
||||
}
|
||||
|
||||
return this.locateView(this.determineFallbackViewId(obj), null, elementsToSearch);
|
||||
},
|
||||
convertModuleIdToViewId: function(moduleId) {
|
||||
return moduleId;
|
||||
},
|
||||
determineFallbackViewId: function (obj) {
|
||||
var funcNameRegex = /function (.{1,})\(/;
|
||||
var results = (funcNameRegex).exec((obj).constructor.toString());
|
||||
var typeName = (results && results.length > 1) ? results[1] : "";
|
||||
|
||||
return 'views/' + typeName;
|
||||
},
|
||||
translateViewIdToArea: function (viewId, area) {
|
||||
return viewId;
|
||||
},
|
||||
locateView: function(viewOrUrlOrId, area, elementsToSearch) {
|
||||
if (typeof viewOrUrlOrId === 'string') {
|
||||
var viewId;
|
||||
|
||||
if (viewEngine.isViewUrl(viewOrUrlOrId)) {
|
||||
viewId = viewEngine.convertViewUrlToViewId(viewOrUrlOrId);
|
||||
} else {
|
||||
viewId = viewOrUrlOrId;
|
||||
}
|
||||
|
||||
if (area) {
|
||||
viewId = this.translateViewIdToArea(viewId, area);
|
||||
}
|
||||
|
||||
if (elementsToSearch) {
|
||||
var existing = findInElements(elementsToSearch, viewId);
|
||||
if (existing) {
|
||||
return system.defer(function(dfd) {
|
||||
dfd.resolve(existing);
|
||||
}).promise();
|
||||
}
|
||||
}
|
||||
|
||||
return viewEngine.createView(viewId);
|
||||
}
|
||||
|
||||
return system.defer(function(dfd) {
|
||||
dfd.resolve(viewOrUrlOrId);
|
||||
}).promise();
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,445 @@
|
|||
define(['./system'], function (system) {
|
||||
var viewModel;
|
||||
|
||||
function ensureSettings(settings) {
|
||||
if (settings == undefined) {
|
||||
settings = {};
|
||||
}
|
||||
|
||||
if (!settings.closeOnDeactivate) {
|
||||
settings.closeOnDeactivate = viewModel.defaults.closeOnDeactivate;
|
||||
}
|
||||
|
||||
if (!settings.beforeActivate) {
|
||||
settings.beforeActivate = viewModel.defaults.beforeActivate;
|
||||
}
|
||||
|
||||
if (!settings.afterDeactivate) {
|
||||
settings.afterDeactivate = viewModel.defaults.afterDeactivate;
|
||||
}
|
||||
|
||||
if (!settings.interpretResponse) {
|
||||
settings.interpretResponse = viewModel.defaults.interpretResponse;
|
||||
}
|
||||
|
||||
if (!settings.areSameItem) {
|
||||
settings.areSameItem = viewModel.defaults.areSameItem;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
function deactivate(item, close, settings, dfd, setter) {
|
||||
if (item && item.deactivate) {
|
||||
system.log('Deactivating', item);
|
||||
|
||||
var result;
|
||||
try {
|
||||
result = item.deactivate(close);
|
||||
} catch(error) {
|
||||
system.log(error);
|
||||
dfd.resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && result.then) {
|
||||
result.then(function() {
|
||||
settings.afterDeactivate(item, close, setter);
|
||||
dfd.resolve(true);
|
||||
}, function(reason) {
|
||||
system.log(reason);
|
||||
dfd.resolve(false);
|
||||
});
|
||||
} else {
|
||||
settings.afterDeactivate(item, close, setter);
|
||||
dfd.resolve(true);
|
||||
}
|
||||
} else {
|
||||
if (item) {
|
||||
settings.afterDeactivate(item, close, setter);
|
||||
}
|
||||
|
||||
dfd.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
function activate(newItem, activeItem, callback, activationData) {
|
||||
if (newItem) {
|
||||
if (newItem.activate) {
|
||||
system.log('Activating', newItem);
|
||||
|
||||
var result;
|
||||
try {
|
||||
result = newItem.activate(activationData);
|
||||
} catch (error) {
|
||||
system.log(error);
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && result.then) {
|
||||
result.then(function() {
|
||||
activeItem(newItem);
|
||||
callback(true);
|
||||
}, function(reason) {
|
||||
system.log(reason);
|
||||
callback(false);
|
||||
});
|
||||
} else {
|
||||
activeItem(newItem);
|
||||
callback(true);
|
||||
}
|
||||
} else {
|
||||
activeItem(newItem);
|
||||
callback(true);
|
||||
}
|
||||
} else {
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
|
||||
function canDeactivateItem(item, close, settings) {
|
||||
return system.defer(function (dfd) {
|
||||
if (item && item.canDeactivate) {
|
||||
var resultOrPromise;
|
||||
try {
|
||||
resultOrPromise = item.canDeactivate(close);
|
||||
} catch(error) {
|
||||
system.log(error);
|
||||
dfd.resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultOrPromise.then) {
|
||||
resultOrPromise.then(function(result) {
|
||||
dfd.resolve(settings.interpretResponse(result));
|
||||
}, function(reason) {
|
||||
system.log(reason);
|
||||
dfd.resolve(false);
|
||||
});
|
||||
} else {
|
||||
dfd.resolve(settings.interpretResponse(resultOrPromise));
|
||||
}
|
||||
} else {
|
||||
dfd.resolve(true);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
function canActivateItem(newItem, activeItem, settings, activationData) {
|
||||
return system.defer(function (dfd) {
|
||||
if (newItem == activeItem()) {
|
||||
dfd.resolve(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newItem && newItem.canActivate) {
|
||||
var resultOrPromise;
|
||||
try {
|
||||
resultOrPromise = newItem.canActivate(activationData);
|
||||
} catch (error) {
|
||||
system.log(error);
|
||||
dfd.resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultOrPromise.then) {
|
||||
resultOrPromise.then(function(result) {
|
||||
dfd.resolve(settings.interpretResponse(result));
|
||||
}, function(reason) {
|
||||
system.log(reason);
|
||||
dfd.resolve(false);
|
||||
});
|
||||
} else {
|
||||
dfd.resolve(settings.interpretResponse(resultOrPromise));
|
||||
}
|
||||
} else {
|
||||
dfd.resolve(true);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
function createActivator(initialActiveItem, settings) {
|
||||
var activeItem = ko.observable(null);
|
||||
|
||||
settings = ensureSettings(settings);
|
||||
|
||||
var computed = ko.computed({
|
||||
read: function () {
|
||||
return activeItem();
|
||||
},
|
||||
write: function (newValue) {
|
||||
computed.viaSetter = true;
|
||||
computed.activateItem(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
computed.settings = settings;
|
||||
settings.activator = computed;
|
||||
|
||||
computed.isActivating = ko.observable(false);
|
||||
|
||||
computed.canDeactivateItem = function (item, close) {
|
||||
return canDeactivateItem(item, close, settings);
|
||||
};
|
||||
|
||||
computed.deactivateItem = function (item, close) {
|
||||
return system.defer(function(dfd) {
|
||||
computed.canDeactivateItem(item, close).then(function(canDeactivate) {
|
||||
if (canDeactivate) {
|
||||
deactivate(item, close, settings, dfd, activeItem);
|
||||
} else {
|
||||
computed.notifySubscribers();
|
||||
dfd.resolve(false);
|
||||
}
|
||||
});
|
||||
}).promise();
|
||||
};
|
||||
|
||||
computed.canActivateItem = function (newItem, activationData) {
|
||||
return canActivateItem(newItem, activeItem, settings, activationData);
|
||||
};
|
||||
|
||||
computed.activateItem = function (newItem, activationData) {
|
||||
var viaSetter = computed.viaSetter;
|
||||
computed.viaSetter = false;
|
||||
|
||||
return system.defer(function (dfd) {
|
||||
if (computed.isActivating()) {
|
||||
dfd.resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
computed.isActivating(true);
|
||||
|
||||
var currentItem = activeItem();
|
||||
if (settings.areSameItem(currentItem, newItem, activationData)) {
|
||||
computed.isActivating(false);
|
||||
dfd.resolve(true);
|
||||
return;
|
||||
}
|
||||
|
||||
computed.canDeactivateItem(currentItem, settings.closeOnDeactivate).then(function (canDeactivate) {
|
||||
if (canDeactivate) {
|
||||
computed.canActivateItem(newItem, activationData).then(function (canActivate) {
|
||||
if (canActivate) {
|
||||
system.defer(function (dfd2) {
|
||||
deactivate(currentItem, settings.closeOnDeactivate, settings, dfd2);
|
||||
}).promise().then(function () {
|
||||
newItem = settings.beforeActivate(newItem, activationData);
|
||||
activate(newItem, activeItem, function (result) {
|
||||
computed.isActivating(false);
|
||||
dfd.resolve(result);
|
||||
}, activationData);
|
||||
});
|
||||
} else {
|
||||
if (viaSetter) {
|
||||
computed.notifySubscribers();
|
||||
}
|
||||
|
||||
computed.isActivating(false);
|
||||
dfd.resolve(false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (viaSetter) {
|
||||
computed.notifySubscribers();
|
||||
}
|
||||
|
||||
computed.isActivating(false);
|
||||
dfd.resolve(false);
|
||||
}
|
||||
});
|
||||
}).promise();
|
||||
};
|
||||
|
||||
computed.canActivate = function () {
|
||||
var toCheck;
|
||||
|
||||
if (initialActiveItem) {
|
||||
toCheck = initialActiveItem;
|
||||
initialActiveItem = false;
|
||||
} else {
|
||||
toCheck = computed();
|
||||
}
|
||||
|
||||
return computed.canActivateItem(toCheck);
|
||||
};
|
||||
|
||||
computed.activate = function () {
|
||||
var toActivate;
|
||||
|
||||
if (initialActiveItem) {
|
||||
toActivate = initialActiveItem;
|
||||
initialActiveItem = false;
|
||||
} else {
|
||||
toActivate = computed();
|
||||
}
|
||||
|
||||
return computed.activateItem(toActivate);
|
||||
};
|
||||
|
||||
computed.canDeactivate = function (close) {
|
||||
return computed.canDeactivateItem(computed(), close);
|
||||
};
|
||||
|
||||
computed.deactivate = function (close) {
|
||||
return computed.deactivateItem(computed(), close);
|
||||
};
|
||||
|
||||
computed.includeIn = function (includeIn) {
|
||||
includeIn.canActivate = function () {
|
||||
return computed.canActivate();
|
||||
};
|
||||
|
||||
includeIn.activate = function () {
|
||||
return computed.activate();
|
||||
};
|
||||
|
||||
includeIn.canDeactivate = function (close) {
|
||||
return computed.canDeactivate(close);
|
||||
};
|
||||
|
||||
includeIn.deactivate = function (close) {
|
||||
return computed.deactivate(close);
|
||||
};
|
||||
};
|
||||
|
||||
if (settings.includeIn) {
|
||||
computed.includeIn(settings.includeIn);
|
||||
} else if (initialActiveItem) {
|
||||
computed.activate();
|
||||
}
|
||||
|
||||
computed.forItems = function (items) {
|
||||
settings.closeOnDeactivate = false;
|
||||
|
||||
settings.determineNextItemToActivate = function (list, lastIndex) {
|
||||
var toRemoveAt = lastIndex - 1;
|
||||
|
||||
if (toRemoveAt == -1 && list.length > 1) {
|
||||
return list[1];
|
||||
}
|
||||
|
||||
if (toRemoveAt > -1 && toRemoveAt < list.length - 1) {
|
||||
return list[toRemoveAt];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
settings.beforeActivate = function (newItem) {
|
||||
var currentItem = computed();
|
||||
|
||||
if (!newItem) {
|
||||
newItem = settings.determineNextItemToActivate(items, currentItem ? items.indexOf(currentItem) : 0);
|
||||
} else {
|
||||
var index = items.indexOf(newItem);
|
||||
|
||||
if (index == -1) {
|
||||
items.push(newItem);
|
||||
} else {
|
||||
newItem = items()[index];
|
||||
}
|
||||
}
|
||||
|
||||
return newItem;
|
||||
};
|
||||
|
||||
settings.afterDeactivate = function (oldItem, close) {
|
||||
if (close) {
|
||||
items.remove(oldItem);
|
||||
}
|
||||
};
|
||||
|
||||
var originalCanDeactivate = computed.canDeactivate;
|
||||
computed.canDeactivate = function (close) {
|
||||
if (close) {
|
||||
return system.defer(function (dfd) {
|
||||
var list = items();
|
||||
var results = [];
|
||||
|
||||
function finish() {
|
||||
for (var j = 0; j < results.length; j++) {
|
||||
if (!results[j]) {
|
||||
dfd.resolve(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dfd.resolve(true);
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
computed.canDeactivateItem(list[i], close).then(function (result) {
|
||||
results.push(result);
|
||||
if (results.length == list.length) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).promise();
|
||||
} else {
|
||||
return originalCanDeactivate();
|
||||
}
|
||||
};
|
||||
|
||||
var originalDeactivate = computed.deactivate;
|
||||
computed.deactivate = function (close) {
|
||||
if (close) {
|
||||
return system.defer(function (dfd) {
|
||||
var list = items();
|
||||
var results = 0;
|
||||
var listLength = list.length;
|
||||
|
||||
function doDeactivate(item) {
|
||||
computed.deactivateItem(item, close).then(function () {
|
||||
results++;
|
||||
items.remove(item);
|
||||
if (results == listLength) {
|
||||
dfd.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < listLength; i++) {
|
||||
doDeactivate(list[i]);
|
||||
}
|
||||
}).promise();
|
||||
} else {
|
||||
return originalDeactivate();
|
||||
}
|
||||
};
|
||||
|
||||
return computed;
|
||||
};
|
||||
|
||||
return computed;
|
||||
}
|
||||
|
||||
return viewModel = {
|
||||
defaults: {
|
||||
closeOnDeactivate: true,
|
||||
interpretResponse: function (value) {
|
||||
if (typeof value == 'string') {
|
||||
var lowered = value.toLowerCase();
|
||||
return lowered == 'yes' || lowered == 'ok';
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
areSameItem: function (currentItem, newItem, activationData) {
|
||||
return currentItem == newItem;
|
||||
},
|
||||
beforeActivate: function (newItem) {
|
||||
return newItem;
|
||||
},
|
||||
afterDeactivate: function (item, close, setter) {
|
||||
if (close && setter) {
|
||||
setter(null);
|
||||
}
|
||||
}
|
||||
},
|
||||
activator: createActivator
|
||||
};
|
||||
});
|
|
@ -0,0 +1,76 @@
|
|||
define(['./system'], function (system) {
|
||||
var viewModelBinder;
|
||||
var insufficientInfoMessage = 'Insufficient Information to Bind';
|
||||
var unexpectedViewMessage = 'Unexpected View Type';
|
||||
|
||||
function doBind(obj, view, action) {
|
||||
if (!view || !obj) {
|
||||
if (viewModelBinder.throwOnErrors) {
|
||||
throw new Error(insufficientInfoMessage);
|
||||
} else {
|
||||
system.log(insufficientInfoMessage, view, obj);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!view.getAttribute) {
|
||||
if (viewModelBinder.throwOnErrors) {
|
||||
throw new Error(unexpectedViewMessage);
|
||||
} else {
|
||||
system.log(unexpectedViewMessage, view, obj);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var viewName = view.getAttribute('data-view');
|
||||
|
||||
try {
|
||||
system.log('Binding', viewName, obj);
|
||||
|
||||
viewModelBinder.beforeBind(obj, view);
|
||||
action();
|
||||
viewModelBinder.afterBind(obj, view);
|
||||
} catch (e) {
|
||||
if (viewModelBinder.throwOnErrors) {
|
||||
throw new Error(e.message + ';\nView: ' + viewName + ";\nModuleId: " + system.getModuleId(obj));
|
||||
} else {
|
||||
system.log(e.message, viewName, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return viewModelBinder = {
|
||||
beforeBind: system.noop,
|
||||
afterBind:system.noop,
|
||||
bindContext: function(bindingContext, view, obj) {
|
||||
if (obj) {
|
||||
bindingContext = bindingContext.createChildContext(obj);
|
||||
}
|
||||
|
||||
doBind(bindingContext, view, function () {
|
||||
if (obj && obj.beforeBind) {
|
||||
obj.beforeBind(view);
|
||||
}
|
||||
|
||||
ko.applyBindings(bindingContext, view);
|
||||
|
||||
if (obj && obj.afterBind) {
|
||||
obj.afterBind(view);
|
||||
}
|
||||
});
|
||||
},
|
||||
bind: function(obj, view) {
|
||||
doBind(obj, view, function () {
|
||||
if (obj.beforeBind) {
|
||||
obj.beforeBind(view);
|
||||
}
|
||||
|
||||
ko.applyBindings(obj, view);
|
||||
|
||||
if (obj.afterBind) {
|
||||
obj.afterBind(view);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,131 @@
|
|||
define(['./system', './composition'], function (system, composition) {
|
||||
|
||||
var widgetPartAttribute = 'data-part',
|
||||
widgetPartSelector = '[' + widgetPartAttribute + ']';
|
||||
|
||||
var kindModuleMaps = {},
|
||||
kindViewMaps = {},
|
||||
bindableSettings = ['model','view','kind'];
|
||||
|
||||
var widget = {
|
||||
getParts: function(elements) {
|
||||
var parts = {};
|
||||
|
||||
if (!system.isArray(elements)) {
|
||||
elements = [elements];
|
||||
}
|
||||
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var element = elements[i];
|
||||
|
||||
if (element.getAttribute) {
|
||||
var id = element.getAttribute(widgetPartAttribute);
|
||||
if (id) {
|
||||
parts[id] = element;
|
||||
}
|
||||
|
||||
var childParts = $(widgetPartSelector, element);
|
||||
|
||||
for (var j = 0; j < childParts.length; j++) {
|
||||
var part = childParts.get(j);
|
||||
parts[part.getAttribute(widgetPartAttribute)] = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parts;
|
||||
},
|
||||
getSettings: function(valueAccessor) {
|
||||
var value = ko.utils.unwrapObservable(valueAccessor()) || {};
|
||||
|
||||
if (typeof value == 'string') {
|
||||
return value;
|
||||
} else {
|
||||
for (var attrName in value) {
|
||||
if (ko.utils.arrayIndexOf(bindableSettings, attrName) != -1) {
|
||||
value[attrName] = ko.utils.unwrapObservable(value[attrName]);
|
||||
} else {
|
||||
value[attrName] = value[attrName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
registerKind: function(kind) {
|
||||
ko.bindingHandlers[kind] = {
|
||||
init: function() {
|
||||
return { controlsDescendantBindings: true };
|
||||
},
|
||||
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
||||
var settings = widget.getSettings(valueAccessor);
|
||||
settings.kind = kind;
|
||||
widget.create(element, settings, bindingContext);
|
||||
}
|
||||
};
|
||||
|
||||
ko.virtualElements.allowedBindings[kind] = true;
|
||||
},
|
||||
mapKind: function(kind, viewId, moduleId) {
|
||||
if (viewId) {
|
||||
kindViewMaps[kind] = viewId;
|
||||
}
|
||||
|
||||
if (moduleId) {
|
||||
kindModuleMaps[kind] = moduleId;
|
||||
}
|
||||
},
|
||||
convertKindToModuleId: function(kind) {
|
||||
return kindModuleMaps[kind] || 'durandal/widgets/' + kind + '/controller';
|
||||
},
|
||||
convertKindToViewId: function (kind) {
|
||||
return kindViewMaps[kind] || 'durandal/widgets/' + kind + '/view';
|
||||
},
|
||||
beforeBind: function(element, view, settings) {
|
||||
var replacementParts = widget.getParts(element);
|
||||
var standardParts = widget.getParts(view);
|
||||
|
||||
for (var partId in replacementParts) {
|
||||
$(standardParts[partId]).replaceWith(replacementParts[partId]);
|
||||
}
|
||||
},
|
||||
createCompositionSettings: function(settings) {
|
||||
if (!settings.model) {
|
||||
settings.model = this.convertKindToModuleId(settings.kind);
|
||||
}
|
||||
|
||||
if (!settings.view) {
|
||||
settings.view = this.convertKindToViewId(settings.kind);
|
||||
}
|
||||
|
||||
settings.preserveContext = true;
|
||||
settings.beforeBind = this.beforeBind;
|
||||
|
||||
return settings;
|
||||
},
|
||||
create: function (element, settings, bindingContext) {
|
||||
if (typeof settings == 'string') {
|
||||
settings = {
|
||||
kind: settings
|
||||
};
|
||||
}
|
||||
|
||||
var compositionSettings = widget.createCompositionSettings(settings);
|
||||
composition.compose(element, compositionSettings, bindingContext);
|
||||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.widget = {
|
||||
init: function() {
|
||||
return { controlsDescendantBindings: true };
|
||||
},
|
||||
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
||||
var settings = widget.getSettings(valueAccessor);
|
||||
widget.create(element, settings, bindingContext);
|
||||
}
|
||||
};
|
||||
|
||||
ko.virtualElements.allowedBindings.widget = true;
|
||||
|
||||
return widget;
|
||||
});
|
|
@ -0,0 +1,57 @@
|
|||
require.config({
|
||||
paths: { "text": "durandal/amd/text" }
|
||||
});
|
||||
|
||||
define(function (require) {
|
||||
var system = require('durandal/system'),
|
||||
app = require('durandal/app'),
|
||||
router = require('durandal/plugins/router'),
|
||||
viewLocator = require('durandal/viewLocator'),
|
||||
logger = require('services/logger'),
|
||||
dataservice = require('services/dataservice'),
|
||||
context = require('services/context'),
|
||||
base = require('viewmodels/base'),
|
||||
enums = require('services/enums'),
|
||||
notifications = require('services/notifications');
|
||||
|
||||
system.debug(true);
|
||||
|
||||
$.ajaxSetup({
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
error: function (xmlHttpRequest, type, errorThrown) {
|
||||
if (xmlHttpRequest.status == 0) return;
|
||||
base.hideLoading(true);
|
||||
app.showMessage('There was an error, try again later', 'Error', [enums.options.ok]);
|
||||
logger.log(xmlHttpRequest.responseText, type, xmlHttpRequest);
|
||||
},
|
||||
});
|
||||
|
||||
dataservice.getLoggedEmployeeInfo(enums.pictureType.small).then(function (employee) {
|
||||
context.currentUser = employee;
|
||||
|
||||
app.start().then(function () {
|
||||
// route will use conventions for modules
|
||||
// assuming viewmodels/views folder structure
|
||||
router.useConvention();
|
||||
viewLocator.useConvention();
|
||||
|
||||
notifications.startConnection();
|
||||
|
||||
app.title = 'MyCompany';
|
||||
app.setRoot('viewmodels/shell');
|
||||
|
||||
router.handleInvalidRoute = function (route, params) {
|
||||
logger.log('No route found', route, 'main');
|
||||
};
|
||||
|
||||
// handle escape key for modal dialogs
|
||||
$(document).keyup(function (e) {
|
||||
// esc
|
||||
if (e.keyCode == 27) {
|
||||
$(".button-close").last().click();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
define(function () {
|
||||
function openLync(email) {
|
||||
// open the sip link in a new window instead of put an href
|
||||
// to avoid IE11 open a blank page
|
||||
var newWindow = window.open('sip:' + email);
|
||||
if (newWindow)
|
||||
newWindow.close();
|
||||
}
|
||||
|
||||
var communicatorService = {
|
||||
openLync: openLync
|
||||
};
|
||||
|
||||
return communicatorService;
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
define(['config'], function (config) {
|
||||
var user = {};
|
||||
|
||||
var context = {
|
||||
currentUser: user,
|
||||
};
|
||||
|
||||
return context;
|
||||
});
|
|
@ -0,0 +1,446 @@
|
|||
define(['services/logger', 'durandal/system', 'services/model'], function (logger, system, model) {
|
||||
var apiBaseUrl = 'api/';
|
||||
|
||||
var getLoggedEmployeeInfo = function (pictureType) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'GET',
|
||||
cache: false,
|
||||
url: apiBaseUrl + 'Employees/current/' + pictureType
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
var employee = new model.Employee(data);
|
||||
log('Retrieved current user from remote data source', data);
|
||||
deferred.resolve(employee);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getEmployee = function (employeeId, pictureType) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'employees/' + employeeId + '/' + pictureType
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
var employee = new model.Employee(data);
|
||||
deferred.resolve(employee);
|
||||
|
||||
log('Retrieved employee', data);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getVisitors = function (parameters, cache) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'visitors?' +
|
||||
'filter=' + parameters.filter +
|
||||
'&pictureType=' + parameters.pictureType +
|
||||
'&pageSize=' + parameters.pageSize +
|
||||
'&pageCount=' + parameters.pageCount,
|
||||
cache: cache ? cache : true
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
var visitors = [];
|
||||
var length = data.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var visitor = new model.Visitor(data[i]);
|
||||
visitors.push(visitor);
|
||||
}
|
||||
|
||||
deferred.resolve(visitors);
|
||||
log('Retrieved visitors from remote data source', visitors);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getVisitorsCount = function (filter) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'visitors/count?' +
|
||||
'filter=' + filter
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
deferred.resolve(data);
|
||||
log('Retrieved visitors count from remote data source', data);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var deleteVisitor = function (visitorId) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'DELETE',
|
||||
url: apiBaseUrl + 'visitors/' + visitorId
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded() {
|
||||
deferred.resolve();
|
||||
log('Deleted visitor with id ' + visitorId, null);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var addVisitor = function (visitor, file) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'POST',
|
||||
data: ko.toJSON(visitor),
|
||||
url: apiBaseUrl + 'visitors'
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(id) {
|
||||
var v = visitor();
|
||||
v.visitorId(id);
|
||||
log('Added visitor', v);
|
||||
|
||||
if (file && file.selection) {
|
||||
uploadPicture(file, id)
|
||||
.then(function () {
|
||||
deferred.resolve(v);
|
||||
}).fail(function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
deferred.resolve(v);
|
||||
}
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var updateVisitor = function (visitor, file) {
|
||||
return system.defer(function (deferred) {
|
||||
delete visitor().visits;
|
||||
|
||||
var options = {
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(ko.mapping.toJS(visitor)),
|
||||
url: apiBaseUrl + 'visitors'
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded() {
|
||||
log('Updated visitor with id ' + visitor().visitorId(), visitor);
|
||||
|
||||
if (file && file.selection) {
|
||||
uploadPicture(file, visitor().visitorId())
|
||||
.then(function () {
|
||||
deferred.resolve(visitor);
|
||||
}).fail(function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
deferred.resolve(visitor);
|
||||
}
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getVisitorPicture = function (visitorId, pictureType) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'VisitorPictures/' + visitorId + '/' + pictureType
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
if (data) {
|
||||
deferred.resolve('data:image/jpeg;base64,' + data);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
log('Retrieved visitor picture', data);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getVisits = function (parameters, cache) {
|
||||
return system.defer(function (deferred) {
|
||||
var localeDate = moment().subtract('hours', 1).toDate();
|
||||
var date = new Date(localeDate.getUTCFullYear(), localeDate.getUTCMonth(), localeDate.getUTCDate(), localeDate.getUTCHours(), localeDate.getUTCMinutes(), localeDate.getUTCSeconds());
|
||||
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'visits/user?' +
|
||||
'filter=' + parameters.filter +
|
||||
'&pictureType=' + parameters.pictureType +
|
||||
'&pageSize=' + parameters.pageSize +
|
||||
'&pageCount=' + parameters.pageCount +
|
||||
'&dateFilter=' + date.toJSON(),
|
||||
cache: cache ? cache : true
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
var visits = [];
|
||||
var length = data.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var visit = new model.Visit(data[i], true);
|
||||
visits.push(visit);
|
||||
}
|
||||
|
||||
deferred.resolve(visits);
|
||||
log('Retrieved visits from remote data source', visits);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getVisit = function (visitId, pictureType) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'visits/' + visitId + '/' + pictureType
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
var visit = new model.Visit(data, true);
|
||||
|
||||
deferred.resolve(visit);
|
||||
log('Retrieved visit from remote data source', visit);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var getVisitsCount = function (filter) {
|
||||
return system.defer(function (deferred) {
|
||||
var localeDate = moment().subtract('hours', 1).toDate();
|
||||
var date = new Date(localeDate.getUTCFullYear(), localeDate.getUTCMonth(), localeDate.getUTCDate(), localeDate.getUTCHours(), localeDate.getUTCMinutes(), localeDate.getUTCSeconds());
|
||||
|
||||
var options = {
|
||||
type: 'GET',
|
||||
url: apiBaseUrl + 'visits/user/count?' +
|
||||
'filter=' + filter +
|
||||
'&dateFilter=' + date.toJSON()
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(data) {
|
||||
deferred.resolve(data);
|
||||
log('Retrieved visitors count from remote data source', data);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var deleteVisit = function (visitId) {
|
||||
return system.defer(function (deferred) {
|
||||
var options = {
|
||||
type: 'DELETE',
|
||||
url: apiBaseUrl + 'visits/' + visitId
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded() {
|
||||
deferred.resolve();
|
||||
log('Deleted visit with id ' + visitId, null);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var addVisit = function (visit) {
|
||||
return system.defer(function (deferred) {
|
||||
visit().employee = null;
|
||||
visit().visitor = null;
|
||||
|
||||
var options = {
|
||||
type: 'POST',
|
||||
data: ko.toJSON(visit),
|
||||
url: apiBaseUrl + 'visits'
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded(id) {
|
||||
var v = visit();
|
||||
v.visitId(id);
|
||||
log('Added visit', v);
|
||||
deferred.resolve(v);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
var updateVisit = function (visit) {
|
||||
return system.defer(function (deferred) {
|
||||
var v = ko.mapping.toJS(visit);
|
||||
v.employee = null;
|
||||
v.visitor = null;
|
||||
|
||||
var options = {
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(v),
|
||||
url: apiBaseUrl + 'visits'
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(succeeded)
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
function succeeded() {
|
||||
log('Updated visit with id ' + visit().visitId(), visit);
|
||||
deferred.resolve(visit);
|
||||
}
|
||||
}).promise();
|
||||
};
|
||||
|
||||
//var getVisitorCRMDetails = function (visitorId) {
|
||||
// return system.defer(function (deferred) {
|
||||
// var options = {
|
||||
// type: 'GET',
|
||||
// url: apiBaseUrl + 'crm/' + visitorId
|
||||
// };
|
||||
// $.ajax(options)
|
||||
// .then(succeeded)
|
||||
// .fail(function (jqXHR, textStatus) {
|
||||
// failed(jqXHR, textStatus);
|
||||
// deferred.reject();
|
||||
// });
|
||||
|
||||
// function succeeded(data) {
|
||||
// deferred.resolve(data);
|
||||
// log('Retrieved CRM data', data);
|
||||
// }
|
||||
// }).promise();
|
||||
//};
|
||||
|
||||
var dataservice = {
|
||||
getLoggedEmployeeInfo: getLoggedEmployeeInfo,
|
||||
getEmployee: getEmployee,
|
||||
getVisitors: getVisitors,
|
||||
getVisitorsCount: getVisitorsCount,
|
||||
deleteVisitor: deleteVisitor,
|
||||
addVisitor: addVisitor,
|
||||
updateVisitor: updateVisitor,
|
||||
getVisitorPicture: getVisitorPicture,
|
||||
getVisits: getVisits,
|
||||
getVisitsCount: getVisitsCount,
|
||||
deleteVisit: deleteVisit,
|
||||
addVisit: addVisit,
|
||||
updateVisit: updateVisit,
|
||||
getVisit: getVisit,
|
||||
//getVisitorCRMDetails: getVisitorCRMDetails
|
||||
};
|
||||
|
||||
return dataservice;
|
||||
|
||||
//#region Internal methods
|
||||
|
||||
function log(msg, data) {
|
||||
logger.log(msg, data, system.getModuleId(dataservice));
|
||||
}
|
||||
|
||||
function failed(jqXHR, textStatus) {
|
||||
var msg = 'Error getting data. ' + textStatus;
|
||||
logger.log(msg, jqXHR, system.getModuleId(dataservice));
|
||||
}
|
||||
|
||||
function uploadPicture(file, visitorId) {
|
||||
return system.defer(function (deferred) {
|
||||
var data = new FormData();
|
||||
data.append('image-file', file.data);
|
||||
if (visitorId)
|
||||
data.append('visitorId', visitorId);
|
||||
if (file.selection)
|
||||
data.append('image-crop', JSON.stringify(file.selection));
|
||||
|
||||
var options = {
|
||||
type: 'POST',
|
||||
data: data,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
url: apiBaseUrl + 'visitorpictures/pictures'
|
||||
};
|
||||
$.ajax(options)
|
||||
.then(function () {
|
||||
deferred.resolve();
|
||||
log('Upload picture');
|
||||
})
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
failed(jqXHR, textStatus);
|
||||
deferred.reject();
|
||||
}
|
||||
);
|
||||
}).promise();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
define(function () {
|
||||
var pictureType = {
|
||||
small: 1,
|
||||
big: 2
|
||||
};
|
||||
|
||||
var options = {
|
||||
ok: 'ok',
|
||||
cancel: 'cancel',
|
||||
yes: 'yes',
|
||||
no: 'no',
|
||||
close: 'close'
|
||||
};
|
||||
|
||||
var enums = {
|
||||
pictureType: pictureType,
|
||||
options: options
|
||||
};
|
||||
|
||||
return enums;
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
define(['durandal/system'],
|
||||
function (system) {
|
||||
var logger = {
|
||||
log: log
|
||||
};
|
||||
|
||||
return logger;
|
||||
|
||||
function log(message, data, source) {
|
||||
source = source ? '[' + source + '] ' : '';
|
||||
if (data) {
|
||||
system.log(source, message, data);
|
||||
} else {
|
||||
system.log(source, message);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,148 @@
|
|||
define(['config'], function (config) {
|
||||
var Visitor = function (entity) {
|
||||
var visitor = this;
|
||||
|
||||
visitor.visitorId = entity && entity.VisitorId;
|
||||
visitor.firstName = entity && entity.FirstName;
|
||||
visitor.lastName = entity && entity.LastName;
|
||||
visitor.pictureContent = entity && entity.VisitorPictures && entity.VisitorPictures.length > 0 && entity.VisitorPictures[0].Content;
|
||||
visitor.company = entity && entity.Company;
|
||||
visitor.personalId = entity && entity.PersonalId;
|
||||
visitor.email = entity && entity.Email;
|
||||
visitor.position = entity && entity.Position;
|
||||
visitor.createdDateTime = entity && entity.CreatedDateTime;
|
||||
visitor.lastModifiedDateTime = entity && entity.LastModifiedDateTime;
|
||||
visitor.crmAccountManager = entity && entity.CrmAccountManager;
|
||||
visitor.crmLeads = entity && entity.CrmLeads;
|
||||
|
||||
visitor.visits = [undefined, undefined, undefined, undefined];
|
||||
if (entity && entity.Visits && entity.Visits.length > 0) {
|
||||
for (var i = 0; i < entity.Visits.length; i++) {
|
||||
visitor.visits[i] = new Visit(entity.Visits[i]);
|
||||
}
|
||||
}
|
||||
visitor.lastVisit = entity && entity.LastVisit ? new Visit(entity.LastVisit, false) : new Visit(null, false);
|
||||
|
||||
visitor = ko.mapping.fromJS(visitor);
|
||||
visitor = addVisitorComputeds(visitor);
|
||||
visitor = addVisitorValidations(visitor);
|
||||
|
||||
return visitor;
|
||||
};
|
||||
|
||||
var Visit = function (entity, includeVisitor) {
|
||||
var visit = this;
|
||||
|
||||
visit.visitId = entity && entity.VisitId;
|
||||
visit.visitDateTime = (entity && entity.VisitDateTime) ? new Date(entity.VisitDateTime + '+00:00') : new Date();
|
||||
visit.createdDateTime = entity && entity.CreatedDateTime;
|
||||
visit.comments = entity && entity.Comments;
|
||||
visit.plate = entity && entity.Plate;
|
||||
visit.hasCar = entity && entity.HasCar;
|
||||
visit.visitorId = entity && entity.VisitorId;
|
||||
visit.employeeId = entity && entity.EmployeeId;
|
||||
|
||||
visit.employee = new Employee(entity && entity.Employee);
|
||||
|
||||
if (includeVisitor) {
|
||||
visit.visitor = ko.observable(new Visitor(entity && entity.Visitor));
|
||||
} else {
|
||||
visit.visitor = ko.observable({});
|
||||
}
|
||||
|
||||
visit = ko.mapping.fromJS(visit);
|
||||
visit = addVisitComputeds(visit);
|
||||
visit = addVisitValidations(visit);
|
||||
|
||||
return visit;
|
||||
};
|
||||
|
||||
var Employee = function (entity) {
|
||||
var employee = this;
|
||||
|
||||
employee.employeeId = entity && entity.EmployeeId;
|
||||
employee.firstName = entity && entity.FirstName;
|
||||
employee.lastName = entity && entity.LastName;
|
||||
employee.pictureContent = entity && entity.EmployeePictures && entity.EmployeePictures.length > 0 ? entity.EmployeePictures[0].Content : null;
|
||||
employee.position = entity && entity.JobTitle;
|
||||
employee.email = entity && entity.Email;
|
||||
|
||||
return addEmployeeComputeds(ko.mapping.fromJS(employee));
|
||||
};
|
||||
|
||||
var model = {
|
||||
Visitor: Visitor,
|
||||
Visit: Visit,
|
||||
Employee: Employee
|
||||
};
|
||||
|
||||
return model;
|
||||
|
||||
//#region Internal methods
|
||||
|
||||
function addEmployeeComputeds(entity) {
|
||||
entity.fullName = ko.computed(function () {
|
||||
return ((entity.firstName() || '') + ' ' + (entity.lastName() || '')).trim();
|
||||
});
|
||||
entity.picture = ko.computed(function () {
|
||||
var content = entity.pictureContent();
|
||||
return content ? 'data:image/jpeg;base64,' + content : config.defaultPicture;
|
||||
});
|
||||
return entity;
|
||||
}
|
||||
|
||||
function addVisitorComputeds(entity) {
|
||||
entity.fullName = ko.computed(function () {
|
||||
return (entity.firstName() || '') + ' ' + (entity.lastName() || '');
|
||||
});
|
||||
entity.picture = ko.computed(function () {
|
||||
var content = entity.pictureContent();
|
||||
return content ? 'data:image/jpeg;base64,' + content : config.defaultPicture;
|
||||
});
|
||||
entity.nextVisit = ko.computed(function () {
|
||||
if (entity.visits()[0]) {
|
||||
return entity.visits()[0];
|
||||
} else {
|
||||
return new Visit();
|
||||
}
|
||||
});
|
||||
return entity;
|
||||
}
|
||||
|
||||
function addVisitComputeds(entity) {
|
||||
entity.displayDate = ko.computed(function () {
|
||||
if (!entity.visitId()) return ' - ';
|
||||
|
||||
var date = moment.utc(entity.visitDateTime().toUTCString());
|
||||
return entity.visitDateTime() && date.isValid() ? date.local().format(config.dateFormat) : ' - ';
|
||||
});
|
||||
entity.displayTime = ko.computed(function () {
|
||||
if (!entity.visitId()) return ' - ';
|
||||
|
||||
var date = moment.utc(entity.visitDateTime().toUTCString());
|
||||
return entity.visitDateTime() && date.isValid() ? date.local().format(config.timeFormat) : ' - ';
|
||||
});
|
||||
return entity;
|
||||
}
|
||||
|
||||
function addVisitorValidations(entity) {
|
||||
entity.firstName.extend({ required: true });
|
||||
entity.lastName.extend({ required: true });
|
||||
entity.company.extend({ required: true });
|
||||
entity.email.extend({ required: true, email: true });
|
||||
|
||||
entity["errors"] = ko.validation.group(entity); // ko.validatedObservable()
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
function addVisitValidations(entity) {
|
||||
entity.visitDateTime.extend({ date: true });
|
||||
entity.visitorId.extend({ required: true });
|
||||
|
||||
entity["errors"] = ko.validation.group(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
define(['services/logger', 'config', 'durandal/plugins/router'], function (logger, config, router) {
|
||||
function navigateTo(url) {
|
||||
if (!url) return;
|
||||
|
||||
url = config.isNoAuth ? 'noauth' + url : url;
|
||||
router.navigateTo(url);
|
||||
}
|
||||
|
||||
function back() {
|
||||
router.navigateBack();
|
||||
}
|
||||
|
||||
var navigationService = {
|
||||
navigateTo: navigateTo,
|
||||
back: back
|
||||
};
|
||||
|
||||
return navigationService;
|
||||
});
|
|
@ -0,0 +1,77 @@
|
|||
define(['services/logger', 'services/navigation'], function (logger, navigation) {
|
||||
var notificationHub = $.connection.visitorsNotificationHub,
|
||||
notificationOptions = {
|
||||
"debug": false,
|
||||
"positionClass": "toast-top-full-width",
|
||||
"fadeIn": 300,
|
||||
"fadeOut": 1000,
|
||||
"timeOut": 0,
|
||||
"extendedTimeOut": 1000
|
||||
},
|
||||
subscriptions = {};
|
||||
|
||||
function subscribe(event, source, callback) {
|
||||
if (!subscriptions[event])
|
||||
subscriptions[event] = {};
|
||||
|
||||
subscriptions[event][source] = callback;
|
||||
};
|
||||
|
||||
function executeCallbacks(event) {
|
||||
if (!subscriptions[event])
|
||||
return;
|
||||
|
||||
var args = Array.prototype.slice.apply(arguments).slice(1, arguments.length);
|
||||
//var args = arguments.slice(1, arguments.length);
|
||||
|
||||
for (var source in subscriptions[event]) {
|
||||
|
||||
var func = subscriptions[event][source];
|
||||
if(func)
|
||||
func.apply(null, args);
|
||||
}
|
||||
}
|
||||
|
||||
function notifyVisitArrived(visit) {
|
||||
toastr.options = notificationOptions;
|
||||
var url = '#/visits?visitId=' + visit.VisitId;
|
||||
toastr.options.onclick = function (e) {
|
||||
navigation.navigateTo(url);
|
||||
toastr.clear($toast);
|
||||
return true;
|
||||
};
|
||||
|
||||
var message = visit.Visitor.FirstName + ' ' + visit.Visitor.LastName + ' has arrived.';
|
||||
var $toast = toastr["info"](message);
|
||||
|
||||
executeCallbacks('visitArrived', visit);
|
||||
};
|
||||
|
||||
function notifyVisitorPicturesChanged(visitorPictures) {
|
||||
executeCallbacks('visitorPicturesChanged', visitorPictures);
|
||||
};
|
||||
|
||||
function startConnection() {
|
||||
if (notificationHub) {
|
||||
notificationHub.client.notifyVisitArrived = notifyVisitArrived;
|
||||
notificationHub.client.notifyVisitorPicturesChanged = notifyVisitorPicturesChanged;
|
||||
|
||||
$.connection.hub.start().done(function (myHubConnection) {
|
||||
if ($.connection.hub.state == 1) {
|
||||
logger.log("connected");
|
||||
}
|
||||
}).fail(function (err) {
|
||||
logger.log(err);
|
||||
});
|
||||
} else {
|
||||
logger.log('notification hub unavailable');
|
||||
}
|
||||
}
|
||||
|
||||
var notificationService = {
|
||||
startConnection: startConnection,
|
||||
subscribe: subscribe
|
||||
};
|
||||
|
||||
return notificationService;
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
define(function () {
|
||||
var isBusy = ko.observable(false).extend({ throttle: 300 }),
|
||||
pendingActions = 0;
|
||||
|
||||
var vm = {
|
||||
showLoading: showLoading,
|
||||
hideLoading: hideLoading,
|
||||
isBusy: isBusy
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function showLoading() {
|
||||
pendingActions++;
|
||||
isBusy(true);
|
||||
}
|
||||
|
||||
function hideLoading(forceIgnoringPendingActions) {
|
||||
setTimeout(function () {
|
||||
if (forceIgnoringPendingActions) {
|
||||
pendingActions = 0;
|
||||
} else {
|
||||
if (pendingActions > 0)
|
||||
pendingActions--;
|
||||
}
|
||||
|
||||
if (pendingActions == 0) {
|
||||
isBusy(false);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
});
|
|
@ -0,0 +1,123 @@
|
|||
define(['services/model', 'services/dataservice', 'services/enums', 'viewmodels/base', 'durandal/system'],
|
||||
function (model, dataservice, enums, base, system) {
|
||||
var steps = {
|
||||
selectBigSize: { id: 1, minSelectionWidth: 280, minSelectionHeight: 380 },
|
||||
selectSmallSize: { id: 2, minSelectionWidth: 100, minSelectionHeight: 100, maxSelectionWidth: 200, maxSelectionHeight: 200 }
|
||||
};
|
||||
|
||||
var image = ko.observable(),
|
||||
title = ko.observable(),
|
||||
actionText = ko.observable(),
|
||||
step,
|
||||
bigSelection,
|
||||
cropControl,
|
||||
$image;
|
||||
|
||||
var vm = {
|
||||
activate: activate,
|
||||
viewAttached: viewAttached,
|
||||
title: title,
|
||||
actionText: actionText,
|
||||
close: close,
|
||||
accept: accept,
|
||||
image: image,
|
||||
imageLoaded: imageLoaded
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate(routeData) {
|
||||
if (routeData && routeData.picture) {
|
||||
step = steps.selectBigSize;
|
||||
title('1/2 Select your big size image');
|
||||
actionText('Next');
|
||||
image(routeData.picture);
|
||||
} else {
|
||||
// show error message
|
||||
}
|
||||
};
|
||||
|
||||
function viewAttached() {
|
||||
$image = $('.crop');
|
||||
|
||||
setTimeout(function () {
|
||||
var coords = getInitialCoords();
|
||||
|
||||
cropControl = $image.imgAreaSelect({
|
||||
aspectRatio: step.minSelectionWidth + ':' + step.minSelectionHeight,
|
||||
minWidth: step.minSelectionWidth,
|
||||
minHeight: step.minSelectionHeight,
|
||||
handles: true,
|
||||
x1: coords.x1,
|
||||
y1: coords.y1,
|
||||
x2: coords.x2,
|
||||
y2: coords.y2,
|
||||
instance: true,
|
||||
parent: $('.modal-crop')
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function imageLoaded() {
|
||||
// centering the modal window after image was loaded
|
||||
var $modal = $('.modal-crop').parent();
|
||||
var width = $modal.width();
|
||||
var height = $modal.height();
|
||||
$modal.css({
|
||||
'margin-top': (-height / 2).toString() + 'px',
|
||||
'margin-left': (-width / 2).toString() + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
function close() {
|
||||
vm.modal.close();
|
||||
}
|
||||
|
||||
function accept() {
|
||||
if (step.id == steps.selectBigSize.id) {
|
||||
bigSelection = cropControl.getSelection();
|
||||
step = steps.selectSmallSize;
|
||||
|
||||
var coords = getInitialCoords();
|
||||
cropControl.setOptions({
|
||||
aspectRatio: step.minSelectionWidth + ':' + step.minSelectionHeight,
|
||||
minWidth: step.minSelectionWidth,
|
||||
minHeight: step.minSelectionHeight,
|
||||
maxWidth: step.maxSelectionWidth,
|
||||
maxHeight: step.maxSelectionHeight,
|
||||
x1: coords.x1,
|
||||
y1: coords.y1,
|
||||
x2: coords.x2,
|
||||
y2: coords.y2,
|
||||
});
|
||||
cropControl.update();
|
||||
|
||||
title('2/2 Select your small size image');
|
||||
actionText('Finish');
|
||||
$image.hide().fadeIn();
|
||||
}
|
||||
else if (step.id == steps.selectSmallSize.id) {
|
||||
var w = $image.width();
|
||||
var h = $image.height();
|
||||
vm.modal.close({ bigSelection: bigSelection, smallSelection: cropControl.getSelection(), w: w, h: h });
|
||||
}
|
||||
}
|
||||
|
||||
function getInitialCoords() {
|
||||
var width = $image.innerWidth(),
|
||||
height = $image.innerHeight(),
|
||||
x1, x2, y1, y2;
|
||||
|
||||
x1 = (width / 2) - (step.minSelectionWidth / 2);
|
||||
x2 = width > step.minSelectionWidth ? x1 + step.minSelectionWidth : width;
|
||||
y1 = (height / 2) - (step.minSelectionHeight / 2);
|
||||
y2 = height > step.minSelectionHeight ? y1 + step.minSelectionHeight : height;
|
||||
|
||||
return {
|
||||
x1: x1,
|
||||
x2: x2,
|
||||
y1: y1,
|
||||
y2: y2
|
||||
};
|
||||
};
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
define(['durandal/system', 'services/logger', 'durandal/plugins/router', 'config', 'services/context', 'services/navigation', 'viewmodels/base'],
|
||||
function(system, logger, router, config, context, navigation, base) {
|
||||
var shell = {
|
||||
activate: activate,
|
||||
router: router,
|
||||
isBusy: base.isBusy,
|
||||
home: home
|
||||
};
|
||||
return shell;
|
||||
|
||||
function activate() {
|
||||
logger.log('MyCompany Loaded', null, system.getModuleId(shell));
|
||||
|
||||
router.map(config.routes);
|
||||
return router.activate(config.startModule);
|
||||
}
|
||||
|
||||
function home() {
|
||||
handleNoAuthLink("", true);
|
||||
}
|
||||
|
||||
function handleNoAuthLink(route, executeIfNoAuth) {
|
||||
var noauthIndex = window.location.href.indexOf("noauth");
|
||||
var url;
|
||||
if (noauthIndex != -1) {
|
||||
if (window.location.pathname)
|
||||
url = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
else
|
||||
url = window.location.protocol + "//" + window.location.host + "/noauth/";
|
||||
|
||||
if (executeIfNoAuth) {
|
||||
window.location.href = url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (window.location.pathname)
|
||||
url = window.location.protocol + "//" + window.location.host + window.location.pathname + route;
|
||||
else
|
||||
url = window.location.protocol + "//" + window.location.host + "/" + route;
|
||||
|
||||
window.location.href = url;
|
||||
}
|
||||
};
|
||||
}
|
||||
);
|
|
@ -0,0 +1,50 @@
|
|||
define(['services/dataservice', 'services/context'], function (dataservice, context) {
|
||||
var initialized = false;
|
||||
|
||||
var vm = {
|
||||
activate: activate,
|
||||
name: context.currentUser.fullName,
|
||||
picture: context.currentUser.picture,
|
||||
openFAQ: openFAQ,
|
||||
signout: signout
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate() {
|
||||
if (initialized) return;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
function openFAQ() {
|
||||
handleNoAuthLink("questions/index", true);
|
||||
}
|
||||
|
||||
function signout() {
|
||||
handleNoAuthLink("account/signout", false);
|
||||
}
|
||||
|
||||
function handleNoAuthLink(route, executeIfNoAuth) {
|
||||
var noauthIndex = window.location.href.indexOf("noauth");
|
||||
var url;
|
||||
if (noauthIndex != -1) {
|
||||
if ( window.location.pathname)
|
||||
url = window.location.protocol + "//" + window.location.host + window.location.pathname + "/" + route;
|
||||
else
|
||||
url = window.location.protocol + "//" + window.location.host + "/noauth/" + route;
|
||||
|
||||
if (executeIfNoAuth) {
|
||||
window.location.href = url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (window.location.pathname)
|
||||
url = window.location.protocol + "//" + window.location.host + window.location.pathname + route;
|
||||
else
|
||||
url = window.location.protocol + "//" + window.location.host + "/" + route;
|
||||
|
||||
window.location.href = url;
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,131 @@
|
|||
define(['services/enums', 'config', 'viewmodels/base'],
|
||||
function (enums, config, base) {
|
||||
var ListViewModel = function () {
|
||||
var source = ko.observableArray(),
|
||||
filter = ko.observable(''),
|
||||
throttledFilter = ko.computed(filter).extend({ throttle: 300 }),
|
||||
sourceItemsCount = ko.observable(0),
|
||||
pages = ko.observableArray(),
|
||||
pageSelected = 0,
|
||||
numPages = 0,
|
||||
getDataMethod = null,
|
||||
getDataCountMethod = null,
|
||||
anyRecord = ko.computed(function () {
|
||||
return source().length > 0;
|
||||
}, this);
|
||||
|
||||
throttledFilter.subscribe(function () {
|
||||
refresh();
|
||||
});
|
||||
|
||||
sourceItemsCount.subscribe(function (count) {
|
||||
calculatePaginator(count);
|
||||
});
|
||||
|
||||
var vm = {
|
||||
initialize: initialize,
|
||||
source: source,
|
||||
sourceItemsCount: sourceItemsCount,
|
||||
refresh: refresh,
|
||||
filter: filter,
|
||||
pages: pages,
|
||||
paginate: paginate,
|
||||
nextPage: nextPage,
|
||||
previousPage: previousPage,
|
||||
anyRecord: anyRecord,
|
||||
removeSourceItem: removeSourceItem
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function initialize(getData, getCount) {
|
||||
getDataMethod = getData;
|
||||
getDataCountMethod = getCount;
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
pageSelected = 0;
|
||||
base.showLoading();
|
||||
|
||||
return $.when(
|
||||
getDataCountMethod(filter()),
|
||||
getData(false))
|
||||
.done(function (count) {
|
||||
sourceItemsCount(count);
|
||||
sourceItemsCount.valueHasMutated();
|
||||
base.hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
function getData(cache) {
|
||||
var parameters = {
|
||||
filter: filter(),
|
||||
pictureType: enums.pictureType.small,
|
||||
pageSize: config.pageSize,
|
||||
pageCount: pageSelected
|
||||
};
|
||||
|
||||
base.showLoading();
|
||||
return getDataMethod(parameters, cache).then(function (data) {
|
||||
source(data);
|
||||
base.hideLoading();
|
||||
$('.multi-ellipsis').dotdotdot();
|
||||
});
|
||||
}
|
||||
|
||||
function paginate(page) {
|
||||
pageSelected = page.number - 1;
|
||||
getData();
|
||||
calculatePaginator(sourceItemsCount());
|
||||
}
|
||||
|
||||
function nextPage() {
|
||||
if (pageSelected == (numPages - 1)) return;
|
||||
|
||||
pageSelected = pageSelected + 1;
|
||||
getData();
|
||||
calculatePaginator(sourceItemsCount());
|
||||
}
|
||||
|
||||
function previousPage() {
|
||||
if (pageSelected == 0) return;
|
||||
|
||||
pageSelected = pageSelected - 1;
|
||||
getData();
|
||||
calculatePaginator(sourceItemsCount());
|
||||
}
|
||||
|
||||
function calculatePaginator(count) {
|
||||
pages.removeAll();
|
||||
numPages = Math.ceil(count / config.pageSize);
|
||||
var firstPage = Math.floor((pageSelected + 1) / 12) * 12;
|
||||
if (firstPage > 0)
|
||||
firstPage = firstPage - 2;
|
||||
|
||||
for (var i = firstPage; i < firstPage + Math.min(12, numPages) && i < numPages ; i++) {
|
||||
var isActive = pageSelected == i;
|
||||
pages.push({ number: i + 1, activated: isActive, clickable: true });
|
||||
}
|
||||
|
||||
if (numPages > 10 && pages()[pages().length - 1].number != numPages) {
|
||||
pages.push({ number: "...", activated: false, clickable: false });
|
||||
pages.push({ number: numPages, activated: false, clickable: true });
|
||||
}
|
||||
}
|
||||
|
||||
function removeSourceItem(item) {
|
||||
if (source().length == 1) {
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
source.remove(item);
|
||||
var count = sourceItemsCount() - 1;
|
||||
sourceItemsCount(count);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
ListViewModel: ListViewModel
|
||||
};
|
||||
});
|
|
@ -0,0 +1,69 @@
|
|||
define(['services/dataservice', 'services/enums', 'viewmodels/base', 'config', 'services/communicator', 'services/notifications'], function (dataservice, enums, base, config, communicator, notifications) {
|
||||
var visitEntity = ko.observable(),
|
||||
employeePicture = ko.observable();
|
||||
|
||||
var vm = {
|
||||
activate: activate,
|
||||
visitEntity: visitEntity,
|
||||
employeePicture: employeePicture,
|
||||
openLync: openLync,
|
||||
close: close
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate(routeData) {
|
||||
if (routeData && routeData.visit) {
|
||||
routeData.visit.visitor().bigPicture = ko.observable(config.defaultBigPicture);
|
||||
employeePicture(config.defaultBigPicture);
|
||||
visitEntity(routeData.visit);
|
||||
|
||||
//base.showLoading();
|
||||
//dataservice.getVisitorCRMDetails(routeData.visit.visitor().visitorId()).then(function (data) {
|
||||
// if (data) {
|
||||
// visitEntity().visitor().crmAccountManager(data.CRMAccountManager);
|
||||
// visitEntity().visitor().crmLeads(data.CRMLeads);
|
||||
// }
|
||||
// base.hideLoading();
|
||||
//});
|
||||
|
||||
base.showLoading();
|
||||
dataservice.getVisitorPicture(routeData.visit.visitor().visitorId(), enums.pictureType.big).then(function (data) {
|
||||
if (data) {
|
||||
visitEntity().visitor().bigPicture(data);
|
||||
}
|
||||
base.hideLoading();
|
||||
});
|
||||
base.showLoading();
|
||||
dataservice.getEmployee(routeData.visit.employee.employeeId(), enums.pictureType.big).then(function (data) {
|
||||
if (data) {
|
||||
employeePicture(data.picture());
|
||||
}
|
||||
base.hideLoading();
|
||||
});
|
||||
subscribeToNotifications();
|
||||
} else {
|
||||
// show error message
|
||||
}
|
||||
};
|
||||
|
||||
function subscribeToNotifications() {
|
||||
notifications.subscribe('visitorPicturesChanged', 'visitDetail', function (visitorPictures) {
|
||||
if (!visitorPictures
|
||||
|| !visitorPictures[0]
|
||||
|| visitorPictures[0].VisitorId != visitEntity().visitor().visitorId())
|
||||
return;
|
||||
|
||||
var picture = 'data:image/jpeg;base64,' + visitorPictures[0].Content;
|
||||
visitEntity().visitor().bigPicture(picture);
|
||||
});
|
||||
}
|
||||
function close() {
|
||||
vm.modal.close();
|
||||
}
|
||||
|
||||
function openLync(employee) {
|
||||
communicator.openLync(employee.email());
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,134 @@
|
|||
define(['services/model', 'services/dataservice', 'services/enums', 'services/context', 'viewmodels/base', 'config'],
|
||||
function (model, dataservice, enums, context, base, config) {
|
||||
var modes = {
|
||||
add: 1,
|
||||
update: 2
|
||||
};
|
||||
|
||||
var visitEntity = ko.observable(),
|
||||
title = ko.observable(),
|
||||
actionText = ko.observable(),
|
||||
selectedVisitor,
|
||||
mode;
|
||||
|
||||
var vm = {
|
||||
title: title,
|
||||
actionText: actionText,
|
||||
activate: activate,
|
||||
viewAttached: viewAttached,
|
||||
visitEntity: visitEntity,
|
||||
close: close,
|
||||
accept: accept
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate(routeData) {
|
||||
if (routeData && routeData.visit) {
|
||||
mode = modes.update;
|
||||
title('Edit visit');
|
||||
actionText('Save changes');
|
||||
visitEntity(routeData.visit);
|
||||
} else {
|
||||
mode = modes.add;
|
||||
title('New visit');
|
||||
actionText('Save changes');
|
||||
visitEntity(new model.Visit());
|
||||
}
|
||||
|
||||
visitEntity().plate.subscribe(function (data) {
|
||||
if (data) {
|
||||
visitEntity().hasCar(true);
|
||||
} else {
|
||||
visitEntity().hasCar(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function close() {
|
||||
vm.modal.close();
|
||||
}
|
||||
|
||||
function accept() {
|
||||
if (!visitEntity().isValid()) {
|
||||
visitEntity().errors.showAllMessages(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == modes.add) {
|
||||
visitEntity().employeeId(context.currentUser.employeeId());
|
||||
|
||||
base.showLoading();
|
||||
dataservice.addVisit(visitEntity).then(function (data) {
|
||||
base.hideLoading();
|
||||
vm.modal.close(data);
|
||||
});
|
||||
}
|
||||
else if (mode == modes.update) {
|
||||
base.showLoading();
|
||||
dataservice.updateVisit(visitEntity).then(function (data) {
|
||||
if (selectedVisitor) {
|
||||
// manage entity data in memory to avoid calling the server for refresh the list
|
||||
visitEntity().visitor(new model.Visitor(selectedVisitor));
|
||||
}
|
||||
base.hideLoading();
|
||||
vm.modal.close(visitEntity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function viewAttached() {
|
||||
$('#visitor-id-input').select2({
|
||||
placeholder: 'Search for a visitor',
|
||||
ajax: {
|
||||
url: 'api/visitors',
|
||||
dataType: 'json',
|
||||
data: function (term) {
|
||||
return {
|
||||
filter: term,
|
||||
pageSize: config.pageSize,
|
||||
pictureType: enums.pictureType.small,
|
||||
pageCount: 0
|
||||
};
|
||||
},
|
||||
results: function (data) {
|
||||
var visitors = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var visitor = new model.Visitor(data[i]);
|
||||
visitors.push({
|
||||
id: visitor.visitorId(),
|
||||
text: visitor.fullName(),
|
||||
picture: visitor.picture(),
|
||||
firstName: visitor.firstName(),
|
||||
lastName: visitor.lastName(),
|
||||
pictureContent: visitor.pictureContent(),
|
||||
company: visitor.company(),
|
||||
});
|
||||
}
|
||||
return { results: visitors };
|
||||
}
|
||||
},
|
||||
formatResult: function (visitor) {
|
||||
return "<img class='picture' src='" + visitor.picture + "' />" + visitor.text;
|
||||
},
|
||||
initSelection: function (element, callback) {
|
||||
var visitor = visitEntity().visitor();
|
||||
callback({
|
||||
id: visitor.visitorId(),
|
||||
text: visitor.fullName(),
|
||||
picture: visitor.picture()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#visitor-id-input').on('change', function (e) {
|
||||
selectedVisitor = {
|
||||
VisitorId: e.added.id,
|
||||
FirstName: e.added.firstName,
|
||||
LastName: e.added.lastName,
|
||||
VisitorPictures: [{ Content: e.added.pictureContent }],
|
||||
Company: e.added.company
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,69 @@
|
|||
define(['services/dataservice', 'services/enums', 'config', 'viewmodels/base', 'services/communicator', 'services/notifications'], function (dataservice, enums, config, base, communicator, notifications) {
|
||||
var visitorEntity = ko.observable(),
|
||||
visits = ko.observable(),
|
||||
visitor;
|
||||
|
||||
var vm = {
|
||||
activate: activate,
|
||||
visitorEntity: visitorEntity,
|
||||
close: close,
|
||||
visits: visits,
|
||||
chooseVisitTemplate: chooseVisitTemplate,
|
||||
openLync: openLync,
|
||||
viewAttached: viewAttached
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate(routeData) {
|
||||
if (routeData && routeData.visitor) {
|
||||
base.showLoading();
|
||||
visits(null);
|
||||
visitor = routeData.visitor;
|
||||
visitor.bigPicture = ko.observable(config.defaultBigPicture);
|
||||
visitorEntity(visitor);
|
||||
|
||||
dataservice.getVisitorPicture(routeData.visitor.visitorId(), enums.pictureType.big).then(function (data) {
|
||||
if (data) {
|
||||
visitor.bigPicture(data);
|
||||
}
|
||||
|
||||
base.hideLoading();
|
||||
});
|
||||
|
||||
subscribeToNotifications();
|
||||
} else {
|
||||
// show error message
|
||||
}
|
||||
};
|
||||
|
||||
function close() {
|
||||
vm.modal.close();
|
||||
}
|
||||
|
||||
function openLync(employee) {
|
||||
communicator.openLync(employee.email());
|
||||
}
|
||||
|
||||
function viewAttached() {
|
||||
// to avoid parse foreach visits before durandal compose the view
|
||||
// and have the templates are loaded
|
||||
visits(visitor.visits());
|
||||
}
|
||||
|
||||
function chooseVisitTemplate(visit) {
|
||||
return visit ? 'visit-template' : 'no-visit-template';
|
||||
}
|
||||
|
||||
function subscribeToNotifications() {
|
||||
notifications.subscribe('visitorPicturesChanged', 'visitorDetail', function (visitorPictures) {
|
||||
if (!visitorPictures
|
||||
|| !visitorPictures[0]
|
||||
|| visitorPictures[0].VisitorId != visitorEntity().visitorId())
|
||||
return;
|
||||
|
||||
var picture = 'data:image/jpeg;base64,' + visitorPictures[0].Content;
|
||||
visitorEntity().bigPicture(picture);
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,98 @@
|
|||
define(['services/model', 'services/dataservice', 'services/enums', 'viewmodels/base', 'durandal/app', 'config'],
|
||||
function (model, dataservice, enums, base, app, config) {
|
||||
var modes = {
|
||||
add: 1,
|
||||
update: 2
|
||||
};
|
||||
|
||||
var visitorEntity = ko.observable(),
|
||||
file = ko.observable(),
|
||||
picture = ko.observable(),
|
||||
title = ko.observable(),
|
||||
actionText = ko.observable(),
|
||||
imageButtonText = ko.computed(function () {
|
||||
return picture() ? 'Change image' : 'Add image';
|
||||
}),
|
||||
mode;
|
||||
|
||||
var vm = {
|
||||
title: title,
|
||||
actionText: actionText,
|
||||
activate: activate,
|
||||
visitorEntity: visitorEntity,
|
||||
close: close,
|
||||
accept: accept,
|
||||
file: file,
|
||||
picture: picture,
|
||||
imageChanged: imageChanged,
|
||||
cropSelection: null,
|
||||
imageButtonText: imageButtonText
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate(routeData) {
|
||||
file(null);
|
||||
picture(null);
|
||||
vm.cropSelection = null;
|
||||
|
||||
if (routeData && routeData.visitor) {
|
||||
mode = modes.update;
|
||||
title('Edit visitor');
|
||||
actionText('Save changes');
|
||||
visitorEntity(routeData.visitor);
|
||||
|
||||
base.showLoading();
|
||||
dataservice.getVisitorPicture(routeData.visitor.visitorId(), enums.pictureType.big).then(function (data) {
|
||||
if (data) {
|
||||
picture(data);
|
||||
} else {
|
||||
picture(config.defaultBigPicture);
|
||||
}
|
||||
base.hideLoading();
|
||||
});
|
||||
} else {
|
||||
mode = modes.add;
|
||||
title('New visitor');
|
||||
actionText('Save changes');
|
||||
visitorEntity(new model.Visitor());
|
||||
}
|
||||
};
|
||||
|
||||
function close() {
|
||||
vm.modal.close();
|
||||
}
|
||||
|
||||
function accept() {
|
||||
if (!visitorEntity().isValid()) {
|
||||
visitorEntity().errors.showAllMessages(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == modes.add) {
|
||||
base.showLoading();
|
||||
dataservice.addVisitor(visitorEntity, { data: file(), selection: vm.cropSelection }).then(function (data) {
|
||||
base.hideLoading();
|
||||
vm.modal.close(data);
|
||||
});
|
||||
}
|
||||
else if (mode == modes.update) {
|
||||
base.showLoading();
|
||||
dataservice.updateVisitor(visitorEntity, { data: file(), selection: vm.cropSelection }).then(function (data) {
|
||||
base.hideLoading();
|
||||
vm.modal.close(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function imageChanged (image) {
|
||||
app.showModal('viewmodels/cropImageWizard', { picture: image }).then(function (data) {
|
||||
if (data) {
|
||||
vm.cropSelection = data;
|
||||
picture(image);
|
||||
} else {
|
||||
vm.cropSelection = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,84 @@
|
|||
define(['services/dataservice', 'services/enums', 'durandal/app', 'services/logger', 'viewmodels/viewModels', 'viewmodels/base', 'services/notifications'],
|
||||
function (dataservice, enums, app, logger, viewModels, base, notifications) {
|
||||
var initialized = false,
|
||||
vmList = new viewModels.ListViewModel();
|
||||
|
||||
var vm = {
|
||||
activate: activate,
|
||||
title: 'Visitors view',
|
||||
visitors: vmList.source,
|
||||
visitorsCount: vmList.sourceItemsCount,
|
||||
refresh: vmList.refresh,
|
||||
filter: vmList.filter,
|
||||
pages: vmList.pages,
|
||||
paginate: vmList.paginate,
|
||||
nextPage: vmList.nextPage,
|
||||
previousPage: vmList.previousPage,
|
||||
anyRecord: vmList.anyRecord,
|
||||
add: add,
|
||||
edit: edit,
|
||||
deleteVisitor: deleteVisitor,
|
||||
openDetail: openDetail
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate() {
|
||||
if (!initialized) {
|
||||
vmList.initialize(dataservice.getVisitors, dataservice.getVisitorsCount);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
subscribeToNotifications();
|
||||
return vmList.refresh();
|
||||
}
|
||||
|
||||
function add() {
|
||||
app.showModal('viewmodels/visitorForm').then(function (visitor) {
|
||||
if (visitor) {
|
||||
vmList.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit(entity) {
|
||||
app.showModal('viewmodels/visitorForm', { visitor: entity }).then(function (visitor) {
|
||||
if (visitor) {
|
||||
vmList.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteVisitor(entity) {
|
||||
var message = 'Are you sure you want to delete ' + entity.fullName() + '?';
|
||||
app.showMessage(message, 'confirmation', [enums.options.yes, enums.options.no])
|
||||
.then(function (dialogResult) {
|
||||
if (dialogResult == enums.options.yes) {
|
||||
base.showLoading();
|
||||
dataservice.deleteVisitor(entity.visitorId()).then(function () {
|
||||
vmList.removeSourceItem(entity);
|
||||
base.hideLoading();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openDetail(entity) {
|
||||
app.showModal('viewmodels/visitorDetail', { visitor: entity });
|
||||
}
|
||||
|
||||
function subscribeToNotifications() {
|
||||
notifications.subscribe('visitorPicturesChanged', 'visitors', function (visitorPictures) {
|
||||
if (!visitorPictures || !visitorPictures[1])
|
||||
return;
|
||||
|
||||
var smallPicture = visitorPictures[1].Content;
|
||||
var visitorId = visitorPictures[1].VisitorId;
|
||||
var visitors = vmList.source();
|
||||
visitors.forEach(function (visitor) {
|
||||
if (visitor.visitorId() == visitorId)
|
||||
visitor.pictureContent(smallPicture);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,96 @@
|
|||
define(['services/dataservice', 'services/enums', 'durandal/app', 'viewmodels/viewModels', 'viewmodels/base', 'services/notifications'],
|
||||
function (dataservice, enums, app, viewModels, base, notifications) {
|
||||
var initialized = false,
|
||||
vmList = new viewModels.ListViewModel();
|
||||
|
||||
var vm = {
|
||||
activate: activate,
|
||||
viewAttached: viewAttached,
|
||||
title: 'Visits view',
|
||||
visits: vmList.source,
|
||||
visitsCount: vmList.sourceItemsCount,
|
||||
refresh: vmList.refresh,
|
||||
filter: vmList.filter,
|
||||
pages: vmList.pages,
|
||||
paginate: vmList.paginate,
|
||||
nextPage: vmList.nextPage,
|
||||
previousPage: vmList.previousPage,
|
||||
anyRecord: vmList.anyRecord,
|
||||
add: add,
|
||||
edit: edit,
|
||||
deleteVisit: deleteVisit,
|
||||
openDetail: openDetail
|
||||
};
|
||||
|
||||
return vm;
|
||||
|
||||
function activate(routeData) {
|
||||
base.showLoading();
|
||||
|
||||
if (!initialized || routeData && routeData.visitId) {
|
||||
vmList.initialize(dataservice.getVisits, dataservice.getVisitsCount);
|
||||
initialized = true;
|
||||
|
||||
if (routeData && routeData.visitId) {
|
||||
base.showLoading();
|
||||
dataservice.getVisit(routeData.visitId, enums.pictureType.small).then(function (entity) {
|
||||
openDetail(entity);
|
||||
base.hideLoading();
|
||||
});
|
||||
}
|
||||
}
|
||||
subscribeToNotifications();
|
||||
return vmList.refresh();
|
||||
}
|
||||
|
||||
|
||||
function viewAttached() {
|
||||
$('.multi-ellipsis').dotdotdot();
|
||||
base.hideLoading();
|
||||
}
|
||||
|
||||
function add() {
|
||||
app.showModal('viewmodels/visitForm').then(function (visit) {
|
||||
if (visit) {
|
||||
vmList.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit(entity) {
|
||||
app.showModal('viewmodels/visitForm', { visit: entity });
|
||||
}
|
||||
|
||||
function deleteVisit(entity) {
|
||||
var message = 'Are you sure you want to delete the visit of ' + entity.visitor().fullName() + '?';
|
||||
app.showMessage(message, 'confirmation', [enums.options.yes, enums.options.no])
|
||||
.then(function (dialogResult) {
|
||||
if (dialogResult == enums.options.yes) {
|
||||
base.showLoading();
|
||||
dataservice.deleteVisit(entity.visitId()).then(function () {
|
||||
vmList.removeSourceItem(entity);
|
||||
base.hideLoading();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openDetail(entity) {
|
||||
app.showModal('viewmodels/visitDetail', { visit: entity });
|
||||
}
|
||||
|
||||
function subscribeToNotifications() {
|
||||
notifications.subscribe('visitorPicturesChanged','visits', function (visitorPictures) {
|
||||
if (!visitorPictures || !visitorPictures[1])
|
||||
return;
|
||||
|
||||
var smallPicture = visitorPictures[1].Content;
|
||||
var visitorId = visitorPictures[1].VisitorId;
|
||||
var visits = vmList.source();
|
||||
visits.forEach(function (visit) {
|
||||
if (visit.visitor().visitorId() == visitorId)
|
||||
visit.visitor().pictureContent(smallPicture);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
<div class="modal autoclose">
|
||||
<div class="modal-header">
|
||||
<span class="title-modal" data-bind="html: title"></span>
|
||||
<button class="button-close" data-bind="click: close"></button>
|
||||
</div>
|
||||
<div class="modal-body modal-crop">
|
||||
<img class="crop" src="Content/Images/no-photo-big.png" data-bind="event: { load: imageLoaded }, attr: { src: image }" />
|
||||
<div class="buttons">
|
||||
<button class="button-primary autofocus" data-bind="{html: actionText, click: accept}"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<div class="loading">
|
||||
<div id="fountainG_1" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_2" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_3" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_4" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_5" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_6" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_7" class="fountainG">
|
||||
</div>
|
||||
<div id="fountainG_8" class="fountainG">
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,10 @@
|
|||
<div class="content-nav-buttons">
|
||||
<nav class="btn-group" data-bind="foreach: router.visibleRoutes">
|
||||
<div class="content-nav-button" data-bind="css: { active: isActive }">
|
||||
<div class="icon"></div>
|
||||
<a class="nav-button" data-bind="attr: { href: hash }, html: caption"></a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
|
@ -0,0 +1,20 @@
|
|||
<section class="content-pagination">
|
||||
<ul data-bind="foreach: pages">
|
||||
<li data-bind="css: { active: activated}">
|
||||
<div data-bind="{if: clickable}">
|
||||
<a href="#" data-bind="{text: number, click: $root.paginate}"></a>
|
||||
</div>
|
||||
<div data-bind="{if: !clickable}">...</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="content-arrows">
|
||||
<div class="arrow-type">
|
||||
<button class="arrow" data-bind="click: previousPage"><</button>
|
||||
</div>
|
||||
<div class="arrow-type margin-arrow">
|
||||
<button class="arrow" data-bind="click: nextPage">></button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</section>
|
|
@ -0,0 +1,27 @@
|
|||
<!-- Button to avoid ie to get signout as default action -->
|
||||
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;" />
|
||||
<div id="main-container">
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span6">
|
||||
<a class="brand" href="#" data-bind="click: home"></a>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<!--ko compose: {model: 'viewmodels/user'} -->
|
||||
<!--/ko-->
|
||||
</div>
|
||||
</div>
|
||||
<!--ko compose: {view: 'nav' } -->
|
||||
<!--/ko-->
|
||||
</div>
|
||||
</header>
|
||||
<section id="content" class="main container-fluid">
|
||||
<div class="loading-background" data-bind="visible: isBusy || router.isNavigating, compose: { view: 'loading' }">
|
||||
</div>
|
||||
<!--ko compose: {model: router.activeItem,
|
||||
afterCompose: router.afterCompose,
|
||||
transition: 'entrance' } -->
|
||||
<!--/ko-->
|
||||
</section>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
<section class="user-data">
|
||||
|
||||
<a href="#" title="FAQs">
|
||||
<button data-bind="click: openFAQ" class="button-primary button-right button-faq" title="FAQs">FAQ</button>
|
||||
</a>
|
||||
|
||||
<a href="#" title="sign out">
|
||||
<button data-bind="click: signout" class="button-primary button-right">Sign out</button>
|
||||
</a>
|
||||
<img data-bind="attr: { src: picture }" />
|
||||
<span class="user-name" data-bind="text: name"></span>
|
||||
</section>
|
|
@ -0,0 +1,54 @@
|
|||
<div class="modal-detail modal-detail-newwidth autoclose">
|
||||
<div class="modal-detail-header">
|
||||
<span class="title-modal">Visit details</span>
|
||||
<button class="button-close new-margin-top" data-bind="click: close"></button>
|
||||
</div>
|
||||
<div class="modal-detail-body" data-bind="with: visitEntity">
|
||||
<div class="box-avatar">
|
||||
<img data-bind="attr: { src: visitor().bigPicture }" />
|
||||
</div>
|
||||
<div class="box-info">
|
||||
<div class="info-up">
|
||||
<span class="box-name" data-bind="text: visitor().fullName"></span>
|
||||
<div class="box-clock"></div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="info-middle">
|
||||
<ul>
|
||||
<li><span data-bind="text: visitor().company"></span></li>
|
||||
<li><span data-bind="text: visitor().position"></span></li>
|
||||
<li><span>Date: </span><span data-bind="text: displayDate"></span></li>
|
||||
<li><span>Time: </span><span data-bind="text: displayTime"></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--<div class="info-down">
|
||||
<span>CRM Data</span>
|
||||
<ul>
|
||||
<li><span>Account Manager: </span><span data-bind="text: visitor().crmAccountManager"></span></li>
|
||||
<li><span>Active Leads: </span><span data-bind="text: visitor().crmLeads"></span></li>
|
||||
</ul>
|
||||
</div>-->
|
||||
<div data-bind="visible: hasCar">
|
||||
<span>License plate: </span>
|
||||
<span data-bind="text: plate"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-visite-to" data-bind="with: employee">
|
||||
<img data-bind="attr: { src: $root.employeePicture }" />
|
||||
<div class="visite-to-info">
|
||||
<span>Visits</span>
|
||||
<span class="visite-to-name" data-bind="text: fullName"></span>
|
||||
<div class="visite-to-down">
|
||||
<div class="visite-to-company">
|
||||
<span data-bind="text: position"></span>
|
||||
</div>
|
||||
<div class="visite-to-lync">
|
||||
<div data-bind="click: $root.openLync" title="Contact with lync" class="lync"><img src="Content/Images/lync-ico.png" /></div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче