From f9c6a4e18750dc9b54757e2601a10f3f612f0bed Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Mon, 30 Mar 2020 17:11:56 +0200 Subject: [PATCH] start first steps --- zero.Core/Entities/Setup/SetupSave.cs | 41 +++++ zero.Core/Extensions/ValidatorExtensions.cs | 12 ++ zero.Core/Validation/SetupSaveValidator.cs | 32 ++++ zero.Web/App/Components/Buttons/button.vue | 8 +- zero.Web/App/Components/Forms/property.vue | 14 +- zero.Web/Controllers/SetupController.cs | 8 + zero.Web/Sass/Core/_forms.scss | 5 + zero.Web/Sass/Core/_settings.scss | 1 + zero.Web/Sass/Modules/Buttons/_button.scss | 20 ++- zero.Web/Sass/Setup/_all.scss | 4 +- zero.Web/Sass/Setup/_steps.scss | 39 ----- zero.Web/Setup/Steps/step-application.vue | 36 ++++ zero.Web/Setup/Steps/step-database.vue | 40 +++++ zero.Web/Setup/Steps/step-user.vue | 4 +- zero.Web/Setup/setup.vue | 62 ++++++- zero.Web/wwwroot/Assets/setup.js | 178 ++++++++++++++++++-- 16 files changed, 430 insertions(+), 74 deletions(-) create mode 100644 zero.Core/Entities/Setup/SetupSave.cs create mode 100644 zero.Core/Validation/SetupSaveValidator.cs delete mode 100644 zero.Web/Sass/Setup/_steps.scss create mode 100644 zero.Web/Setup/Steps/step-application.vue create mode 100644 zero.Web/Setup/Steps/step-database.vue diff --git a/zero.Core/Entities/Setup/SetupSave.cs b/zero.Core/Entities/Setup/SetupSave.cs new file mode 100644 index 00000000..920c01d2 --- /dev/null +++ b/zero.Core/Entities/Setup/SetupSave.cs @@ -0,0 +1,41 @@ +namespace zero.Core.Entities.Setup +{ + public sealed class SetupSave + { + public string AppName { get; set; } + + public SetupUserSave User { get; set; } + + public SetupDatabaseSave Database { get; set; } + + public SetupSavePart Part { get; set; } + } + + + public sealed class SetupUserSave + { + public string Name { get; set; } + + public string Email { get; set; } + + public string Password { get; set; } + } + + public sealed class SetupDatabaseSave + { + public string Url { get; set; } + + public string Name { get; set; } + } + + + public enum SetupSavePart + { + ValidateUser = 0, + ValidateApplication = 1, + ValidateDatabase = 2, + ValidateFolderAccess = 3, + WriteSettings = 4, + SaveData = 5 + } +} diff --git a/zero.Core/Extensions/ValidatorExtensions.cs b/zero.Core/Extensions/ValidatorExtensions.cs index 26c27e6f..53ee9c44 100644 --- a/zero.Core/Extensions/ValidatorExtensions.cs +++ b/zero.Core/Extensions/ValidatorExtensions.cs @@ -21,6 +21,18 @@ namespace zero.Core.Extensions } + /// + /// Validate an email + /// + public static IRuleBuilderOptions Url(this IRuleBuilder ruleBuilder) + { + return ruleBuilder.Must((root, value, context) => + { + return value.IsNullOrWhiteSpace() || Uri.IsWellFormedUriString(value, UriKind.Absolute); + }).WithMessage("@errors/invalid_uri"); + } + + /// /// Validate an email /// diff --git a/zero.Core/Validation/SetupSaveValidator.cs b/zero.Core/Validation/SetupSaveValidator.cs new file mode 100644 index 00000000..42227f84 --- /dev/null +++ b/zero.Core/Validation/SetupSaveValidator.cs @@ -0,0 +1,32 @@ +using FluentValidation; +using zero.Core.Entities.Setup; +using zero.Core.Extensions; + +namespace zero.Core.Validation +{ + public class SetupSaveValidator : AbstractValidator + { + public SetupSaveValidator() + { + When(x => x.Part == SetupSavePart.ValidateUser, () => + { + RuleFor(x => x.User).NotNull(); + RuleFor(x => x.User.Email).NotEmpty().Email(); + RuleFor(x => x.User.Name).MaximumLength(40).NotEmpty(); + RuleFor(x => x.User.Password).MaximumLength(1024); // TODO password policy + }); + + When(x => x.Part == SetupSavePart.ValidateApplication, () => + { + RuleFor(x => x.AppName).MaximumLength(40).NotEmpty(); + }); + + When(x => x.Part == SetupSavePart.ValidateDatabase, () => + { + RuleFor(x => x.Database.Url).NotEmpty().Url(); + RuleFor(x => x.Database.Name).NotEmpty(); + }); + + } + } +} diff --git a/zero.Web/App/Components/Buttons/button.vue b/zero.Web/App/Components/Buttons/button.vue index 1189769d..d053b7ef 100644 --- a/zero.Web/App/Components/Buttons/button.vue +++ b/zero.Web/App/Components/Buttons/button.vue @@ -1,5 +1,5 @@  @@ -18,7 +18,7 @@ type: String, default: 'default' }, - theme: { + type: { type: String, default: 'action' }, @@ -26,9 +26,9 @@ }, computed: { - themeClass() + typeClass() { - return 'theme-' + this.theme; + return 'type-' + this.type; } }, diff --git a/zero.Web/App/Components/Forms/property.vue b/zero.Web/App/Components/Forms/property.vue index 151874c0..99aa1ac5 100644 --- a/zero.Web/App/Components/Forms/property.vue +++ b/zero.Web/App/Components/Forms/property.vue @@ -42,6 +42,13 @@ { position: relative; display: flex; + + & + .ui-property + { + padding-top: 25px; + margin-top: 25px; + border-top: 1px solid var(--color-line); + } } .ui-property.is-vertical @@ -91,11 +98,4 @@ { flex: 1; } - - .ui-property + .ui-property - { - padding-top: 25px; - margin-top: 25px; - border-top: 1px solid var(--color-line); - } \ No newline at end of file diff --git a/zero.Web/Controllers/SetupController.cs b/zero.Web/Controllers/SetupController.cs index 3263a67b..da97d2b1 100644 --- a/zero.Web/Controllers/SetupController.cs +++ b/zero.Web/Controllers/SetupController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; using zero.Core; +using zero.Core.Entities.Setup; using zero.Web.Controllers; namespace zero.Web.Setup @@ -17,5 +19,11 @@ namespace zero.Web.Setup { return View("/Views/Setup.cshtml"); } + + [HttpPost] + public async Task Save(SetupSave model) + { + return Ok(); + } } } diff --git a/zero.Web/Sass/Core/_forms.scss b/zero.Web/Sass/Core/_forms.scss index 648891dd..f6228872 100644 --- a/zero.Web/Sass/Core/_forms.scss +++ b/zero.Web/Sass/Core/_forms.scss @@ -15,4 +15,9 @@ input, textarea vertical-align: middle; box-sizing: border-box; width: 100%; + + &:focus + { + border: 1px solid var(--color-line-mid); + } } diff --git a/zero.Web/Sass/Core/_settings.scss b/zero.Web/Sass/Core/_settings.scss index 82512840..aaca0fb5 100644 --- a/zero.Web/Sass/Core/_settings.scss +++ b/zero.Web/Sass/Core/_settings.scss @@ -17,6 +17,7 @@ // line colors --color-line: #eaebec; + --color-line-mid: #d7d8d9; } diff --git a/zero.Web/Sass/Modules/Buttons/_button.scss b/zero.Web/Sass/Modules/Buttons/_button.scss index 86d85f44..361f953f 100644 --- a/zero.Web/Sass/Modules/Buttons/_button.scss +++ b/zero.Web/Sass/Modules/Buttons/_button.scss @@ -15,9 +15,11 @@ button display: inline-block; color: white; background: var(--color-primary); - padding: 0 30px; + padding: 0 20px; + min-width: 80px; height: 40px; line-height: 40px; + text-align: center; border-radius: 3px; font-size: 14px; font-weight: 600; @@ -28,7 +30,6 @@ button cursor: pointer; user-select: none; border: none; - margin-top: 2rem; will-change: transform, background, border-color; transition: background .2s, transform .2s, opacity .2s; overflow: hidden; @@ -49,6 +50,21 @@ button pointer-events: none; //background: var(--color-dark); } + + &.type-outline + { + background: var(--color-bg); + color: var(--color-fg); + border: 1px solid var(--color-line); + box-sizing: border-box; + position: relative; + top: 1px; + } + + & + .ui-button + { + margin-left: 10px; + } } diff --git a/zero.Web/Sass/Setup/_all.scss b/zero.Web/Sass/Setup/_all.scss index a6d69862..cbe18ed8 100644 --- a/zero.Web/Sass/Setup/_all.scss +++ b/zero.Web/Sass/Setup/_all.scss @@ -1,4 +1,2 @@ -@import "canvas"; - -@import "steps"; +@import "canvas"; \ No newline at end of file diff --git a/zero.Web/Sass/Setup/_steps.scss b/zero.Web/Sass/Setup/_steps.scss deleted file mode 100644 index 999f93b4..00000000 --- a/zero.Web/Sass/Setup/_steps.scss +++ /dev/null @@ -1,39 +0,0 @@ - - -.setup -{ - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: space-between; -} - -.setup-step -{ - -} - -.setup-step h2 -{ - text-align: center; -} - -.setup-step p -{ - color: var(--color-fg-mid); - font-size: 0.9rem; - line-height: 1.6; - margin: 0 0 2rem; -} - -.setup-step p b -{ - color: var(--color-fg); - font-weight: 600; -} - -.setup-step .ui-property + .ui-property -{ - padding-top: 0; - border-top: none; -} \ No newline at end of file diff --git a/zero.Web/Setup/Steps/step-application.vue b/zero.Web/Setup/Steps/step-application.vue new file mode 100644 index 00000000..9ef6acfc --- /dev/null +++ b/zero.Web/Setup/Steps/step-application.vue @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/zero.Web/Setup/Steps/step-database.vue b/zero.Web/Setup/Steps/step-database.vue new file mode 100644 index 00000000..0fc5f0d6 --- /dev/null +++ b/zero.Web/Setup/Steps/step-database.vue @@ -0,0 +1,40 @@ + + + + \ No newline at end of file diff --git a/zero.Web/Setup/Steps/step-user.vue b/zero.Web/Setup/Steps/step-user.vue index 5d3ab54c..795a23b3 100644 --- a/zero.Web/Setup/Steps/step-user.vue +++ b/zero.Web/Setup/Steps/step-user.vue @@ -4,7 +4,7 @@

First we need some basic credentials from you to create a login. This login is the solely superadmin which is required to change critical application data.

- + @@ -12,7 +12,7 @@ - + diff --git a/zero.Web/Setup/setup.vue b/zero.Web/Setup/setup.vue index c7a984f6..cd93d62e 100644 --- a/zero.Web/Setup/setup.vue +++ b/zero.Web/Setup/setup.vue @@ -1,25 +1,31 @@  \ No newline at end of file + + + + \ No newline at end of file diff --git a/zero.Web/wwwroot/Assets/setup.js b/zero.Web/wwwroot/Assets/setup.js index f3be2f65..b161d194 100644 --- a/zero.Web/wwwroot/Assets/setup.js +++ b/zero.Web/wwwroot/Assets/setup.js @@ -63,7 +63,7 @@ /******/ /******/ var hotApplyOnUpdate = true; /******/ // eslint-disable-next-line no-unused-vars -/******/ var hotCurrentHash = "a2a24dda5c1a2e3219bc"; +/******/ var hotCurrentHash = "5d6e4d17647bbd821f8b"; /******/ var hotRequestTimeout = 10000; /******/ var hotCurrentModuleData = {}; /******/ var hotCurrentChildModule; @@ -902,6 +902,78 @@ eval("// style-loader: Adds some css to the DOM by adding a