Merge remote-tracking branch 'origin/feature/data-and-ui-customization-v2' into dev

# Conflicts:
#	docker-compose.override.yml
#	src/Web/WebMVC/WebMVC.csproj
#	src/Web/WebMVC/wwwroot/css/shared/components/identity/identity.css
#	src/Web/WebMVC/wwwroot/css/site.min.css
#	src/Web/WebSPA/AppSettings.cs
This commit is contained in:
Eduard Tomas 2017-06-28 12:20:20 +02:00
commit 96c3f5c2bc
98 changed files with 2479 additions and 602 deletions

View File

@ -29,6 +29,7 @@ services:
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- EventBusConnection=rabbitmq
- UseCustomizationData=True
ports:
- "5101:80"
@ -40,6 +41,7 @@ services:
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
- UseCustomizationData=True
ports:
- "5105:80"
@ -50,6 +52,7 @@ services:
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- EventBusConnection=rabbitmq
- UseCustomizationData=True
ports:
- "5102:80"
@ -79,6 +82,7 @@ services:
- OrderingUrlHC=http://ordering.api/hc
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
- BasketUrlHC=http://basket.api/hc
- UseCustomizationData=True
ports:
- "5104:80"
@ -92,6 +96,7 @@ services:
- IdentityUrl=http://10.0.75.1:5105
- MarketingUrl=http://marketing.api #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser.
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
- UseCustomizationData=True
ports:
- "5100:80"

View File

@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
@ -42,8 +44,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\U
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{F16E3C6A-1C94-4EAB-BE91-099618060B68}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "test\Services\IntegrationTests\IntegrationTests.csproj", "{5B810E3D-112E-4857-B197-F09D2FD41E27}"

View File

@ -1,8 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.6
VisualStudioVersion = 15.0.26430.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
ProjectSection(ProjectDependencies) = postProject
{A579E108-5445-403D-A407-339AC4D1611B} = {A579E108-5445-403D-A407-339AC4D1611B}
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}
{23FB706A-2701-41E9-8BF9-28936001CA41} = {23FB706A-2701-41E9-8BF9-28936001CA41}
{F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {F0333D8E-0B27-42B7-B2C6-78F3657624E2}
{42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {42681D9D-750A-4DF7-BD9F-9292CFD5C253}
{2110CBB0-3B38-4EE4-A743-DF6968D80D90} = {2110CBB0-3B38-4EE4-A743-DF6968D80D90}
{231226CE-690B-4979-8870-9A79D80928E2} = {231226CE-690B-4979-8870-9A79D80928E2}
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} = {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{91CF7717-08AB-4E65-B10E-0B426F01E2E8}"
@ -49,7 +61,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UnitTests
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Droid", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Droid\eShopOnContainers.TestRunner.Droid.csproj", "{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.Windows", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.Windows\eShopOnContainers.TestRunner.Windows.csproj", "{A7337243-33B8-463A-87AD-944B75EFD820}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.TestRunner.iOS", "src\Mobile\eShopOnContainers\eShopOnContainers.TestRunner.iOS\eShopOnContainers.TestRunner.iOS.csproj", "{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}"
EndProject
@ -67,18 +79,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\U
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
ProjectSection(ProjectDependencies) = postProject
{A579E108-5445-403D-A407-339AC4D1611B} = {A579E108-5445-403D-A407-339AC4D1611B}
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}
{23FB706A-2701-41E9-8BF9-28936001CA41} = {23FB706A-2701-41E9-8BF9-28936001CA41}
{F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {F0333D8E-0B27-42B7-B2C6-78F3657624E2}
{42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {42681D9D-750A-4DF7-BD9F-9292CFD5C253}
{2110CBB0-3B38-4EE4-A743-DF6968D80D90} = {2110CBB0-3B38-4EE4-A743-DF6968D80D90}
{231226CE-690B-4979-8870-9A79D80928E2} = {231226CE-690B-4979-8870-9A79D80928E2}
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} = {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{B473B70F-0796-4862-B1AD-BB742D93B868}"
@ -133,6 +133,54 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|ARM.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhone.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x64.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x64.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x86.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x86.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|ARM.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhone.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x64.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x64.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x86.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x86.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|Any CPU.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|ARM.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|ARM.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhone.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhone.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x64.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x64.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x86.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x86.Build.0 = Release|Any CPU
{2110CBB0-3B38-4EE4-A743-DF6968D80D90}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{2110CBB0-3B38-4EE4-A743-DF6968D80D90}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{2110CBB0-3B38-4EE4-A743-DF6968D80D90}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@ -599,72 +647,72 @@ Global
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.ActiveCfg = Release|Any CPU
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Build.0 = Release|Any CPU
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Deploy.0 = Release|Any CPU
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.ActiveCfg = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.Build.0 = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.Deploy.0 = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.ActiveCfg = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.Build.0 = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.Deploy.0 = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.ActiveCfg = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.Build.0 = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.Deploy.0 = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.ActiveCfg = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.Build.0 = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.Deploy.0 = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.ActiveCfg = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.Build.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.Deploy.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.ActiveCfg = Debug|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Build.0 = Debug|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Deploy.0 = Debug|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.ActiveCfg = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Build.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Deploy.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.Build.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.ActiveCfg = Debug|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Build.0 = Debug|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Deploy.0 = Debug|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.ActiveCfg = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.Build.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.Deploy.0 = Debug|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|Any CPU.ActiveCfg = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.ActiveCfg = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.Build.0 = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.Deploy.0 = Release|ARM
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|iPhone.ActiveCfg = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|iPhoneSimulator.ActiveCfg = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.ActiveCfg = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.Build.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.Deploy.0 = Release|x64
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.ActiveCfg = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.Build.0 = Release|x86
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.Deploy.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|ARM.ActiveCfg = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|ARM.Build.0 = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|ARM.Deploy.0 = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhone.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhone.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhone.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x64.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x64.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x64.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x86.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x86.Build.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x86.Deploy.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|Any CPU.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|Any CPU.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|Any CPU.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|ARM.ActiveCfg = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|ARM.Build.0 = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|ARM.Deploy.0 = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhone.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhone.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhone.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhoneSimulator.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhoneSimulator.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhoneSimulator.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x64.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x64.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x64.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.Build.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.Deploy.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.ActiveCfg = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.Build.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.Deploy.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.ActiveCfg = Debug|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.Build.0 = Debug|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.Deploy.0 = Debug|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.ActiveCfg = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.Build.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.Deploy.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.Build.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.ActiveCfg = Debug|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.Build.0 = Debug|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.Deploy.0 = Debug|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x86.ActiveCfg = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x86.Build.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x86.Deploy.0 = Debug|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|Any CPU.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|ARM.ActiveCfg = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|ARM.Build.0 = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|ARM.Deploy.0 = Release|ARM
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|iPhone.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|iPhoneSimulator.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x64.ActiveCfg = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x64.Build.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x64.Deploy.0 = Release|x64
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.ActiveCfg = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Build.0 = Release|x86
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Deploy.0 = Release|x86
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
@ -986,54 +1034,6 @@ Global
{A579E108-5445-403D-A407-339AC4D1611B}.Release|x64.Build.0 = Release|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.ActiveCfg = Release|Any CPU
{A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|ARM.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhone.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x64.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x64.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x86.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.AppStore|x86.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|ARM.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhone.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x64.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x64.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x86.ActiveCfg = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Debug|x86.Build.0 = Debug|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|Any CPU.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|ARM.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|ARM.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhone.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhone.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x64.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x64.Build.0 = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x86.ActiveCfg = Release|Any CPU
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x86.Build.0 = Release|Any CPU
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@ -1492,7 +1492,7 @@ Global
{B7B1D395-4E06-4036-BE86-C216756B9367} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E}
{F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {B7B1D395-4E06-4036-BE86-C216756B9367}
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {B7B1D395-4E06-4036-BE86-C216756B9367}
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F} = {B7B1D395-4E06-4036-BE86-C216756B9367}
{A7337243-33B8-463A-87AD-944B75EFD820} = {B7B1D395-4E06-4036-BE86-C216756B9367}
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {B7B1D395-4E06-4036-BE86-C216756B9367}
{95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{02DF7FEE-C302-433D-A6CD-237A2569F236} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}

View File

@ -21,6 +21,11 @@
<Content Include="Pics\**\*;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Setup\**\*;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Remove="Setup\Catalogitems - Copy.zip" />
<None Remove="Setup\Catalogitems - Copy.zip" />
<Compile Include="IntegrationEvents\EventHandling\AnyFutureIntegrationEventHandler.cs.txt" />
<Content Update="web.config;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
@ -50,6 +55,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
@ -72,6 +78,9 @@
<None Update="Pics\*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Setup\*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -5,5 +5,7 @@
public string ExternalCatalogBaseUrl {get;set;}
public string EventBusConnection { get; set; }
public bool UseCustomizationData { get; set; }
}
}

View File

@ -235,7 +235,10 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
items.ForEach(x =>
{
x.PictureUri = x.PictureUri.Replace("http://externalcatalogbaseurltobereplaced", baseUri);
if (!x.PictureUri.Contains('/'))
{
x.PictureUri = $"{baseUri}/api/v1/pic/{x.PictureUri}";
}
});
return items;

View File

@ -15,16 +15,58 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
_env = env;
}
[HttpGet("{id}")]
[HttpGet("{filename}")]
// GET: /<controller>/
public IActionResult GetImage(int id)
public IActionResult GetImage(string filename)
{
var webRoot = _env.WebRootPath;
var path = Path.Combine(webRoot, id + ".png");
var path = Path.Combine(webRoot, filename);
var buffer = System.IO.File.ReadAllBytes(path);
return File(buffer, "image/png");
string imageFileExtension = Path.GetExtension(filename);
string mimetype = GetImageMimeTypeFromImageFileExtension(imageFileExtension);
var buffer = System.IO.File.ReadAllBytes(path);
return File(buffer, mimetype);
}
private string GetImageMimeTypeFromImageFileExtension(string extension)
{
string mimetype;
switch (extension)
{
case "png":
mimetype = "image/png";
break;
case "gif":
mimetype = "image/gif";
break;
case "jpg":
case "jpeg":
mimetype = "image/jpeg";
break;
case "bmp":
mimetype = "image/bmp";
break;
case "tiff":
mimetype = "image/tiff";
break;
case "wmf":
mimetype = "image/wmf";
break;
case "jp2":
mimetype = "image/jp2";
break;
case "svg":
mimetype = "image/svg+xml";
break;
default:
mimetype = "application/octet-stream";
break;
}
return mimetype;
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Catalog.API.Extensions
{
public static class LinqSelectExtensions
{
public static IEnumerable<SelectTryResult<TSource, TResult>> SelectTry<TSource, TResult>(this IEnumerable<TSource> enumerable, Func<TSource, TResult> selector)
{
foreach (TSource element in enumerable)
{
SelectTryResult<TSource, TResult> returnedValue;
try
{
returnedValue = new SelectTryResult<TSource, TResult>(element, selector(element), null);
}
catch (Exception ex)
{
returnedValue = new SelectTryResult<TSource, TResult>(element, default(TResult), ex);
}
yield return returnedValue;
}
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.CaughtException));
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<TSource, Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.Source, x.CaughtException));
}
public class SelectTryResult<TSource, TResult>
{
internal SelectTryResult(TSource source, TResult result, Exception exception)
{
Source = source;
Result = result;
CaughtException = exception;
}
public TSource Source { get; private set; }
public TResult Result { get; private set; }
public Exception CaughtException { get; private set; }
}
}
}

View File

@ -2,47 +2,115 @@
{
using EntityFrameworkCore;
using Extensions.Logging;
using global::Catalog.API.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
public class CatalogContextSeed
{
public static async Task SeedAsync(IApplicationBuilder applicationBuilder, ILoggerFactory loggerFactory, int? retry = 0)
public static async Task SeedAsync(IApplicationBuilder applicationBuilder, IHostingEnvironment env, ILoggerFactory loggerFactory, int? retry = 0)
{
var log = loggerFactory.CreateLogger("catalog seed");
var context = (CatalogContext)applicationBuilder
.ApplicationServices.GetService(typeof(CatalogContext));
context.Database.Migrate();
var settings = (CatalogSettings)applicationBuilder
.ApplicationServices.GetRequiredService<IOptions<CatalogSettings>>().Value;
var useCustomizationData = settings.UseCustomizationData;
var contentRootPath = env.ContentRootPath;
var picturePath = env.WebRootPath;
if (!context.CatalogBrands.Any())
{
context.CatalogBrands.AddRange(
GetPreconfiguredCatalogBrands());
context.CatalogBrands.AddRange(useCustomizationData
? GetCatalogBrandsFromFile(contentRootPath, log)
: GetPreconfiguredCatalogBrands()
);
await context.SaveChangesAsync();
}
if (!context.CatalogTypes.Any())
{
context.CatalogTypes.AddRange(
GetPreconfiguredCatalogTypes());
context.CatalogTypes.AddRange(useCustomizationData
? GetCatalogTypesFromFile(contentRootPath, log)
: GetPreconfiguredCatalogTypes()
);
await context.SaveChangesAsync();
}
if (!context.CatalogItems.Any())
{
context.CatalogItems.AddRange(
GetPreconfiguredItems());
context.CatalogItems.AddRange(useCustomizationData
? GetCatalogItemsFromFile(contentRootPath, context, log)
: GetPreconfiguredItems()
);
await context.SaveChangesAsync();
GetCatalogItemPictures(contentRootPath, picturePath);
}
}
static IEnumerable<CatalogBrand> GetCatalogBrandsFromFile(string contentRootPath, ILogger log)
{
string csvFileCatalogBrands = Path.Combine(contentRootPath, "Setup", "CatalogBrands.csv");
if (!File.Exists(csvFileCatalogBrands))
{
return GetPreconfiguredCatalogBrands();
}
string[] csvheaders;
try
{
string[] requiredHeaders = { "catalogbrand" };
csvheaders = GetHeaders( csvFileCatalogBrands, requiredHeaders );
}
catch (Exception ex)
{
log.LogError(ex.Message);
return GetPreconfiguredCatalogBrands();
}
return File.ReadAllLines(csvFileCatalogBrands)
.Skip(1) // skip header row
.SelectTry(x => CreateCatalogBrand(x))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.Where(x => x != null);
}
static CatalogBrand CreateCatalogBrand(string brand)
{
brand = brand.Trim('"').Trim();
if (String.IsNullOrEmpty(brand))
{
throw new Exception("catalog Brand Name is empty");
}
return new CatalogBrand
{
Brand = brand,
};
}
static IEnumerable<CatalogBrand> GetPreconfiguredCatalogBrands()
{
return new List<CatalogBrand>()
@ -50,11 +118,54 @@
new CatalogBrand() { Brand = "Azure"},
new CatalogBrand() { Brand = ".NET" },
new CatalogBrand() { Brand = "Visual Studio" },
new CatalogBrand() { Brand = "SQL Server" },
new CatalogBrand() { Brand = "SQL Server" },
new CatalogBrand() { Brand = "Other" }
};
}
static IEnumerable<CatalogType> GetCatalogTypesFromFile(string contentRootPath, ILogger log)
{
string csvFileCatalogTypes = Path.Combine(contentRootPath, "Setup", "CatalogTypes.csv");
if (!File.Exists(csvFileCatalogTypes))
{
return GetPreconfiguredCatalogTypes();
}
string[] csvheaders;
try
{
string[] requiredHeaders = { "catalogtype" };
csvheaders = GetHeaders( csvFileCatalogTypes, requiredHeaders );
}
catch (Exception ex)
{
log.LogError(ex.Message);
return GetPreconfiguredCatalogTypes();
}
return File.ReadAllLines(csvFileCatalogTypes)
.Skip(1) // skip header row
.SelectTry(x => CreateCatalogType(x))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.Where(x => x != null);
}
static CatalogType CreateCatalogType(string type)
{
type = type.Trim('"').Trim();
if (String.IsNullOrEmpty(type))
{
throw new Exception("catalog Type Name is empty");
}
return new CatalogType
{
Type = type,
};
}
static IEnumerable<CatalogType> GetPreconfiguredCatalogTypes()
{
return new List<CatalogType>()
@ -66,23 +177,204 @@
};
}
static IEnumerable<CatalogItem> GetCatalogItemsFromFile(string contentRootPath, CatalogContext context, ILogger log)
{
string csvFileCatalogItems = Path.Combine(contentRootPath, "Setup", "CatalogItems.csv");
if (!File.Exists(csvFileCatalogItems))
{
return GetPreconfiguredItems();
}
string[] csvheaders;
try
{
string[] requiredHeaders = { "catalogtypename", "catalogbrandname", "description", "name", "price", "pictureuri" };
string[] optionalheaders = { "availablestock", "restockthreshold", "maxstockthreshold", "onreorder" };
csvheaders = GetHeaders(csvFileCatalogItems, requiredHeaders, optionalheaders );
}
catch (Exception ex)
{
log.LogError(ex.Message);
return GetPreconfiguredItems();
}
var catalogTypeIdLookup = context.CatalogTypes.ToDictionary(ct => ct.Type, ct => ct.Id);
var catalogBrandIdLookup = context.CatalogBrands.ToDictionary(ct => ct.Brand, ct => ct.Id);
return File.ReadAllLines(csvFileCatalogItems)
.Skip(1) // skip header row
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") )
.SelectTry(column => CreateCatalogItem(column, csvheaders, catalogTypeIdLookup, catalogBrandIdLookup))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.Where(x => x != null);
}
static CatalogItem CreateCatalogItem(string[] column, string[] headers, Dictionary<String, int> catalogTypeIdLookup, Dictionary<String, int> catalogBrandIdLookup)
{
if (column.Count() != headers.Count())
{
throw new Exception($"column count '{column.Count()}' not the same as headers count'{headers.Count()}'");
}
string catalogTypeName = column[Array.IndexOf(headers, "catalogtypename")].Trim('"').Trim();
if (!catalogTypeIdLookup.ContainsKey(catalogTypeName))
{
throw new Exception($"type={catalogTypeName} does not exist in catalogTypes");
}
string catalogBrandName = column[Array.IndexOf(headers, "catalogbrandname")].Trim('"').Trim();
if (!catalogBrandIdLookup.ContainsKey(catalogBrandName))
{
throw new Exception($"type={catalogTypeName} does not exist in catalogTypes");
}
string priceString = column[Array.IndexOf(headers, "price")].Trim('"').Trim();
if (!Decimal.TryParse(priceString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out Decimal price))
{
throw new Exception($"price={priceString}is not a valid decimal number");
}
var catalogItem = new CatalogItem()
{
CatalogTypeId = catalogTypeIdLookup[catalogTypeName],
CatalogBrandId = catalogBrandIdLookup[catalogBrandName],
Description = column[Array.IndexOf(headers, "description")].Trim('"').Trim(),
Name = column[Array.IndexOf(headers, "name")].Trim('"').Trim(),
Price = price,
PictureUri = column[Array.IndexOf(headers, "pictureuri")].Trim('"').Trim(),
};
int availableStockIndex = Array.IndexOf(headers, "availablestock");
if (availableStockIndex != -1)
{
string availableStockString = column[availableStockIndex].Trim('"').Trim();
if (!String.IsNullOrEmpty(availableStockString))
{
if ( int.TryParse(availableStockString, out int availableStock))
{
catalogItem.AvailableStock = availableStock;
}
else
{
throw new Exception($"availableStock={availableStockString} is not a valid integer");
}
}
}
int restockThresholdIndex = Array.IndexOf(headers, "restockthreshold");
if (restockThresholdIndex != -1)
{
string restockThresholdString = column[restockThresholdIndex].Trim('"').Trim();
if (!String.IsNullOrEmpty(restockThresholdString))
{
if (int.TryParse(restockThresholdString, out int restockThreshold))
{
catalogItem.RestockThreshold = restockThreshold;
}
else
{
throw new Exception($"restockThreshold={restockThreshold} is not a valid integer");
}
}
}
int maxStockThresholdIndex = Array.IndexOf(headers, "maxstockthreshold");
if (maxStockThresholdIndex != -1)
{
string maxStockThresholdString = column[maxStockThresholdIndex].Trim('"').Trim();
if (!String.IsNullOrEmpty(maxStockThresholdString))
{
if (int.TryParse(maxStockThresholdString, out int maxStockThreshold))
{
catalogItem.MaxStockThreshold = maxStockThreshold;
}
else
{
throw new Exception($"maxStockThreshold={maxStockThreshold} is not a valid integer");
}
}
}
int onReorderIndex = Array.IndexOf(headers, "onreorder");
if (onReorderIndex != -1)
{
string onReorderString = column[onReorderIndex].Trim('"').Trim();
if (!String.IsNullOrEmpty(onReorderString))
{
if (bool.TryParse(onReorderString, out bool onReorder))
{
catalogItem.OnReorder = onReorder;
}
else
{
throw new Exception($"onReorder={onReorderString} is not a valid boolean");
}
}
}
return catalogItem;
}
static IEnumerable<CatalogItem> GetPreconfiguredItems()
{
return new List<CatalogItem>()
{
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Bot Black Hoodie", Name = ".NET Bot Black Hoodie", Price = 19.5M, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/1", AvailableStock = 100},
new CatalogItem() { CatalogTypeId=1,CatalogBrandId=2, Description = ".NET Black & White Mug", Name = ".NET Black & White Mug", Price= 8.50M, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/2", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Prism White T-Shirt", Name = "Prism White T-Shirt", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/3", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Foundation T-shirt", Name = ".NET Foundation T-shirt", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/4", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=5, Description = "Roslyn Red Sheet", Name = "Roslyn Red Sheet", Price = 8.5M, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/5", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Blue Hoodie", Name = ".NET Blue Hoodie", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/6", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Roslyn Red T-Shirt", Name = "Roslyn Red T-Shirt", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/7", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Kudu Purple Hoodie", Name = "Kudu Purple Hoodie", Price = 8.5M, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/8", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=1,CatalogBrandId=5, Description = "Cup<T> White Mug", Name = "Cup<T> White Mug", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/9", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=2, Description = ".NET Foundation Sheet", Name = ".NET Foundation Sheet", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/10", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=2, Description = "Cup<T> Sheet", Name = "Cup<T> Sheet", Price = 8.5M, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/11", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Prism White TShirt", Name = "Prism White TShirt", Price = 12, PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/pic/12", AvailableStock = 100 }
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Bot Black Hoodie", Name = ".NET Bot Black Hoodie", Price = 19.5M, PictureUri = "1.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=1,CatalogBrandId=2, Description = ".NET Black & White Mug", Name = ".NET Black & White Mug", Price= 8.50M, PictureUri = "2.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Prism White T-Shirt", Name = "Prism White T-Shirt", Price = 12, PictureUri = "3.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Foundation T-shirt", Name = ".NET Foundation T-shirt", Price = 12, PictureUri = "4.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=5, Description = "Roslyn Red Sheet", Name = "Roslyn Red Sheet", Price = 8.5M, PictureUri = "5.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Blue Hoodie", Name = ".NET Blue Hoodie", Price = 12, PictureUri = "6.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Roslyn Red T-Shirt", Name = "Roslyn Red T-Shirt", Price = 12, PictureUri = "7.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Kudu Purple Hoodie", Name = "Kudu Purple Hoodie", Price = 8.5M, PictureUri = "8.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=1,CatalogBrandId=5, Description = "Cup<T> White Mug", Name = "Cup<T> White Mug", Price = 12, PictureUri = "9.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=2, Description = ".NET Foundation Sheet", Name = ".NET Foundation Sheet", Price = 12, PictureUri = "10.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=2, Description = "Cup<T> Sheet", Name = "Cup<T> Sheet", Price = 8.5M, PictureUri = "11.png", AvailableStock = 100 },
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Prism White TShirt", Name = "Prism White TShirt", Price = 12, PictureUri = "12.png", AvailableStock = 100 }
};
}
static string[] GetHeaders(string csvfile, string[] requiredHeaders, string[] optionalHeaders = null)
{
string[] csvheaders = File.ReadLines(csvfile).First().ToLowerInvariant().Split(',');
if (csvheaders.Count() < requiredHeaders.Count())
{
throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is bigger then csv header count '{csvheaders.Count()}' ");
}
if (optionalHeaders != null)
{
if (csvheaders.Count() > (requiredHeaders.Count() + optionalHeaders.Count()))
{
throw new Exception($"csv header count '{csvheaders.Count()}' is larger then required '{requiredHeaders.Count()}' and optional '{optionalHeaders.Count()}' headers count");
}
}
foreach (var requiredHeader in requiredHeaders)
{
if (!csvheaders.Contains(requiredHeader))
{
throw new Exception($"does not contain required header '{requiredHeader}'");
}
}
return csvheaders;
}
static void GetCatalogItemPictures(string contentRootPath, string picturePath)
{
DirectoryInfo directory = new DirectoryInfo(picturePath);
foreach (FileInfo file in directory.GetFiles())
{
file.Delete();
}
string zipFileCatalogItemPictures = Path.Combine(contentRootPath, "Setup", "CatalogItems.zip");
ZipFile.ExtractToDirectory(zipFileCatalogItemPictures, picturePath);
}
}
}

View File

@ -0,0 +1,8 @@
CatalogBrand
Azure
.NET
Visual Studio
SQL Server
Other
CatalogBrandTestOne
CatalogBrandTestTwo
1 CatalogBrand
2 Azure
3 .NET
4 Visual Studio
5 SQL Server
6 Other
7 CatalogBrandTestOne
8 CatalogBrandTestTwo

View File

@ -0,0 +1,14 @@
CatalogTypeName,CatalogBrandName,Description,Name,Price,PictureUri,availablestock,onreorder
T-Shirt,.NET,".NET Bot Black Hoodie, and more",.NET Bot Black Hoodie,19.5,1.png,100,false
Mug,.NET,.NET Black & White Mug,.NET Black & White Mug,8.50,2.png,89,true
T-Shirt,Other,Prism White T-Shirt,Prism White T-Shirt,12,3.png,56,false
T-Shirt,.NET,.NET Foundation T-shirt,.NET Foundation T-shirt,12,4.png,120,false
Sheet,Other,Roslyn Red Sheet,Roslyn Red Sheet,8.5,5.png,55,false
T-Shirt,.NET,.NET Blue Hoodie,.NET Blue Hoodie,12,6.png,17,false
T-Shirt,Other,Roslyn Red T-Shirt,Roslyn Red T-Shirt",12,7.png,8,false
T-Shirt,Other,Kudu Purple Hoodie,Kudu Purple Hoodie,8.5,8.png,34,false
Mug,Other,Cup<T> White Mug,Cup<T> White Mug,12,9.png,76,false
Sheet,.NET,.NET Foundation Sheet,.NET Foundation Sheet,12,10.png,11,false
Sheet,.NET,Cup<T> Sheet,Cup<T> Sheet,8.5,11.png,3,false
T-Shirt,Other,Prism White TShirt,Prism White TShirt,12,12.png,0,false
Mug, Other, De los Palotes, pepito, 12, 12.png, 0, false
Can't render this file because it contains an unexpected character in line 8 and column 52.

View File

@ -0,0 +1,7 @@
CatalogType
Mug
T-Shirt
Sheet
USB Memory Stick
CatalogTypeTestOne
CatalogTypeTestTwo
1 CatalogType
2 Mug
3 T-Shirt
4 Sheet
5 USB Memory Stick
6 CatalogTypeTestOne
7 CatalogTypeTestTwo

View File

@ -153,7 +153,7 @@
var context = (CatalogContext)app
.ApplicationServices.GetService(typeof(CatalogContext));
WaitForSqlAvailabilityAsync(context, loggerFactory, app).Wait();
WaitForSqlAvailabilityAsync(context, loggerFactory, app, env).Wait();
ConfigureEventBus(app);
@ -165,13 +165,13 @@
integrationEventLogContext.Database.Migrate();
}
private async Task WaitForSqlAvailabilityAsync(CatalogContext ctx, ILoggerFactory loggerFactory, IApplicationBuilder app, int retries = 0)
private async Task WaitForSqlAvailabilityAsync(CatalogContext ctx, ILoggerFactory loggerFactory, IApplicationBuilder app, IHostingEnvironment env, int retries = 0)
{
var logger = loggerFactory.CreateLogger(nameof(Startup));
var policy = CreatePolicy(retries, logger, nameof (WaitForSqlAvailabilityAsync));
await policy.ExecuteAsync(async () =>
{
await CatalogContextSeed.SeedAsync(app, loggerFactory);
await CatalogContextSeed.SeedAsync(app, env, loggerFactory);
});
}

View File

@ -1,6 +1,7 @@
{
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word",
"ExternalCatalogBaseUrl": "http://localhost:5101",
"UseCustomizationData": true,
"Logging": {
"IncludeScopes": false,
"LogLevel": {

View File

@ -8,5 +8,6 @@ namespace eShopOnContainers.Identity
public class AppSettings
{
public string MvcClient { get; set; }
public bool UseCustomizationData { get; set; }
}
}

View File

@ -3,13 +3,21 @@
using AspNetCore.Identity;
using EntityFrameworkCore;
using Extensions.Logging;
using global::eShopOnContainers.Identity;
using global::Identity.API.Data;
using global::Identity.API.Models;
using Identity.API.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
public class ApplicationContextSeed
@ -21,23 +29,38 @@
_passwordHasher = passwordHasher;
}
public async Task SeedAsync(IApplicationBuilder applicationBuilder, ILoggerFactory loggerFactory, int? retry = 0)
public async Task SeedAsync(IApplicationBuilder applicationBuilder, IHostingEnvironment env, ILoggerFactory loggerFactory, int? retry = 0)
{
int retryForAvaiability = retry.Value;
try
{
var log = loggerFactory.CreateLogger("application seed");
var context = (ApplicationDbContext)applicationBuilder
.ApplicationServices.GetService(typeof(ApplicationDbContext));
context.Database.Migrate();
var settings = (AppSettings)applicationBuilder
.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Value;
var useCustomizationData = settings.UseCustomizationData;
var contentRootPath = env.ContentRootPath;
var webroot = env.WebRootPath;
if (!context.Users.Any())
{
context.Users.AddRange(
GetDefaultUser());
context.Users.AddRange(useCustomizationData
? GetUsersFromFile(contentRootPath, log)
: GetDefaultUser());
await context.SaveChangesAsync();
}
if (useCustomizationData)
{
GetPreconfiguredImages(contentRootPath, webroot, log);
}
}
catch (Exception ex)
{
@ -46,14 +69,93 @@
retryForAvaiability++;
var log = loggerFactory.CreateLogger("catalog seed");
log.LogError(ex.Message);
await SeedAsync(applicationBuilder, loggerFactory, retryForAvaiability);
await SeedAsync(applicationBuilder, env, loggerFactory, retryForAvaiability);
}
}
}
private ApplicationUser GetDefaultUser()
private IEnumerable<ApplicationUser> GetUsersFromFile(string contentRootPath, ILogger log)
{
var user =
string csvFileUsers = Path.Combine(contentRootPath, "Setup", "Users.csv");
if (!File.Exists(csvFileUsers))
{
return GetDefaultUser();
}
string[] csvheaders;
try
{
string[] requiredHeaders = {
"cardholdername", "cardnumber", "cardtype", "city", "country",
"email", "expiration", "lastname", "name", "phonenumber",
"username", "zipcode", "state", "street", "securitynumber",
"normalizedemail", "normalizedusername", "password"
};
csvheaders = GetHeaders(requiredHeaders, csvFileUsers);
}
catch (Exception ex)
{
log.LogError(ex.Message);
return GetDefaultUser();
}
List<ApplicationUser> users = File.ReadAllLines(csvFileUsers)
.Skip(1) // skip header column
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") )
.SelectTry(column => CreateApplicationUser(column, csvheaders))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.Where(x => x != null)
.ToList();
return users;
}
private ApplicationUser CreateApplicationUser(string[] column, string[] headers)
{
if (column.Count() != headers.Count())
{
throw new Exception($"column count '{column.Count()}' not the same as headers count'{headers.Count()}'");
}
string cardtypeString = column[Array.IndexOf(headers, "cardtype")].Trim('"').Trim();
if (!int.TryParse(cardtypeString, out int cardtype))
{
throw new Exception($"cardtype='{cardtypeString}' is not a number");
}
var user = new ApplicationUser
{
CardHolderName = column[Array.IndexOf(headers, "cardholdername")].Trim('"').Trim(),
CardNumber = column[Array.IndexOf(headers, "cardnumber")].Trim('"').Trim(),
CardType = cardtype,
City = column[Array.IndexOf(headers, "city")].Trim('"').Trim(),
Country = column[Array.IndexOf(headers, "country")].Trim('"').Trim(),
Email = column[Array.IndexOf(headers, "email")].Trim('"').Trim(),
Expiration = column[Array.IndexOf(headers, "expiration")].Trim('"').Trim(),
Id = Guid.NewGuid().ToString(),
LastName = column[Array.IndexOf(headers, "lastname")].Trim('"').Trim(),
Name = column[Array.IndexOf(headers, "name")].Trim('"').Trim(),
PhoneNumber = column[Array.IndexOf(headers, "phonenumber")].Trim('"').Trim(),
UserName = column[Array.IndexOf(headers, "username")].Trim('"').Trim(),
ZipCode = column[Array.IndexOf(headers, "zipcode")].Trim('"').Trim(),
State = column[Array.IndexOf(headers, "state")].Trim('"').Trim(),
Street = column[Array.IndexOf(headers, "street")].Trim('"').Trim(),
SecurityNumber = column[Array.IndexOf(headers, "securitynumber")].Trim('"').Trim(),
NormalizedEmail = column[Array.IndexOf(headers, "normalizedemail")].Trim('"').Trim(),
NormalizedUserName = column[Array.IndexOf(headers, "normalizedusername")].Trim('"').Trim(),
SecurityStamp = Guid.NewGuid().ToString("D"),
PasswordHash = column[Array.IndexOf(headers, "password")].Trim('"').Trim(), // Note: This is the password
};
user.PasswordHash = _passwordHasher.HashPassword(user, user.PasswordHash);
return user;
}
private IEnumerable<ApplicationUser> GetDefaultUser()
{
var user =
new ApplicationUser()
{
CardHolderName = "DemoUser",
@ -63,23 +165,86 @@
Country = "U.S.",
Email = "demouser@microsoft.com",
Expiration = "12/20",
Id = Guid.NewGuid().ToString(),
LastName = "DemoLastName",
Name = "DemoUser",
PhoneNumber = "1234567890",
UserName = "demouser@microsoft.com",
ZipCode = "98052",
State = "WA",
Street = "15703 NE 61st Ct",
SecurityNumber = "535",
NormalizedEmail = "DEMOUSER@MICROSOFT.COM",
NormalizedUserName = "DEMOUSER@MICROSOFT.COM",
SecurityStamp = Guid.NewGuid().ToString("D")
Id = Guid.NewGuid().ToString(),
LastName = "DemoLastName",
Name = "DemoUser",
PhoneNumber = "1234567890",
UserName = "demouser@microsoft.com",
ZipCode = "98052",
State = "WA",
Street = "15703 NE 61st Ct",
SecurityNumber = "535",
NormalizedEmail = "DEMOUSER@MICROSOFT.COM",
NormalizedUserName = "DEMOUSER@MICROSOFT.COM",
SecurityStamp = Guid.NewGuid().ToString("D"),
};
user.PasswordHash = _passwordHasher.HashPassword(user, "Pass@word1");
return user;
return new List<ApplicationUser>()
{
user
};
}
static string[] GetHeaders(string[] requiredHeaders, string csvfile)
{
string[] csvheaders = File.ReadLines(csvfile).First().ToLowerInvariant().Split(',');
if (csvheaders.Count() != requiredHeaders.Count())
{
throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is different then read header '{csvheaders.Count()}'");
}
foreach (var requiredHeader in requiredHeaders)
{
if (!csvheaders.Contains(requiredHeader))
{
throw new Exception($"does not contain required header '{requiredHeader}'");
}
}
return csvheaders;
}
static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger log)
{
try
{
string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip");
if (!File.Exists(imagesZipFile))
{
log.LogError($" zip file '{imagesZipFile}' does not exists.");
return;
}
string imagePath = Path.Combine(webroot, "images");
string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray();
using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
if (imageFiles.Contains(entry.Name))
{
string destinationFilename = Path.Combine(imagePath, entry.Name);
if (File.Exists(destinationFilename))
{
File.Delete(destinationFilename);
}
entry.ExtractToFile(destinationFilename);
}
else
{
log.LogWarning($"Skip file '{entry.Name}' in zipfile '{imagesZipFile}'");
}
}
}
}
catch (Exception ex)
{
log.LogError($"Exception in method GetPreconfiguredImages WebMVC. Exception Message={ex.Message}");
}
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Identity.API.Extensions
{
public static class LinqSelectExtensions
{
public static IEnumerable<SelectTryResult<TSource, TResult>> SelectTry<TSource, TResult>(this IEnumerable<TSource> enumerable, Func<TSource, TResult> selector)
{
foreach (TSource element in enumerable)
{
SelectTryResult<TSource, TResult> returnedValue;
try
{
returnedValue = new SelectTryResult<TSource, TResult>(element, selector(element), null);
}
catch (Exception ex)
{
returnedValue = new SelectTryResult<TSource, TResult>(element, default(TResult), ex);
}
yield return returnedValue;
}
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.CaughtException));
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<TSource, Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.Source, x.CaughtException));
}
public class SelectTryResult<TSource, TResult>
{
internal SelectTryResult(TSource source, TResult result, Exception exception)
{
Source = source;
Result = result;
CaughtException = exception;
}
public TSource Source { get; private set; }
public TResult Result { get; private set; }
public Exception CaughtException { get; private set; }
}
}
}

View File

@ -8,7 +8,13 @@
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<Content Include="Setup\**\*;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.2" />
@ -70,6 +76,9 @@
<None Update="Dockerfile">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Setup\*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,2 @@
CardHolderName,CardNumber,CardType,City,Country,Email,Expiration,LastName,Name,PhoneNumber,UserName,ZipCode,State,Street,SecurityNumber,NormalizedEmail,NormalizedUserName,Password
DemoUser,4012888888881881,1,Redmond,U.S.,demouser@microsoft.com,12/20,DemoLastName,DemoUser,1234567890,demouser@microsoft.com,98052,WA,15703 NE 61st Ct,535,DEMOUSER@MICROSOFT.COM,DEMOUSER@MICROSOFT.COM,Pass@word1
1 CardHolderName CardNumber CardType City Country Email Expiration LastName Name PhoneNumber UserName ZipCode State Street SecurityNumber NormalizedEmail NormalizedUserName Password
2 DemoUser 4012888888881881 1 Redmond U.S. demouser@microsoft.com 12/20 DemoLastName DemoUser 1234567890 demouser@microsoft.com 98052 WA 15703 NE 61st Ct 535 DEMOUSER@MICROSOFT.COM DEMOUSER@MICROSOFT.COM Pass@word1

Binary file not shown.

View File

@ -153,7 +153,7 @@ namespace eShopOnContainers.Identity
//Seed Data
var hasher = new PasswordHasher<ApplicationUser>();
new ApplicationContextSeed(hasher).SeedAsync(app, loggerFactory).Wait();
new ApplicationContextSeed(hasher).SeedAsync(app, env, loggerFactory).Wait();
}
private async Task InitializeGrantStoreAndConfiguration(IApplicationBuilder app)

View File

@ -40,10 +40,7 @@
<br><div class="brand"></div>
</div>
<div class="col-sm-6">
<br />
<br>
<br />
<div class="text hidden-xs">&copy; e-ShoponContainers. All right reserved</div>
<img class="text hidden-xs" src="~/images/main_footer_text.PNG" width="335" height="26" alt="footer text image" />
</div>
</div>
</div>

View File

@ -6,6 +6,7 @@
"MvcClient": "http://localhost:5100",
"SpaClient": "http://localhost:5104",
"XamarinCallback": "http://localhost:5105/xamarincallback",
"UseCustomizationData": true,
"Logging": {
"IncludeScopes": false,
"LogLevel": {

View File

@ -476,11 +476,7 @@ footer {
}
footer .text {
text-align: right;
width: 100%;
height: 100%;
color: #83D01B;
margin-top: 10px;
margin-top: 55px;
}
.text {

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 252 B

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Ordering.API.Extensions
{
public static class LinqSelectExtensions
{
public static IEnumerable<SelectTryResult<TSource, TResult>> SelectTry<TSource, TResult>(this IEnumerable<TSource> enumerable, Func<TSource, TResult> selector)
{
foreach (TSource element in enumerable)
{
SelectTryResult<TSource, TResult> returnedValue;
try
{
returnedValue = new SelectTryResult<TSource, TResult>(element, selector(element), null);
}
catch (Exception ex)
{
returnedValue = new SelectTryResult<TSource, TResult>(element, default(TResult), ex);
}
yield return returnedValue;
}
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.CaughtException));
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<TSource, Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.Source, x.CaughtException));
}
public class SelectTryResult<TSource, TResult>
{
internal SelectTryResult(TSource source, TResult result, Exception exception)
{
Source = source;
Result = result;
CaughtException = exception;
}
public TSource Source { get; private set; }
public TResult Result { get; private set; }
public Exception CaughtException { get; private set; }
}
}
}

View File

@ -8,40 +8,175 @@
using System.Threading.Tasks;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using System.IO;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using global::Ordering.API.Extensions;
public class OrderingContextSeed
{
public static async Task SeedAsync(IApplicationBuilder applicationBuilder)
public static async Task SeedAsync(IApplicationBuilder applicationBuilder, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var log = loggerFactory.CreateLogger("ordering seed");
var context = (OrderingContext)applicationBuilder
.ApplicationServices.GetService(typeof(OrderingContext));
var settings = applicationBuilder
.ApplicationServices.GetRequiredService<IOptions<OrderingSettings>>().Value;
var useCustomizationData = settings.UseCustomizationData;
var contentRootPath = env.ContentRootPath;
using (context)
{
context.Database.Migrate();
if (!context.CardTypes.Any())
{
context.CardTypes.Add(CardType.Amex);
context.CardTypes.Add(CardType.Visa);
context.CardTypes.Add(CardType.MasterCard);
context.CardTypes.AddRange(useCustomizationData
? GetCardTypesFromFile(contentRootPath, log)
: GetPredefinedCardTypes());
await context.SaveChangesAsync();
}
if (!context.OrderStatus.Any())
{
context.OrderStatus.Add(OrderStatus.Submitted);
context.OrderStatus.Add(OrderStatus.AwaitingValidation);
context.OrderStatus.Add(OrderStatus.StockConfirmed);
context.OrderStatus.Add(OrderStatus.Paid);
context.OrderStatus.Add(OrderStatus.Shipped);
context.OrderStatus.Add(OrderStatus.Cancelled);
context.OrderStatus.AddRange(useCustomizationData
? GetOrderStatusFromFile(contentRootPath, log)
: GetPredefinedOrderStatus());
}
await context.SaveChangesAsync();
}
}
static IEnumerable<CardType> GetCardTypesFromFile(string contentRootPath, ILogger log)
{
string csvFileCardTypes = Path.Combine(contentRootPath, "Setup", "CardTypes.csv");
if (!File.Exists(csvFileCardTypes))
{
return GetPredefinedCardTypes();
}
string[] csvheaders;
try
{
string[] requiredHeaders = { "CardType" };
csvheaders = GetHeaders(requiredHeaders, csvFileCardTypes);
}
catch (Exception ex)
{
log.LogError(ex.Message);
return GetPredefinedCardTypes();
}
int id = 1;
return File.ReadAllLines(csvFileCardTypes)
.Skip(1) // skip header column
.SelectTry(x => CreateCardType(x, ref id))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.Where(x => x != null);
}
static CardType CreateCardType(string value, ref int id)
{
if (String.IsNullOrEmpty(value))
{
throw new Exception("Orderstatus is null or empty");
}
return new CardType(id++, value.Trim('"').Trim());
}
private static IEnumerable<CardType> GetPredefinedCardTypes()
{
return new List<CardType>()
{
CardType.Amex,
CardType.Visa,
CardType.MasterCard
};
}
static IEnumerable<OrderStatus> GetOrderStatusFromFile(string contentRootPath, ILogger log)
{
string csvFileOrderStatus = Path.Combine(contentRootPath, "Setup", "OrderStatus.csv");
if (!File.Exists(csvFileOrderStatus))
{
return GetPredefinedOrderStatus();
}
string[] csvheaders;
try
{
string[] requiredHeaders = { "OrderStatus" };
csvheaders = GetHeaders(requiredHeaders, csvFileOrderStatus);
}
catch (Exception ex)
{
log.LogError(ex.Message);
return GetPredefinedOrderStatus();
}
int id = 1;
return File.ReadAllLines(csvFileOrderStatus)
.Skip(1) // skip header row
.SelectTry(x => CreateOrderStatus(x, ref id))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.Where(x => x != null);
}
static OrderStatus CreateOrderStatus(string value, ref int id)
{
if (String.IsNullOrEmpty(value))
{
throw new Exception("Orderstatus is null or empty");
}
return new OrderStatus(id++, value.Trim('"').Trim().ToLowerInvariant());
}
static IEnumerable<OrderStatus> GetPredefinedOrderStatus()
{
return new List<OrderStatus>()
{
OrderStatus.Submitted,
OrderStatus.AwaitingValidation,
OrderStatus.StockConfirmed,
OrderStatus.Paid,
OrderStatus.Shipped,
OrderStatus.Cancelled
};
}
static string[] GetHeaders(string[] requiredHeaders, string csvfile)
{
string[] csvheaders = File.ReadLines(csvfile).First().ToLowerInvariant().Split(',');
if (csvheaders.Count() != requiredHeaders.Count())
{
throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is different then read header '{csvheaders.Count()}'");
}
foreach (var requiredHeader in requiredHeaders)
{
if (!csvheaders.Contains(requiredHeader))
{
throw new Exception($"does not contain required header '{requiredHeader}'");
}
}
return csvheaders;
}
}
}

View File

@ -16,6 +16,9 @@
<Content Include=".dockerignore;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Setup\**\*;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
@ -73,6 +76,9 @@
<None Update="Dockerfile">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Setup\*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,7 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API
{
public class OrderingSettings
{
public bool UseCustomizationData { get; set; }
}
}

View File

@ -0,0 +1,5 @@
CardType
Amex
Visa
MasterCard
Capital One
1 CardType
2 Amex
3 Visa
4 MasterCard
5 Capital One

View File

@ -0,0 +1,7 @@
OrderStatus
Submitted
AwaitingValidation
StockConfirmed
Paid
Shipped
Cancelled
1 OrderStatus
2 Submitted
3 AwaitingValidation
4 StockConfirmed
5 Paid
6 Shipped
7 Cancelled

View File

@ -87,6 +87,8 @@
ServiceLifetime.Scoped //Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request)
);
services.Configure<OrderingSettings>(Configuration);
services.AddSwaggerGen(options =>
{
options.DescribeAllEnumsAsStrings();
@ -159,7 +161,7 @@
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
WaitForSqlAvailabilityAsync(loggerFactory, app).Wait();
WaitForSqlAvailabilityAsync(loggerFactory, app, env).Wait();
ConfigureEventBus(app);
var integrationEventLogContext = new IntegrationEventLogContext(
@ -200,13 +202,13 @@
}
private async Task WaitForSqlAvailabilityAsync(ILoggerFactory loggerFactory, IApplicationBuilder app, int retries = 0)
private async Task WaitForSqlAvailabilityAsync(ILoggerFactory loggerFactory, IApplicationBuilder app, IHostingEnvironment env, int retries = 0)
{
var logger = loggerFactory.CreateLogger(nameof(Startup));
var policy = CreatePolicy(retries, logger, nameof(WaitForSqlAvailabilityAsync));
await policy.ExecuteAsync(async () =>
{
await OrderingContextSeed.SeedAsync(app);
await OrderingContextSeed.SeedAsync(app, env, loggerFactory);
});
}

View File

@ -1,6 +1,7 @@
{
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
"IdentityUrl": "http://localhost:5105",
"UseCustomizationData": true,
"Logging": {
"IncludeScopes": false,
"LogLevel": {

View File

@ -13,6 +13,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
public string BasketUrl { get; set; }
public string MarketingUrl { get; set; }
public Logging Logging { get; set; }
public bool UseCustomizationData { get; set; }
}
public class Connectionstrings

View File

@ -0,0 +1,97 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.WebMVC;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace WebMVC.Infrastructure
{
public class WebContextSeed
{
public static void Seed(IApplicationBuilder applicationBuilder, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var log = loggerFactory.CreateLogger("WebMVC seed");
var settings = (AppSettings)applicationBuilder
.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Value;
var useCustomizationData = settings.UseCustomizationData;
var contentRootPath = env.ContentRootPath;
var webroot = env.WebRootPath;
if (useCustomizationData)
{
GetPreconfiguredImages(contentRootPath, webroot, log);
GetPreconfiguredCSS(contentRootPath, webroot, log);
}
}
static void GetPreconfiguredCSS(string contentRootPath, string webroot, ILogger log)
{
try
{
string overrideCssFile = Path.Combine(contentRootPath, "Setup", "override.css");
if (!File.Exists(overrideCssFile))
{
log.LogError($" override css file '{overrideCssFile}' does not exists.");
return;
}
string destinationFilename = Path.Combine(webroot, "css", "override.css");
File.Copy(overrideCssFile, destinationFilename, true );
}
catch (Exception ex)
{
log.LogError($"Exception in method GetPreconfiguredCSS WebMVC. Exception Message={ex.Message}");
}
}
static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger log)
{
try
{
string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip");
if (!File.Exists(imagesZipFile))
{
log.LogError($" zip file '{imagesZipFile}' does not exists.");
return;
}
string imagePath = Path.Combine(webroot, "images");
string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray();
using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
if (imageFiles.Contains(entry.Name))
{
string destinationFilename = Path.Combine(imagePath, entry.Name);
if (File.Exists(destinationFilename))
{
File.Delete(destinationFilename);
}
entry.ExtractToFile(destinationFilename);
}
else
{
log.LogWarning($"Skip file '{entry.Name}' in zipfile '{imagesZipFile}'");
}
}
}
}
catch ( Exception ex )
{
log.LogError($"Exception in method GetPreconfiguredImages WebMVC. Exception Message={ex.Message}");
}
}
}
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
.esh-catalog-button {
background-color: #83D01B; /* to override the style of this button ie. to make it red, use background-color: #FF001b; */
}

View File

@ -12,6 +12,7 @@ using Microsoft.Extensions.HealthChecks;
using Microsoft.Extensions.Logging;
using System;
using System.IdentityModel.Tokens.Jwt;
using WebMVC.Infrastructure;
namespace Microsoft.eShopOnContainers.WebMVC
{
@ -129,6 +130,9 @@ namespace Microsoft.eShopOnContainers.WebMVC
Scope = { "openid", "profile", "orders", "basket", "marketing" }
};
//Seed Data
WebContextSeed.Seed(app, env, loggerFactory);
//Wait untill identity service is ready on compose.
app.UseOpenIdConnectAuthentication(oidcOptions);

View File

@ -68,9 +68,9 @@
<img class="esh-orders_detail-image" src="@item.PictureUrl">
</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-4">@item.ProductName</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">$ @Math.Round(item.UnitPrice, 2)</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">$ @item.UnitPrice.ToString("N2")</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">@item.Units</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-2">$ @Math.Round(item.Units * item.UnitPrice, 2)</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-2">$ @Math.Round(item.Units * item.UnitPrice, 2).ToString("N2")</section>
</article>
}
</section>

View File

@ -20,14 +20,14 @@
<input type="hidden" value="@item.ProductName" name=@("orderitems[" + i + "].ProductName") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
$ @item.UnitPrice
$ @item.UnitPrice.ToString("N2")
<input type="hidden" value="@item.UnitPrice" name=@("orderitems[" + i + "].UnitPrice") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
@item.Units
<input type="hidden" value="@item.Units" name=@("orderitems[" + i + "].Units") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-2">$ @Math.Round(item.Units * item.UnitPrice, 2)</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-2">$ @Math.Round(item.Units * item.UnitPrice, 2).ToString("N2")</section>
</article>
}
</section>
@ -41,7 +41,7 @@
<article class="esh-orders_new-items row">
<section class="esh-orders_new-item col-xs-9"></section>
<section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">
$ @Model.Total
$ @Model.Total.ToString("N2")
<input type="hidden" value="@Model.Total" name="Total"/>
</section>
</article>

View File

@ -23,12 +23,12 @@
<img class="esh-basket-image" src="@item.PictureUrl" />
</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-3">@item.ProductName</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-2">$ @item.UnitPrice</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-2">$ @item.UnitPrice.ToString("N2")</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-2">
<input type="hidden" name="@("quantities[" + i +"].Key")" value="@item.Id" />
<input type="number" class="esh-basket-input" min="1" name="@("quantities[" + i +"].Value")" value="@item.Quantity" />
</section>
<section class="esh-basket-item esh-basket-item--middle esh-basket-item--mark col-xs-2">$ @Math.Round(item.Quantity * item.UnitPrice, 2)</section>
<section class="esh-basket-item esh-basket-item--middle esh-basket-item--mark col-xs-2">$ @Math.Round(item.Quantity * item.UnitPrice, 2).ToString("N2")</section>
</div>
<div class="row">

View File

@ -19,12 +19,14 @@
<link rel="stylesheet" href="~/css/orders/orders.component.css" />
<link rel="stylesheet" href="~/css/orders/orders-detail/orders-detail.component.css" />
<link rel="stylesheet" href="~/css/orders/orders-new/orders-new.component.css" />
<link rel="stylesheet" href="~/css/override.css" type="text/css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
<link rel="stylesheet" href="~/css/override.css" type="text/css" />
</environment>
</head>
<body>
@ -56,7 +58,7 @@
</section>
<section class="col-sm-6">
<div class="esh-app-footer-text hidden-xs"> e-ShoponContainers. By Microsoft Corp. </div>
<img class="esh-app-footer-text hidden-xs" src="~/images/main_footer_text.png" width="335" height="26" alt="footer text image" />
</section>
</article>

View File

@ -9,6 +9,24 @@
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Extensions\LinqSelectExtensions.cs" />
<Compile Remove="Services\CustomUIService.cs" />
<Compile Remove="Services\ICustomUIService.cs" />
</ItemGroup>
<ItemGroup>
<Content Remove="Views\Shared\_Footer.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Setup\images.zip">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Setup\override.css">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<!--<ItemGroup>
<Compile Remove="wwwroot\lib\bootstrap\**" />

View File

@ -7,6 +7,7 @@
"CallBackUrl": "http://localhost:5100/",
"IsClusterEnv": "False",
"UseResilientHttp": "True",
"UseCustomizationData": true,
"Logging": {
"IncludeScopes": false,
"LogLevel": {

View File

@ -0,0 +1,42 @@
[
{
"outputFile": "wwwroot/css/orders/orders.component.css",
"inputFile": "wwwroot/css/orders/orders.component.scss"
},
{
"outputFile": "wwwroot/css/orders/orders-new/orders-new.component.css",
"inputFile": "wwwroot/css/orders/orders-new/orders-new.component.scss"
},
{
"outputFile": "wwwroot/css/orders/orders-detail/orders-detail.component.css",
"inputFile": "wwwroot/css/orders/orders-detail/orders-detail.component.scss"
},
{
"outputFile": "wwwroot/css/catalog/catalog.component.css",
"inputFile": "wwwroot/css/catalog/catalog.component.scss"
},
{
"outputFile": "wwwroot/css/basket/basket.component.css",
"inputFile": "wwwroot/css/basket/basket.component.scss"
},
{
"outputFile": "wwwroot/css/basket/basket-status/basket-status.component.css",
"inputFile": "wwwroot/css/basket/basket-status/basket-status.component.scss"
},
{
"outputFile": "wwwroot/css/shared/components/header/header.css",
"inputFile": "wwwroot/css/shared/components/header/header.scss"
},
{
"outputFile": "wwwroot/css/shared/components/identity/identity.css",
"inputFile": "wwwroot/css/shared/components/identity/identity.scss"
},
{
"outputFile": "wwwroot/css/shared/components/pager/pager.css",
"inputFile": "wwwroot/css/shared/components/pager/pager.scss"
},
{
"outputFile": "wwwroot/css/app.component.css",
"inputFile": "wwwroot/css/app.component.scss"
}
]

View File

@ -0,0 +1,49 @@
{
"compilers": {
"less": {
"autoPrefix": "",
"cssComb": "none",
"ieCompat": true,
"strictMath": false,
"strictUnits": false,
"relativeUrls": true,
"rootPath": "",
"sourceMapRoot": "",
"sourceMapBasePath": "",
"sourceMap": false
},
"sass": {
"includePath": "",
"indentType": "space",
"indentWidth": 2,
"outputStyle": "expanded",
"Precision": 5,
"relativeUrls": true,
"sourceMapRoot": "",
"sourceMap": false
},
"stylus": {
"sourceMap": false
},
"babel": {
"sourceMap": false
},
"coffeescript": {
"bare": false,
"runtimeMode": "node",
"sourceMap": false
}
},
"minifiers": {
"css": {
"enabled": true,
"termSemicolons": true,
"gzip": false
},
"javascript": {
"enabled": true,
"termSemicolons": true,
"gzip": false
}
}
}

View File

@ -0,0 +1,58 @@
// Colors
$color-brand: #00A69C;
$color-brand-dark: darken($color-brand, 10%);
$color-brand-darker: darken($color-brand, 20%);
$color-brand-bright: lighten($color-brand, 10%);
$color-brand-brighter: lighten($color-brand, 20%);
$color-secondary: #83D01B;
$color-secondary-dark: darken($color-secondary, 5%);
$color-secondary-darker: darken($color-secondary, 20%);
$color-secondary-bright: lighten($color-secondary, 10%);
$color-secondary-brighter: lighten($color-secondary, 20%);
$color-background-dark: #333333;
$color-background-darker: #000000;
$color-background-bright: #EEEEFF;
$color-background-brighter: #FFFFFF;
$color-foreground-dark: #333333;
$color-foreground-darker: #000000;
$color-foreground-bright: #EEEEEE;
$color-foreground-brighter: #FFFFFF;
// Animations
$animation-speed-default: .35s;
$animation-speed-slow: .5s;
$animation-speed-fast: .15s;
// Fonts
$font-weight-light: 200;
$font-weight-semilight: 300;
$font-weight-normal: 400;
$font-weight-semibold: 600;
$font-weight-bold: 700;
$font-size-xs: .65rem; // 10.4px
$font-size-s: .85rem; // 13.6px
$font-size-m: 1rem; // 16px
$font-size-l: 1.25rem; // 20px
$font-size-xl: 1.5rem; // 24px
// Medias
$media-screen-xxs: 360px;
$media-screen-xs: 640px;
$media-screen-s: 768px;
$media-screen-m: 1024px;
$media-screen-l: 1280px;
$media-screen-xl: 1440px;
$media-screen-xxl: 1680px;
$media-screen-xxxl: 1920px;
// Borders
$border-light: 1px;
// Images
$image_path: '../../images/';
$image-main_banner: '#{$image_path}main_banner.png';
$image-arrow_down: '#{$image_path}arrow-down.png';

View File

@ -1,20 +1,14 @@
.esh-app-footer {
background-color: #000000;
border-top: 1px solid #EEEEEE;
margin-top: 2.5rem;
padding-bottom: 2.5rem;
padding-top: 2.5rem;
width: 100%;
.esh-app-footer {
background-color: #000000;
border-top: 1px solid #EEEEEE;
margin-top: 2.5rem;
padding-bottom: 2.5rem;
padding-top: 2.5rem;
width: 100%;
}
.esh-app-footer-brand {
height: 50px;
width: 230px;
height: 50px;
width: 230px;
}
.esh-app-footer-text {
color: #83D01B;
line-height: 50px;
text-align: right;
width: 100%;
}

View File

@ -0,0 +1,23 @@
@import './variables';
.esh-app {
&-footer {
$margin: 2.5rem;
$padding: 2.5rem;
background-color: $color-background-darker;
border-top: $border-light solid $color-foreground-bright;
margin-top: $margin;
padding-bottom: $padding;
padding-top: $padding;
width: 100%;
$height: 50px;
&-brand {
height: $height;
width: 230px;
}
}
}

View File

@ -1,38 +1,39 @@
.esh-basketstatus {
cursor: pointer;
display: inline-block;
float: right;
position: relative;
transition: all 0.35s;
.esh-basketstatus {
cursor: pointer;
display: inline-block;
float: right;
position: relative;
transition: all 0.35s;
}
.esh-basketstatus.is-disabled {
opacity: .5;
pointer-events: none;
}
.esh-basketstatus.is-disabled {
opacity: .5;
pointer-events: none;
}
.esh-basketstatus-image {
height: 36px;
margin-top: .5rem;
height: 36px;
margin-top: .5rem;
}
.esh-basketstatus-badge {
background-color: #83D01B;
border-radius: 50%;
color: #FFFFFF;
display: block;
height: 1.5rem;
left: 50%;
position: absolute;
text-align: center;
top: 0;
transform: translateX(-38%);
transition: all 0.35s;
width: 1.5rem;
background-color: #83D01B;
border-radius: 50%;
color: #FFFFFF;
display: block;
height: 1.5rem;
left: 50%;
position: absolute;
text-align: center;
top: 0;
transform: translateX(-38%);
transition: all 0.35s;
width: 1.5rem;
}
.esh-basketstatus:hover .esh-basketstatus-badge {
background-color: transparent;
color: #75b918;
transition: all 0.35s;
background-color: transparent;
color: #75b918;
transition: all 0.35s;
}

View File

@ -0,0 +1,41 @@
@import '../../variables';
.esh-basketstatus {
cursor: pointer;
display: inline-block;
float: right;
position: relative;
transition: all $animation-speed-default;
&.is-disabled {
opacity: .5;
pointer-events: none;
}
&-image {
height: 36px;
margin-top: .5rem;
}
&-badge {
$size: 1.5rem;
background-color: $color-secondary;
border-radius: 50%;
color: $color-foreground-brighter;
display: block;
height: $size;
left: 50%;
position: absolute;
text-align: center;
top: 0;
transform: translateX(-38%);
transition: all $animation-speed-default;
width: $size;
}
&:hover &-badge {
background-color: transparent;
color: $color-secondary-dark;
transition: all $animation-speed-default;
}
}

View File

@ -1,78 +1,79 @@
.esh-basket {
min-height: 80vh;
.esh-basket {
min-height: 80vh;
}
.esh-basket-titles {
padding-bottom: 1rem;
padding-top: 2rem;
padding-bottom: 1rem;
padding-top: 2rem;
}
.esh-basket-titles--clean {
padding-bottom: 0;
padding-top: 0;
padding-bottom: 0;
padding-top: 0;
}
.esh-basket-title {
text-transform: uppercase;
text-transform: uppercase;
}
.esh-basket-items--border {
border-bottom: 1px solid #EEEEEE;
padding: .5rem 0;
border-bottom: 1px solid #EEEEEE;
padding: .5rem 0;
}
.esh-basket-items--border:last-of-type {
border-color: transparent;
}
.esh-basket-items--border:last-of-type {
border-color: transparent;
}
.esh-basket-items-margin-left1 {
margin-left: 1px;
}
.esh-basket-item {
font-size: 1rem;
font-weight: 300;
font-size: 1rem;
font-weight: 300;
}
.esh-basket-item--middle {
line-height: 8rem;
line-height: 8rem;
}
@media screen and (max-width: 1024px) {
.esh-basket-item--middle {
line-height: 1rem;
}
.esh-basket-item--middle {
line-height: 1rem;
}
}
.esh-basket-item--mark {
color: #00A69C;
color: #00A69C;
}
.esh-basket-image {
height: 8rem;
height: 8rem;
}
.esh-basket-input {
line-height: 1rem;
width: 100%;
line-height: 1rem;
width: 100%;
}
.esh-basket-checkout {
border: none;
border-radius: 0;
background-color: #83D01B;
color: #FFFFFF;
display: inline-block;
font-size: 1rem;
font-weight: 400;
margin-top: 1rem;
padding: 1rem 1.5rem;
text-align: center;
text-transform: uppercase;
transition: all 0.35s;
background-color: #83D01B;
border: 0;
border-radius: 0;
color: #FFFFFF;
display: inline-block;
font-size: 1rem;
font-weight: 400;
margin-top: 1rem;
padding: 1rem 1.5rem;
text-align: center;
text-transform: uppercase;
transition: all 0.35s;
}
.esh-basket-checkout:hover {
background-color: #4a760f;
transition: all 0.35s;
background-color: #4a760f;
transition: all 0.35s;
}
.esh-basket-margin12{
margin-left: 12px;
}

View File

@ -0,0 +1,89 @@
@import '../variables';
@mixin margin-left($distance) {
margin-left: $distance;
}
.esh-basket {
min-height: 80vh;
&-titles {
padding-bottom: 1rem;
padding-top: 2rem;
&--clean {
padding-bottom: 0;
padding-top: 0;
}
}
&-title {
text-transform: uppercase;
}
&-items {
&--border {
border-bottom: $border-light solid $color-foreground-bright;
padding: .5rem 0;
&:last-of-type {
border-color: transparent;
}
}
&-margin-left1 {
@include margin-left(1px);
}
}
$item-height: 8rem;
&-item {
font-size: $font-size-m;
font-weight: $font-weight-semilight;
&--middle {
line-height: $item-height;
@media screen and (max-width: $media-screen-m) {
line-height: $font-size-m;
}
}
&--mark {
color: $color-brand;
}
}
&-image {
height: $item-height;
}
&-input {
line-height: 1rem;
width: 100%;
}
&-checkout {
background-color: $color-secondary;
border: 0;
border-radius: 0;
color: $color-foreground-brighter;
display: inline-block;
font-size: 1rem;
font-weight: $font-weight-normal;
margin-top: 1rem;
padding: 1rem 1.5rem;
text-align: center;
text-transform: uppercase;
transition: all $animation-speed-default;
&:hover {
background-color: $color-secondary-darker;
transition: all $animation-speed-default;
}
}
}

View File

@ -1,147 +1,149 @@
.esh-catalog-hero {
background-image: url("../../images/main_banner.png");
background-size: cover;
height: 260px;
width: 100%;
.esh-catalog-hero {
background-image: url("../../images/main_banner.png");
background-size: cover;
height: 260px;
width: 100%;
}
.esh-catalog-title {
position: relative;
top: 74.28571px;
position: relative;
top: 74.28571px;
}
.esh-catalog-filters {
background-color: #00A69C;
height: 65px;
background-color: #00A69C;
height: 65px;
}
.esh-catalog-filter {
background-color: transparent;
border-color: #00d9cc;
color: #FFFFFF;
cursor: pointer;
margin-right: 1rem;
margin-top: .5rem;
outline-color: #83D01B;
padding-bottom: 0;
padding-left: 0.5rem;
padding-right: 0.5rem;
padding-top: 1.5rem;
min-width: 140px;
-webkit-appearance: none;
-webkit-appearance: none;
background-color: transparent;
border-color: #00d9cc;
color: #FFFFFF;
cursor: pointer;
margin-right: 1rem;
margin-top: .5rem;
min-width: 140px;
outline-color: #83D01B;
padding-bottom: 0;
padding-left: 0.5rem;
padding-right: 0.5rem;
padding-top: 1.5rem;
}
.esh-catalog-filter option {
background-color: #00A69C;
}
.esh-catalog-filter option {
background-color: #00A69C;
}
.esh-catalog-label {
display: inline-block;
position: relative;
z-index: 0;
display: inline-block;
position: relative;
z-index: 0;
}
.esh-catalog-label::before {
color: rgba(255, 255, 255, 0.5);
content: attr(data-title);
font-size: 0.65rem;
margin-top: 0.65rem;
margin-left: 0.5rem;
position: absolute;
text-transform: uppercase;
z-index: 1;
}
.esh-catalog-label::before {
color: rgba(255, 255, 255, 0.5);
content: attr(data-title);
font-size: 0.65rem;
margin-left: 0.5rem;
margin-top: 0.65rem;
position: absolute;
text-transform: uppercase;
z-index: 1;
}
.esh-catalog-label::after {
background-image: url("../../images/arrow-down.png");
height: 7px;
content: '';
position: absolute;
right: 1.5rem;
top: 2.5rem;
width: 10px;
z-index: 1;
}
.esh-catalog-label::after {
background-image: url("../../images/arrow-down.png");
content: '';
height: 7px;
position: absolute;
right: 1.5rem;
top: 2.5rem;
width: 10px;
z-index: 1;
}
.esh-catalog-send {
background-color: #83D01B;
color: #FFFFFF;
cursor: pointer;
font-size: 1rem;
transform: translateY(.5rem);
padding: 0.5rem;
transition: all 0.35s;
background-color: #83D01B;
color: #FFFFFF;
cursor: pointer;
font-size: 1rem;
margin-top: -1.5rem;
padding: 0.5rem;
transition: all 0.35s;
}
.esh-catalog-send:hover {
background-color: #4a760f;
transition: all 0.35s;
}
.esh-catalog-send:hover {
background-color: #4a760f;
transition: all 0.35s;
}
.esh-catalog-items {
margin-top: 1rem;
margin-top: 1rem;
}
.esh-catalog-item {
text-align: center;
margin-bottom: 1.5rem;
width: 33%;
display: inline-block;
float: none !important;
margin-bottom: 1.5rem;
text-align: center;
width: 33%;
display: inline-block;
float: none !important;
}
@media screen and (max-width: 1024px) {
.esh-catalog-item {
width: 50%;
}
.esh-catalog-item {
width: 50%;
}
}
@media screen and (max-width: 768px) {
.esh-catalog-item {
width: 100%;
}
.esh-catalog-item {
width: 100%;
}
}
.esh-catalog-thumbnail {
max-width: 370px;
width: 100%;
max-width: 370px;
width: 100%;
}
.esh-catalog-button {
background-color: #83D01B;
border: none;
color: #FFFFFF;
cursor: pointer;
font-size: 1rem;
height: 3rem;
margin-top: 1rem;
transition: all 0.35s;
width: 80%;
background-color: #83D01B;
border: 0;
color: #FFFFFF;
cursor: pointer;
font-size: 1rem;
height: 3rem;
margin-top: 1rem;
transition: all 0.35s;
width: 80%;
}
.esh-catalog-button.is-disabled {
opacity: .5;
pointer-events: none;
}
.esh-catalog-button:hover {
background-color: #4a760f;
transition: all 0.35s;
}
.esh-catalog-button.is-disabled {
opacity: .5;
pointer-events: none;
}
.esh-catalog-button:hover {
background-color: #4a760f;
transition: all 0.35s;
}
.esh-catalog-name {
font-size: 1rem;
font-weight: 300;
margin-top: .5rem;
text-align: center;
text-transform: uppercase;
font-size: 1rem;
font-weight: 300;
margin-top: .5rem;
text-align: center;
text-transform: uppercase;
}
.esh-catalog-price {
text-align: center;
font-weight: 900;
font-size: 28px;
font-size: 28px;
font-weight: 900;
text-align: center;
}
.esh-catalog-price::before {
content: '$';
}
.esh-catalog-price::before {
content: '$';
}

View File

@ -0,0 +1,154 @@
@import '../variables';
.esh-catalog {
$banner-height: 260px;
&-hero {
background-image: url($image-main_banner);
background-size: cover;
height: $banner-height;
width: 100%;
}
&-title {
position: relative;
top: $banner-height / 3.5;
}
$filter-height: 65px;
&-filters {
background-color: $color-brand;
height: $filter-height;
}
$filter-padding: .5rem;
&-filter {
-webkit-appearance: none;
background-color: transparent;
border-color: $color-brand-bright;
color: $color-foreground-brighter;
cursor: pointer;
margin-right: 1rem;
margin-top: .5rem;
min-width: 140px;
outline-color: $color-secondary;
padding-bottom: 0;
padding-left: $filter-padding;
padding-right: $filter-padding;
padding-top: $filter-padding * 3;
option {
background-color: $color-brand;
}
}
&-label {
display: inline-block;
position: relative;
z-index: 0;
&::before {
color: rgba($color-foreground-brighter, .5);
content: attr(data-title);
font-size: $font-size-xs;
margin-left: $filter-padding;
margin-top: $font-size-xs;
position: absolute;
text-transform: uppercase;
z-index: 1;
}
&::after {
background-image: url($image-arrow_down);
content: '';
height: 7px; //png height
position: absolute;
right: $filter-padding * 3;
top: $filter-padding * 5;
width: 10px; //png width
z-index: 1;
}
}
&-send {
background-color: $color-secondary;
color: $color-foreground-brighter;
cursor: pointer;
font-size: $font-size-m;
margin-top: -$filter-padding * 3;
padding: $filter-padding;
transition: all $animation-speed-default;
&:hover {
background-color: $color-secondary-darker;
transition: all $animation-speed-default;
}
}
&-items {
margin-top: 1rem;
}
&-item {
margin-bottom: 1.5rem;
text-align: center;
width: 33%;
display: inline-block;
float: none !important;
@media screen and (max-width: $media-screen-m) {
width: 50%;
}
@media screen and (max-width: $media-screen-s) {
width: 100%;
}
}
&-thumbnail {
max-width: 370px;
width: 100%;
}
&-button {
background-color: $color-secondary;
border: 0;
color: $color-foreground-brighter;
cursor: pointer;
font-size: $font-size-m;
height: 3rem;
margin-top: 1rem;
transition: all $animation-speed-default;
width: 80%;
&.is-disabled {
opacity: .5;
pointer-events: none;
}
&:hover {
background-color: $color-secondary-darker;
transition: all $animation-speed-default;
}
}
&-name {
font-size: $font-size-m;
font-weight: $font-weight-semilight;
margin-top: .5rem;
text-align: center;
text-transform: uppercase;
}
&-price {
font-size: 28px;
font-weight: 900;
text-align: center;
&::before {
content: '$';
}
}
}

View File

@ -1,52 +1,53 @@
.esh-orders_detail {
min-height: 80vh;
.esh-orders_detail {
min-height: 80vh;
}
.esh-orders_detail-section {
padding: 1rem 0;
padding: 1rem 0;
}
.esh-orders_detail-section--right {
text-align: right;
text-align: right;
}
.esh-orders_detail-titles {
padding-bottom: 1rem;
padding-top: 2rem;
padding-bottom: 1rem;
padding-top: 2rem;
}
.esh-orders_detail-title {
text-transform: uppercase;
text-transform: uppercase;
}
.esh-orders_detail-items--border {
border-bottom: 1px solid #EEEEEE;
padding: .5rem 0;
border-bottom: 1px solid #EEEEEE;
padding: .5rem 0;
}
.esh-orders_detail-items--border:last-of-type {
border-color: transparent;
}
.esh-orders_detail-items--border:last-of-type {
border-color: transparent;
}
.esh-orders_detail-item {
font-size: 1rem;
font-weight: 300;
font-size: 1rem;
font-weight: 300;
}
.esh-orders_detail-item--middle {
line-height: 8rem;
line-height: 8rem;
}
@media screen and (max-width: 768px) {
.esh-orders_detail-item--middle {
line-height: 1rem;
}
.esh-orders_detail-item--middle {
line-height: 1rem;
}
}
.esh-orders_detail-item--mark {
color: #83D01B;
color: #83D01B;
}
.esh-orders_detail-image {
height: 8rem;
height: 8rem;
}

View File

@ -0,0 +1,56 @@
@import '../../variables';
.esh-orders_detail {
min-height: 80vh;
&-section {
padding: 1rem 0;
&--right {
text-align: right;
}
}
&-titles {
padding-bottom: 1rem;
padding-top: 2rem;
}
&-title {
text-transform: uppercase;
}
&-items {
&--border {
border-bottom: $border-light solid $color-foreground-bright;
padding: .5rem 0;
&:last-of-type {
border-color: transparent;
}
}
}
$item-height: 8rem;
&-item {
font-size: $font-size-m;
font-weight: $font-weight-semilight;
&--middle {
line-height: $item-height;
@media screen and (max-width: $media-screen-s) {
line-height: $font-size-m;
}
}
&--mark {
color: $color-secondary;
}
}
&-image {
height: $item-height;
}
}

View File

@ -1,91 +1,96 @@
.esh-orders_new {
min-height: 80vh;
.esh-orders_new {
min-height: 80vh;
}
.esh-orders_new-header {
background-color: #00A69C;
height: 4rem;
background-color: #00A69C;
height: 4rem;
}
.esh-orders_new-back {
color: rgba(255, 255, 255, 0.4);
line-height: 4rem;
text-decoration: none;
text-transform: uppercase;
transition: color 0.35s;
color: rgba(255, 255, 255, 0.4);
line-height: 4rem;
text-decoration: none;
text-transform: uppercase;
transition: color 0.35s;
}
.esh-orders_new-back:hover {
color: #FFFFFF;
transition: color 0.35s;
}
.esh-orders_new-back:hover {
color: #FFFFFF;
transition: color 0.35s;
}
.esh-orders_new-section {
padding: 1rem 0;
padding: 1rem 0;
}
.esh-orders_new-section--right {
text-align: right;
text-align: right;
}
.esh-orders_new-placeOrder {
background-color: #83D01B;
border: 0;
border-radius: 0;
color: #FFFFFF;
display: inline-block;
font-size: 1rem;
font-weight: 400;
margin-top: 1rem;
padding: 1rem 1.5rem;
text-align: center;
text-transform: uppercase;
transition: all 0.35s;
background-color: #83D01B;
border: 0;
border-radius: 0;
color: #FFFFFF;
display: inline-block;
font-size: 1rem;
font-weight: 400;
margin-top: 1rem;
padding: 1rem 1.5rem;
text-align: center;
text-transform: uppercase;
transition: all 0.35s;
}
.esh-orders_new-placeOrder:hover {
background-color: #4a760f;
transition: all 0.35s;
}
.esh-orders_new-placeOrder:hover {
background-color: #4a760f;
transition: all 0.35s;
}
.esh-orders_new-titles {
padding-bottom: 1rem;
padding-top: 2rem;
padding-bottom: 1rem;
padding-top: 2rem;
}
.esh-orders_new-title {
font-size: 1.25rem;
text-transform: uppercase;
font-size: 1.25rem;
text-transform: uppercase;
}
.esh-orders_new-items--border {
border-bottom: 1px solid #EEEEEE;
padding: .5rem 0;
border-bottom: 1px solid #EEEEEE;
padding: .5rem 0;
}
.esh-orders_new-items--border:last-of-type {
border-color: transparent;
}
.esh-orders_new-items--border:last-of-type {
border-color: transparent;
}
.esh-orders_new-item {
font-size: 1rem;
font-weight: 300;
font-size: 1rem;
font-weight: 300;
}
.esh-orders_new-item--middle {
line-height: 8rem;
line-height: 8rem;
}
@media screen and (max-width: 768px) {
.esh-orders_new-item--middle {
line-height: 1rem;
}
.esh-orders_new-item--middle {
line-height: 1rem;
}
}
.esh-orders_new-item--mark {
color: #83D01B;
color: #83D01B;
}
.esh-orders_new-image {
height: 8rem;
height: 8rem;
}
.esh-orders_new-alert {
margin-top: 10px;
}

View File

@ -0,0 +1,101 @@
@import '../../variables';
.esh-orders_new {
min-height: 80vh;
$header-height: 4rem;
&-header {
background-color: #00A69C;
height: $header-height;
}
&-back {
color: rgba($color-foreground-brighter, .4);
line-height: $header-height;
text-decoration: none;
text-transform: uppercase;
transition: color $animation-speed-default;
&:hover {
color: $color-foreground-brighter;
transition: color $animation-speed-default;
}
}
&-section {
padding: 1rem 0;
&--right {
text-align: right;
}
}
&-placeOrder {
background-color: $color-secondary;
border: 0;
border-radius: 0;
color: $color-foreground-brighter;
display: inline-block;
font-size: 1rem;
font-weight: $font-weight-normal;
margin-top: 1rem;
padding: 1rem 1.5rem;
text-align: center;
text-transform: uppercase;
transition: all $animation-speed-default;
&:hover {
background-color: $color-secondary-darker;
transition: all $animation-speed-default;
}
}
&-titles {
padding-bottom: 1rem;
padding-top: 2rem;
}
&-title {
font-size: $font-size-l;
text-transform: uppercase;
}
&-items {
&--border {
border-bottom: $border-light solid $color-foreground-bright;
padding: .5rem 0;
&:last-of-type {
border-color: transparent;
}
}
}
$item-height: 8rem;
&-item {
font-size: $font-size-m;
font-weight: $font-weight-semilight;
&--middle {
line-height: $item-height;
@media screen and (max-width: $media-screen-s) {
line-height: $font-size-m;
}
}
&--mark {
color: $color-secondary;
}
}
&-image {
height: $item-height;
}
&-alert {
margin-top: 10px;
}
}

View File

@ -1,74 +1,75 @@
.esh-orders {
min-height: 80vh;
overflow-x: hidden;
.esh-orders {
min-height: 80vh;
overflow-x: hidden;
}
.esh-orders-header {
background-color: #00A69C;
height: 4rem;
background-color: #00A69C;
height: 4rem;
}
.esh-orders-back {
color: rgba(255, 255, 255, 0.4);
line-height: 4rem;
text-transform: uppercase;
text-decoration: none;
transition: color 0.35s;
color: rgba(255, 255, 255, 0.4);
line-height: 4rem;
text-decoration: none;
text-transform: uppercase;
transition: color 0.35s;
}
.esh-orders-back:hover {
color: #FFFFFF;
transition: color 0.35s;
}
.esh-orders-back:hover {
color: #FFFFFF;
transition: color 0.35s;
}
.esh-orders-titles {
padding-bottom: 1rem;
padding-top: 2rem;
padding-bottom: 1rem;
padding-top: 2rem;
}
.esh-orders-title {
text-transform: uppercase;
text-transform: uppercase;
}
.esh-orders-items {
height: 2rem;
line-height: 2rem;
position: relative;
height: 2rem;
line-height: 2rem;
position: relative;
}
.esh-orders-items:nth-of-type(2n + 1):before {
background-color: #EEEEFF;
content: '';
height: 100%;
left: 0;
margin-left: -100vw;
position: absolute;
top: 0;
width: 200vw;
z-index: -1;
}
.esh-orders-items:nth-of-type(2n + 1):before {
background-color: #EEEEFF;
content: '';
height: 100%;
left: 0;
margin-left: -100vw;
position: absolute;
top: 0;
width: 200vw;
z-index: -1;
}
.esh-orders-item {
font-weight: 300;
font-weight: 300;
}
.esh-orders-item--hover {
opacity: 0;
pointer-events: none;
opacity: 0;
pointer-events: none;
}
.esh-orders-items:hover .esh-orders-item--hover {
opacity: 1;
pointer-events: all;
opacity: 1;
pointer-events: all;
}
.esh-orders-link {
color: #83D01B;
text-decoration: none;
transition: color 0.35s;
color: #83D01B;
text-decoration: none;
transition: color 0.35s;
}
.esh-orders-link:hover {
color: #75b918;
transition: color 0.35s;
}
.esh-orders-link:hover {
color: #75b918;
transition: color 0.35s;
}

View File

@ -0,0 +1,81 @@
@import '../variables';
.esh-orders {
min-height: 80vh;
overflow-x: hidden;
$header-height: 4rem;
&-header {
background-color: #00A69C;
height: $header-height;
}
&-back {
color: rgba($color-foreground-brighter, .4);
line-height: $header-height;
text-decoration: none;
text-transform: uppercase;
transition: color $animation-speed-default;
&:hover {
color: $color-foreground-brighter;
transition: color $animation-speed-default;
}
}
&-titles {
padding-bottom: 1rem;
padding-top: 2rem;
}
&-title {
text-transform: uppercase;
}
&-items {
$height: 2rem;
height: $height;
line-height: $height;
position: relative;
&:nth-of-type(2n + 1) {
&:before {
background-color: $color-background-bright;
content: '';
height: 100%;
left: 0;
margin-left: -100vw;
position: absolute;
top: 0;
width: 200vw;
z-index: -1;
}
}
}
&-item {
font-weight: $font-weight-semilight;
&--hover {
opacity: 0;
pointer-events: none;
}
}
&-items:hover &-item--hover {
opacity: 1;
pointer-events: all;
}
&-link {
color: $color-secondary;
text-decoration: none;
transition: color $animation-speed-default;
&:hover {
color: $color-secondary-dark;
transition: color $animation-speed-default;
}
}
}

View File

@ -0,0 +1,3 @@
.esh-catalog-button {
background-color: #83D01B; /* to override the style of this button ie. to make it red, use background-color: #FF001b; */
}

View File

@ -1,31 +1,18 @@
.esh-header {
background-color: #00A69C;
height: 4rem;
.esh-header {
background-color: #00A69C;
height: 4rem;
}
.esh-header-title {
color: rgba(255, 255, 255, 0.5) !important;
line-height: 4rem;
text-transform: uppercase;
text-decoration: none;
transition: color 0.35s;
margin-right: 15px;
}
.esh-header-title:hover {
color: #FFFFFF !important;
transition: color 0.35s;
}
.esh-header-back {
color: rgba(255, 255, 255, 0.5) !important;
line-height: 4rem;
text-transform: uppercase;
text-decoration: none;
transition: color 0.35s;
color: rgba(255, 255, 255, 0.5);
line-height: 4rem;
text-decoration: none;
text-transform: uppercase;
transition: color 0.35s;
}
.esh-header-back:hover {
color: #FFFFFF;
transition: color 0.35s;
}
.esh-header-back:hover {
color: #FFFFFF !important;
transition: color 0.35s;
}

View File

@ -0,0 +1,21 @@
@import '../../../variables';
.esh-header {
$header-height: 4rem;
background-color: $color-brand;
height: $header-height;
&-back {
color: rgba($color-foreground-brighter, .5);
line-height: $header-height;
text-decoration: none;
text-transform: uppercase;
transition: color $animation-speed-default;
&:hover {
color: $color-foreground-brighter;
transition: color $animation-speed-default;
}
}
}

View File

@ -1,57 +1,57 @@
.esh-identity {
line-height: 3rem;
position: relative;
text-align: right;
.esh-identity {
line-height: 3rem;
position: relative;
text-align: right;
}
.esh-identity-section {
display: inline-block;
width: 100%;
display: inline-block;
width: 100%;
}
.esh-identity-name {
display: inline-block;
display: inline-block;
}
.esh-identity-name--upper {
text-transform: uppercase;
text-transform: uppercase;
}
@media screen and (max-width: 768px) {
.esh-identity-name {
font-size: 0.85rem;
}
.esh-identity-name {
font-size: 0.85rem;
}
}
.esh-identity-image {
display: inline-block;
display: inline-block;
}
.esh-identity-drop {
background: #FFFFFF;
height: 0rem;
min-width: 14rem;
right: 0;
overflow: hidden;
padding: .5rem;
position: absolute;
top: 2.5rem;
transition: height 0.35s;
background: #FFFFFF;
height: 0;
min-width: 14rem;
overflow: hidden;
padding: .5rem;
position: absolute;
right: 0;
top: 2.5rem;
transition: height 0.35s;
}
.esh-identity:hover .esh-identity-drop {
border: 1px solid #EEEEEE;
height: 9.5rem;
transition: height 0.35s;
border: 1px solid #EEEEEE;
height: 7rem;
transition: height 0.35s;
}
.esh-identity-item {
cursor: pointer;
display: block;
transition: color 0.35s;
cursor: pointer;
transition: color 0.35s;
}
.esh-identity-item:hover {
color: #75b918;
transition: color 0.35s;
}
.esh-identity-item:hover {
color: #75b918;
transition: color 0.35s;
}

View File

@ -0,0 +1,56 @@
@import '../../../variables';
.esh-identity {
line-height: 3rem;
position: relative;
text-align: right;
&-section {
display: inline-block;
width: 100%;
}
&-name {
display: inline-block;
&--upper {
text-transform: uppercase;
}
@media screen and (max-width: $media-screen-s) {
font-size: $font-size-s;
}
}
&-image {
display: inline-block;
}
&-drop {
background: $color-background-brighter;
height: 0;
min-width: 14rem;
overflow: hidden;
padding: .5rem;
position: absolute;
right: 0;
top: 2.5rem;
transition: height $animation-speed-default;
}
&:hover &-drop {
border: $border-light solid $color-foreground-bright;
height: 7rem;
transition: height $animation-speed-default;
}
&-item {
cursor: pointer;
transition: color $animation-speed-default;
&:hover {
color: $color-secondary-dark;
transition: color $animation-speed-default;
}
}
}

View File

@ -1,34 +1,35 @@
.esh-pager-wrapper {
padding-top: 1rem;
text-align: center;
.esh-pager-wrapper {
padding-top: 1rem;
text-align: center;
}
.esh-pager-item {
margin: 0 5vw;
margin: 0 5vw;
}
.esh-pager-item.is-disabled {
opacity: 0;
pointer-events: none;
}
.esh-pager-item--navigable {
display: inline-block;
cursor: pointer;
cursor: pointer;
display: inline-block;
}
.esh-pager-item--navigable.is-disabled {
opacity: 0;
pointer-events: none;
}
.esh-pager-item--navigable:hover {
color: #83D01B;
}
.esh-pager-item--navigable:hover {
color: #83D01B;
}
@media screen and (max-width: 1280px) {
.esh-pager-item {
font-size: 0.85rem;
}
.esh-pager-item {
font-size: 0.85rem;
}
}
@media screen and (max-width: 1024px) {
.esh-pager-item {
margin: 0 4vw;
}
.esh-pager-item {
margin: 0 2.5vw;
}
}

View File

@ -0,0 +1,36 @@
@import '../../../variables';
.esh-pager {
&-wrapper {
padding-top: 1rem;
text-align: center;
}
&-item {
$margin: 5vw;
margin: 0 $margin;
&.is-disabled {
opacity: 0;
pointer-events: none;
}
&--navigable {
cursor: pointer;
display: inline-block;
&:hover {
color: $color-secondary;
}
}
@media screen and (max-width: $media-screen-l) {
font-size: $font-size-s;
}
@media screen and (max-width: $media-screen-m) {
margin: 0 $margin / 2;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 KiB

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 252 B

View File

@ -13,5 +13,6 @@ namespace eShopOnContainers.WebSPA
public string IdentityUrl { get; set; }
public string BasketUrl { get; set; }
public string MarketingUrl { get; set; }
public bool UseCustomizationData { get; set; }
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -51,3 +51,8 @@ $media-screen-xxxl: 1920px;
// Borders
$border-light: 1px;
// Images
$image_path: '/assets/images/';
$image-main_banner: '#{$image_path}main_banner.png';
$image-arrow_down: '#{$image_path}arrow-down.png';

View File

@ -32,7 +32,7 @@
</section>
<section class="col-sm-6">
<div class="esh-app-footer-text hidden-xs"> e-ShoponContainers. All right reserved </div>
<img class="esh-app-footer-text hidden-xs" src="assets/images/main_footer_text.png" width="335" height="26" alt="footer text image" />
</section>
</article>

View File

@ -19,11 +19,5 @@
width: 230px;
}
&-text {
color: $color-secondary;
line-height: $height;
text-align: right;
width: 100%;
}
}
}

View File

@ -17,7 +17,7 @@
<img class="esh-basket-image" src="{{item.pictureUrl}}" />
</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-3">{{item.productName}}</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-2">$ {{item.unitPrice}}</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-2">$ {{item.unitPrice | number:'.2-2'}}</section>
<section class="esh-basket-item esh-basket-item--middle col-xs-2">
<input class="esh-basket-input"
type="number"
@ -25,7 +25,7 @@
[(ngModel)]="item.quantity"
(change)="itemQuantityChanged(item)" />
</section>
<section class="esh-basket-item esh-basket-item--middle esh-basket-item--mark col-xs-2">$ {{item.unitPrice * item.quantity}}</section>
<section class="esh-basket-item esh-basket-item--middle esh-basket-item--mark col-xs-2">$ {{(item.unitPrice * item.quantity) | number:'.2-2'}}</section>
</article>
<br/>
<div class="esh-basket-items-margin-left1 row">
@ -42,7 +42,7 @@
<article class="esh-basket-items row">
<section class="esh-basket-item col-xs-9"></section>
<section class="esh-basket-item esh-basket-item--mark col-xs-2">$ {{totalPrice}}</section>
<section class="esh-basket-item esh-basket-item--mark col-xs-2">$ {{totalPrice | number:'.2-2'}}</section>
</article>
<article class="esh-basket-items row">

View File

@ -37,7 +37,7 @@
<span>{{item.name}}</span>
</div>
<div class="esh-catalog-price">
<span>{{item.price}}</span>
<span>{{item.price | number:'.2-2'}}</span>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
$banner-height: 260px;
&-hero {
background-image: url('../../assets/images/main_banner.png');
background-image: url($image-main_banner);
background-size: cover;
height: $banner-height;
width: 100%;
@ -61,7 +61,7 @@
}
&::after {
background-image: url('../../assets/images/arrow-down.png');
background-image: url($image-arrow_down);
content: '';
height: 7px; //png height
position: absolute;

View File

@ -57,9 +57,9 @@
<img class="esh-orders_detail-image" src="{{item.pictureurl}}">
</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-4">{{item.productname}}</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">$ {{item.unitprice}}</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">$ {{item.unitprice | number:'.2-2'}}</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">{{item.units}}</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-2">$ {{item.units * item.unitprice}}</section>
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-2">$ {{(item.units * item.unitprice) | number:'.2-2'}}</section>
</article>
</section>
@ -71,7 +71,7 @@
<article class="esh-orders_detail-items row">
<section class="esh-orders_detail-item col-xs-9"></section>
<section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ {{order.total}}</section>
<section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ {{order.total | number:'.2-2'}}</section>
</article>
</section>
</div>

View File

@ -86,9 +86,9 @@
<img class="esh-orders_new-image" src="{{item.pictureurl}}">
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-4">{{item.productname}}</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">$ {{item.unitprice}}</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">$ {{item.unitprice | number:'.2-2'}}</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">{{item.units}}</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-2">$ {{item.units * item.unitprice}}</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-2">$ {{(item.units * item.unitprice) | number:'.2-2'}}</section>
</article>
</section>
@ -100,7 +100,7 @@
<article class="esh-orders_new-items row">
<section class="esh-orders_new-item col-xs-9"></section>
<section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">$ {{order.total}}</section>
<section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">$ {{order.total | number:'.2-2'}}</section>
</article>
</section>
<section class="esh-orders_new-section">

View File

@ -0,0 +1,73 @@
using eShopOnContainers.WebSPA;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace WebSPA.Infrastructure
{
public class WebContextSeed
{
public static void Seed(IApplicationBuilder applicationBuilder, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var log = loggerFactory.CreateLogger("WebSPA seed");
var settings = (AppSettings)applicationBuilder
.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Value;
var useCustomizationData = settings.UseCustomizationData;
var contentRootPath = env.ContentRootPath;
var webroot = env.WebRootPath;
if (useCustomizationData)
{
GetPreconfiguredImages(contentRootPath, webroot, log);
}
}
static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger log)
{
try
{
string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip");
if (!File.Exists(imagesZipFile))
{
log.LogError($" zip file '{imagesZipFile}' does not exists.");
return;
}
string imagePath = Path.Combine(webroot, "assets", "images");
string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray();
using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
if (imageFiles.Contains(entry.Name))
{
string destinationFilename = Path.Combine(imagePath, entry.Name);
if (File.Exists(destinationFilename))
{
File.Delete(destinationFilename);
}
entry.ExtractToFile(destinationFilename);
}
else
{
log.LogWarning($"Skip file '{entry.Name}' in zipfile '{imagesZipFile}'");
}
}
}
}
catch (Exception ex)
{
log.LogError($"Exception in method GetPreconfiguredImages WebSPA. Exception Message={ex.Message}");
}
}
}
}

Binary file not shown.

View File

@ -11,6 +11,7 @@ using Microsoft.Extensions.HealthChecks;
using Newtonsoft.Json.Serialization;
using eShopOnContainers.WebSPA;
using Microsoft.eShopOnContainers.BuildingBlocks;
using WebSPA.Infrastructure;
namespace eShopConContainers.WebSPA
{
@ -99,6 +100,9 @@ namespace eShopConContainers.WebSPA
// await next.Invoke();
// });
//Seed Data
WebContextSeed.Seed(app, env, loggerFactory);
app.Use(async (context, next) =>
{
await next();

View File

@ -16,6 +16,9 @@
<ItemGroup>
<Compile Remove="node_modules\**\*;Client\**\*" />
<Content Include="Setup\images.zip">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="appsettings.json;">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>

View File

@ -5,6 +5,7 @@
"IdentityUrl": "http://localhost:5105",
"MarketingUrl": "http://localhost:5110",
"CallBackUrl": "http://localhost:5104/",
"UseCustomizationData": true,
"IsClusterEnv": "False",
"Logging": {
"IncludeScopes": false,