├── ContosoAir ├── ContosoAir.Website_and_Services.sln ├── LICENSE ├── README.md └── src │ ├── ContosoAir.Services │ ├── ContosoAir.Services.njsproj │ ├── README.md │ ├── api │ │ ├── airports │ │ │ ├── airports.controller.js │ │ │ ├── airports.data.all.json │ │ │ ├── airports.data.json │ │ │ └── airports.router.js │ │ ├── alternatives │ │ │ ├── alternatives.controller.js │ │ │ ├── alternatives.data.json │ │ │ └── alternatives.router.js │ │ ├── assets │ │ │ ├── assets.router.js │ │ │ └── documents │ │ │ │ ├── alternatives-option1b.png │ │ │ │ ├── alternatives-option2b.png │ │ │ │ ├── alternatives-option3b.png │ │ │ │ ├── alternatives-option4b.png │ │ │ │ ├── boarding-311718169315b.png │ │ │ │ ├── drink-311718169315.png │ │ │ │ └── map-311718169315.png │ │ ├── booking │ │ │ ├── booking.controller.js │ │ │ ├── booking.data-utf8.json │ │ │ ├── booking.data.json │ │ │ └── booking.router.js │ │ ├── deals │ │ │ ├── deals.controller.js │ │ │ ├── deals.data-utf8.json │ │ │ ├── deals.data.json │ │ │ └── deals.router.js │ │ ├── feedback │ │ │ └── feedback.data.json │ │ ├── flights │ │ │ ├── checkin.data.json │ │ │ ├── flights.controller.js │ │ │ ├── flights.data-utf8.json │ │ │ ├── flights.data.json │ │ │ └── flights.router.js │ │ ├── notifications │ │ │ ├── messages.model.js │ │ │ ├── notifications.controller.js │ │ │ ├── notifications.router.js │ │ │ ├── payloads.model.js │ │ │ └── types.model.js │ │ ├── seats │ │ │ ├── seats.controller.js │ │ │ ├── seats.data-utf8.json │ │ │ ├── seats.data.json │ │ │ └── seats.router.js │ │ └── videos │ │ │ ├── videos.controller.js │ │ │ ├── videos.data.json │ │ │ └── videos.router.js │ ├── config.js │ ├── cosmos_mongo_partition_insert.js │ ├── local_mongo_db_insert.js │ ├── mongo_db_insert.js │ ├── package-lock.json │ ├── package.json │ ├── server.js │ ├── sql_db_flightinsert.js │ ├── sql_db_insert.js │ ├── utils.js │ └── web.config │ └── ContosoAir.Website │ ├── .ember-cli │ ├── .gitignore │ ├── .sassLint.yml │ ├── ContosoAir.Website.njsproj │ ├── README.md │ ├── angular-cli.json │ ├── gulpfile.js │ ├── karma.conf.js │ ├── package-lock.json │ ├── package.json │ ├── server.js │ ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── app.routes.ts │ │ ├── booking │ │ │ ├── booking.component.html │ │ │ └── booking.component.ts │ │ ├── city-video │ │ │ ├── city-video.component.ts │ │ │ ├── city-video.service.ts │ │ │ └── video.ts │ │ ├── city │ │ │ └── city.component.ts │ │ ├── flights │ │ │ ├── days.component.html │ │ │ ├── days.component.ts │ │ │ ├── feedback.ts │ │ │ ├── flight.ts │ │ │ ├── flights.component.html │ │ │ ├── flights.component.ts │ │ │ ├── flights.service.spec.ts │ │ │ ├── flights.service.ts │ │ │ ├── flightsFeedback.service.ts │ │ │ ├── options.component.html │ │ │ ├── options.component.ts │ │ │ ├── results.component.html │ │ │ └── results.component.ts │ │ ├── home │ │ │ └── home.component.ts │ │ ├── seats │ │ │ ├── seats.component.html │ │ │ ├── seats.component.ts │ │ │ ├── seats.service.spec.ts │ │ │ └── seats.service.ts │ │ └── shared │ │ │ ├── airport.ts │ │ │ ├── airports.service.spec.ts │ │ │ ├── airports.service.ts │ │ │ ├── auth.service.ts │ │ │ ├── booking.service.ts │ │ │ ├── deal.ts │ │ │ ├── deals.component.html │ │ │ ├── deals.component.ts │ │ │ ├── deals.service.spec.ts │ │ │ ├── deals.service.ts │ │ │ ├── footer.component.html │ │ │ ├── footer.component.ts │ │ │ ├── guard.service.ts │ │ │ ├── home.component.html │ │ │ ├── loading.component.html │ │ │ ├── loading.component.ts │ │ │ ├── navbar.component.html │ │ │ ├── navbar.component.ts │ │ │ ├── search.component.html │ │ │ ├── search.component.ts │ │ │ └── utc.pipe.ts │ ├── assets │ │ ├── .gitkeep │ │ ├── b-barcelona.jpg │ │ ├── b-footer.jpg │ │ ├── b-home.jpg │ │ ├── barcelona.jpg │ │ ├── cities │ │ │ ├── barcelona.jpg │ │ │ ├── barcelona_m.jpg │ │ │ ├── hawaii.jpg │ │ │ ├── hawaii_m.jpg │ │ │ ├── paris.jpg │ │ │ └── paris_m.jpg │ │ ├── fonts │ │ │ └── Karla-Regular.ttf │ │ ├── logo_contoso_air.svg │ │ ├── logo_contoso_air2.svg │ │ ├── microsoft.svg │ │ └── plane.png │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── icons │ │ ├── arrow-left.svg │ │ ├── arrow-right.svg │ │ ├── calendar.svg │ │ └── logo.svg │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ ├── styles │ │ ├── _booking.scss │ │ ├── _cities.scss │ │ ├── _cityinfo.scss │ │ ├── _days.scss │ │ ├── _deals.scss │ │ ├── _flights.scss │ │ ├── _footer.scss │ │ ├── _loading.scss │ │ ├── _navbar.scss │ │ ├── _overrides.scss │ │ ├── _search.scss │ │ ├── _seats.scss │ │ ├── _variables.scss │ │ └── _vendor.scss │ ├── test.ts │ └── tsconfig.json │ ├── tslint.json │ ├── utils │ └── icons_template.css │ └── web.config ├── MSReady ├── Module1-Migrating MongoDB Apps to Azure Cosmos DB(Mongo API).MD └── images │ ├── RDP credSSP.jpg │ ├── Throughput1.jpg │ ├── Throughput2.jpg │ ├── Throughput3.jpg │ ├── Throughput4.jpg │ ├── addcosmos.jpg │ ├── addregion.jpg │ ├── addregion2.jpg │ ├── allexport.jpg │ ├── charts_thruput_menu.jpg │ ├── collections.jpg │ ├── config.jpg │ ├── configjs.png │ ├── configpartition.jpg │ ├── contoso1.jpg │ ├── contoso2.jpg │ ├── contosotime.jpg │ ├── cosistency3.jpg │ ├── cosmos1.jpg │ ├── cosmos2.jpg │ ├── cosmosdb1.jpg │ ├── cosmosdb2.jpg │ ├── cosmosdb3.jpg │ ├── createcollection.jpg │ ├── createnewcollection.jpg │ ├── dashboard1.png │ ├── data_index_storage_consume_vs_available.jpg │ ├── deploymentsuccess1.png │ ├── empirical_portability.jpg │ ├── enable.jpg │ ├── envprep1.png │ ├── fix.jpg │ ├── fsbrowse.png │ ├── importall.jpg │ ├── insertpartitiondat.jpg │ ├── japanreplication.png │ ├── jumpvm1.png │ ├── jumpvm2.jpg │ ├── jumpvm4.jpg │ ├── jumpvm5.jpg │ ├── jumpvm6.jpg │ ├── latency1.jpg │ ├── latency2.jpg │ ├── launchlab1.png │ ├── line66.png │ ├── line68.png │ ├── module3.jpg │ ├── module4.jpg │ ├── mongo.jpg │ ├── mongodb.jpg │ ├── openflightscs.png │ ├── password1.png │ ├── projects.png │ ├── rdc.jpg │ ├── rdc2.jpg │ ├── region.png │ ├── replicate.jpg │ ├── replication_latency.jpg │ ├── rgnav1.png │ ├── scalethroughput.png │ ├── signup.jpg │ ├── signup1.png │ ├── storage1.jpg │ ├── storage2.jpg │ ├── username1.png │ └── xrdp.jpg ├── README.md ├── SECURITY.md ├── challenges ├── AdditionalModules.md ├── Module0-Getting Started.MD ├── Module1-Introduction to Cosmos DB.MD ├── Module2-Migrating MongoDB Apps to Azure Cosmos DB(Mongo API).MD ├── Module3-Migrating MongoDB Apps to Azure Cosmos DB(SQL API).MD ├── README.MD └── images │ ├── GetStartedOnYourOwn.jpg │ ├── Integrate.jpg │ ├── ManualFailover.jpg │ ├── ManualFailover1.jpg │ ├── Notification.jpg │ ├── QEslection.jpg │ ├── SourceInfo.jpg │ ├── SourceInfoNxt1.jpg │ ├── Throughput1.jpg │ ├── Throughput2.jpg │ ├── Throughput3.jpg │ ├── Throughput4.jpg │ ├── accountkey.jpg │ ├── acs-list.png │ ├── addcosmos.jpg │ ├── addregion.jpg │ ├── addregion2.jpg │ ├── advancedPage.jpg │ ├── allexport.jpg │ ├── automaticFailover.jpg │ ├── availability.jpg │ ├── az-getcred.png │ ├── azureinfo.png │ ├── charts_thruput_menu.jpg │ ├── charts_thruput_menu.png │ ├── collection.jpg │ ├── collections.jpg │ ├── colletion.jpg │ ├── config.jpg │ ├── configjs.png │ ├── configpartition.jpg │ ├── connString.jpg │ ├── connect.jpg │ ├── connect2.jpg │ ├── connector.jpg │ ├── contoso1.jpg │ ├── contoso2.jpg │ ├── contosoapp.jpg │ ├── contosotime.jpg │ ├── copyCollectionName.jpg │ ├── copyDBname.jpg │ ├── copythruput.jpg │ ├── cosistency3.jpg │ ├── cosmos1.jpg │ ├── cosmos2.jpg │ ├── cosmos_create.jpg │ ├── cosmosdb.jpg │ ├── cosmosdb1.jpg │ ├── cosmosdb2.jpg │ ├── cosmosdb3.jpg │ ├── cosmosdbDocuments.jpg │ ├── cosmosdb_notification.jpg │ ├── cosmosdbinfo1.jpg │ ├── cosmosdbinformation.jpg │ ├── cosmosdbinformation1.jpg │ ├── cosmosdboverview.jpg │ ├── cosmoskeyandurl.jpg │ ├── cosmosrg.jpg │ ├── cosmosurl.jpg │ ├── createcollection.jpg │ ├── createnewcollection.jpg │ ├── creds-email.png │ ├── dashboard1.png │ ├── data_index_storage_consume_vs_available.jpg │ ├── dataexplorer.jpg │ ├── deploymentsuccess1.png │ ├── dtui.jpg │ ├── empirical_portability.jpg │ ├── empirical_portability.png │ ├── entervmcreds.jpg │ ├── envprep1.png │ ├── expandCollection.jpg │ ├── expanddb.jpg │ ├── exportStatus.jpg │ ├── failover2.jpg │ ├── file2.jpg │ ├── file2.png │ ├── fnxcreate.jpg │ ├── fnxinfo.jpg │ ├── fsbrowse.png │ ├── fuctionappsearch.jpg │ ├── functioncreated.jpg │ ├── getFunctn.jpg │ ├── getdata.jpg │ ├── getfxnurl.jpg │ ├── httptrigger.jpg │ ├── httpvalue.jpg │ ├── importall.jpg │ ├── importtodb.jpg │ ├── insertpartitiondat.jpg │ ├── japanreplication.png │ ├── jumpboxinfo.png │ ├── jumpconnect.jpg │ ├── jumpvm1.jpg │ ├── jumpvm1.png │ ├── jumpvm2.jpg │ ├── jumpvm3.jpg │ ├── jumpvm4.jpg │ ├── jumpvm5.jpg │ ├── jumpvm6.jpg │ ├── k8sgetnodes.png │ ├── keys.jpg │ ├── latency1.jpg │ ├── latency2.jpg │ ├── launch.png │ ├── launchlab1.png │ ├── line66.png │ ├── line68.png │ ├── mig-toolWelcome.jpg │ ├── migrationtool.jpg │ ├── module.jpg │ ├── module1.jpg │ ├── module2.jpg │ ├── module3.jpg │ ├── module4.jpg │ ├── mongo.jpg │ ├── mongodb.jpg │ ├── navigator.jpg │ ├── navigatorsimple.jpg │ ├── new.jpg │ ├── notepad.jpg │ ├── openflightscs.png │ ├── partition.jpg │ ├── password1.png │ ├── piechart.jpg │ ├── piechart1.jpg │ ├── powerbivm.png │ ├── projects.png │ ├── query_op.jpg │ ├── queryeditor.jpg │ ├── queryexplorer.jpg │ ├── queryrun.jpg │ ├── rdc.jpg │ ├── rdc2.jpg │ ├── records.jpg │ ├── region.png │ ├── regionok.jpg │ ├── replicate.jpg │ ├── replication_latency.jpg │ ├── replicationsave.jpg │ ├── reportview.jpg │ ├── resourcegrp.jpg │ ├── rg.jpg │ ├── rgnav1.png │ ├── scalesettings.jpg │ ├── scalethroughput.png │ ├── selectAddCollection.jpg │ ├── selectCosmosDB.jpg │ ├── selectID.jpg │ ├── selectmongodocdb.jpg │ ├── selectrecord.jpg │ ├── showhide.jpg │ ├── signup.jpg │ ├── signup1.png │ ├── sqlcommands.jpg │ ├── sqlconfig.jpg │ ├── sqlcosmos.jpg │ ├── sqldataexplore.jpg │ ├── sqlkey.jpg │ ├── status200.jpg │ ├── stock.jpg │ ├── storage1.jpg │ ├── storage2.jpg │ ├── targetThruput.jpg │ ├── targetinfocollection.jpg │ ├── targetinfodb.jpg │ ├── typeCosmosDB.jpg │ ├── username1.png │ ├── virtualmachine.png │ ├── xrdp.jpg │ └── yes.PNG └── template ├── azuredeploy.json ├── azuredeploy.parameters.json └── mysql-resources.json /ContosoAir/ContosoAir.Website_and_Services.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.15 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "ContosoAir.Services", "src\ContosoAir.Services\ContosoAir.Services.njsproj", "{A9CC5D29-D90B-4A74-B508-46860C4B9FC4}" 7 | EndProject 8 | Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "ContosoAir.Website", "src\ContosoAir.Website\ContosoAir.Website.njsproj", "{591605AC-C696-4027-9F9B-59FBB008E33C}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {A9CC5D29-D90B-4A74-B508-46860C4B9FC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {A9CC5D29-D90B-4A74-B508-46860C4B9FC4}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {A9CC5D29-D90B-4A74-B508-46860C4B9FC4}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {A9CC5D29-D90B-4A74-B508-46860C4B9FC4}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {591605AC-C696-4027-9F9B-59FBB008E33C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {591605AC-C696-4027-9F9B-59FBB008E33C}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {591605AC-C696-4027-9F9B-59FBB008E33C}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {591605AC-C696-4027-9F9B-59FBB008E33C}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {1D639EAD-97BC-4CEE-82B7-EE6896C90992} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ContosoAir/README.md: -------------------------------------------------------------------------------- 1 | # story-a-gda-hol-immersion 2 | This repository contains the code for story A for Micorosoft Hands on Lab 3 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/README.md: -------------------------------------------------------------------------------- 1 | # ContosoAir Services 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/airports/airports.controller.js: -------------------------------------------------------------------------------- 1 | const data = require('./airports.data'); 2 | 3 | let get = (req, res) => { 4 | res.send(data); 5 | }; 6 | 7 | let getSingle = (req, res) => { 8 | let airports = data.filter(airport => airport.code === req.params.id); 9 | if (airports.length > 0) { 10 | return res.send(airports[0]); 11 | } 12 | 13 | res.send(404); 14 | }; 15 | 16 | module.exports = { 17 | get: get, 18 | getSingle: getSingle 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/airports/airports.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./airports.controller'); 2 | 3 | const routes = { 4 | base: '/api/airports/', 5 | single: '/api/airports/:id' 6 | }; 7 | 8 | module.exports = server => { 9 | server.get(routes.base, controller.get); 10 | server.get(routes.single, controller.getSingle); 11 | }; 12 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/alternatives/alternatives.controller.js: -------------------------------------------------------------------------------- 1 | const data = require('./alternatives.data'); 2 | 3 | let get = (req, res) => { 4 | const protocol = `http${process.env.isLocal ? '' : 's'}`; 5 | 6 | for (let key in data) { 7 | let item = data[key]; 8 | if (typeof data[key] === 'string') { 9 | data[key] = data[key].replace('$', `${protocol}://${req.headers.host}`); 10 | } else { 11 | for (let subkey in data[key]) { 12 | let item = data[key][subkey]; 13 | if (typeof data[key][subkey].image === 'string') { 14 | data[key][subkey].image = data[key][subkey].image.replace('$', `${protocol}://${req.headers.host}`); 15 | } 16 | } 17 | } 18 | } 19 | res.send(data); 20 | }; 21 | 22 | module.exports = { 23 | get: get 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/alternatives/alternatives.data.json: -------------------------------------------------------------------------------- 1 | { 2 | "from": "Paris", 3 | "to": "Barcelona", 4 | "boardingpass": "$/documents/boarding-311718169315b.png", 5 | "map": "$/documents/map-311718169315.png", 6 | "coupon": "$/documents/drink-311718169315.png", 7 | "flights": [ 8 | { 9 | "id": 1, 10 | "departure": "02:40pm", 11 | "arrival": "05:40pm", 12 | "stops": 0, 13 | "image": "$/documents/alternatives-option1b.png" 14 | }, 15 | { 16 | "id": 2, 17 | "departure": "12:15pm", 18 | "arrival": "02:40pm", 19 | "stops": 0, 20 | "image": "$/documents/alternatives-option2b.png" 21 | }, 22 | { 23 | "id": 3, 24 | "departure": "04:20pm", 25 | "arrival": "07:40pm", 26 | "stops": 0, 27 | "image": "$/documents/alternatives-option3b.png" 28 | }, 29 | { 30 | "id": 4, 31 | "departure": "03:20pm", 32 | "arrival": "06:30pm", 33 | "stops": 1, 34 | "image": "$/documents/alternatives-option4b.png" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/alternatives/alternatives.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./alternatives.controller'); 2 | 3 | const routes = { 4 | base: '/api/alternatives/' 5 | }; 6 | 7 | module.exports = server => { 8 | server.get(routes.base, controller.get); 9 | }; 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/assets.router.js: -------------------------------------------------------------------------------- 1 | const restify = require('restify'); 2 | 3 | module.exports = server => { 4 | server.get(/\/documents\/?.*/, restify.serveStatic({ 5 | directory: './api/assets', 6 | default: 'map' 7 | })); 8 | }; 9 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option1b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option1b.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option2b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option2b.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option3b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option3b.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option4b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/alternatives-option4b.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/boarding-311718169315b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/boarding-311718169315b.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/drink-311718169315.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/drink-311718169315.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/assets/documents/map-311718169315.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CosmosDB-GBB-Hackathon/279a73d22476334078c4936f1f46df0942d03880/ContosoAir/src/ContosoAir.Services/api/assets/documents/map-311718169315.png -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/booking/booking.data-utf8.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "booking_id": "i9WMDb", 4 | "userName": "John Smith", 5 | "seatNumber": "21B", 6 | "fromCode": "BCN", 7 | "toCode": "SEA", 8 | "startDate": "2017-01-28", 9 | "endDate": "2017-01-28", 10 | "thereId": "145", 11 | "backId": "148" 12 | } 13 | ] -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/booking/booking.data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "booking_id": "i9WMDb", 4 | "userName": "John Smith", 5 | "seatNumber": "21B", 6 | "fromCode": "BCN", 7 | "toCode": "SEA", 8 | "startDate": "2017-01-28", 9 | "endDate": "2017-01-28", 10 | "thereId": "145", 11 | "backId": "148" 12 | } 13 | ] -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/booking/booking.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./booking.controller'); 2 | 3 | const routes = { 4 | base: '/api/booking/' 5 | }; 6 | 7 | module.exports = server => { 8 | server.post(routes.base, controller.push); 9 | }; 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/deals/deals.controller.js: -------------------------------------------------------------------------------- 1 | // private variable's Declaration 2 | var request = require('request'); 3 | var config = require('../../config'); 4 | 5 | var data = ''; 6 | var result; 7 | const arr = []; 8 | 9 | // Get Azure function url from config file 10 | var azure_fuction_dealsUrl = config.AZURE_FUNCTION_DEALS_URL; 11 | 12 | // functions declaration 13 | 14 | // Get data from azure function 15 | let get = (req, res) => { 16 | request(azure_fuction_dealsUrl, function (error, response, body) { 17 | if (!error && response.statusCode == 200) { 18 | data = body; 19 | res.send(data); 20 | } 21 | else { 22 | res.send(error); 23 | } 24 | }) 25 | }; 26 | 27 | let getSingle = (req, res) => { 28 | let deals = data.filter(deal => deal.id === req.params.id); 29 | if (deals.length > 0) { 30 | return res.send(deals[0]); 31 | } 32 | res.send(404); 33 | }; 34 | 35 | module.exports = { 36 | get: get, 37 | getSingle: getSingle 38 | }; -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/deals/deals.data-utf8.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "0", 4 | "fromName": "Seattle", 5 | "fromCode": "SEA", 6 | "toName": "Barcelona", 7 | "toCode": "BCN", 8 | "price": "1100", 9 | "departTime": "2017-03-04T08:45:00Z", 10 | "arrivalTime": "2017-03-05T14:55:00Z", 11 | "hours": "10h 30m", 12 | "stops": "1", 13 | "since": null 14 | }, 15 | { 16 | "id": "1", 17 | "fromName": "Barcelona", 18 | "fromCode": "BCN", 19 | "toName": "Seattle", 20 | "toCode": "SEA", 21 | "price": "750", 22 | "departTime": "2017-03-04T08:45:00Z", 23 | "arrivalTime": "2017-03-05T12:20:00Z", 24 | "hours": "09h 15m", 25 | "stops": "1", 26 | "since": null 27 | }, 28 | { 29 | "id": "2", 30 | "fromName": "Seattle", 31 | "fromCode": "SEA", 32 | "toName": "Barcelona", 33 | "toCode": "BCN", 34 | "price": "1070", 35 | "departTime": "2017-03-04T08:45:00Z", 36 | "arrivalTime": "2017-03-05T14:25:00Z", 37 | "hours": "10h 0m", 38 | "stops": "1", 39 | "since": null 40 | }, 41 | { 42 | "id": "3", 43 | "fromName": "Seattle", 44 | "fromCode": "SEA", 45 | "toName": "Barcelona", 46 | "toCode": "BCN", 47 | "price": "750", 48 | "departTime": "2017-03-04T08:45:00Z", 49 | "arrivalTime": "2017-03-05T14:25:00Z", 50 | "hours": "11h 20m", 51 | "stops": "1", 52 | "since": null 53 | }, 54 | { 55 | "id": "4", 56 | "fromName": "Seattle", 57 | "fromCode": "SEA", 58 | "toName": "Barcelona", 59 | "toCode": "BCN", 60 | "price": "479", 61 | "departTime": null, 62 | "arrivalTime": null, 63 | "hours": null, 64 | "stops": null, 65 | "since": "2017-02-13T00:00:01Z" 66 | }, 67 | { 68 | "id": "5", 69 | "fromName": "Seattle", 70 | "fromCode": "SEA", 71 | "toName": "Barcelona", 72 | "toCode": "BCN", 73 | "price": "535", 74 | "departTime": null, 75 | "arrivalTime": null, 76 | "hours": null, 77 | "stops": null, 78 | "since": "2017-02-13T00:00:01Z" 79 | }, 80 | { 81 | "id": "6", 82 | "fromName": "Seattle", 83 | "fromCode": "SEA", 84 | "toName": "Barcelona", 85 | "toCode": "BCN", 86 | "price": "626", 87 | "departTime": null, 88 | "arrivalTime": null, 89 | "hours": null, 90 | "stops": null, 91 | "since": "2017-02-13T00:00:01Z" 92 | }, 93 | { 94 | "id": "7", 95 | "fromName": "Barcelona", 96 | "fromCode": "BCN", 97 | "toName": "Seattle", 98 | "toCode": "SEA", 99 | "price": "528", 100 | "departTime": null, 101 | "arrivalTime": null, 102 | "hours": null, 103 | "stops": null, 104 | "since": "2017-02-13T00:00:01Z" 105 | }, 106 | { 107 | "id": "8", 108 | "fromName": "Seattle", 109 | "fromCode": "SEA", 110 | "toName": "Barcelona", 111 | "toCode": "BCN", 112 | "price": "1100", 113 | "departTime": "2017-03-04T08:45:00Z", 114 | "arrivalTime": "2017-03-05T14:55:00Z", 115 | "hours": "10h 30m", 116 | "stops": "1", 117 | "since": null 118 | } 119 | ] 120 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/deals/deals.data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "0", 4 | "fromName": "Seattle", 5 | "fromCode": "SEA", 6 | "toName": "Barcelona", 7 | "toCode": "BCN", 8 | "price": "1100", 9 | "departTime": "2017-03-04T08:45:00Z", 10 | "arrivalTime": "2017-03-05T14:55:00Z", 11 | "hours": "10h 30m", 12 | "stops": "1", 13 | "since": null 14 | }, 15 | { 16 | "id": "1", 17 | "fromName": "Barcelona", 18 | "fromCode": "BCN", 19 | "toName": "Seattle", 20 | "toCode": "SEA", 21 | "price": "750", 22 | "departTime": "2017-03-04T08:45:00Z", 23 | "arrivalTime": "2017-03-05T12:20:00Z", 24 | "hours": "09h 15m", 25 | "stops": "1", 26 | "since": null 27 | }, 28 | { 29 | "id": "2", 30 | "fromName": "Seattle", 31 | "fromCode": "SEA", 32 | "toName": "Barcelona", 33 | "toCode": "BCN", 34 | "price": "1070", 35 | "departTime": "2017-03-04T08:45:00Z", 36 | "arrivalTime": "2017-03-05T14:25:00Z", 37 | "hours": "10h 0m", 38 | "stops": "1", 39 | "since": null 40 | }, 41 | { 42 | "id": "3", 43 | "fromName": "Seattle", 44 | "fromCode": "SEA", 45 | "toName": "Barcelona", 46 | "toCode": "BCN", 47 | "price": "750", 48 | "departTime": "2017-03-04T08:45:00Z", 49 | "arrivalTime": "2017-03-05T14:25:00Z", 50 | "hours": "11h 20m", 51 | "stops": "1", 52 | "since": null 53 | }, 54 | { 55 | "id": "4", 56 | "fromName": "Seattle", 57 | "fromCode": "SEA", 58 | "toName": "Barcelona", 59 | "toCode": "BCN", 60 | "price": "479", 61 | "departTime": null, 62 | "arrivalTime": null, 63 | "hours": null, 64 | "stops": null, 65 | "since": "2017-02-13T00:00:01Z" 66 | }, 67 | { 68 | "id": "5", 69 | "fromName": "Seattle", 70 | "fromCode": "SEA", 71 | "toName": "Barcelona", 72 | "toCode": "BCN", 73 | "price": "535", 74 | "departTime": null, 75 | "arrivalTime": null, 76 | "hours": null, 77 | "stops": null, 78 | "since": "2017-02-13T00:00:01Z" 79 | }, 80 | { 81 | "id": "6", 82 | "fromName": "Seattle", 83 | "fromCode": "SEA", 84 | "toName": "Barcelona", 85 | "toCode": "BCN", 86 | "price": "626", 87 | "departTime": null, 88 | "arrivalTime": null, 89 | "hours": null, 90 | "stops": null, 91 | "since": "2017-02-13T00:00:01Z" 92 | }, 93 | { 94 | "id": "7", 95 | "fromName": "Barcelona", 96 | "fromCode": "BCN", 97 | "toName": "Seattle", 98 | "toCode": "SEA", 99 | "price": "528", 100 | "departTime": null, 101 | "arrivalTime": null, 102 | "hours": null, 103 | "stops": null, 104 | "since": "2017-02-13T00:00:01Z" 105 | }, 106 | { 107 | "id": "8", 108 | "fromName": "Seattle", 109 | "fromCode": "SEA", 110 | "toName": "Barcelona", 111 | "toCode": "BCN", 112 | "price": "1100", 113 | "departTime": "2017-03-04T08:45:00Z", 114 | "arrivalTime": "2017-03-05T14:55:00Z", 115 | "hours": "10h 30m", 116 | "stops": "1", 117 | "since": null 118 | } 119 | ] 120 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/deals/deals.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./deals.controller'); 2 | 3 | const routes = { 4 | base: '/api/deals/', 5 | single: '/api/deals/:id' 6 | }; 7 | 8 | module.exports = server => { 9 | server.get(routes.base, controller.get); 10 | server.get(routes.single, controller.getSingle); 11 | }; 12 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/flights/checkin.data.json: -------------------------------------------------------------------------------- 1 | { 2 | "terminal": "B4", 3 | "gate": "A8", 4 | "seat": "C3" 5 | } 6 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/flights/flights.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./flights.controller'); 2 | 3 | const routes = { 4 | base: '/api/flights/', 5 | single: '/api/flights/:id', 6 | checkin: '/api/flights/checkin/:id', 7 | feedback: '/api/flights/feedback/:flightId' 8 | }; 9 | 10 | module.exports = server => { 11 | server.get(routes.base, controller.get); 12 | server.get(routes.single, controller.getSingle); 13 | server.get(routes.checkin, controller.checkin); 14 | server.get(routes.feedback, controller.getFlightFeedback); 15 | }; 16 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/notifications/messages.model.js: -------------------------------------------------------------------------------- 1 | const types = require('./types.model'); 2 | 3 | let messages = {}; 4 | messages[types.none] = ''; 5 | messages[types.checkInAvailable] = 'Check-in available!'; 6 | messages[types.delayedFlight] = 'The flight has been delayed'; 7 | messages[types.giveFeedback] = 'Give feedback'; 8 | 9 | module.exports = messages; 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/notifications/notifications.controller.js: -------------------------------------------------------------------------------- 1 | const azure = require('azure'); 2 | const config = require('../../config'); 3 | const types = require('./types.model'); 4 | const messages = require('./messages.model'); 5 | const payloads = require('./payloads.model'); 6 | 7 | var notificationHubService = ''; 8 | 9 | let checkError = (error, platform) => { 10 | if (error) { 11 | console.log('Error notification ' + platform); 12 | } 13 | }; 14 | 15 | let checkCounter = (counter, res) => { 16 | if (counter < 3) { 17 | return; 18 | } 19 | 20 | res.send(200); 21 | }; 22 | 23 | let post = (req, res) => { 24 | // Put on a service 25 | 26 | let counter = 0; 27 | let body = JSON.parse(req.body); 28 | let type = body.type || types.none; 29 | let tag = body.tag || null; 30 | let options = { message: messages[type], type: type }; 31 | 32 | // Send to Android 33 | notificationHubService.gcm.send(tag, payloads.android(options), error => { 34 | counter++; 35 | checkError(error, 'Android'); 36 | checkCounter(counter, res); 37 | }); 38 | 39 | // Send to iOS 40 | notificationHubService.apns.send(tag, payloads.ios(options), error => { 41 | counter++; 42 | checkError(error, 'iOS'); 43 | checkCounter(counter, res); 44 | }); 45 | 46 | // Send to windows 47 | notificationHubService.wns.send(tag, payloads.windows(options), 'wns/toast', error => { 48 | counter++; 49 | checkError(error, 'Windows'); 50 | checkCounter(counter, res); 51 | }); 52 | }; 53 | 54 | module.exports = { 55 | post: post 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/notifications/notifications.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./notifications.controller'); 2 | 3 | const routes = { 4 | base: '/api/notifications/' 5 | }; 6 | 7 | module.exports = server => { 8 | server.post(routes.base, controller.post); 9 | }; 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/notifications/payloads.model.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | android: options => { 3 | return { 4 | data: { 5 | message: options.message, 6 | type: options.type 7 | } 8 | }; 9 | }, 10 | 11 | ios: options => { 12 | return { 13 | aps: { 14 | alert: options.message 15 | }, 16 | 17 | type: options.type 18 | }; 19 | }, 20 | 21 | windows: options => { 22 | return `${options.message}`; 23 | } 24 | } -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/notifications/types.model.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | none: 0, 3 | checkInAvailable: 1, 4 | delayedFlight: 2, 5 | giveFeedback: 3 6 | } 7 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/seats/seats.controller.js: -------------------------------------------------------------------------------- 1 | // private variable's Declaration 2 | var config = require('../../config'); 3 | var DocumentClient = require("documentdb").DocumentClient; 4 | var host = config.DOCUMENT_DB_ENDPOINT; 5 | var masterKey = config.DOCUMENT_DB_PRIMARYKEY; 6 | var seatCollectionUrl = "dbs/" + config.DOCUMENT_DB_DATABASE + "/colls/" + config.DOCUMENT_DB_SEAT; 7 | 8 | // Get preferred region from config file 9 | var DocumentBase = require('documentdb').DocumentBase; 10 | var connectionPolicy = new DocumentBase.ConnectionPolicy(); 11 | 12 | // Set preferred region in connection policy 13 | connectionPolicy.PreferredLocations.push(config.DOCUMENT_DB_PREFERRED_REGION); 14 | 15 | var client = new DocumentClient(host, { masterKey: masterKey }, connectionPolicy); 16 | 17 | const arr = []; 18 | var data = ''; 19 | 20 | // functions declaration 21 | 22 | // Fetch seats data from SqlDB api seats collection 23 | let get = (req, res) => { 24 | 25 | let resultString = new Array(); 26 | let querySpec = { 27 | query: 'SELECT c.seat_seg.col_A, c.seat_seg.col_B, c.seat_seg.col_C, c.seat_seg.col_D, c.seat_seg.col_E, c.seat_seg.col_F from ' + config.DOCUMENT_DB_SEAT + ' c ORDER BY c.seat_Row', 28 | } 29 | 30 | client.queryDocuments( 31 | seatCollectionUrl, querySpec 32 | ).toArray((err, results) => { 33 | if (!err) { 34 | for (var queryResult of results) { 35 | resultString.push(queryResult); 36 | } 37 | let seat_array = new Array(); 38 | for (var i = 0; i < resultString.length; i++) { 39 | let seat_row = new Array(); 40 | seat_row.push(resultString[i].col_A, resultString[i].col_B, resultString[i].col_C, resultString[i].col_D, resultString[i].col_E, resultString[i].col_F); 41 | seat_array.push(seat_row); 42 | } 43 | 44 | var preferredseatset = false; 45 | for (var i = 0; i <= 8 && preferredseatset != true; i++) { 46 | for (var j = 0; j <= 5 && preferredseatset != true; j++) { 47 | // Set first empty seat as a preferred seat 48 | if (seat_array[i][j] == 0) { 49 | seat_array[i][j] = 2; 50 | preferredseatset = true; 51 | break; 52 | } 53 | } 54 | } 55 | var seat_data = { "options": { "available": 0, "unavailable": 1, "preferred": 2, "contosoair": 3 }, "rows": seat_array }; 56 | res.send(seat_data); 57 | } 58 | else { res.send(err) } 59 | }); 60 | } 61 | 62 | module.exports = { 63 | get: get 64 | }; 65 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/seats/seats.data-utf8.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": "17", 3 | "seat_Row": 17, 4 | "seat_seg": { 5 | "col_A": 1, 6 | "col_B": 0, 7 | "col_C": 0, 8 | "col_D": 1, 9 | "col_E": 3, 10 | "col_F": 1 11 | } 12 | }, 13 | { 14 | "id": "18", 15 | "seat_Row": 18, 16 | "seat_seg": { 17 | "col_A": 1, 18 | "col_B": 1, 19 | "col_C": 1, 20 | "col_D": 0, 21 | "col_E": 1, 22 | "col_F": 1 23 | } 24 | }, 25 | { 26 | "id": "19", 27 | "seat_Row": 19, 28 | "seat_seg": { 29 | "col_A": 1, 30 | "col_B": 1, 31 | "col_C": 0, 32 | "col_D": 1, 33 | "col_E": 0, 34 | "col_F": 0 35 | } 36 | }, 37 | { 38 | "id": "20", 39 | "seat_Row": 20, 40 | "seat_seg": { 41 | "col_A": 0, 42 | "col_B": 1, 43 | "col_C": 1, 44 | "col_D": 0, 45 | "col_E": 0, 46 | "col_F": 1 47 | } 48 | }, 49 | { 50 | "id": "21", 51 | "seat_Row": 21, 52 | "seat_seg": { 53 | "col_A": 1, 54 | "col_B": 1, 55 | "col_C": 0, 56 | "col_D": 0, 57 | "col_E": 1, 58 | "col_F": 0 59 | } 60 | }, 61 | { 62 | "id": "22", 63 | "seat_Row": 22, 64 | "seat_seg": { 65 | "col_A": 1, 66 | "col_B": 0, 67 | "col_C": 0, 68 | "col_D": 1, 69 | "col_E": 1, 70 | "col_F": 0 71 | } 72 | }, 73 | { 74 | "id": "23", 75 | "seat_Row": 23, 76 | "seat_seg": { 77 | "col_A": 1, 78 | "col_B": 1, 79 | "col_C": 0, 80 | "col_D": 0, 81 | "col_E": 0, 82 | "col_F": 1 83 | } 84 | }, 85 | { 86 | "id": "24", 87 | "seat_Row": 24, 88 | "seat_seg": { 89 | "col_A": 0, 90 | "col_B": 0, 91 | "col_C": 0, 92 | "col_D": 1, 93 | "col_E": 1, 94 | "col_F": 0 95 | } 96 | }, 97 | { 98 | "id": "25", 99 | "seat_Row": 25, 100 | "seat_seg": { 101 | "col_A": 1, 102 | "col_B": 0, 103 | "col_C": 0, 104 | "col_D": 1, 105 | "col_E": 0, 106 | "col_F": 0 107 | } 108 | } 109 | ] -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/seats/seats.data.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": "17", 3 | "seat_Row": 17, 4 | "seat_seg": { 5 | "col_A": 1, 6 | "col_B": 0, 7 | "col_C": 0, 8 | "col_D": 1, 9 | "col_E": 3, 10 | "col_F": 1 11 | } 12 | }, 13 | { 14 | "id": "18", 15 | "seat_Row": 18, 16 | "seat_seg": { 17 | "col_A": 1, 18 | "col_B": 1, 19 | "col_C": 1, 20 | "col_D": 0, 21 | "col_E": 1, 22 | "col_F": 1 23 | } 24 | }, 25 | { 26 | "id": "19", 27 | "seat_Row": 19, 28 | "seat_seg": { 29 | "col_A": 1, 30 | "col_B": 1, 31 | "col_C": 0, 32 | "col_D": 1, 33 | "col_E": 0, 34 | "col_F": 0 35 | } 36 | }, 37 | { 38 | "id": "20", 39 | "seat_Row": 20, 40 | "seat_seg": { 41 | "col_A": 0, 42 | "col_B": 1, 43 | "col_C": 1, 44 | "col_D": 0, 45 | "col_E": 0, 46 | "col_F": 1 47 | } 48 | }, 49 | { 50 | "id": "21", 51 | "seat_Row": 21, 52 | "seat_seg": { 53 | "col_A": 1, 54 | "col_B": 1, 55 | "col_C": 0, 56 | "col_D": 0, 57 | "col_E": 1, 58 | "col_F": 0 59 | } 60 | }, 61 | { 62 | "id": "22", 63 | "seat_Row": 22, 64 | "seat_seg": { 65 | "col_A": 1, 66 | "col_B": 0, 67 | "col_C": 0, 68 | "col_D": 1, 69 | "col_E": 1, 70 | "col_F": 0 71 | } 72 | }, 73 | { 74 | "id": "23", 75 | "seat_Row": 23, 76 | "seat_seg": { 77 | "col_A": 1, 78 | "col_B": 1, 79 | "col_C": 0, 80 | "col_D": 0, 81 | "col_E": 0, 82 | "col_F": 1 83 | } 84 | }, 85 | { 86 | "id": "24", 87 | "seat_Row": 24, 88 | "seat_seg": { 89 | "col_A": 0, 90 | "col_B": 0, 91 | "col_C": 0, 92 | "col_D": 1, 93 | "col_E": 1, 94 | "col_F": 0 95 | } 96 | }, 97 | { 98 | "id": "25", 99 | "seat_Row": 25, 100 | "seat_seg": { 101 | "col_A": 1, 102 | "col_B": 0, 103 | "col_C": 0, 104 | "col_D": 1, 105 | "col_E": 0, 106 | "col_F": 0 107 | } 108 | } 109 | ] -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/seats/seats.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./seats.controller'); 2 | 3 | const routes = { 4 | base: '/api/seats/' 5 | }; 6 | 7 | module.exports = server => { 8 | server.get(routes.base, controller.get); 9 | }; 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/videos/videos.controller.js: -------------------------------------------------------------------------------- 1 | const data = require('./videos.data'); 2 | 3 | let get = (req, res) => { 4 | data.links.barcelona = process.env.BARCELONA_VIDEO || data.links.barcelona; 5 | 6 | res.send(data); 7 | }; 8 | 9 | module.exports = { 10 | get: get 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/videos/videos.data.json: -------------------------------------------------------------------------------- 1 | { 2 | "formats": { 3 | "desktop": "(format=mpd-time-csf)", 4 | "mobile": "(format=m3u8-aapl)" 5 | }, 6 | "links": { 7 | "barcelona": "https://contosoairmedia.streaming.mediaservices.windows.net/f15cdbdb-f715-4527-b329-19884c592163/barcelona-with-audio.ism/manifest" 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/api/videos/videos.router.js: -------------------------------------------------------------------------------- 1 | const controller = require('./videos.controller'); 2 | 3 | const routes = { 4 | base: '/api/videos/' 5 | }; 6 | 7 | module.exports = server => { 8 | server.get(routes.base, controller.get); 9 | }; 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | API_MODE: 'MONGO', 3 | 4 | DOCUMENT_DB_ENDPOINT: '', 5 | DOCUMENT_DB_PRIMARYKEY: '', 6 | DOCUMENT_DB_DATABASE: 'contosoairdb', 7 | 8 | DOCUMENT_DB_FLIGHT: 'FlightsCollection', 9 | DOCUMENT_DB_SEAT: 'SeatsCollection', 10 | DOCUMENT_DB_DEAL: 'DealsCollection', 11 | DOCUMENT_DB_BOOKING: 'BookingsCollection', 12 | DOCUMENT_DB_PREFERRED_REGION: 'West US', 13 | 14 | AZURE_FUNCTION_DEALS_URL: '', 15 | 16 | MONGO_DB_CONNECTION_STRING: 'mongodb://localhost:27017/contosoairdb3', 17 | MONGO_DB_COLLECTION: 'feedbackdb', 18 | Mongo_DB_FLIGHT_Partitioned: 'FlightsCollectionPartitioned' 19 | }; 20 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/cosmos_mongo_partition_insert.js: -------------------------------------------------------------------------------- 1 | // private variable's Declaration 2 | var fs = require('fs'); 3 | var MongoClient = require('mongodb').MongoClient; 4 | var config = require('./config') 5 | var assert = require('assert'); 6 | var ObjectId = require('mongodb').ObjectID; 7 | var connectionString = config.MONGO_DB_CONNECTION_STRING; 8 | 9 | var flights_data_to_import = JSON.parse(fs.readFileSync('./api/flights/flights.data-utf8.json', 'utf8')); 10 | 11 | 12 | // Functions Declaration 13 | 14 | var insertDocumentsToCollections = function (db, callback) { 15 | insertDocument(db, config.Mongo_DB_FLIGHT_Partitioned, flights_data_to_import, function () { }); 16 | } 17 | 18 | // Insert Feedback data into MongoDB Database 19 | var insertDocument = function (db, collection, data_to_import, callback) { 20 | for (let i = 0; i < data_to_import.length; i++) { 21 | db.collection(collection).insertOne(data_to_import[i], function (err, result) { 22 | assert.equal(err, null); 23 | if (i === data_to_import.length - 1) { 24 | console.log('Data imported successfully into the ' + collection + ' collection.'); 25 | 26 | setTimeout(function () { 27 | callback(); 28 | }, 1500); 29 | } 30 | }); 31 | } 32 | }; 33 | 34 | // Execution starts 35 | MongoClient.connect(connectionString, function (err, db) { 36 | assert.equal(null, err); 37 | 38 | insertDocumentsToCollections(db, function () { 39 | // db.close(); 40 | // process.exit(); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/local_mongo_db_insert.js: -------------------------------------------------------------------------------- 1 | // private variable's Declaration 2 | var fs = require('fs'); 3 | var MongoClient = require('mongodb').MongoClient; 4 | var config = require('./config') 5 | var assert = require('assert'); 6 | var ObjectId = require('mongodb').ObjectID; 7 | var connectionString = config.MONGO_DB_CONNECTION_STRING; 8 | 9 | var feedback_data_to_import = JSON.parse(fs.readFileSync('./api/feedback/feedback.data.json', 'utf8')); 10 | var flights_data_to_import = JSON.parse(fs.readFileSync('./api/flights/flights.data-utf8.json', 'utf8')); 11 | var seats_data_to_import = JSON.parse(fs.readFileSync('./api/seats/seats.data-utf8.json', 'utf8')); 12 | var deals_data_to_import = JSON.parse(fs.readFileSync('./api/deals/deals.data-utf8.json', 'utf8')); 13 | var booking_data_to_import = JSON.parse(fs.readFileSync('./api/booking/booking.data-utf8.json', 'utf8')); 14 | 15 | // Functions Declaration 16 | 17 | var insertDocumentsToCollections = function (db, callback) { 18 | insertDocument(db, config.MONGO_DB_COLLECTION, feedback_data_to_import, function () { }); 19 | insertDocument(db, config.DOCUMENT_DB_FLIGHT, flights_data_to_import, function () { }); 20 | insertDocument(db, config.DOCUMENT_DB_SEAT, seats_data_to_import, function () { }); 21 | insertDocument(db, config.DOCUMENT_DB_DEAL, deals_data_to_import, function () { }); 22 | insertDocument(db, config.DOCUMENT_DB_BOOKING, booking_data_to_import, function () { }); 23 | } 24 | 25 | // Insert Feedback data into MongoDB Database 26 | var insertDocument = function (db, collection, data_to_import, callback) { 27 | for (let i = 0; i < data_to_import.length; i++) { 28 | db.collection(collection).insertOne(data_to_import[i], function (err, result) { 29 | assert.equal(err, null); 30 | if (i === data_to_import.length - 1) 31 | { 32 | console.log('Data imported successfully into the ' + collection + ' collection.'); 33 | 34 | setTimeout(function () { 35 | callback(); 36 | }, 1500); 37 | } 38 | }); 39 | } 40 | }; 41 | 42 | // Execution starts 43 | MongoClient.connect(connectionString, function (err, db) { 44 | assert.equal(null, err); 45 | 46 | insertDocumentsToCollections(db, function () { 47 | // db.close(); 48 | // process.exit(); 49 | }); 50 | }); -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/mongo_db_insert.js: -------------------------------------------------------------------------------- 1 | // private variable's Declaration 2 | var fs = require('fs'); 3 | var MongoClient = require('mongodb').MongoClient; 4 | var config = require('./config') 5 | var assert = require('assert'); 6 | var ObjectId = require('mongodb').ObjectID; 7 | var connectionString = config.MONGO_DB_CONNECTION_STRING; 8 | var collection = config.MONGO_DB_COLLECTION; 9 | var data_to_import = JSON.parse(fs.readFileSync('./api/feedback/feedback.data.json', 'utf8')); 10 | 11 | // Functions Declaration 12 | 13 | // Insert Feedback data into MongoDB Database 14 | var insertDocument = function (db, callback) { 15 | for (let i = 0; i < data_to_import.length; i++) { 16 | db.collection(collection).insertOne(data_to_import[i], function (err, result) { 17 | assert.equal(err, null); 18 | if (i === data_to_import.length - 1) 19 | { 20 | console.log('Data imported successfully into the ' + collection + ' collection.'); 21 | 22 | setTimeout(function () { 23 | callback(); 24 | }, 1500); 25 | } 26 | }); 27 | } 28 | }; 29 | 30 | // Execution starts 31 | MongoClient.connect(connectionString, function (err, db) { 32 | assert.equal(null, err); 33 | insertDocument(db, function () { 34 | db.close(); 35 | process.exit(); 36 | }); 37 | }); -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "contoso-air.services", 3 | "version": "0.0.0", 4 | "description": "ContosoAir.Services", 5 | "main": "server.js", 6 | "author": { 7 | "name": "Microsoft" 8 | }, 9 | "dependencies": { 10 | "azure": "^1.2.0-preview", 11 | "body-parser": "^1.18.2", 12 | "documentdb": "^1.12.2", 13 | "glob": "^7.1.1", 14 | "request": "^2.83.0", 15 | "restify": "^4.3.0", 16 | "web-request": "^1.0.7", 17 | "mongodb": "2.2.27", 18 | "mongodb-core": "2.1.11", 19 | "async": "^2.5.0" 20 | }, 21 | "scripts": { 22 | "start": "node server.js" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/server.js: -------------------------------------------------------------------------------- 1 | const restify = require('restify'); 2 | const glob = require('glob'); 3 | 4 | // Create server 5 | let server = restify.createServer(); 6 | 7 | // Configure CORS 8 | server.use(restify.CORS()); 9 | 10 | // Configure body 11 | server.use(restify.bodyParser()); 12 | 13 | // Require routers 14 | let modules = glob.sync('./api/**/*.router.*'); 15 | modules.forEach(_module => { 16 | require(_module)(server); 17 | }); 18 | 19 | // Start server 20 | server.listen(8081, () => { 21 | console.log('%s listening at %s', server.name, server.url); 22 | }); 23 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Services/web.config: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | "port": 4200 3 | } -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /src/**/*.css 7 | /src/icons/*.woff 8 | /src/styles/_icons.scss 9 | /src/styles/_fonts.scss 10 | 11 | # dependencies 12 | /node_modules 13 | 14 | # IDEs and editors 15 | /.idea 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | 22 | # IDE - VSCode 23 | .vscode/* 24 | !.vscode/settings.json 25 | !.vscode/tasks.json 26 | !.vscode/launch.json 27 | !.vscode/extensions.json 28 | 29 | # misc 30 | /.sass-cache 31 | /connect.lock 32 | /coverage/* 33 | /libpeerconnection.log 34 | npm-debug.log 35 | testem.log 36 | /typings 37 | 38 | # e2e 39 | /e2e/*.js 40 | /e2e/*.map 41 | 42 | #System Files 43 | .DS_Store 44 | Thumbs.db 45 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/.sassLint.yml: -------------------------------------------------------------------------------- 1 | { 2 | rules: { 3 | 'indentation': 0, 4 | 'nesting-depth': 0, 5 | 'class-name-format': 0, 6 | 'single-line-per-selector': 0 7 | } 8 | } -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/README.md: -------------------------------------------------------------------------------- 1 | # AngularCli 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-beta.31. 4 | 5 | ## Development server 6 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 7 | 8 | ## Code scaffolding 9 | 10 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`. 11 | 12 | ## Build 13 | 14 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 15 | 16 | ## Running unit tests 17 | 18 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 19 | 20 | ## Running end-to-end tests 21 | 22 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 23 | Before running the tests make sure you are serving the app via `ng serve`. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "version": "1.0.0-beta.31", 5 | "name": "angular-cli" 6 | }, 7 | "apps": [ 8 | { 9 | "root": "src", 10 | "outDir": "dist", 11 | "assets": [ 12 | "assets", 13 | "favicon.ico" 14 | ], 15 | "index": "index.html", 16 | "main": "main.ts", 17 | "polyfills": "polyfills.ts", 18 | "test": "test.ts", 19 | "tsconfig": "tsconfig.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.scss" 23 | ], 24 | "scripts": [], 25 | "environments": { 26 | "source": "environments/environment.ts", 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "lint": [ 33 | { 34 | "files": "src/**/*.ts", 35 | "project": "src/tsconfig.json" 36 | }, 37 | { 38 | "files": "e2e/**/*.ts", 39 | "project": "e2e/tsconfig.json" 40 | } 41 | ], 42 | "test": { 43 | "karma": { 44 | "config": "./karma.conf.js" 45 | } 46 | }, 47 | "defaults": { 48 | "styleExt": "css", 49 | "prefixInterfaces": false, 50 | "inline": { 51 | "style": false, 52 | "template": false 53 | }, 54 | "spec": { 55 | "class": false, 56 | "component": true, 57 | "directive": true, 58 | "module": false, 59 | "pipe": true, 60 | "service": true 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const runSequence = require('run-sequence'); 3 | const gulpLoadPlugins = require('gulp-load-plugins'); 4 | const $ = gulpLoadPlugins(); 5 | 6 | gulp.task('serve', ['preprocessor-watch'], $.shell.task(['ng serve --target=development'])); 7 | 8 | gulp.task('prebuild', ['preprocessor'], $.shell.task(['ng build --target=development'])); 9 | 10 | gulp.task('preprod', ['preprocessor'], $.shell.task(['ng build --target=production'])); 11 | 12 | var copyWebConfig = function() { 13 | return gulp.src('./web.config') 14 | .pipe(gulp.dest('./dist')); 15 | }; 16 | 17 | gulp.task('build', ['prebuild'], copyWebConfig); 18 | 19 | gulp.task('prod', ['preprod'], copyWebConfig); 20 | 21 | gulp.task('createIconsFont', function(){ 22 | 23 | var runTimestamp = Math.round(Date.now()/1000); 24 | 25 | return gulp.src('src/icons/**/*.svg') 26 | .pipe($.iconfont({ 27 | fontName: 'icons', 28 | normalize: true, 29 | prependUnicode: false, 30 | formats: ['woff'], 31 | timestamp: runTimestamp, 32 | })) 33 | .on('glyphs', function(glyphs, options) { 34 | gulp.src('utils/icons_template.css') 35 | .pipe($.consolidate('lodash', { 36 | glyphs: glyphs, 37 | fontName: 'icons', 38 | fontPath: 'src/icons/', 39 | className: 'icon' 40 | })) 41 | .pipe($.rename('_icons.scss')) 42 | .pipe(gulp.dest('src/styles')); 43 | }) 44 | .pipe(gulp.dest('src/icons')); 45 | }); 46 | 47 | gulp.task('icons', ['createIconsFont'], function(){ 48 | return gulp.src('src/icons/icons.woff') 49 | .pipe($.inlineFonts({ 50 | name: 'icons', 51 | style: 'normal', 52 | weight: 'normal', 53 | formats: ['woff'] 54 | })) 55 | .pipe($.rename('_fonts.scss')) 56 | .pipe(gulp.dest('src/styles')); 57 | }); 58 | 59 | gulp.task('styles', function(){ 60 | return gulp.src(['src/**/*.scss']) 61 | .pipe($.sassLint({ 62 | configFile: '.sassLint.yml', 63 | formatter: 'checkstyle', 64 | files: {ignore: 'src/styles/_fonts.scss'}, 65 | })) 66 | .pipe($.sassLint.format()) 67 | .pipe($.sassLint.failOnError()) 68 | .pipe($.sass().on('error', $.sass.logError)) 69 | .pipe($.autoprefixer(['last 2 version'])) 70 | .pipe(gulp.dest('src')); 71 | }); 72 | 73 | gulp.task('watch', function(){ 74 | gulp.watch('src/**/*.scss', ['styles']); 75 | gulp.watch('src/icons/*.svg', ['icons']); 76 | }); 77 | 78 | gulp.task('preprocessor', function(cb){ 79 | runSequence('icons','styles', cb); 80 | }); 81 | 82 | gulp.task('preprocessor-watch', function(cb){ 83 | runSequence('icons','styles', 'watch', cb); 84 | }); -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-phantomjs-launcher'), 11 | require('karma-coverage-istanbul-reporter'), 12 | require('@angular/cli/plugins/karma') 13 | ], 14 | files: [ 15 | { pattern: './src/test.ts', watched: false } 16 | ], 17 | preprocessors: { 18 | './src/test.ts': ['@angular/cli'] 19 | }, 20 | mime: { 21 | 'text/x-typescript': ['ts','tsx'] 22 | }, 23 | coverageIstanbulReporter: { 24 | reports: [ 'html', 'lcovonly' ], 25 | fixWebpackSourcePaths: true 26 | }, 27 | angularCli: { 28 | config: './angular-cli.json', 29 | environment: 'dev' 30 | }, 31 | reporters: config.angularCli && config.angularCli.codeCoverage 32 | ? ['progress', 'coverage-istanbul'] 33 | : ['progress'], 34 | port: 9876, 35 | colors: true, 36 | logLevel: config.LOG_INFO, 37 | autoWatch: true, 38 | browsers: ['PhantomJS'], 39 | singleRun: false 40 | }); 41 | }; 42 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "contoso-air.website", 3 | "version": "0.0.0", 4 | "description": "ContosoAir.Website", 5 | "main": "server.js", 6 | "author": { 7 | "name": "Microsoft" 8 | }, 9 | "scripts": { 10 | "ng": "ng", 11 | "start": "gulp serve", 12 | "build": "gulp build", 13 | "prod": "gulp prod", 14 | "test": "ng test --watch false", 15 | "lint": "ng lint" 16 | }, 17 | "engines": { 18 | "node": ">=6.9.0" 19 | }, 20 | "dependencies": { 21 | "@angular/common": "2.4.0", 22 | "@angular/compiler": "2.4.0", 23 | "@angular/core": "2.4.0", 24 | "@angular/forms": "2.4.0", 25 | "@angular/http": "2.4.0", 26 | "@angular/platform-browser": "2.4.0", 27 | "@angular/platform-browser-dynamic": "2.4.0", 28 | "@angular/router": "3.4.0", 29 | "@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.20", 30 | "adal-angular": "1.0.14", 31 | "angular-in-memory-web-api": "0.3.0", 32 | "angular2-adal": "0.1.4", 33 | "bootstrap": "4.0.0-alpha.6", 34 | "chart.js": "^2.7.0", 35 | "core-js": "2.4.1", 36 | "intl": "1.2.5", 37 | "ng2-adal": "0.2.8", 38 | "ng2-charts": "^1.6.0", 39 | "ng2-opd-popup": "^1.1.21", 40 | "rxjs": "5.0.1", 41 | "ts-helpers": "1.1.1", 42 | "zone.js": "0.7.2" 43 | }, 44 | "devDependencies": { 45 | "@angular/cli": "1.0.0-beta.31", 46 | "@angular/compiler-cli": "2.4.0", 47 | "@types/adal": "1.0.25", 48 | "@types/jasmine": "2.5.38", 49 | "@types/node": "6.0.42", 50 | "codelyzer": "~2.0.0-beta.1", 51 | "gulp": "3.9.1", 52 | "gulp-autoprefixer": "3.1.1", 53 | "gulp-consolidate": "0.2.0", 54 | "gulp-iconfont": "8.0.1", 55 | "gulp-inline-fonts": "1.0.3", 56 | "gulp-load-plugins": "1.5.0", 57 | "gulp-rename": "1.2.2", 58 | "gulp-sass": "3.1.0", 59 | "gulp-sass-lint": "1.3.2", 60 | "gulp-shell": "0.5.2", 61 | "jasmine-core": "2.5.2", 62 | "jasmine-spec-reporter": "2.5.0", 63 | "karma": "1.2.0", 64 | "karma-cli": "1.0.1", 65 | "karma-coverage-istanbul-reporter": "0.2.0", 66 | "karma-jasmine": "1.0.2", 67 | "karma-phantomjs-launcher": "1.0.2", 68 | "run-sequence": "1.2.2", 69 | "spa-server": "1.0.0", 70 | "ts-node": "1.2.1", 71 | "tslint": "4.3.0", 72 | "typescript": "~2.0.0" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/server.js: -------------------------------------------------------------------------------- 1 | const serverFactory = require('spa-server'); 2 | 3 | var server = serverFactory.create({ 4 | path: './dist', 5 | port: process.env.port || 5000 6 | }); 7 | 8 | server.start(); 9 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 7 | 10 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, HostBinding, OnInit } from '@angular/core'; 2 | import {NgbDatepickerConfig, NgbDateStruct} from '@ng-bootstrap/ng-bootstrap'; 3 | import { AdalService } from 'ng2-adal/core'; 4 | import { Router, NavigationEnd } from '@angular/router'; 5 | import { AuthService } from './shared/auth.service'; 6 | 7 | @Component({ 8 | selector: 'body', 9 | templateUrl: './app.component.html', 10 | providers: [NgbDatepickerConfig] 11 | }) 12 | export class AppComponent implements OnInit { 13 | @HostBinding('class') public cssClass = 'route'; 14 | UserAuthenticated: boolean; 15 | constructor(datepickerConfig: NgbDatepickerConfig, private router: Router, private adalService: AdalService, private authService: AuthService) { 16 | 17 | // customize default values of datepickers used by this component tree 18 | let date = new Date(); 19 | let year = date.getFullYear(); 20 | let month = date.getMonth() + 1; 21 | let day = date.getDate(); 22 | datepickerConfig.minDate = {year: year, month: month, day: 1}; 23 | datepickerConfig.maxDate = {year: 2099, month: 12, day: 31}; 24 | 25 | // days that don't belong to current month are not visible 26 | datepickerConfig.outsideDays = 'hidden'; 27 | 28 | // disable past days 29 | datepickerConfig.markDisabled = (date: NgbDateStruct) => { 30 | const d = new Date(date.year, date.month - 1, date.day); 31 | let current = new Date(); 32 | return d.getDate() < current.getDate() && d.getMonth() === current.getMonth(); 33 | }; 34 | } 35 | 36 | ngOnInit() { 37 | //adal service 38 | if(this.adalService.userInfo.isAuthenticated){ 39 | this.UserAuthenticated = true; 40 | } 41 | 42 | //scroll to top then route is changed 43 | this.router.events.subscribe((evt) => { 44 | let current_route = this.router.url.substr(1); 45 | if(current_route){ 46 | this.cssClass = 'route-' + current_route; 47 | } 48 | if (!(evt instanceof NavigationEnd)) { 49 | return; 50 | } 51 | document.body.scrollTop = 0; 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { NgModule } from '@angular/core'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { HttpModule } from '@angular/http'; 6 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 7 | 8 | import { AppComponent } from './app.component'; 9 | import { NavbarComponent } from './shared/navbar.component'; 10 | import { FooterComponent } from './shared/footer.component'; 11 | import { FlightsComponent } from './flights/flights.component'; 12 | import { SeatsComponent } from './seats/seats.component'; 13 | import { DealsComponent } from './shared/deals.component'; 14 | import { SearchComponent } from './shared/search.component'; 15 | import { HomeComponent } from './home/home.component'; 16 | import { CityComponent } from './city/city.component'; 17 | import { LoadingComponent } from './shared/loading.component'; 18 | import { CityVideoComponent } from './city-video/city-video.component'; 19 | import { BookingComponent } from './booking/booking.component'; 20 | import { DaysComponent } from './flights/days.component'; 21 | import { OptionsComponent } from './flights/options.component'; 22 | import { ResultsComponent } from './flights/results.component'; 23 | import { BookingService } from './shared/booking.service'; 24 | import { AdalService } from 'ng2-adal/core'; 25 | import { GuardService } from './shared/guard.service'; 26 | import { AuthService } from './shared/auth.service'; 27 | import { UTCPipe } from './shared/utc.pipe'; 28 | import { routing } from './app.routes'; 29 | import { ChartsModule } from 'ng2-charts'; 30 | import { PopupModule } from 'ng2-opd-popup'; 31 | 32 | 33 | @NgModule({ 34 | declarations: [ 35 | AppComponent, 36 | NavbarComponent, 37 | FooterComponent, 38 | DealsComponent, 39 | FlightsComponent, 40 | SeatsComponent, 41 | SearchComponent, 42 | HomeComponent, 43 | LoadingComponent, 44 | CityComponent, 45 | CityVideoComponent, 46 | BookingComponent, 47 | OptionsComponent, 48 | ResultsComponent, 49 | DaysComponent, 50 | UTCPipe 51 | ], 52 | imports: [ 53 | BrowserModule, 54 | FormsModule, 55 | HttpModule, 56 | routing, 57 | NgbModule.forRoot(), 58 | ChartsModule, 59 | PopupModule.forRoot() 60 | ], 61 | providers: [BookingService, AuthService, GuardService, AdalService], 62 | bootstrap: [AppComponent] 63 | }) 64 | 65 | export class AppModule { 66 | constructor(private adalService: AdalService, private authService: AuthService) { 67 | //adal service init 68 | this.adalService.init(this.authService.adalConfig); 69 | this.adalService.handleWindowCallback(); 70 | this.adalService.getUser(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { ModuleWithProviders } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { HomeComponent } from './home/home.component'; 4 | import { FlightsComponent } from './flights/flights.component'; 5 | import { CityComponent } from './city/city.component'; 6 | import { CityVideoComponent } from './city-video/city-video.component'; 7 | import { SeatsComponent } from './seats/seats.component'; 8 | import { BookingComponent } from './booking/booking.component'; 9 | import { GuardService } from './shared/guard.service'; 10 | 11 | // Route Configuration 12 | export const routes: Routes = [ 13 | { 14 | path: '', 15 | pathMatch: 'full', 16 | component: HomeComponent, 17 | canActivate: [GuardService] 18 | }, 19 | { 20 | path: 'barcelona', 21 | component: CityComponent, 22 | canActivate: [GuardService] 23 | }, 24 | { 25 | path: 'barcelona-video', 26 | component: CityVideoComponent, 27 | canActivate: [GuardService] 28 | }, 29 | { 30 | path: 'flights', 31 | component: FlightsComponent, 32 | canActivate: [GuardService] 33 | }, 34 | { 35 | path: 'seats', 36 | component: SeatsComponent, 37 | canActivate: [GuardService] 38 | }, 39 | { 40 | path: 'booking', 41 | component: BookingComponent, 42 | canActivate: [GuardService] 43 | } 44 | ]; 45 | 46 | export const routing: ModuleWithProviders = RouterModule.forRoot(routes); 47 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/booking/booking.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { BookingService } from '../shared/booking.service'; 3 | import { AdalService } from 'ng2-adal/core'; 4 | 5 | @Component({ 6 | templateUrl: './booking.component.html' 7 | }) 8 | export class BookingComponent implements OnInit { 9 | booking: any; 10 | name: string; 11 | price: number; 12 | letters: string[]; 13 | BookingReady: boolean; 14 | PurchaseReady: boolean; 15 | 16 | constructor(private bookingService: BookingService, private adalService: AdalService) { 17 | this.BookingReady = true; 18 | this.PurchaseReady = false; 19 | this.adalService.getUser().subscribe( 20 | res => { 21 | this.name = res.profile.name; 22 | }, 23 | err => { 24 | console.log(err); 25 | } 26 | ); 27 | } 28 | 29 | ngOnInit() { 30 | this.letters = ['A', 'B', 'C', 'D', 'E', 'F']; 31 | this.booking = this.bookingService.get(); 32 | 33 | //asign random seats to flights 34 | for (let i = 0; i < this.booking.there.segments.length; i++) { 35 | this.booking.there.segments[i].seat = this.booking.seat; 36 | } 37 | for (let i = 0; i < this.booking.back.segments.length; i++) { 38 | this.booking.back.segments[i].seat = this.booking.seat; 39 | } 40 | // asign selected seat 41 | this.price = parseInt(this.booking.there.price, 10) + parseInt(this.booking.back.price, 10); 42 | } 43 | 44 | complete() { 45 | this.BookingReady = false; 46 | this.booking.username = this.name; 47 | this.bookingService.push().subscribe( 48 | res => { 49 | this.BookingReady = true; 50 | this.PurchaseReady = true; 51 | }, 52 | err => { 53 | console.log(err); 54 | } 55 | ); 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/city-video/city-video.component.ts: -------------------------------------------------------------------------------- 1 | import { DomSanitizer, SafeStyle } from '@angular/platform-browser'; 2 | import { Component } from '@angular/core'; 3 | import { CityVideosService } from './city-video.service'; 4 | import { Video } from './video'; 5 | 6 | @Component({ 7 | providers: [ CityVideosService ], 8 | templateUrl: '../shared/home.component.html' 9 | }) 10 | export class CityVideoComponent { 11 | CityPage: boolean; 12 | VideoPage: boolean; 13 | CurrentCity: string; 14 | SearchReady: boolean; 15 | DealsReady: boolean; 16 | private base: string = 'https://aka.ms/ampembed?url='; 17 | video: Video; 18 | url: SafeStyle; 19 | 20 | constructor(private cityVideosService: CityVideosService, 21 | private sanitizer: DomSanitizer){ 22 | this.CityPage = true; 23 | this.VideoPage = true; 24 | this.CurrentCity = 'BCN'; 25 | this.SearchReady = false; 26 | } 27 | 28 | ngOnInit() { 29 | this.cityVideosService.get().subscribe( 30 | res => { 31 | this.video = res; 32 | this.url = this.sanitizer.bypassSecurityTrustResourceUrl(this.base + this.video.links.barcelona + this.video.formats.desktop + '?autoplay=true'); 33 | }, 34 | err => { 35 | console.log(err); 36 | } 37 | ); 38 | } 39 | 40 | onSearchReady(status: boolean) { 41 | this.SearchReady = status; 42 | } 43 | 44 | onDealsReady(status: boolean) { 45 | this.DealsReady = status; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ContosoAir/src/ContosoAir.Website/src/app/city-video/city-video.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Observable'; 4 | import 'rxjs/add/operator/catch'; 5 | import 'rxjs/add/operator/map'; 6 | import { Video } from './video'; 7 | import { environment } from '../../environments/environment'; 8 | 9 | @Injectable() 10 | export class CityVideosService { 11 | private videosUrl = environment.api_url + 'videos'; 12 | 13 | constructor (private http: Http) {} 14 | 15 | get(): Observable