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
@ -29,6 +29,7 @@ services:
|
|||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
- 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.
|
- 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
|
- EventBusConnection=rabbitmq
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5101:80"
|
- "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
|
- 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
|
- 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.
|
- 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:
|
ports:
|
||||||
- "5105:80"
|
- "5105:80"
|
||||||
|
|
||||||
@ -50,6 +52,7 @@ services:
|
|||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
- 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.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||||
- EventBusConnection=rabbitmq
|
- EventBusConnection=rabbitmq
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5102:80"
|
- "5102:80"
|
||||||
|
|
||||||
@ -79,6 +82,7 @@ services:
|
|||||||
- OrderingUrlHC=http://ordering.api/hc
|
- 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.
|
- 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
|
- BasketUrlHC=http://basket.api/hc
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5104:80"
|
- "5104:80"
|
||||||
|
|
||||||
@ -92,6 +96,7 @@ services:
|
|||||||
- IdentityUrl=http://10.0.75.1:5105
|
- 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.
|
- 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.
|
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5100:80"
|
- "5100:80"
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26430.12
|
VisualStudioVersion = 15.0.26430.12
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
|
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
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
|
||||||
EndProject
|
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}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{F16E3C6A-1C94-4EAB-BE91-099618060B68}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "test\Services\IntegrationTests\IntegrationTests.csproj", "{5B810E3D-112E-4857-B197-F09D2FD41E27}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "test\Services\IntegrationTests\IntegrationTests.csproj", "{5B810E3D-112E-4857-B197-F09D2FD41E27}"
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26430.6
|
VisualStudioVersion = 15.0.26430.13
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{91CF7717-08AB-4E65-B10E-0B426F01E2E8}"
|
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
|
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}"
|
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
|
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
|
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}"
|
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
|
EndProject
|
||||||
@ -67,18 +79,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\U
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
|
||||||
EndProject
|
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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{B473B70F-0796-4862-B1AD-BB742D93B868}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{B473B70F-0796-4862-B1AD-BB742D93B868}"
|
||||||
@ -133,6 +133,54 @@ Global
|
|||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
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|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|ARM.ActiveCfg = Release|Any CPU
|
||||||
{2110CBB0-3B38-4EE4-A743-DF6968D80D90}.Ad-Hoc|iPhone.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.ActiveCfg = Release|Any CPU
|
||||||
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Build.0 = 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
|
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1}.Release|x86.Deploy.0 = Release|Any CPU
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.ActiveCfg = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|ARM.ActiveCfg = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.Build.0 = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|ARM.Build.0 = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|ARM.Deploy.0 = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|ARM.Deploy.0 = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhone.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhone.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhone.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhone.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x64.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x64.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x64.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x64.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.ActiveCfg = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x86.ActiveCfg = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.Build.0 = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x86.Build.0 = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Ad-Hoc|x86.Deploy.0 = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Ad-Hoc|x86.Deploy.0 = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|Any CPU.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|Any CPU.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|Any CPU.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|Any CPU.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.ActiveCfg = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|ARM.ActiveCfg = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.Build.0 = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|ARM.Build.0 = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|ARM.Deploy.0 = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|ARM.Deploy.0 = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhone.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhone.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhone.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhone.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhoneSimulator.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhoneSimulator.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|iPhoneSimulator.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|iPhoneSimulator.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x64.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x64.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x64.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x64.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.ActiveCfg = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.ActiveCfg = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.Build.0 = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.Build.0 = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.AppStore|x86.Deploy.0 = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.AppStore|x86.Deploy.0 = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.ActiveCfg = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.Build.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.Build.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|Any CPU.Deploy.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|Any CPU.Deploy.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.ActiveCfg = Debug|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Build.0 = Debug|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Deploy.0 = Debug|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.ActiveCfg = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.ActiveCfg = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Build.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.Build.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Deploy.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhone.Deploy.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.Build.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.Build.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.ActiveCfg = Debug|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Build.0 = Debug|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.Build.0 = Debug|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Deploy.0 = Debug|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x64.Deploy.0 = Debug|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.ActiveCfg = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.Build.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x86.Build.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x86.Deploy.0 = Debug|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Debug|x86.Deploy.0 = Debug|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|Any CPU.ActiveCfg = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.ActiveCfg = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.Build.0 = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|ARM.Build.0 = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|ARM.Deploy.0 = Release|ARM
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|ARM.Deploy.0 = Release|ARM
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|iPhone.ActiveCfg = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|iPhone.ActiveCfg = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|iPhoneSimulator.ActiveCfg = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|iPhoneSimulator.ActiveCfg = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.ActiveCfg = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x64.ActiveCfg = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.Build.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x64.Build.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x64.Deploy.0 = Release|x64
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x64.Deploy.0 = Release|x64
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.ActiveCfg = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.ActiveCfg = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.Build.0 = Release|x86
|
{A7337243-33B8-463A-87AD-944B75EFD820}.Release|x86.Build.0 = Release|x86
|
||||||
{02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Release|x86.Deploy.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|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|ARM.ActiveCfg = Ad-Hoc|iPhone
|
||||||
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}.Ad-Hoc|iPhone.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|x64.Build.0 = Release|Any CPU
|
||||||
{A579E108-5445-403D-A407-339AC4D1611B}.Release|x86.ActiveCfg = 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
|
{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.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|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|ARM.ActiveCfg = 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}
|
{B7B1D395-4E06-4036-BE86-C216756B9367} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E}
|
||||||
{F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
{F7B6A162-BC4D-4924-B16A-713F9B0344E7} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
||||||
{A289A7F0-ACD8-42AE-87B6-AB1AFD310BF1} = {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}
|
{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
||||||
{95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
|
{95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
|
||||||
{02DF7FEE-C302-433D-A6CD-237A2569F236} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
|
{02DF7FEE-C302-433D-A6CD-237A2569F236} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
<Content Include="Pics\**\*;">
|
<Content Include="Pics\**\*;">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</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" />
|
<Compile Include="IntegrationEvents\EventHandling\AnyFutureIntegrationEventHandler.cs.txt" />
|
||||||
<Content Update="web.config;">
|
<Content Update="web.config;">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
@ -50,6 +55,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
|
||||||
|
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -72,6 +78,9 @@
|
|||||||
<None Update="Pics\*">
|
<None Update="Pics\*">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Setup\*">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -5,5 +5,7 @@
|
|||||||
public string ExternalCatalogBaseUrl {get;set;}
|
public string ExternalCatalogBaseUrl {get;set;}
|
||||||
|
|
||||||
public string EventBusConnection { get; set; }
|
public string EventBusConnection { get; set; }
|
||||||
|
|
||||||
|
public bool UseCustomizationData { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,10 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
|||||||
|
|
||||||
items.ForEach(x =>
|
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;
|
return items;
|
||||||
|
@ -15,16 +15,58 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
|||||||
_env = env;
|
_env = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{filename}")]
|
||||||
// GET: /<controller>/
|
// GET: /<controller>/
|
||||||
public IActionResult GetImage(int id)
|
public IActionResult GetImage(string filename)
|
||||||
{
|
{
|
||||||
var webRoot = _env.WebRootPath;
|
var webRoot = _env.WebRootPath;
|
||||||
var path = Path.Combine(webRoot, id + ".png");
|
var path = Path.Combine(webRoot, filename);
|
||||||
|
|
||||||
var buffer = System.IO.File.ReadAllBytes(path);
|
string imageFileExtension = Path.GetExtension(filename);
|
||||||
|
string mimetype = GetImageMimeTypeFromImageFileExtension(imageFileExtension);
|
||||||
return File(buffer, "image/png");
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,47 +2,115 @@
|
|||||||
{
|
{
|
||||||
using EntityFrameworkCore;
|
using EntityFrameworkCore;
|
||||||
using Extensions.Logging;
|
using Extensions.Logging;
|
||||||
|
using global::Catalog.API.Extensions;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Model;
|
using Model;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class CatalogContextSeed
|
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
|
var context = (CatalogContext)applicationBuilder
|
||||||
.ApplicationServices.GetService(typeof(CatalogContext));
|
.ApplicationServices.GetService(typeof(CatalogContext));
|
||||||
|
|
||||||
context.Database.Migrate();
|
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())
|
if (!context.CatalogBrands.Any())
|
||||||
{
|
{
|
||||||
context.CatalogBrands.AddRange(
|
context.CatalogBrands.AddRange(useCustomizationData
|
||||||
GetPreconfiguredCatalogBrands());
|
? GetCatalogBrandsFromFile(contentRootPath, log)
|
||||||
|
: GetPreconfiguredCatalogBrands()
|
||||||
|
);
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.CatalogTypes.Any())
|
if (!context.CatalogTypes.Any())
|
||||||
{
|
{
|
||||||
context.CatalogTypes.AddRange(
|
context.CatalogTypes.AddRange(useCustomizationData
|
||||||
GetPreconfiguredCatalogTypes());
|
? GetCatalogTypesFromFile(contentRootPath, log)
|
||||||
|
: GetPreconfiguredCatalogTypes()
|
||||||
|
);
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.CatalogItems.Any())
|
if (!context.CatalogItems.Any())
|
||||||
{
|
{
|
||||||
context.CatalogItems.AddRange(
|
context.CatalogItems.AddRange(useCustomizationData
|
||||||
GetPreconfiguredItems());
|
? GetCatalogItemsFromFile(contentRootPath, context, log)
|
||||||
|
: GetPreconfiguredItems()
|
||||||
|
);
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
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()
|
static IEnumerable<CatalogBrand> GetPreconfiguredCatalogBrands()
|
||||||
{
|
{
|
||||||
return new List<CatalogBrand>()
|
return new List<CatalogBrand>()
|
||||||
@ -50,11 +118,54 @@
|
|||||||
new CatalogBrand() { Brand = "Azure"},
|
new CatalogBrand() { Brand = "Azure"},
|
||||||
new CatalogBrand() { Brand = ".NET" },
|
new CatalogBrand() { Brand = ".NET" },
|
||||||
new CatalogBrand() { Brand = "Visual Studio" },
|
new CatalogBrand() { Brand = "Visual Studio" },
|
||||||
new CatalogBrand() { Brand = "SQL Server" },
|
new CatalogBrand() { Brand = "SQL Server" },
|
||||||
new CatalogBrand() { Brand = "Other" }
|
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()
|
static IEnumerable<CatalogType> GetPreconfiguredCatalogTypes()
|
||||||
{
|
{
|
||||||
return new List<CatalogType>()
|
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()
|
static IEnumerable<CatalogItem> GetPreconfiguredItems()
|
||||||
{
|
{
|
||||||
return new List<CatalogItem>()
|
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=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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/2", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/3", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/4", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/5", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/6", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/7", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/8", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/9", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/10", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/11", 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 = "http://externalcatalogbaseurltobereplaced/api/v1/pic/12", 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
8
src/Services/Catalog/Catalog.API/Setup/CatalogBrands.csv
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
CatalogBrand
|
||||||
|
Azure
|
||||||
|
.NET
|
||||||
|
Visual Studio
|
||||||
|
SQL Server
|
||||||
|
Other
|
||||||
|
CatalogBrandTestOne
|
||||||
|
CatalogBrandTestTwo
|
|
14
src/Services/Catalog/Catalog.API/Setup/CatalogItems.csv
Normal 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.
|
7
src/Services/Catalog/Catalog.API/Setup/CatalogTypes.csv
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CatalogType
|
||||||
|
Mug
|
||||||
|
T-Shirt
|
||||||
|
Sheet
|
||||||
|
USB Memory Stick
|
||||||
|
CatalogTypeTestOne
|
||||||
|
CatalogTypeTestTwo
|
|
BIN
src/Services/Catalog/Catalog.API/Setup/Catalogitems.zip
Normal file
@ -153,7 +153,7 @@
|
|||||||
var context = (CatalogContext)app
|
var context = (CatalogContext)app
|
||||||
.ApplicationServices.GetService(typeof(CatalogContext));
|
.ApplicationServices.GetService(typeof(CatalogContext));
|
||||||
|
|
||||||
WaitForSqlAvailabilityAsync(context, loggerFactory, app).Wait();
|
WaitForSqlAvailabilityAsync(context, loggerFactory, app, env).Wait();
|
||||||
|
|
||||||
ConfigureEventBus(app);
|
ConfigureEventBus(app);
|
||||||
|
|
||||||
@ -165,13 +165,13 @@
|
|||||||
integrationEventLogContext.Database.Migrate();
|
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 logger = loggerFactory.CreateLogger(nameof(Startup));
|
||||||
var policy = CreatePolicy(retries, logger, nameof (WaitForSqlAvailabilityAsync));
|
var policy = CreatePolicy(retries, logger, nameof (WaitForSqlAvailabilityAsync));
|
||||||
await policy.ExecuteAsync(async () =>
|
await policy.ExecuteAsync(async () =>
|
||||||
{
|
{
|
||||||
await CatalogContextSeed.SeedAsync(app, loggerFactory);
|
await CatalogContextSeed.SeedAsync(app, env, loggerFactory);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word",
|
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word",
|
||||||
"ExternalCatalogBaseUrl": "http://localhost:5101",
|
"ExternalCatalogBaseUrl": "http://localhost:5101",
|
||||||
|
"UseCustomizationData": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
@ -8,5 +8,6 @@ namespace eShopOnContainers.Identity
|
|||||||
public class AppSettings
|
public class AppSettings
|
||||||
{
|
{
|
||||||
public string MvcClient { get; set; }
|
public string MvcClient { get; set; }
|
||||||
|
public bool UseCustomizationData { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,21 @@
|
|||||||
using AspNetCore.Identity;
|
using AspNetCore.Identity;
|
||||||
using EntityFrameworkCore;
|
using EntityFrameworkCore;
|
||||||
using Extensions.Logging;
|
using Extensions.Logging;
|
||||||
|
using global::eShopOnContainers.Identity;
|
||||||
using global::Identity.API.Data;
|
using global::Identity.API.Data;
|
||||||
using global::Identity.API.Models;
|
using global::Identity.API.Models;
|
||||||
|
using Identity.API.Extensions;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class ApplicationContextSeed
|
public class ApplicationContextSeed
|
||||||
@ -21,23 +29,38 @@
|
|||||||
_passwordHasher = passwordHasher;
|
_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;
|
int retryForAvaiability = retry.Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var log = loggerFactory.CreateLogger("application seed");
|
||||||
|
|
||||||
var context = (ApplicationDbContext)applicationBuilder
|
var context = (ApplicationDbContext)applicationBuilder
|
||||||
.ApplicationServices.GetService(typeof(ApplicationDbContext));
|
.ApplicationServices.GetService(typeof(ApplicationDbContext));
|
||||||
|
|
||||||
context.Database.Migrate();
|
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())
|
if (!context.Users.Any())
|
||||||
{
|
{
|
||||||
context.Users.AddRange(
|
context.Users.AddRange(useCustomizationData
|
||||||
GetDefaultUser());
|
? GetUsersFromFile(contentRootPath, log)
|
||||||
|
: GetDefaultUser());
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useCustomizationData)
|
||||||
|
{
|
||||||
|
GetPreconfiguredImages(contentRootPath, webroot, log);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -46,14 +69,93 @@
|
|||||||
retryForAvaiability++;
|
retryForAvaiability++;
|
||||||
var log = loggerFactory.CreateLogger("catalog seed");
|
var log = loggerFactory.CreateLogger("catalog seed");
|
||||||
log.LogError(ex.Message);
|
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()
|
new ApplicationUser()
|
||||||
{
|
{
|
||||||
CardHolderName = "DemoUser",
|
CardHolderName = "DemoUser",
|
||||||
@ -63,23 +165,86 @@
|
|||||||
Country = "U.S.",
|
Country = "U.S.",
|
||||||
Email = "demouser@microsoft.com",
|
Email = "demouser@microsoft.com",
|
||||||
Expiration = "12/20",
|
Expiration = "12/20",
|
||||||
Id = Guid.NewGuid().ToString(),
|
Id = Guid.NewGuid().ToString(),
|
||||||
LastName = "DemoLastName",
|
LastName = "DemoLastName",
|
||||||
Name = "DemoUser",
|
Name = "DemoUser",
|
||||||
PhoneNumber = "1234567890",
|
PhoneNumber = "1234567890",
|
||||||
UserName = "demouser@microsoft.com",
|
UserName = "demouser@microsoft.com",
|
||||||
ZipCode = "98052",
|
ZipCode = "98052",
|
||||||
State = "WA",
|
State = "WA",
|
||||||
Street = "15703 NE 61st Ct",
|
Street = "15703 NE 61st Ct",
|
||||||
SecurityNumber = "535",
|
SecurityNumber = "535",
|
||||||
NormalizedEmail = "DEMOUSER@MICROSOFT.COM",
|
NormalizedEmail = "DEMOUSER@MICROSOFT.COM",
|
||||||
NormalizedUserName = "DEMOUSER@MICROSOFT.COM",
|
NormalizedUserName = "DEMOUSER@MICROSOFT.COM",
|
||||||
SecurityStamp = Guid.NewGuid().ToString("D")
|
SecurityStamp = Guid.NewGuid().ToString("D"),
|
||||||
};
|
};
|
||||||
|
|
||||||
user.PasswordHash = _passwordHasher.HashPassword(user, "Pass@word1");
|
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}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,13 @@
|
|||||||
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
||||||
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Setup\**\*;">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.1.0" />
|
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.2" />
|
||||||
@ -70,6 +76,9 @@
|
|||||||
<None Update="Dockerfile">
|
<None Update="Dockerfile">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Setup\*">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
2
src/Services/Identity/Identity.API/Setup/Users.csv
Normal 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
|
|
BIN
src/Services/Identity/Identity.API/Setup/images.zip
Normal file
@ -153,7 +153,7 @@ namespace eShopOnContainers.Identity
|
|||||||
|
|
||||||
//Seed Data
|
//Seed Data
|
||||||
var hasher = new PasswordHasher<ApplicationUser>();
|
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)
|
private async Task InitializeGrantStoreAndConfiguration(IApplicationBuilder app)
|
||||||
|
@ -40,10 +40,7 @@
|
|||||||
<br><div class="brand"></div>
|
<br><div class="brand"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<br />
|
<img class="text hidden-xs" src="~/images/main_footer_text.PNG" width="335" height="26" alt="footer text image" />
|
||||||
<br>
|
|
||||||
<br />
|
|
||||||
<div class="text hidden-xs">© e-ShoponContainers. All right reserved</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"MvcClient": "http://localhost:5100",
|
"MvcClient": "http://localhost:5100",
|
||||||
"SpaClient": "http://localhost:5104",
|
"SpaClient": "http://localhost:5104",
|
||||||
"XamarinCallback": "http://localhost:5105/xamarincallback",
|
"XamarinCallback": "http://localhost:5105/xamarincallback",
|
||||||
|
"UseCustomizationData": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
@ -476,11 +476,7 @@ footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
footer .text {
|
footer .text {
|
||||||
text-align: right;
|
margin-top: 55px;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
color: #83D01B;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 252 B |
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,40 +8,175 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
|
||||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
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 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
|
var context = (OrderingContext)applicationBuilder
|
||||||
.ApplicationServices.GetService(typeof(OrderingContext));
|
.ApplicationServices.GetService(typeof(OrderingContext));
|
||||||
|
|
||||||
|
var settings = applicationBuilder
|
||||||
|
.ApplicationServices.GetRequiredService<IOptions<OrderingSettings>>().Value;
|
||||||
|
|
||||||
|
var useCustomizationData = settings.UseCustomizationData;
|
||||||
|
var contentRootPath = env.ContentRootPath;
|
||||||
|
|
||||||
|
|
||||||
using (context)
|
using (context)
|
||||||
{
|
{
|
||||||
context.Database.Migrate();
|
context.Database.Migrate();
|
||||||
|
|
||||||
if (!context.CardTypes.Any())
|
if (!context.CardTypes.Any())
|
||||||
{
|
{
|
||||||
context.CardTypes.Add(CardType.Amex);
|
context.CardTypes.AddRange(useCustomizationData
|
||||||
context.CardTypes.Add(CardType.Visa);
|
? GetCardTypesFromFile(contentRootPath, log)
|
||||||
context.CardTypes.Add(CardType.MasterCard);
|
: GetPredefinedCardTypes());
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.OrderStatus.Any())
|
if (!context.OrderStatus.Any())
|
||||||
{
|
{
|
||||||
context.OrderStatus.Add(OrderStatus.Submitted);
|
context.OrderStatus.AddRange(useCustomizationData
|
||||||
context.OrderStatus.Add(OrderStatus.AwaitingValidation);
|
? GetOrderStatusFromFile(contentRootPath, log)
|
||||||
context.OrderStatus.Add(OrderStatus.StockConfirmed);
|
: GetPredefinedOrderStatus());
|
||||||
context.OrderStatus.Add(OrderStatus.Paid);
|
|
||||||
context.OrderStatus.Add(OrderStatus.Shipped);
|
|
||||||
context.OrderStatus.Add(OrderStatus.Cancelled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
<Content Include=".dockerignore;">
|
<Content Include=".dockerignore;">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Setup\**\*;">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -73,6 +76,9 @@
|
|||||||
<None Update="Dockerfile">
|
<None Update="Dockerfile">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Setup\*">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
7
src/Services/Ordering/Ordering.API/OrderingSettings.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API
|
||||||
|
{
|
||||||
|
public class OrderingSettings
|
||||||
|
{
|
||||||
|
public bool UseCustomizationData { get; set; }
|
||||||
|
}
|
||||||
|
}
|
5
src/Services/Ordering/Ordering.API/Setup/CardTypes.csv
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
CardType
|
||||||
|
Amex
|
||||||
|
Visa
|
||||||
|
MasterCard
|
||||||
|
Capital One
|
|
7
src/Services/Ordering/Ordering.API/Setup/OrderStatus.csv
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
OrderStatus
|
||||||
|
Submitted
|
||||||
|
AwaitingValidation
|
||||||
|
StockConfirmed
|
||||||
|
Paid
|
||||||
|
Shipped
|
||||||
|
Cancelled
|
|
@ -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)
|
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 =>
|
services.AddSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
options.DescribeAllEnumsAsStrings();
|
options.DescribeAllEnumsAsStrings();
|
||||||
@ -159,7 +161,7 @@
|
|||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
||||||
});
|
});
|
||||||
|
|
||||||
WaitForSqlAvailabilityAsync(loggerFactory, app).Wait();
|
WaitForSqlAvailabilityAsync(loggerFactory, app, env).Wait();
|
||||||
ConfigureEventBus(app);
|
ConfigureEventBus(app);
|
||||||
|
|
||||||
var integrationEventLogContext = new IntegrationEventLogContext(
|
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 logger = loggerFactory.CreateLogger(nameof(Startup));
|
||||||
var policy = CreatePolicy(retries, logger, nameof(WaitForSqlAvailabilityAsync));
|
var policy = CreatePolicy(retries, logger, nameof(WaitForSqlAvailabilityAsync));
|
||||||
await policy.ExecuteAsync(async () =>
|
await policy.ExecuteAsync(async () =>
|
||||||
{
|
{
|
||||||
await OrderingContextSeed.SeedAsync(app);
|
await OrderingContextSeed.SeedAsync(app, env, loggerFactory);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
|
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
|
||||||
"IdentityUrl": "http://localhost:5105",
|
"IdentityUrl": "http://localhost:5105",
|
||||||
|
"UseCustomizationData": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
@ -13,6 +13,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
public string BasketUrl { get; set; }
|
public string BasketUrl { get; set; }
|
||||||
public string MarketingUrl { get; set; }
|
public string MarketingUrl { get; set; }
|
||||||
public Logging Logging { get; set; }
|
public Logging Logging { get; set; }
|
||||||
|
public bool UseCustomizationData { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Connectionstrings
|
public class Connectionstrings
|
||||||
|
97
src/Web/WebMVC/Infrastructure/WebContextSeed.cs
Normal 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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
src/Web/WebMVC/Setup/images.zip
Normal file
3
src/Web/WebMVC/Setup/override.css
Normal 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; */
|
||||||
|
}
|
@ -12,6 +12,7 @@ using Microsoft.Extensions.HealthChecks;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using WebMVC.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC
|
namespace Microsoft.eShopOnContainers.WebMVC
|
||||||
{
|
{
|
||||||
@ -129,6 +130,9 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
Scope = { "openid", "profile", "orders", "basket", "marketing" }
|
Scope = { "openid", "profile", "orders", "basket", "marketing" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Seed Data
|
||||||
|
WebContextSeed.Seed(app, env, loggerFactory);
|
||||||
|
|
||||||
//Wait untill identity service is ready on compose.
|
//Wait untill identity service is ready on compose.
|
||||||
app.UseOpenIdConnectAuthentication(oidcOptions);
|
app.UseOpenIdConnectAuthentication(oidcOptions);
|
||||||
|
|
||||||
|
@ -68,9 +68,9 @@
|
|||||||
<img class="esh-orders_detail-image" src="@item.PictureUrl">
|
<img class="esh-orders_detail-image" src="@item.PictureUrl">
|
||||||
</section>
|
</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-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-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>
|
</article>
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
<input type="hidden" value="@item.ProductName" name=@("orderitems[" + i + "].ProductName") />
|
<input type="hidden" value="@item.ProductName" name=@("orderitems[" + i + "].ProductName") />
|
||||||
</section>
|
</section>
|
||||||
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
|
<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") />
|
<input type="hidden" value="@item.UnitPrice" name=@("orderitems[" + i + "].UnitPrice") />
|
||||||
</section>
|
</section>
|
||||||
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
|
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
|
||||||
@item.Units
|
@item.Units
|
||||||
<input type="hidden" value="@item.Units" name=@("orderitems[" + i + "].Units") />
|
<input type="hidden" value="@item.Units" name=@("orderitems[" + i + "].Units") />
|
||||||
</section>
|
</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>
|
</article>
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<article class="esh-orders_new-items row">
|
<article class="esh-orders_new-items row">
|
||||||
<section class="esh-orders_new-item col-xs-9"></section>
|
<section class="esh-orders_new-item col-xs-9"></section>
|
||||||
<section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">
|
<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"/>
|
<input type="hidden" value="@Model.Total" name="Total"/>
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
<img class="esh-basket-image" src="@item.PictureUrl" />
|
<img class="esh-basket-image" src="@item.PictureUrl" />
|
||||||
</section>
|
</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-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">
|
<section class="esh-basket-item esh-basket-item--middle col-xs-2">
|
||||||
<input type="hidden" name="@("quantities[" + i +"].Key")" value="@item.Id" />
|
<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" />
|
<input type="number" class="esh-basket-input" min="1" name="@("quantities[" + i +"].Value")" value="@item.Quantity" />
|
||||||
</section>
|
</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>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
|
@ -19,12 +19,14 @@
|
|||||||
<link rel="stylesheet" href="~/css/orders/orders.component.css" />
|
<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-detail/orders-detail.component.css" />
|
||||||
<link rel="stylesheet" href="~/css/orders/orders-new/orders-new.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>
|
||||||
<environment names="Staging,Production">
|
<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"
|
<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-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
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/site.min.css" asp-append-version="true" />
|
||||||
|
<link rel="stylesheet" href="~/css/override.css" type="text/css" />
|
||||||
</environment>
|
</environment>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -56,7 +58,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="col-sm-6">
|
<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>
|
</section>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
@ -9,6 +9,24 @@
|
|||||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||||
</PropertyGroup>
|
</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>
|
<!--<ItemGroup>
|
||||||
<Compile Remove="wwwroot\lib\bootstrap\**" />
|
<Compile Remove="wwwroot\lib\bootstrap\**" />
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"CallBackUrl": "http://localhost:5100/",
|
"CallBackUrl": "http://localhost:5100/",
|
||||||
"IsClusterEnv": "False",
|
"IsClusterEnv": "False",
|
||||||
"UseResilientHttp": "True",
|
"UseResilientHttp": "True",
|
||||||
|
"UseCustomizationData": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
42
src/Web/WebMVC/compilerconfig.json
Normal 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"
|
||||||
|
}
|
||||||
|
]
|
49
src/Web/WebMVC/compilerconfig.json.defaults
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
src/Web/WebMVC/wwwroot/css/_variables.scss
Normal 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';
|
@ -1,20 +1,14 @@
|
|||||||
.esh-app-footer {
|
.esh-app-footer {
|
||||||
background-color: #000000;
|
background-color: #000000;
|
||||||
border-top: 1px solid #EEEEEE;
|
border-top: 1px solid #EEEEEE;
|
||||||
margin-top: 2.5rem;
|
margin-top: 2.5rem;
|
||||||
padding-bottom: 2.5rem;
|
padding-bottom: 2.5rem;
|
||||||
padding-top: 2.5rem;
|
padding-top: 2.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-app-footer-brand {
|
.esh-app-footer-brand {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 230px;
|
width: 230px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-app-footer-text {
|
|
||||||
color: #83D01B;
|
|
||||||
line-height: 50px;
|
|
||||||
text-align: right;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
23
src/Web/WebMVC/wwwroot/css/app.component.scss
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,38 +1,39 @@
|
|||||||
.esh-basketstatus {
|
.esh-basketstatus {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
float: right;
|
float: right;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basketstatus.is-disabled {
|
.esh-basketstatus.is-disabled {
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basketstatus-image {
|
.esh-basketstatus-image {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basketstatus-badge {
|
.esh-basketstatus-badge {
|
||||||
background-color: #83D01B;
|
background-color: #83D01B;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
display: block;
|
display: block;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
top: 0;
|
top: 0;
|
||||||
transform: translateX(-38%);
|
transform: translateX(-38%);
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basketstatus:hover .esh-basketstatus-badge {
|
.esh-basketstatus:hover .esh-basketstatus-badge {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #75b918;
|
color: #75b918;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,78 +1,79 @@
|
|||||||
.esh-basket {
|
.esh-basket {
|
||||||
min-height: 80vh;
|
min-height: 80vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-titles {
|
.esh-basket-titles {
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-titles--clean {
|
.esh-basket-titles--clean {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-title {
|
.esh-basket-title {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-items--border {
|
.esh-basket-items--border {
|
||||||
border-bottom: 1px solid #EEEEEE;
|
border-bottom: 1px solid #EEEEEE;
|
||||||
padding: .5rem 0;
|
padding: .5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-items--border:last-of-type {
|
.esh-basket-items--border:last-of-type {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.esh-basket-items-margin-left1 {
|
||||||
|
margin-left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.esh-basket-item {
|
.esh-basket-item {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-item--middle {
|
.esh-basket-item--middle {
|
||||||
line-height: 8rem;
|
line-height: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
.esh-basket-item--middle {
|
.esh-basket-item--middle {
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-item--mark {
|
.esh-basket-item--mark {
|
||||||
color: #00A69C;
|
color: #00A69C;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-image {
|
.esh-basket-image {
|
||||||
height: 8rem;
|
height: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-input {
|
.esh-basket-input {
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-checkout {
|
.esh-basket-checkout {
|
||||||
border: none;
|
background-color: #83D01B;
|
||||||
border-radius: 0;
|
border: 0;
|
||||||
background-color: #83D01B;
|
border-radius: 0;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-checkout:hover {
|
.esh-basket-checkout:hover {
|
||||||
background-color: #4a760f;
|
background-color: #4a760f;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-basket-margin12{
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
|
89
src/Web/WebMVC/wwwroot/css/basket/basket.component.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,147 +1,149 @@
|
|||||||
.esh-catalog-hero {
|
.esh-catalog-hero {
|
||||||
background-image: url("../../images/main_banner.png");
|
background-image: url("../../images/main_banner.png");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
height: 260px;
|
height: 260px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-title {
|
.esh-catalog-title {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 74.28571px;
|
top: 74.28571px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-filters {
|
.esh-catalog-filters {
|
||||||
background-color: #00A69C;
|
background-color: #00A69C;
|
||||||
height: 65px;
|
height: 65px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-filter {
|
.esh-catalog-filter {
|
||||||
background-color: transparent;
|
-webkit-appearance: none;
|
||||||
border-color: #00d9cc;
|
background-color: transparent;
|
||||||
color: #FFFFFF;
|
border-color: #00d9cc;
|
||||||
cursor: pointer;
|
color: #FFFFFF;
|
||||||
margin-right: 1rem;
|
cursor: pointer;
|
||||||
margin-top: .5rem;
|
margin-right: 1rem;
|
||||||
outline-color: #83D01B;
|
margin-top: .5rem;
|
||||||
padding-bottom: 0;
|
min-width: 140px;
|
||||||
padding-left: 0.5rem;
|
outline-color: #83D01B;
|
||||||
padding-right: 0.5rem;
|
padding-bottom: 0;
|
||||||
padding-top: 1.5rem;
|
padding-left: 0.5rem;
|
||||||
min-width: 140px;
|
padding-right: 0.5rem;
|
||||||
-webkit-appearance: none;
|
padding-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-filter option {
|
.esh-catalog-filter option {
|
||||||
background-color: #00A69C;
|
background-color: #00A69C;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-label {
|
.esh-catalog-label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-label::before {
|
.esh-catalog-label::before {
|
||||||
color: rgba(255, 255, 255, 0.5);
|
color: rgba(255, 255, 255, 0.5);
|
||||||
content: attr(data-title);
|
content: attr(data-title);
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
margin-top: 0.65rem;
|
margin-left: 0.5rem;
|
||||||
margin-left: 0.5rem;
|
margin-top: 0.65rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-label::after {
|
.esh-catalog-label::after {
|
||||||
background-image: url("../../images/arrow-down.png");
|
background-image: url("../../images/arrow-down.png");
|
||||||
height: 7px;
|
content: '';
|
||||||
content: '';
|
height: 7px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 1.5rem;
|
right: 1.5rem;
|
||||||
top: 2.5rem;
|
top: 2.5rem;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-send {
|
.esh-catalog-send {
|
||||||
background-color: #83D01B;
|
background-color: #83D01B;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
transform: translateY(.5rem);
|
margin-top: -1.5rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-send:hover {
|
.esh-catalog-send:hover {
|
||||||
background-color: #4a760f;
|
background-color: #4a760f;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-items {
|
.esh-catalog-items {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-item {
|
.esh-catalog-item {
|
||||||
text-align: center;
|
margin-bottom: 1.5rem;
|
||||||
margin-bottom: 1.5rem;
|
text-align: center;
|
||||||
width: 33%;
|
width: 33%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
float: none !important;
|
float: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
.esh-catalog-item {
|
.esh-catalog-item {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.esh-catalog-item {
|
.esh-catalog-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-thumbnail {
|
.esh-catalog-thumbnail {
|
||||||
max-width: 370px;
|
max-width: 370px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-button {
|
.esh-catalog-button {
|
||||||
background-color: #83D01B;
|
background-color: #83D01B;
|
||||||
border: none;
|
border: 0;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
.esh-catalog-button.is-disabled {
|
|
||||||
opacity: .5;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.esh-catalog-button:hover {
|
.esh-catalog-button.is-disabled {
|
||||||
background-color: #4a760f;
|
opacity: .5;
|
||||||
transition: all 0.35s;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.esh-catalog-button:hover {
|
||||||
|
background-color: #4a760f;
|
||||||
|
transition: all 0.35s;
|
||||||
|
}
|
||||||
|
|
||||||
.esh-catalog-name {
|
.esh-catalog-name {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-price {
|
.esh-catalog-price {
|
||||||
text-align: center;
|
font-size: 28px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-size: 28px;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.esh-catalog-price::before {
|
||||||
|
content: '$';
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-catalog-price::before {
|
|
||||||
content: '$';
|
|
||||||
}
|
|
||||||
|
154
src/Web/WebMVC/wwwroot/css/catalog/catalog.component.scss
Normal 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: '$';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,52 +1,53 @@
|
|||||||
.esh-orders_detail {
|
.esh-orders_detail {
|
||||||
min-height: 80vh;
|
min-height: 80vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-section {
|
.esh-orders_detail-section {
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-section--right {
|
.esh-orders_detail-section--right {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-titles {
|
.esh-orders_detail-titles {
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-title {
|
.esh-orders_detail-title {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-items--border {
|
.esh-orders_detail-items--border {
|
||||||
border-bottom: 1px solid #EEEEEE;
|
border-bottom: 1px solid #EEEEEE;
|
||||||
padding: .5rem 0;
|
padding: .5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-items--border:last-of-type {
|
.esh-orders_detail-items--border:last-of-type {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-item {
|
.esh-orders_detail-item {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-item--middle {
|
.esh-orders_detail-item--middle {
|
||||||
line-height: 8rem;
|
line-height: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.esh-orders_detail-item--middle {
|
.esh-orders_detail-item--middle {
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-item--mark {
|
.esh-orders_detail-item--mark {
|
||||||
color: #83D01B;
|
color: #83D01B;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_detail-image {
|
.esh-orders_detail-image {
|
||||||
height: 8rem;
|
height: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,91 +1,96 @@
|
|||||||
.esh-orders_new {
|
.esh-orders_new {
|
||||||
min-height: 80vh;
|
min-height: 80vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-header {
|
.esh-orders_new-header {
|
||||||
background-color: #00A69C;
|
background-color: #00A69C;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-back {
|
.esh-orders_new-back {
|
||||||
color: rgba(255, 255, 255, 0.4);
|
color: rgba(255, 255, 255, 0.4);
|
||||||
line-height: 4rem;
|
line-height: 4rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
transition: color 0.35s;
|
transition: color 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-back:hover {
|
.esh-orders_new-back:hover {
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
transition: color 0.35s;
|
transition: color 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-section {
|
.esh-orders_new-section {
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-section--right {
|
.esh-orders_new-section--right {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-placeOrder {
|
.esh-orders_new-placeOrder {
|
||||||
background-color: #83D01B;
|
background-color: #83D01B;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-placeOrder:hover {
|
.esh-orders_new-placeOrder:hover {
|
||||||
background-color: #4a760f;
|
background-color: #4a760f;
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-titles {
|
.esh-orders_new-titles {
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-title {
|
.esh-orders_new-title {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-items--border {
|
.esh-orders_new-items--border {
|
||||||
border-bottom: 1px solid #EEEEEE;
|
border-bottom: 1px solid #EEEEEE;
|
||||||
padding: .5rem 0;
|
padding: .5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-items--border:last-of-type {
|
.esh-orders_new-items--border:last-of-type {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-item {
|
.esh-orders_new-item {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-item--middle {
|
.esh-orders_new-item--middle {
|
||||||
line-height: 8rem;
|
line-height: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.esh-orders_new-item--middle {
|
.esh-orders_new-item--middle {
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-item--mark {
|
.esh-orders_new-item--mark {
|
||||||
color: #83D01B;
|
color: #83D01B;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders_new-image {
|
.esh-orders_new-image {
|
||||||
height: 8rem;
|
height: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.esh-orders_new-alert {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,74 +1,75 @@
|
|||||||
.esh-orders {
|
.esh-orders {
|
||||||
min-height: 80vh;
|
min-height: 80vh;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-header {
|
.esh-orders-header {
|
||||||
background-color: #00A69C;
|
background-color: #00A69C;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-back {
|
.esh-orders-back {
|
||||||
color: rgba(255, 255, 255, 0.4);
|
color: rgba(255, 255, 255, 0.4);
|
||||||
line-height: 4rem;
|
line-height: 4rem;
|
||||||
text-transform: uppercase;
|
text-decoration: none;
|
||||||
text-decoration: none;
|
text-transform: uppercase;
|
||||||
transition: color 0.35s;
|
transition: color 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-back:hover {
|
.esh-orders-back:hover {
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
transition: color 0.35s;
|
transition: color 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-titles {
|
.esh-orders-titles {
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-title {
|
.esh-orders-title {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-items {
|
.esh-orders-items {
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-items:nth-of-type(2n + 1):before {
|
.esh-orders-items:nth-of-type(2n + 1):before {
|
||||||
background-color: #EEEEFF;
|
background-color: #EEEEFF;
|
||||||
content: '';
|
content: '';
|
||||||
height: 100%;
|
height: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
margin-left: -100vw;
|
margin-left: -100vw;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 200vw;
|
width: 200vw;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-item {
|
.esh-orders-item {
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-item--hover {
|
.esh-orders-item--hover {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-items:hover .esh-orders-item--hover {
|
.esh-orders-items:hover .esh-orders-item--hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-link {
|
.esh-orders-link {
|
||||||
color: #83D01B;
|
color: #83D01B;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.35s;
|
transition: color 0.35s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.esh-orders-link:hover {
|
||||||
|
color: #75b918;
|
||||||
|
transition: color 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-orders-link:hover {
|
|
||||||
color: #75b918;
|
|
||||||
transition: color 0.35s;
|
|
||||||
}
|
|
||||||
|
81
src/Web/WebMVC/wwwroot/css/orders/orders.component.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
src/Web/WebMVC/wwwroot/css/override.css
Normal 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; */
|
||||||
|
}
|
@ -1,31 +1,18 @@
|
|||||||
.esh-header {
|
.esh-header {
|
||||||
background-color: #00A69C;
|
background-color: #00A69C;
|
||||||
height: 4rem;
|
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 {
|
.esh-header-back {
|
||||||
color: rgba(255, 255, 255, 0.5) !important;
|
color: rgba(255, 255, 255, 0.5);
|
||||||
line-height: 4rem;
|
line-height: 4rem;
|
||||||
text-transform: uppercase;
|
text-decoration: none;
|
||||||
text-decoration: none;
|
text-transform: uppercase;
|
||||||
transition: color 0.35s;
|
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;
|
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,57 +1,57 @@
|
|||||||
.esh-identity {
|
.esh-identity {
|
||||||
line-height: 3rem;
|
line-height: 3rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-section {
|
.esh-identity-section {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-name {
|
.esh-identity-name {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-name--upper {
|
.esh-identity-name--upper {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.esh-identity-name {
|
.esh-identity-name {
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-image {
|
.esh-identity-image {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-drop {
|
.esh-identity-drop {
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
height: 0rem;
|
height: 0;
|
||||||
min-width: 14rem;
|
min-width: 14rem;
|
||||||
right: 0;
|
overflow: hidden;
|
||||||
overflow: hidden;
|
padding: .5rem;
|
||||||
padding: .5rem;
|
position: absolute;
|
||||||
position: absolute;
|
right: 0;
|
||||||
top: 2.5rem;
|
top: 2.5rem;
|
||||||
transition: height 0.35s;
|
transition: height 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity:hover .esh-identity-drop {
|
.esh-identity:hover .esh-identity-drop {
|
||||||
border: 1px solid #EEEEEE;
|
border: 1px solid #EEEEEE;
|
||||||
height: 9.5rem;
|
height: 7rem;
|
||||||
transition: height 0.35s;
|
transition: height 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-item {
|
.esh-identity-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
transition: color 0.35s;
|
||||||
transition: color 0.35s;
|
}
|
||||||
|
|
||||||
|
.esh-identity-item:hover {
|
||||||
|
color: #75b918;
|
||||||
|
transition: color 0.35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-identity-item:hover {
|
|
||||||
color: #75b918;
|
|
||||||
transition: color 0.35s;
|
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,34 +1,35 @@
|
|||||||
.esh-pager-wrapper {
|
.esh-pager-wrapper {
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-pager-item {
|
.esh-pager-item {
|
||||||
margin: 0 5vw;
|
margin: 0 5vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.esh-pager-item.is-disabled {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-pager-item--navigable {
|
.esh-pager-item--navigable {
|
||||||
display: inline-block;
|
cursor: pointer;
|
||||||
cursor: pointer;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esh-pager-item--navigable.is-disabled {
|
.esh-pager-item--navigable:hover {
|
||||||
opacity: 0;
|
color: #83D01B;
|
||||||
pointer-events: none;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.esh-pager-item--navigable:hover {
|
|
||||||
color: #83D01B;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1280px) {
|
@media screen and (max-width: 1280px) {
|
||||||
.esh-pager-item {
|
.esh-pager-item {
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
.esh-pager-item {
|
.esh-pager-item {
|
||||||
margin: 0 4vw;
|
margin: 0 2.5vw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 229 B |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 760 B |
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 455 B |
Before Width: | Height: | Size: 713 KiB After Width: | Height: | Size: 851 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 7.8 KiB |
BIN
src/Web/WebMVC/wwwroot/images/main_footer_text.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 252 B |
@ -13,5 +13,6 @@ namespace eShopOnContainers.WebSPA
|
|||||||
public string IdentityUrl { get; set; }
|
public string IdentityUrl { get; set; }
|
||||||
public string BasketUrl { get; set; }
|
public string BasketUrl { get; set; }
|
||||||
public string MarketingUrl { get; set; }
|
public string MarketingUrl { get; set; }
|
||||||
|
public bool UseCustomizationData { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
src/Web/WebSPA/Client/assets/images/main_footer_text.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
@ -51,3 +51,8 @@ $media-screen-xxxl: 1920px;
|
|||||||
|
|
||||||
// Borders
|
// Borders
|
||||||
$border-light: 1px;
|
$border-light: 1px;
|
||||||
|
|
||||||
|
// Images
|
||||||
|
$image_path: '/assets/images/';
|
||||||
|
$image-main_banner: '#{$image_path}main_banner.png';
|
||||||
|
$image-arrow_down: '#{$image_path}arrow-down.png';
|
@ -32,7 +32,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="col-sm-6">
|
<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>
|
</section>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
@ -19,11 +19,5 @@
|
|||||||
width: 230px;
|
width: 230px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-text {
|
|
||||||
color: $color-secondary;
|
|
||||||
line-height: $height;
|
|
||||||
text-align: right;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<img class="esh-basket-image" src="{{item.pictureUrl}}" />
|
<img class="esh-basket-image" src="{{item.pictureUrl}}" />
|
||||||
</section>
|
</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-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">
|
<section class="esh-basket-item esh-basket-item--middle col-xs-2">
|
||||||
<input class="esh-basket-input"
|
<input class="esh-basket-input"
|
||||||
type="number"
|
type="number"
|
||||||
@ -25,7 +25,7 @@
|
|||||||
[(ngModel)]="item.quantity"
|
[(ngModel)]="item.quantity"
|
||||||
(change)="itemQuantityChanged(item)" />
|
(change)="itemQuantityChanged(item)" />
|
||||||
</section>
|
</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>
|
</article>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="esh-basket-items-margin-left1 row">
|
<div class="esh-basket-items-margin-left1 row">
|
||||||
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
<article class="esh-basket-items row">
|
<article class="esh-basket-items row">
|
||||||
<section class="esh-basket-item col-xs-9"></section>
|
<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>
|
||||||
|
|
||||||
<article class="esh-basket-items row">
|
<article class="esh-basket-items row">
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
<span>{{item.name}}</span>
|
<span>{{item.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="esh-catalog-price">
|
<div class="esh-catalog-price">
|
||||||
<span>{{item.price}}</span>
|
<span>{{item.price | number:'.2-2'}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
$banner-height: 260px;
|
$banner-height: 260px;
|
||||||
|
|
||||||
&-hero {
|
&-hero {
|
||||||
background-image: url('../../assets/images/main_banner.png');
|
background-image: url($image-main_banner);
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
height: $banner-height;
|
height: $banner-height;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -61,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
background-image: url('../../assets/images/arrow-down.png');
|
background-image: url($image-arrow_down);
|
||||||
content: '';
|
content: '';
|
||||||
height: 7px; //png height
|
height: 7px; //png height
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -57,9 +57,9 @@
|
|||||||
<img class="esh-orders_detail-image" src="{{item.pictureurl}}">
|
<img class="esh-orders_detail-image" src="{{item.pictureurl}}">
|
||||||
</section>
|
</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-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-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>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<article class="esh-orders_detail-items row">
|
<article class="esh-orders_detail-items row">
|
||||||
<section class="esh-orders_detail-item col-xs-9"></section>
|
<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>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,9 +86,9 @@
|
|||||||
<img class="esh-orders_new-image" src="{{item.pictureurl}}">
|
<img class="esh-orders_new-image" src="{{item.pictureurl}}">
|
||||||
</section>
|
</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-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-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>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -100,7 +100,7 @@
|
|||||||
|
|
||||||
<article class="esh-orders_new-items row">
|
<article class="esh-orders_new-items row">
|
||||||
<section class="esh-orders_new-item col-xs-9"></section>
|
<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>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
<section class="esh-orders_new-section">
|
<section class="esh-orders_new-section">
|
||||||
|
73
src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs
Normal 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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
src/Web/WebSPA/Setup/images.zip
Normal file
@ -11,6 +11,7 @@ using Microsoft.Extensions.HealthChecks;
|
|||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
using eShopOnContainers.WebSPA;
|
using eShopOnContainers.WebSPA;
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks;
|
using Microsoft.eShopOnContainers.BuildingBlocks;
|
||||||
|
using WebSPA.Infrastructure;
|
||||||
|
|
||||||
namespace eShopConContainers.WebSPA
|
namespace eShopConContainers.WebSPA
|
||||||
{
|
{
|
||||||
@ -99,6 +100,9 @@ namespace eShopConContainers.WebSPA
|
|||||||
// await next.Invoke();
|
// await next.Invoke();
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
//Seed Data
|
||||||
|
WebContextSeed.Seed(app, env, loggerFactory);
|
||||||
|
|
||||||
app.Use(async (context, next) =>
|
app.Use(async (context, next) =>
|
||||||
{
|
{
|
||||||
await next();
|
await next();
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="node_modules\**\*;Client\**\*" />
|
<Compile Remove="node_modules\**\*;Client\**\*" />
|
||||||
|
<Content Include="Setup\images.zip">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
<Content Update="appsettings.json;">
|
<Content Update="appsettings.json;">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"IdentityUrl": "http://localhost:5105",
|
"IdentityUrl": "http://localhost:5105",
|
||||||
"MarketingUrl": "http://localhost:5110",
|
"MarketingUrl": "http://localhost:5110",
|
||||||
"CallBackUrl": "http://localhost:5104/",
|
"CallBackUrl": "http://localhost:5104/",
|
||||||
|
"UseCustomizationData": true,
|
||||||
"IsClusterEnv": "False",
|
"IsClusterEnv": "False",
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
|