From 19224d592a5b957089352aea4b0757421f5092a3 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 6 Jul 2020 12:45:09 +0200 Subject: [PATCH 01/71] Add optional icon only menu layout --- assets/sass/layout.scss | 42 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index e91200e..9aad28f 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -64,6 +64,7 @@ header { list-style: none; a, span { + position: relative; display: flex; flex-direction: row; align-items: center; @@ -72,7 +73,15 @@ header { .feather { --icon-size: 24px; - margin-right: 10px; + } + + &:hover { + .tip { + visibility: visible; + opacity: 1; + transition: opacity ease-out 100ms; + transition-delay: 150ms; + } } } @@ -129,9 +138,40 @@ header { &.open { transform: translateX(0%); } + + li a { + .tip { + display: block; + margin-left: 8px; + } + } } } } + + @media (min-width: $menuLayoutSwitchTreshold) { + nav ul li a .tip { + visibility: hidden; + position: absolute; + display: block; + width: max-content; + height: 30px; + padding: 4px 8px; + line-height: 22px; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + + text-align: center; + font-size: 18px; + color: $defaultTextColor; + opacity: 0; + transition: opacity ease-out 100ms, visibility step-end 150ms; + transition-delay: 0ms; + background-color: #000; + border-radius: 5px; + } + } } footer { -- 2.47.0 From 8aad5210148792cae75a11f2f619e8c54f160045 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 6 Jul 2020 12:49:28 +0200 Subject: [PATCH 02/71] Fix last menu item tip overflowing out of document --- assets/sass/layout.scss | 46 ++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 9aad28f..9c179ec 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -150,26 +150,34 @@ header { } @media (min-width: $menuLayoutSwitchTreshold) { - nav ul li a .tip { - visibility: hidden; - position: absolute; - display: block; - width: max-content; - height: 30px; - padding: 4px 8px; - line-height: 22px; - top: calc(100% + 8px); - left: 50%; - transform: translateX(-50%); + nav ul li { + a .tip { + visibility: hidden; + position: absolute; + display: block; + width: max-content; + height: 30px; + padding: 4px 8px; + line-height: 22px; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); - text-align: center; - font-size: 18px; - color: $defaultTextColor; - opacity: 0; - transition: opacity ease-out 100ms, visibility step-end 150ms; - transition-delay: 0ms; - background-color: #000; - border-radius: 5px; + text-align: center; + font-size: 18px; + color: $defaultTextColor; + opacity: 0; + transition: opacity ease-out 100ms, visibility step-end 150ms; + transition-delay: 0ms; + background-color: #000; + border-radius: 5px; + } + + &:last-child a .tip { + left: unset; + right: 4px; + transform: none; + } } } } -- 2.47.0 From 6a57dcdf9101d35c4674629d26c07688e47ac65d Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 12 Jul 2020 12:12:47 +0200 Subject: [PATCH 03/71] Promote some views to wms-core and update dependencies --- package.json | 19 +++-- views/errors/400.njk | 2 - views/errors/401.njk | 2 - views/errors/403.njk | 2 - views/errors/404.njk | 2 - views/errors/429.njk | 2 - views/errors/500.njk | 2 - views/errors/503.njk | 2 - views/errors/error.njk | 36 ---------- views/layouts/barebone.njk | 37 ---------- views/layouts/base.njk | 2 +- views/macros.njk | 142 ------------------------------------- 12 files changed, 13 insertions(+), 237 deletions(-) delete mode 100644 views/errors/400.njk delete mode 100644 views/errors/401.njk delete mode 100644 views/errors/403.njk delete mode 100644 views/errors/404.njk delete mode 100644 views/errors/429.njk delete mode 100644 views/errors/500.njk delete mode 100644 views/errors/503.njk delete mode 100644 views/errors/error.njk delete mode 100644 views/layouts/barebone.njk delete mode 100644 views/macros.njk diff --git a/package.json b/package.json index f9bf4df..beda726 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,14 @@ "@babel/preset-env": "^7.9.5", "@types/config": "^0.0.36", "@types/express": "^4.17.6", + "@types/express-session": "^1.17.0", "@types/formidable": "^1.0.31", - "@types/jest": "^25.2.1", + "@types/jest": "^26.0.4", + "@types/mysql": "^2.15.15", "@types/node": "^13.13.2", + "@types/nodemailer": "^6.4.0", + "@types/nunjucks": "^3.1.3", + "@types/ws": "^7.2.6", "babel-loader": "^8.1.0", "concurrently": "^5.1.0", "css-loader": "^3.5.2", @@ -28,16 +33,16 @@ "file-loader": "^6.0.0", "imagemin": "^7.0.1", "imagemin-gifsicle": "^7.0.0", - "imagemin-mozjpeg": "^8.0.0", - "imagemin-pngquant": "^8.0.0", - "imagemin-svgo": "^7.1.0", + "imagemin-mozjpeg": "^9.0.0", + "imagemin-pngquant": "^9.0.0", + "imagemin-svgo": "^8.0.0", "img-loader": "^3.0.1", - "jest": "^25.4.0", + "jest": "^26.1.0", "mini-css-extract-plugin": "^0.9.0", "node-sass": "^4.14.0", "nodemon": "^2.0.3", - "sass-loader": "^8.0.2", - "ts-jest": "^25.4.0", + "sass-loader": "^9.0.2", + "ts-jest": "^26.1.1", "typescript": "^3.8.3", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.43.0", diff --git a/views/errors/400.njk b/views/errors/400.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/400.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/401.njk b/views/errors/401.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/401.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/403.njk b/views/errors/403.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/403.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/404.njk b/views/errors/404.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/404.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/429.njk b/views/errors/429.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/429.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/500.njk b/views/errors/500.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/500.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/503.njk b/views/errors/503.njk deleted file mode 100644 index a5bc022..0000000 --- a/views/errors/503.njk +++ /dev/null @@ -1,2 +0,0 @@ -{% extends './error.njk' %} -{% import 'macros.njk' as macros %} diff --git a/views/errors/error.njk b/views/errors/error.njk deleted file mode 100644 index 3d05ea9..0000000 --- a/views/errors/error.njk +++ /dev/null @@ -1,36 +0,0 @@ -{% extends '../layouts/barebone.njk' %} - -{% set title = error_code + ' - ' + error_message %} - -{% block _stylesheets %} - -{% endblock %} - -{% block _body %} - - -
- {% if flash %} - {{ macros.messages(flash) }} - {% endif %} - -
{{ error_code }}
-
{{ error_message }}
-
{{ error_instructions|safe }}
- - -
- -
- Error ID: {{ error_id }} -
- If you think this isn't right, please contact us with the above error ID at - {{ app.contact_email }}. -
-{% endblock %} \ No newline at end of file diff --git a/views/layouts/barebone.njk b/views/layouts/barebone.njk deleted file mode 100644 index 3a82d94..0000000 --- a/views/layouts/barebone.njk +++ /dev/null @@ -1,37 +0,0 @@ - - - - - {{ title }} - - - - - - - - {% if description %} - - {% endif %} - - {% if refresh_after %} - - {% endif %} - - {% block _stylesheets %}{% endblock %} - {% block _scripts %} - - {% endblock %} - - - -
- {% block header %}{% endblock %} -
- -{% block _body %}{% endblock %} - -
{% block footer %}{% endblock %}
- - - \ No newline at end of file diff --git a/views/layouts/base.njk b/views/layouts/base.njk index f87c6aa..cb76570 100644 --- a/views/layouts/base.njk +++ b/views/layouts/base.njk @@ -1,4 +1,4 @@ -{% extends './barebone.njk' %} +{% extends 'layouts/barebone.njk' %} {% import 'macros.njk' as macros %} {% block _stylesheets %} diff --git a/views/macros.njk b/views/macros.njk deleted file mode 100644 index 789700a..0000000 --- a/views/macros.njk +++ /dev/null @@ -1,142 +0,0 @@ -{% macro message(type, content, raw=false, discreet=false) %} -
- - - {{ content|safe if raw else content }} - -
-{% endmacro %} - -{% macro messages(flash) %} - {% set flashed = flash() %} - {% set display = 0 %} - - {% for type, bag in flashed %} - {% if bag|length %} - {% set display = 1 %} - {% endif %} - {% endfor %} - - {% if display %} -
- {% for type, bag in flashed %} - {% for content in bag %} - {{ message(type, content) }} - {% endfor %} - {% endfor %} -
- {% endif %} -{% endmacro %} - -{% macro csrf(getCSRFToken) %} - -{% endmacro %} - -{% macro field(_locals, type, name, value, placeholder, hint, validation_attributes='', extraData='') %} - {% set validation = _locals.validation() %} - {% set validation = validation[name] if validation[name] or null %} - {% set previousFormData = _locals.previousFormData() %} - {% set value = previousFormData[name] or value or validation.value or '' %} - - {% if type == 'hidden' %} - {% if validation %} - {{ message('error', validation.message) }} - {% endif %} - - {% else %} -
- {% if type == 'duration' %} -
- {% for f in extraData %} -
- {% if previousFormData[name] %} - {% set v = value[f] %} - {% else %} - {% set v = (value % 60) if f == 's' else (((value - value % 60) / 60 % 60) if f == 'm' else ((value - value % 3600) / 3600 if f == 'h')) %} - {% endif %} - - -
- {% endfor %} -
- {% elseif type == 'select' %} - - - {% else %} - - {% endif %} - - - {{ fieldError(_locals, name) }} - {% if hint %} -
{{ hint }}
- {% endif %} -
- {% endif %} -{% endmacro %} - -{% macro fieldError(_locals, name) %} - {% set validation = _locals.validation() %} - {% set validation = validation[name] if validation[name] or null %} - {% if validation %} -
{{ validation.message }}
- {% endif %} -{% endmacro %} - -{% macro websocket(websocketUrl, listener, reconnectOnClose = 1, checkFunction = 0) %} - -{% endmacro %} - -{% macro paginate(pagination, routeName) %} - {% if pagination.hasPrevious() or pagination.hasNext() %} - - {% endif %} -{% endmacro %} \ No newline at end of file -- 2.47.0 From 5f4bcae38cef09beed27a7eeeda376ad044b6162 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 12 Jul 2020 12:13:26 +0200 Subject: [PATCH 04/71] Rename ExampleApp.test.ts to more useful App.test.ts --- test/{ExampleApp.test.ts => App.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{ExampleApp.test.ts => App.test.ts} (100%) diff --git a/test/ExampleApp.test.ts b/test/App.test.ts similarity index 100% rename from test/ExampleApp.test.ts rename to test/App.test.ts -- 2.47.0 From e7e5981af741c74c8c99e4cb5b4cecf3216d4a45 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 12 Jul 2020 12:15:22 +0200 Subject: [PATCH 05/71] Improve progress bar design --- assets/sass/layout.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index e91200e..a818460 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -652,6 +652,7 @@ button, .button { top: 0; width: var(--progress); height: 100%; + transition: width ease-out 150ms; background: $secondary; } -- 2.47.0 From c87eec28b23461cfb3d109ecc417b01af751954f Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 15 Jul 2020 11:04:45 +0200 Subject: [PATCH 06/71] Make icon only menu layout default --- assets/sass/layout.scss | 94 ++++++++++++++++++++++++++++++++++++++--- views/layouts/base.njk | 2 +- 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index a818460..9890bcc 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -63,21 +63,54 @@ header { li { list-style: none; - a, span { + a, button { + position: relative; + height: 64px; + margin: 0; + padding: 0 24px; + display: flex; flex-direction: row; align-items: center; - height: 64px; - padding: 0 24px; + + &:hover, &:active { + &:not(button) { + background-color: rgba(255, 255, 255, 0.07); + } + + .tip { + visibility: visible; + opacity: 1; + transition: opacity ease-out 100ms; + transition-delay: 150ms; + } + } .feather { --icon-size: 24px; - margin-right: 10px; } } - a:hover, a:active { - background-color: rgba(255, 255, 255, 0.07); + button { + margin: 8px; + padding: 24px; + height: 32px; + + .feather { + margin-right: 0; + } + + .tip { + text-transform: initial; + font-weight: initial; + } + } + + form { + display: flex; + justify-content: center; + align-items: center; + padding: 0; } } } @@ -129,6 +162,55 @@ header { &.open { transform: translateX(0%); } + + li { + a, button { + .tip { + display: block; + margin-left: 8px; + text-transform: inherit; + font-weight: inherit; + } + } + } + } + } + } + + @media (min-width: $menuLayoutSwitchTreshold) { + nav ul li { + a, button { + .tip { + visibility: hidden; + position: absolute; + display: block; + width: max-content; + height: 30px; + padding: 4px 8px; + line-height: 22px; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + + text-align: center; + font-size: 18px; + color: $defaultTextColor; + opacity: 0; + transition: opacity ease-out 100ms, visibility step-end 150ms; + transition-delay: 0ms; + background-color: #000; + border-radius: 5px; + } + } + + &:last-child { + a, button { + .tip { + left: unset; + right: 4px; + transform: none; + } + } } } } diff --git a/views/layouts/base.njk b/views/layouts/base.njk index cb76570..f350e8e 100644 --- a/views/layouts/base.njk +++ b/views/layouts/base.njk @@ -16,7 +16,7 @@ {% endblock %} -- 2.47.0 From ffe92674e5c3a51ded4ce6fe5c404af0c3a1a313 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 27 Jul 2020 16:02:33 +0200 Subject: [PATCH 07/71] Improve panels design --- assets/sass/layout.scss | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 9890bcc..12ae4d8 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -252,15 +252,23 @@ section > h2, .panel > h2 { align-items: center; position: relative; text-align: center; - margin-top: 16px; + margin-top: 4px; - &::before, &::after { + font-size: 24px; + line-height: 1; + + .feather { + margin: 0 16px 0 0; + opacity: 0.1; + } + + &::after { content: ""; flex: 1; - margin: 0 32px; + margin: 0 16px; height: 0; border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; + opacity: 0.1; } } @@ -353,7 +361,7 @@ form { & + .feather { position: absolute; - z-index: -1; + pointer-events: none; right: 8px; bottom: 8px; @@ -557,7 +565,8 @@ button, .button { } .panel { - margin: 16px 0; + position: relative; + margin: 16px 0 48px; padding: 8px; background-color: $panelBackground; border-radius: 5px; @@ -565,6 +574,14 @@ button, .button { p { margin: 16px 8px; } + + > .feather:first-child { + position: absolute; + --icon-size: 24px; + opacity: 0.1; + top: 8px; + left: 8px; + } } .sub-panel { -- 2.47.0 From 3b94b9818c945645c2e6e5e14407f2b3ac9bf07b Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 27 Jul 2020 17:29:52 +0200 Subject: [PATCH 08/71] Fix .inline-fields alignment --- assets/sass/layout.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 12ae4d8..964fa6f 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -348,6 +348,7 @@ form { display: block; padding: 32px 8px 8px 8px; width: 100%; + height: 60px; } select { @@ -426,7 +427,7 @@ form { .inline-fields { display: flex; flex-direction: row; - align-items: center; + align-items: start; margin: 16px auto; .form-field { -- 2.47.0 From 7d75df2f56d17bfcd0cd48b453b6b4a2a3fde2bf Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 30 Jul 2020 10:54:14 +0200 Subject: [PATCH 09/71] Improve tips styling and allow it in any button --- assets/sass/layout.scss | 82 +++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 964fa6f..a4091db 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -21,6 +21,46 @@ body { background-color: $backgroundColor; } +@mixin tip { + position: relative; + + .tip { + visibility: hidden; + position: absolute; + z-index: 10000; + pointer-events: none; + display: block; + width: max-content; + height: 30px; + padding: 4px 8px; + line-height: 22px; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + + text-align: center; + font-size: 18px; + color: $defaultTextColor; + opacity: 0; + transition: opacity ease-out 100ms, visibility step-end 150ms; + transition-delay: 0ms; + background-color: #000; + border-radius: 5px; + + text-transform: initial; + font-weight: initial; + } + + &:hover, &:active { + .tip { + visibility: visible; + opacity: 1; + transition: opacity ease-out 100ms; + transition-delay: 150ms; + } + } +} + header { display: flex; flex-direction: row; @@ -77,13 +117,6 @@ header { &:not(button) { background-color: rgba(255, 255, 255, 0.07); } - - .tip { - visibility: visible; - opacity: 1; - transition: opacity ease-out 100ms; - transition-delay: 150ms; - } } .feather { @@ -99,11 +132,6 @@ header { .feather { margin-right: 0; } - - .tip { - text-transform: initial; - font-weight: initial; - } } form { @@ -179,32 +207,12 @@ header { @media (min-width: $menuLayoutSwitchTreshold) { nav ul li { - a, button { - .tip { - visibility: hidden; - position: absolute; - display: block; - width: max-content; - height: 30px; - padding: 4px 8px; - line-height: 22px; - top: calc(100% + 8px); - left: 50%; - transform: translateX(-50%); - - text-align: center; - font-size: 18px; - color: $defaultTextColor; - opacity: 0; - transition: opacity ease-out 100ms, visibility step-end 150ms; - transition-delay: 0ms; - background-color: #000; - border-radius: 5px; - } + a, button, .button { + @include tip; } &:last-child { - a, button { + a, button, .button { .tip { left: unset; right: 4px; @@ -226,6 +234,10 @@ footer { main { flex: 1; padding: 8px; + + button, .button { + @include tip; + } } h1 { -- 2.47.0 From 95f61333f6fefe57f20b7fd6f7fdf7d3d916d25c Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 30 Jul 2020 10:54:29 +0200 Subject: [PATCH 10/71] Add basic breadcrumb style --- assets/sass/layout.scss | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index a4091db..1ae1210 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -564,6 +564,19 @@ button, .button { } } +.breadcrumb { + list-style: none; + display: flex; + flex-direction: row; + margin: 0; + padding: 8px; + + > *:not(:first-child)::before { + content: '›'; + padding: 0 8px; + } +} + // --- // --- Layout helpers // --- -- 2.47.0 From 3f3bec85fc806c992ab0d952af496415d49f5209 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 30 Jul 2020 11:14:02 +0200 Subject: [PATCH 11/71] layout.scss: fix select chevron position when field has error --- assets/sass/layout.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 1ae1210..178bd47 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -376,7 +376,7 @@ form { position: absolute; pointer-events: none; right: 8px; - bottom: 8px; + top: 30px; transition: transform 150ms ease-out; } -- 2.47.0 From b136bdc64ebce998018e73618ca314d5ceee525d Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 30 Aug 2020 09:32:22 +0200 Subject: [PATCH 12/71] Fix main header css selector and set default icon size to 16px --- assets/sass/layout.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 178bd47..cd3f0d8 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -61,7 +61,7 @@ body { } } -header { +body > header { display: flex; flex-direction: row; justify-content: space-between; @@ -623,7 +623,7 @@ button, .button { // --- .feather { flex-shrink: 0; - --icon-size: 24px; + --icon-size: 16px; width: var(--icon-size); height: var(--icon-size); stroke: currentColor; -- 2.47.0 From 4316daf241b31b31a873df8cf18fcfad8f797bad Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 30 Aug 2020 21:02:37 +0200 Subject: [PATCH 13/71] header: add menu dropdowns and auth-user special menu item --- assets/sass/layout.scss | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index cd3f0d8..a11e09a 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -62,6 +62,7 @@ body { } body > header { + z-index: 0; display: flex; flex-direction: row; justify-content: space-between; @@ -101,6 +102,7 @@ body > header { font-size: 20px; li { + position: relative; list-style: none; a, button { @@ -140,6 +142,35 @@ body > header { align-items: center; padding: 0; } + + &.auth-user { + img { + width: 48px; + height: 48px; + border-radius: 3px; + margin-right: 8px; + } + } + + .dropdown { + position: absolute; + z-index: -1; + top: 100%; + right: 0; + display: none; + + white-space: nowrap; + background: $headerBackground; + border-radius: 0 0 3px 3px; + + a { + padding: 0 8px; + } + } + + &:hover .dropdown { + display: block; + } } } @@ -177,7 +208,7 @@ body > header { } } - ul { + > ul { flex-direction: column; position: absolute; z-index: 10; @@ -200,6 +231,12 @@ body > header { font-weight: inherit; } } + + .dropdown { + position: initial; + display: block; + padding-left: 32px; + } } } } -- 2.47.0 From 7143e7a84323d0f714f9af76e20b034bcc0930e1 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 30 Aug 2020 21:02:57 +0200 Subject: [PATCH 14/71] Add textarea styling --- assets/sass/layout.scss | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index a11e09a..c228448 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -378,7 +378,7 @@ form { } } - input, select, .input-group { + input, select, textarea, .input-group { border: 0; color: $defaultTextColor; background: lighten($panelBackground, 4%); @@ -393,7 +393,7 @@ form { } } - input, select, .form-display { + input, select, textarea, .form-display { display: block; padding: 32px 8px 8px 8px; width: 100%; @@ -424,6 +424,11 @@ form { } } + textarea { + resize: vertical; + min-height: 100px; + } + input[type=color] { height: calc(32px + 8px + 32px); } -- 2.47.0 From 61c8f32c47a49a6352edf0c919fd769b982617c7 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 30 Aug 2020 21:04:59 +0200 Subject: [PATCH 15/71] Fix header z-index --- assets/sass/layout.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index c228448..8d29983 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -62,7 +62,7 @@ body { } body > header { - z-index: 0; + z-index: 50; display: flex; flex-direction: row; justify-content: space-between; -- 2.47.0 From f45daa4a9f5dbc341d18ff3faa1a2ae86d7fb888 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 2 Sep 2020 20:41:58 +0200 Subject: [PATCH 16/71] Improve links hover feedback --- assets/sass/layout.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 8d29983..f46c5e7 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -334,7 +334,7 @@ a { text-decoration: none; &:hover { - color: lighten($secondary, 5%); + color: lighten($secondary, 10%); } .feather.feather-external-link { -- 2.47.0 From 54faa5c873c52d62a304dcada9e31ff2ee359f72 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 3 Sep 2020 08:28:57 +0200 Subject: [PATCH 17/71] Use config package's multi-directory built-in support This avoids full object overriding when you just want to set specific fields --- config/default.ts | 4 ++-- config/production.ts | 4 ++-- config/test.ts | 4 ++-- package.json | 2 +- src/main.ts | 6 ++++++ tsconfig.json | 3 +-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/config/default.ts b/config/default.ts index 8f2cf14..aed8601 100644 --- a/config/default.ts +++ b/config/default.ts @@ -1,4 +1,4 @@ -export default Object.assign(require("wms-core/config/default").default, { +export default { app: { name: 'Example App', contact_email: 'contact@example.net' @@ -42,4 +42,4 @@ export default Object.assign(require("wms-core/config/default").default, { cache: false }, approval_mode: false, -}); \ No newline at end of file +} diff --git a/config/production.ts b/config/production.ts index d3ba121..4143867 100644 --- a/config/production.ts +++ b/config/production.ts @@ -1,4 +1,4 @@ -export default Object.assign(require("wms-core/config/production").default, { +export default { log_level: "DEBUG", db_log_level: "ERROR", public_url: "https://watch-my.stream", @@ -12,4 +12,4 @@ export default Object.assign(require("wms-core/config/production").default, { secure: true, allow_invalid_tls: false } -}); \ No newline at end of file +} diff --git a/config/test.ts b/config/test.ts index 149ace2..61f7c4a 100644 --- a/config/test.ts +++ b/config/test.ts @@ -1,4 +1,4 @@ -export default Object.assign(require("wms-core/config/test").default, { +export default { mysql: { host: "localhost", user: "root", @@ -6,4 +6,4 @@ export default Object.assign(require("wms-core/config/test").default, { database: "wms2_test", create_database_automatically: true } -}); \ No newline at end of file +} diff --git a/package.json b/package.json index beda726..312a920 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "test": "jest --verbose --runInBand", "dist-webpack": "webpack --mode production", - "dist": "tsc && npm run dist-webpack", + "dist": "(test ! -d dist || rm -r dist) && tsc && npm run dist-webpack && mkdir -p dist/core-config && cp -r node_modules/wms-core/config/* dist/core-config/", "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", "start": "yarn dist && node dist/main.js" }, diff --git a/src/main.ts b/src/main.ts index 1706351..17025eb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,9 @@ +// Load config from specified path or default + wms-core/config (default defaults) +process.env['NODE_CONFIG_DIR'] = + (process.env['NODE_CONFIG_DIR'] || './config/') + + require('path').delimiter + + __dirname + '/core-config/'; + import Logger from "wms-core/Logger"; import App from "./App"; import config from "config"; diff --git a/tsconfig.json b/tsconfig.json index a6bf63a..803227e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,6 @@ ] }, "include": [ - "src/**/*", - "node_modules/wms-core" + "src/**/*" ] } \ No newline at end of file -- 2.47.0 From 52929e5be01141894b6431141f903943691e0105 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 3 Sep 2020 08:29:37 +0200 Subject: [PATCH 18/71] package.json: fix repository url --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 312a920..da81981 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "example-app", "version": "0.1.0", "description": "Example App based on wms-core", - "repository": "git@gitlab.com:ArisuOngaku/wms-boilerplate.git", + "repository": "https://gitlab.com/ArisuOngaku/wms-boilerplate", "author": "Alice Gaudon ", "private": true, "main": "dist/main.js", -- 2.47.0 From bce48f81b66847fc14814dfc23fa102eeedd4f13 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 3 Sep 2020 08:30:15 +0200 Subject: [PATCH 19/71] package.json: upgrade dependencies and move wms-core to regular deps --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index da81981..9135767 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,13 @@ "@types/formidable": "^1.0.31", "@types/jest": "^26.0.4", "@types/mysql": "^2.15.15", - "@types/node": "^13.13.2", + "@types/node": "^14.6.3", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", "@types/ws": "^7.2.6", "babel-loader": "^8.1.0", "concurrently": "^5.1.0", - "css-loader": "^3.5.2", + "css-loader": "^4.2.2", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", "imagemin": "^7.0.1", @@ -38,19 +38,19 @@ "imagemin-svgo": "^8.0.0", "img-loader": "^3.0.1", "jest": "^26.1.0", - "mini-css-extract-plugin": "^0.9.0", + "mini-css-extract-plugin": "^0.11.0", "node-sass": "^4.14.0", "nodemon": "^2.0.3", - "sass-loader": "^9.0.2", + "sass-loader": "^10.0.1", "ts-jest": "^26.1.1", - "typescript": "^3.8.3", + "typescript": "^4.0.2", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.43.0", - "webpack-cli": "^3.3.11", - "wms-core": "^0" + "webpack-cli": "^3.3.11" }, "dependencies": { "config": "^3.3.1", - "express": "^4.17.1" + "express": "^4.17.1", + "wms-core": "^0.21.7" } } -- 2.47.0 From 5157b12b77b5ffe0cea7b8f2caa26793fafe2195 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 3 Sep 2020 11:46:00 +0200 Subject: [PATCH 20/71] tsconfig.json: restore wms-core/types include and add test --- src/controllers/HomeController.ts | 8 ++++++++ tsconfig.json | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index 847c759..ad035b4 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -5,6 +5,7 @@ export default class HomeController extends Controller { routes(): void { this.get('/', this.getHome, 'home'); this.get('/about', this.getAbout, 'about'); + this.get('/back', this.goBack, 'about'); } private async getHome(req: Request, res: Response) { @@ -14,4 +15,11 @@ export default class HomeController extends Controller { private async getAbout(req: Request, res: Response) { res.render('about'); } + + /** + * This is to test and assert that wms-core extended types are available + */ + private async goBack(req: Request, res: Response) { + res.redirectBack(); + } } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 803227e..18f1bee 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ ] }, "include": [ - "src/**/*" + "src/**/*", + "node_modules/wms-core/types" ] } \ No newline at end of file -- 2.47.0 From 3b124a993bfcb9e7799bef59c50055bd99f02482 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 3 Sep 2020 12:58:07 +0200 Subject: [PATCH 21/71] main.ts: fix config path order --- package.json | 2 +- src/main.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9135767..f108311 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "test": "jest --verbose --runInBand", "dist-webpack": "webpack --mode production", - "dist": "(test ! -d dist || rm -r dist) && tsc && npm run dist-webpack && mkdir -p dist/core-config && cp -r node_modules/wms-core/config/* dist/core-config/", + "dist": "(test ! -d dist || rm -r dist) && tsc && npm run dist-webpack", "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", "start": "yarn dist && node dist/main.js" }, diff --git a/src/main.ts b/src/main.ts index 17025eb..b3f32d5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,14 +1,16 @@ // Load config from specified path or default + wms-core/config (default defaults) process.env['NODE_CONFIG_DIR'] = - (process.env['NODE_CONFIG_DIR'] || './config/') + __dirname + '/../node_modules/wms-core/config/' + require('path').delimiter - + __dirname + '/core-config/'; + + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); import Logger from "wms-core/Logger"; import App from "./App"; import config from "config"; (async () => { + Logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); + const app = new App(config.get('port')); await app.start(); })().catch(err => { -- 2.47.0 From 3598f6818368f72566349931483285bbbc4089a7 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 5 Sep 2020 17:36:08 +0200 Subject: [PATCH 22/71] Add font-awesome --- assets/js/app.js | 1 + assets/js/font-awesome.js | 4 ++++ package.json | 1 + 3 files changed, 6 insertions(+) create mode 100644 assets/js/font-awesome.js diff --git a/assets/js/app.js b/assets/js/app.js index 10fa287..039ac2e 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -3,6 +3,7 @@ import './message_icons'; import './forms'; import './copyable_text'; import './main_menu'; +import './font-awesome'; import '../sass/app.scss'; diff --git a/assets/js/font-awesome.js b/assets/js/font-awesome.js new file mode 100644 index 0000000..5ce65ff --- /dev/null +++ b/assets/js/font-awesome.js @@ -0,0 +1,4 @@ +import '../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss'; +import '../../node_modules/@fortawesome/fontawesome-free/scss/regular.scss'; +import '../../node_modules/@fortawesome/fontawesome-free/scss/solid.scss'; +import '../../node_modules/@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/package.json b/package.json index f108311..500a667 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", + "@fortawesome/fontawesome-free": "^5.14.0", "@types/config": "^0.0.36", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", -- 2.47.0 From c68d5819b10cb18ebd029c364857e34cd1dc8b4c Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 5 Sep 2020 17:34:26 +0200 Subject: [PATCH 23/71] Allow links that are target=_blank to opt-out from the icon --- assets/js/external_links.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/js/external_links.js b/assets/js/external_links.js index 7108c4e..d72b537 100644 --- a/assets/js/external_links.js +++ b/assets/js/external_links.js @@ -2,7 +2,9 @@ import feather from "feather-icons"; document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('a[target="_blank"]').forEach(el => { - el.innerHTML += ``; + if (!el.classList.contains('no-icon')) { + el.innerHTML += ``; + } }); feather.replace(); -- 2.47.0 From f70112e95654789495b5b8ee50d149c3c22661b3 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 10 Sep 2020 15:19:31 +0200 Subject: [PATCH 24/71] Add optional input field illustration feather icon --- assets/sass/_vars.scss | 1 + assets/sass/layout.scss | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/assets/sass/_vars.scss b/assets/sass/_vars.scss index 21d06e7..f0eb1fc 100644 --- a/assets/sass/_vars.scss +++ b/assets/sass/_vars.scss @@ -9,6 +9,7 @@ $defaultTextColor: #ffffff; $headerBackground: darken($primary, 7.5%); $footerBackground: lighten($headerBackground, 1%); $panelBackground: lighten($headerBackground, 1%); +$inputBackground: darken($panelBackground, 4%); $info: #4499ff; $infoText: darken($info, 42%); diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index f46c5e7..9ab7d43 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -353,6 +353,20 @@ form { display: flex; flex-direction: column; margin: 16px auto; + background: $inputBackground; + border-radius: 5px; + overflow: hidden; + + > .feather.icon { + position: absolute; + top: 50%; + right: 8px; + transform: translateY(-50%); + z-index: 0; + + --icon-size: 24px; + opacity: 0.75; + } label { position: absolute; @@ -379,10 +393,10 @@ form { } input, select, textarea, .input-group { + z-index: 1; border: 0; color: $defaultTextColor; - background: lighten($panelBackground, 4%); - border-radius: 5px; + background: transparent; font-size: 16px; &:focus, &:not([value=""]), &[type="file"] { @@ -435,17 +449,22 @@ form { &.inline { flex-direction: row; + align-items: center; input[type=checkbox] { - text-align: left; width: min-content; height: min-content; + margin: 8px; + text-align: left; & ~ label { position: static; + flex-grow: 1; display: inline; - padding-left: 8px; + padding: 8px; + font-size: 16px; + text-align: left; } } } -- 2.47.0 From 16895e52e8c3b6489303ea71d44eb5ac71c84a4b Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 10 Sep 2020 16:17:06 +0200 Subject: [PATCH 25/71] Fix input hint and errors display --- assets/sass/layout.scss | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 9ab7d43..808aafb 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -349,15 +349,17 @@ form { text-align: center; .form-field { - position: relative; display: flex; flex-direction: column; margin: 16px auto; - background: $inputBackground; - border-radius: 5px; - overflow: hidden; - > .feather.icon { + .control { + position: relative; + background: $inputBackground; + border-radius: 5px; + } + + .feather.icon { position: absolute; top: 50%; right: 8px; @@ -447,7 +449,8 @@ form { height: calc(32px + 8px + 32px); } - &.inline { + &.inline .control { + display: flex; flex-direction: row; align-items: center; -- 2.47.0 From ab8e756034e072e0090c54535aa62d45cf497753 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 10 Sep 2020 21:02:17 +0200 Subject: [PATCH 26/71] Make sure textareas have the right font --- assets/sass/layout.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 808aafb..6168bf5 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -443,6 +443,7 @@ form { textarea { resize: vertical; min-height: 100px; + font-family: inherit; } input[type=color] { -- 2.47.0 From a92b657e4aeba63c50190a5554934e62c2c1d120 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 15 Sep 2020 16:30:25 +0200 Subject: [PATCH 27/71] forms: make value property update a function and update textareas too --- assets/js/forms.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/assets/js/forms.js b/assets/js/forms.js index dd3f184..a65d2f9 100644 --- a/assets/js/forms.js +++ b/assets/js/forms.js @@ -1,13 +1,20 @@ // For labels to update their state (css selectors based on the value attribute) document.addEventListener('DOMContentLoaded', () => { - document.querySelectorAll('input').forEach(el => { - if (el.type !== 'checkbox') { - el.setAttribute('value', el.value); - el.addEventListener('change', () => { - el.setAttribute('value', el.value); - }); - } - }); + window.updateInputs = () => { + document.querySelectorAll('input, textarea').forEach(el => { + if (!el.inputSetup) { + el.inputSetup = true; + if (el.type !== 'checkbox') { + el.setAttribute('value', el.value); + el.addEventListener('change', () => { + el.setAttribute('value', el.value); + }); + } + } + }); + }; + + updateInputs(); }); window.applyFormMessages = function (formElement, messages) { -- 2.47.0 From 7664d368486ec0df356a9b6ce2c40e7aca87d70e Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 15 Sep 2020 16:34:21 +0200 Subject: [PATCH 28/71] Force .feather icon vertical alignment --- assets/sass/layout.scss | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 6168bf5..fbe8b5b 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -687,10 +687,16 @@ button, .button { // --- Feather // --- .feather { + display: inline-flex; + justify-content: center; + align-items: center; + flex-shrink: 0; - --icon-size: 16px; width: var(--icon-size); height: var(--icon-size); + + --icon-size: 16px; + font-size: var(--icon-size); stroke: currentColor; stroke-width: 2; stroke-linecap: square; -- 2.47.0 From a3a19da038d6a91f2ad44b85f5cfbd3e054c945c Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 15 Sep 2020 16:32:02 +0200 Subject: [PATCH 29/71] Fix inline controls styling --- assets/sass/layout.scss | 46 +++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index fbe8b5b..dd587d4 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -450,32 +450,38 @@ form { height: calc(32px + 8px + 32px); } - &.inline .control { + &.inline { display: flex; flex-direction: row; - align-items: center; - input[type=checkbox] { - width: min-content; - height: min-content; - margin: 8px; - text-align: left; + .control { + display: flex; + flex-direction: row; + align-items: center; + flex-grow: 1; - & ~ label { - position: static; - flex-grow: 1; - display: inline; - padding: 8px; - - font-size: 16px; + input[type=checkbox] { + width: min-content; + height: min-content; + margin: 8px; text-align: left; + + & ~ label { + position: static; + flex-grow: 1; + display: inline; + padding: 8px; + + font-size: 16px; + text-align: left; + } } } } .input-group { display: flex; - flex-shrink: 1; + flex-grow: 1; flex-direction: row; div { @@ -484,19 +490,9 @@ form { input { width: 100%; - margin-top: 24px; - padding-top: 8px; border: 0; background: transparent; } - - > input + * { - position: absolute; - top: 32px; - right: 28px; - user-select: none; - text-align: right; - } } } } -- 2.47.0 From 5f2215f4919ae52a858e7aff260c5780c76e3223 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 16 Sep 2020 12:38:33 +0200 Subject: [PATCH 30/71] Prevent tooltips and dropdowns from overflowing on y axis --- assets/js/app.js | 1 + assets/js/tooltips-and-dropdowns.js | 30 +++++++++++++++++++++++++++++ assets/sass/layout.scss | 6 +++++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 assets/js/tooltips-and-dropdowns.js diff --git a/assets/js/app.js b/assets/js/app.js index 039ac2e..48eba69 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -2,6 +2,7 @@ import './external_links'; import './message_icons'; import './forms'; import './copyable_text'; +import './tooltips-and-dropdowns'; import './main_menu'; import './font-awesome'; diff --git a/assets/js/tooltips-and-dropdowns.js b/assets/js/tooltips-and-dropdowns.js new file mode 100644 index 0000000..3fa6e5b --- /dev/null +++ b/assets/js/tooltips-and-dropdowns.js @@ -0,0 +1,30 @@ +document.addEventListener('DOMContentLoaded', () => { + window.updateTooltips = () => { + console.debug('Update tooltips'); + const elements = document.querySelectorAll('.tip, .dropdown'); + + // Calculate max potential displacement + let max = 0; + elements.forEach(el => { + const box = el.getBoundingClientRect(); + if (max < box.height) max = box.height; + }); + + // Prevent displacement + elements.forEach(el => { + if (!el.tooltipSetup) { + el.tooltipSetup = true; + const box = el.getBoundingClientRect(); + if (box.bottom >= document.body.clientHeight - (max + 32)) { + el.classList.add('top'); + } + } + }); + }; + window.addEventListener('popstate', () => { + updateTooltips(); + }); + window.requestAnimationFrame(() => { + updateTooltips(); + }); +}); \ No newline at end of file diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index dd587d4..e05bbcb 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -49,6 +49,11 @@ body { text-transform: initial; font-weight: initial; + + &.top { + top: auto; + bottom: calc(100% + 8px); + } } &:hover, &:active { @@ -157,7 +162,6 @@ body > header { z-index: -1; top: 100%; right: 0; - display: none; white-space: nowrap; background: $headerBackground; -- 2.47.0 From dcdc8dd7040641e62844b12955aa32224ed1c4ce Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 23 Sep 2020 13:30:48 +0200 Subject: [PATCH 31/71] Convert frontend js to typescript --- assets/config.json | 2 +- assets/js/copyable_text.js | 12 ------ assets/js/main_menu.js | 17 -------- assets/js/tooltips-and-dropdowns.js | 30 -------------- assets/ts/PersistentWebSocket.ts | 39 +++++++++++++++++++ assets/{js/app.js => ts/app.ts} | 3 +- assets/ts/copyable_text.ts | 15 +++++++ .../external_links.ts} | 2 +- .../font-awesome.js => ts/font-awesome.ts} | 0 assets/{js/forms.js => ts/forms.ts} | 36 +++++++++-------- assets/ts/main_menu.ts | 21 ++++++++++ .../message_icons.js => ts/message_icons.ts} | 15 ++++--- assets/ts/tooltips-and-dropdowns.ts | 31 +++++++++++++++ package.json | 2 + tsconfig.frontend.json | 18 +++++++++ tsconfig.json | 3 +- webpack.config.js | 13 +++++++ 17 files changed, 174 insertions(+), 85 deletions(-) delete mode 100644 assets/js/copyable_text.js delete mode 100644 assets/js/main_menu.js delete mode 100644 assets/js/tooltips-and-dropdowns.js create mode 100644 assets/ts/PersistentWebSocket.ts rename assets/{js/app.js => ts/app.ts} (87%) create mode 100644 assets/ts/copyable_text.ts rename assets/{js/external_links.js => ts/external_links.ts} (98%) rename assets/{js/font-awesome.js => ts/font-awesome.ts} (100%) rename assets/{js/forms.js => ts/forms.ts} (52%) create mode 100644 assets/ts/main_menu.ts rename assets/{js/message_icons.js => ts/message_icons.ts} (60%) create mode 100644 assets/ts/tooltips-and-dropdowns.ts create mode 100644 tsconfig.frontend.json diff --git a/assets/config.json b/assets/config.json index 5c18915..6bcf54c 100644 --- a/assets/config.json +++ b/assets/config.json @@ -1,6 +1,6 @@ { "bundles": { - "app": "js/app.js", + "app": "ts/app.ts", "layout": "sass/layout.scss", "error": "sass/error.scss", "logo": "img/logo.svg", diff --git a/assets/js/copyable_text.js b/assets/js/copyable_text.js deleted file mode 100644 index 6501a1a..0000000 --- a/assets/js/copyable_text.js +++ /dev/null @@ -1,12 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - document.querySelectorAll('.copyable-text').forEach(el => { - const contentEl = el.querySelector('.content'); - contentEl.addEventListener('click', () => { - window.getSelection().selectAllChildren(contentEl); - }); - el.querySelector('.copy-button').addEventListener('click', () => { - window.getSelection().selectAllChildren(contentEl); - document.execCommand('copy'); - }); - }); -}); \ No newline at end of file diff --git a/assets/js/main_menu.js b/assets/js/main_menu.js deleted file mode 100644 index f2a89da..0000000 --- a/assets/js/main_menu.js +++ /dev/null @@ -1,17 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const menuButton = document.getElementById('menu-button'); - const mainMenu = document.getElementById('main-menu'); - - menuButton.addEventListener('click', (e) => { - e.stopPropagation(); - mainMenu.classList.toggle('open'); - }); - - mainMenu.addEventListener('click', (e) => { - e.stopPropagation(); - }); - - document.addEventListener('click', () => { - mainMenu.classList.remove('open'); - }); -}); \ No newline at end of file diff --git a/assets/js/tooltips-and-dropdowns.js b/assets/js/tooltips-and-dropdowns.js deleted file mode 100644 index 3fa6e5b..0000000 --- a/assets/js/tooltips-and-dropdowns.js +++ /dev/null @@ -1,30 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - window.updateTooltips = () => { - console.debug('Update tooltips'); - const elements = document.querySelectorAll('.tip, .dropdown'); - - // Calculate max potential displacement - let max = 0; - elements.forEach(el => { - const box = el.getBoundingClientRect(); - if (max < box.height) max = box.height; - }); - - // Prevent displacement - elements.forEach(el => { - if (!el.tooltipSetup) { - el.tooltipSetup = true; - const box = el.getBoundingClientRect(); - if (box.bottom >= document.body.clientHeight - (max + 32)) { - el.classList.add('top'); - } - } - }); - }; - window.addEventListener('popstate', () => { - updateTooltips(); - }); - window.requestAnimationFrame(() => { - updateTooltips(); - }); -}); \ No newline at end of file diff --git a/assets/ts/PersistentWebSocket.ts b/assets/ts/PersistentWebSocket.ts new file mode 100644 index 0000000..b53f948 --- /dev/null +++ b/assets/ts/PersistentWebSocket.ts @@ -0,0 +1,39 @@ +export default class PersistentWebsocket { + private webSocket?: WebSocket; + + public constructor( + protected readonly url: string, + private readonly handler: MessageHandler, + protected readonly reconnectOnClose: boolean = true, + ) { + } + + public run() { + this.webSocket = new WebSocket(this.url); + this.webSocket.addEventListener('open', (e) => { + console.debug('Websocket connected'); + }); + this.webSocket.addEventListener('message', (e) => { + this.handler(this.webSocket!, e); + }); + this.webSocket.addEventListener('error', (e) => { + console.error('Websocket error', e); + }); + this.webSocket.addEventListener('close', (e) => { + this.webSocket = undefined; + console.debug('Websocket closed', e.code, e.reason); + + if (this.reconnectOnClose) { + setTimeout(() => this.run(), 1000); + } + }); + } + + public send(data: string) { + if (!this.webSocket) throw new Error('WebSocket not connected'); + + this.webSocket.send(data); + } +} + +export type MessageHandler = (webSocket: WebSocket, e: MessageEvent) => void; diff --git a/assets/js/app.js b/assets/ts/app.ts similarity index 87% rename from assets/js/app.js rename to assets/ts/app.ts index 48eba69..8594552 100644 --- a/assets/js/app.js +++ b/assets/ts/app.ts @@ -6,6 +6,5 @@ import './tooltips-and-dropdowns'; import './main_menu'; import './font-awesome'; +// css import '../sass/app.scss'; - -console.log('Hello world!'); \ No newline at end of file diff --git a/assets/ts/copyable_text.ts b/assets/ts/copyable_text.ts new file mode 100644 index 0000000..60d58ab --- /dev/null +++ b/assets/ts/copyable_text.ts @@ -0,0 +1,15 @@ +document.addEventListener('DOMContentLoaded', () => { + document.querySelectorAll('.copyable-text').forEach(el => { + const contentEl = el.querySelector('.content'); + const selection = window.getSelection(); + if (contentEl && selection) { + contentEl.addEventListener('click', () => { + selection.selectAllChildren(contentEl); + }); + el.querySelector('.copy-button')?.addEventListener('click', () => { + selection.selectAllChildren(contentEl); + document.execCommand('copy'); + }); + } + }); +}); diff --git a/assets/js/external_links.js b/assets/ts/external_links.ts similarity index 98% rename from assets/js/external_links.js rename to assets/ts/external_links.ts index d72b537..bc9ba26 100644 --- a/assets/js/external_links.js +++ b/assets/ts/external_links.ts @@ -8,4 +8,4 @@ document.addEventListener('DOMContentLoaded', () => { }); feather.replace(); -}); \ No newline at end of file +}); diff --git a/assets/js/font-awesome.js b/assets/ts/font-awesome.ts similarity index 100% rename from assets/js/font-awesome.js rename to assets/ts/font-awesome.ts diff --git a/assets/js/forms.js b/assets/ts/forms.ts similarity index 52% rename from assets/js/forms.js rename to assets/ts/forms.ts index a65d2f9..46cd108 100644 --- a/assets/js/forms.js +++ b/assets/ts/forms.ts @@ -1,25 +1,29 @@ -// For labels to update their state (css selectors based on the value attribute) -document.addEventListener('DOMContentLoaded', () => { - window.updateInputs = () => { - document.querySelectorAll('input, textarea').forEach(el => { - if (!el.inputSetup) { - el.inputSetup = true; - if (el.type !== 'checkbox') { +/* + * For labels to update their state (css selectors based on the value attribute) + */ +export function updateInputs() { + document.querySelectorAll('input, textarea').forEach(el => { + if (!el.dataset.inputSetup) { + el.dataset.inputSetup = 'true'; + if (el.type !== 'checkbox') { + el.setAttribute('value', el.value); + el.addEventListener('change', () => { el.setAttribute('value', el.value); - el.addEventListener('change', () => { - el.setAttribute('value', el.value); - }); - } + }); } - }); - }; + } + }); +} +document.addEventListener('DOMContentLoaded', () => { updateInputs(); }); -window.applyFormMessages = function (formElement, messages) { +export function applyFormMessages(formElement: HTMLFormElement, messages: { [p: string]: any }) { for (const fieldName of Object.keys(messages)) { const field = formElement.querySelector('#field-' + fieldName); + if (!field) continue; + let parent = field.parentElement; while (parent && !parent.classList.contains('form-field')) parent = parent.parentElement; @@ -28,9 +32,9 @@ window.applyFormMessages = function (formElement, messages) { if (!err) { err = document.createElement('div'); err.classList.add('error'); - parent.insertBefore(err, parent.querySelector('.hint') || parent); + parent?.insertBefore(err, parent.querySelector('.hint') || parent); } err.innerHTML = ` ${messages[fieldName].message}`; } } -} \ No newline at end of file +} diff --git a/assets/ts/main_menu.ts b/assets/ts/main_menu.ts new file mode 100644 index 0000000..4e19e40 --- /dev/null +++ b/assets/ts/main_menu.ts @@ -0,0 +1,21 @@ +document.addEventListener('DOMContentLoaded', () => { + const menuButton = document.getElementById('menu-button'); + const mainMenu = document.getElementById('main-menu'); + + if (menuButton) { + menuButton.addEventListener('click', (e) => { + e.stopPropagation(); + mainMenu?.classList.toggle('open'); + }); + } + + if (mainMenu) { + mainMenu.addEventListener('click', (e) => { + e.stopPropagation(); + }); + + document.addEventListener('click', () => { + mainMenu.classList.remove('open'); + }); + } +}); diff --git a/assets/js/message_icons.js b/assets/ts/message_icons.ts similarity index 60% rename from assets/js/message_icons.js rename to assets/ts/message_icons.ts index b625f55..b737de3 100644 --- a/assets/js/message_icons.js +++ b/assets/ts/message_icons.ts @@ -1,21 +1,26 @@ import feather from "feather-icons"; document.addEventListener('DOMContentLoaded', () => { - const messageTypeToIcon = { + const messageTypeToIcon: { [p: string]: string } = { info: 'info', success: 'check', warning: 'alert-triangle', error: 'x-circle', question: 'help-circle', }; - document.querySelectorAll('.message').forEach(el => { - const type = el.dataset['type']; + + document.querySelectorAll('.message').forEach(el => { const icon = el.querySelector('.icon'); + const type = el.dataset['type']; + if (!icon || !type) return; + if (!messageTypeToIcon[type]) throw new Error(`No icon for type ${type}`); + const svgContainer = document.createElement('div'); svgContainer.innerHTML = feather.icons[messageTypeToIcon[type]].toSvg(); - el.insertBefore(svgContainer.firstChild, icon); + + if (svgContainer.firstChild) el.insertBefore(svgContainer.firstChild, icon); icon.remove(); }); feather.replace(); -}); \ No newline at end of file +}); diff --git a/assets/ts/tooltips-and-dropdowns.ts b/assets/ts/tooltips-and-dropdowns.ts new file mode 100644 index 0000000..e66c732 --- /dev/null +++ b/assets/ts/tooltips-and-dropdowns.ts @@ -0,0 +1,31 @@ +export function updateTooltips() { + console.debug('Updating tooltips'); + const elements = document.querySelectorAll('.tip, .dropdown'); + + // Calculate max potential displacement + let max = 0; + elements.forEach(el => { + const box = el.getBoundingClientRect(); + if (max < box.height) max = box.height; + }); + + // Prevent displacement + elements.forEach(el => { + if (!el.dataset.tooltipSetup) { + el.dataset.tooltipSetup = 'true'; + const box = el.getBoundingClientRect(); + if (box.bottom >= document.body.clientHeight - (max + 32)) { + el.classList.add('top'); + } + } + }); +} + +document.addEventListener('DOMContentLoaded', () => { + window.addEventListener('popstate', () => { + updateTooltips(); + }); + window.requestAnimationFrame(() => { + updateTooltips(); + }); +}); diff --git a/package.json b/package.json index 500a667..3ffa1b4 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@types/config": "^0.0.36", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", + "@types/feather-icons": "^4.7.0", "@types/formidable": "^1.0.31", "@types/jest": "^26.0.4", "@types/mysql": "^2.15.15", @@ -44,6 +45,7 @@ "nodemon": "^2.0.3", "sass-loader": "^10.0.1", "ts-jest": "^26.1.1", + "ts-loader": "^8.0.4", "typescript": "^4.0.2", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.43.0", diff --git a/tsconfig.frontend.json b/tsconfig.frontend.json new file mode 100644 index 0000000..4b5a3f5 --- /dev/null +++ b/tsconfig.frontend.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "public/js", + "target": "ES6", + "strict": true, + "lib": [ + "es2020", + "DOM" + ], + "typeRoots": [ + "./node_modules/@types" + ] + }, + "include": [ + "assets/ts/**/*" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 18f1bee..19d375e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "target": "ES6", "strict": true, "lib": [ - "es2020" + "es2020", + "DOM" ], "typeRoots": [ "./node_modules/@types" diff --git a/webpack.config.js b/webpack.config.js index 478541b..655dee0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -48,6 +48,16 @@ const config = { test: /\.(woff2?|eot|ttf|otf)$/i, use: 'file-loader?name=../fonts/[name].[ext]', }, + { + test: /\.tsx?$/i, + use: { + loader: 'ts-loader', + options: { + configFile: 'tsconfig.frontend.json', + } + }, + exclude: '/node_modules/' + }, { test: /\.(png|jpe?g|gif|svg)$/i, use: [ @@ -68,6 +78,9 @@ const config = { } ], }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, plugins: [ new MiniCssExtractPlugin({ filename: '../css/[name].css', -- 2.47.0 From d91110fb67b18416765229ee6109bafb98df8b85 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 1 Oct 2020 14:38:16 +0200 Subject: [PATCH 32/71] Drop UglifyJS webpack plugin in favor of Terser --- package.json | 1 + webpack.config.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3ffa1b4..4c917b4 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "node-sass": "^4.14.0", "nodemon": "^2.0.3", "sass-loader": "^10.0.1", + "terser-webpack-plugin": "^4.2.2", "ts-jest": "^26.1.1", "ts-loader": "^8.0.4", "typescript": "^4.0.2", diff --git a/webpack.config.js b/webpack.config.js index 655dee0..598acfd 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,6 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); const dev = process.env.NODE_ENV === 'development'; @@ -90,8 +90,9 @@ const config = { if (!dev) { config.optimization = { + minimize: true, minimizer: [ - new UglifyJSPlugin(), + new TerserPlugin(), ] }; } -- 2.47.0 From a8bad1c8c1448ca255bb11adc17fe08a31846ba1 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 5 Oct 2020 13:38:03 +0200 Subject: [PATCH 33/71] Upgrade wms-core and add eslint --- .eslintrc.json | 114 ++++++++++++++++++++++++++++ assets/ts/PersistentWebSocket.ts | 10 +-- assets/ts/forms.ts | 23 +++--- assets/ts/tooltips-and-dropdowns.ts | 2 +- package.json | 12 ++- src/App.ts | 21 ++--- src/controllers/HomeController.ts | 10 +-- src/main.ts | 8 +- test/App.test.ts | 2 +- tsconfig.json | 5 +- tsconfig.test.json | 14 ++++ 11 files changed, 181 insertions(+), 40 deletions(-) create mode 100644 .eslintrc.json create mode 100644 tsconfig.test.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..cdf57c6 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,114 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "parserOptions": { + "project": [ + "./tsconfig.json", + "./tsconfig.test.json", + "./tsconfig.frontend.json" + ] + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-trailing-spaces": "error", + "max-len": [ + "error", + { + "code": 120, + "ignoreStrings": true, + "ignoreTemplateLiterals": true, + "ignoreRegExpLiterals": true + } + ], + "semi": "off", + "@typescript-eslint/semi": [ + "error" + ], + "no-extra-semi": "error", + "eol-last": "error", + "comma-dangle": "off", + "@typescript-eslint/comma-dangle": [ + "error", + { + "arrays": "always-multiline", + "objects": "always-multiline", + "imports": "always-multiline", + "exports": "always-multiline", + "functions": "always-multiline", + "enums": "always-multiline", + "generics": "always-multiline", + "tuples": "always-multiline" + } + ], + "no-extra-parens": "off", + "@typescript-eslint/no-extra-parens": [ + "error" + ], + "no-nested-ternary": "error", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/explicit-module-boundary-types": "error", + "@typescript-eslint/no-unnecessary-condition": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_" + } + ], + "@typescript-eslint/no-non-null-assertion": "error", + "no-useless-return": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": [ + "error" + ], + "no-return-await": "off", + "@typescript-eslint/return-await": [ + "error", + "always" + ], + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { + "accessibility": "explicit" + } + ], + "@typescript-eslint/no-floating-promises": "error" + }, + "ignorePatterns": [ + "jest.config.js", + "webpack.config.js", + "dist/**/*", + "public/**/*", + "config/**/*" + ], + "overrides": [ + { + "files": [ + "test/**/*" + ], + "rules": { + "max-len": [ + "error", + { + "code": 120, + "ignoreTemplateLiterals": true, + "ignoreRegExpLiterals": true, + "ignoreStrings": true + } + ] + } + } + ] +} diff --git a/assets/ts/PersistentWebSocket.ts b/assets/ts/PersistentWebSocket.ts index b53f948..98e474f 100644 --- a/assets/ts/PersistentWebSocket.ts +++ b/assets/ts/PersistentWebSocket.ts @@ -8,13 +8,13 @@ export default class PersistentWebsocket { ) { } - public run() { - this.webSocket = new WebSocket(this.url); - this.webSocket.addEventListener('open', (e) => { + public run(): void { + const _webSocket = this.webSocket = new WebSocket(this.url); + this.webSocket.addEventListener('open', () => { console.debug('Websocket connected'); }); this.webSocket.addEventListener('message', (e) => { - this.handler(this.webSocket!, e); + this.handler(_webSocket, e); }); this.webSocket.addEventListener('error', (e) => { console.error('Websocket error', e); @@ -29,7 +29,7 @@ export default class PersistentWebsocket { }); } - public send(data: string) { + public send(data: string): void { if (!this.webSocket) throw new Error('WebSocket not connected'); this.webSocket.send(data); diff --git a/assets/ts/forms.ts b/assets/ts/forms.ts index 46cd108..d08a65e 100644 --- a/assets/ts/forms.ts +++ b/assets/ts/forms.ts @@ -1,7 +1,9 @@ /* * For labels to update their state (css selectors based on the value attribute) */ -export function updateInputs() { +import {ValidationError} from "wms-core/db/Validator"; + +export function updateInputs(): void { document.querySelectorAll('input, textarea').forEach(el => { if (!el.dataset.inputSetup) { el.dataset.inputSetup = 'true'; @@ -19,7 +21,10 @@ document.addEventListener('DOMContentLoaded', () => { updateInputs(); }); -export function applyFormMessages(formElement: HTMLFormElement, messages: { [p: string]: any }) { +export function applyFormMessages( + formElement: HTMLFormElement, + messages: { [p: string]: ValidationError }, +): void { for (const fieldName of Object.keys(messages)) { const field = formElement.querySelector('#field-' + fieldName); if (!field) continue; @@ -27,14 +32,12 @@ export function applyFormMessages(formElement: HTMLFormElement, messages: { [p: let parent = field.parentElement; while (parent && !parent.classList.contains('form-field')) parent = parent.parentElement; - if (field) { - let err = field.querySelector('.error'); - if (!err) { - err = document.createElement('div'); - err.classList.add('error'); - parent?.insertBefore(err, parent.querySelector('.hint') || parent); - } - err.innerHTML = ` ${messages[fieldName].message}`; + let err = field.querySelector('.error'); + if (!err) { + err = document.createElement('div'); + err.classList.add('error'); + parent?.insertBefore(err, parent.querySelector('.hint') || parent); } + err.innerHTML = ` ${messages[fieldName].message}`; } } diff --git a/assets/ts/tooltips-and-dropdowns.ts b/assets/ts/tooltips-and-dropdowns.ts index e66c732..069b405 100644 --- a/assets/ts/tooltips-and-dropdowns.ts +++ b/assets/ts/tooltips-and-dropdowns.ts @@ -1,4 +1,4 @@ -export function updateTooltips() { +export function updateTooltips(): void { console.debug('Updating tooltips'); const elements = document.querySelectorAll('.tip, .dropdown'); diff --git a/package.json b/package.json index 4c917b4..04056cc 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,12 @@ "scripts": { "test": "jest --verbose --runInBand", "dist-webpack": "webpack --mode production", - "dist": "(test ! -d dist || rm -r dist) && tsc && npm run dist-webpack", + "dist": "yarn compile && yarn dist-webpack", + "clean": "(test ! -d dist || rm -r dist)", + "compile": "yarn clean && tsc && mv dist/src/* dist/", "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", - "start": "yarn dist && node dist/main.js" + "start": "yarn dist && node dist/main.js", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx" }, "devDependencies": { "@babel/core": "^7.9.0", @@ -28,9 +31,12 @@ "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", "@types/ws": "^7.2.6", + "@typescript-eslint/eslint-plugin": "^4.3.0", + "@typescript-eslint/parser": "^4.3.0", "babel-loader": "^8.1.0", "concurrently": "^5.1.0", "css-loader": "^4.2.2", + "eslint": "^7.10.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", "imagemin": "^7.0.1", @@ -55,6 +61,6 @@ "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "wms-core": "^0.21.7" + "wms-core": "^0.22.0-rc.24" } } diff --git a/src/App.ts b/src/App.ts index 713f51b..c8dac6b 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,6 +1,5 @@ import Application from "wms-core/Application"; -import {Type} from "wms-core/Utils"; -import Migration from "wms-core/db/Migration"; +import Migration, {MigrationType} from "wms-core/db/Migration"; import CreateMigrationsTable from "wms-core/migrations/CreateMigrationsTable"; import CreateLogsTable from "wms-core/migrations/CreateLogsTable"; import ExpressAppComponent from "wms-core/components/ExpressAppComponent"; @@ -18,16 +17,17 @@ import CsrfProtectionComponent from "wms-core/components/CsrfProtectionComponent import WebSocketServerComponent from "wms-core/components/WebSocketServerComponent"; import HomeController from "./controllers/HomeController"; import AutoUpdateComponent from "wms-core/components/AutoUpdateComponent"; +import packageJson = require('../package.json'); export default class App extends Application { - private readonly port: number; - - constructor(port: number) { - super(require('../package.json').version); - this.port = port; + public constructor( + private readonly addr: string, + private readonly port: number, + ) { + super(packageJson.version); } - protected getMigrations(): Type[] { + protected getMigrations(): MigrationType[] { return [ CreateMigrationsTable, CreateLogsTable, @@ -44,7 +44,7 @@ export default class App extends Application { const redisComponent = new RedisComponent(); const mysqlComponent = new MysqlComponent(); - const expressAppComponent = new ExpressAppComponent(this.port); + const expressAppComponent = new ExpressAppComponent(this.addr, this.port); this.use(expressAppComponent); this.use(new NunjucksComponent()); this.use(new LogRequestsComponent()); @@ -79,9 +79,10 @@ export default class App extends Application { } private registerWebSocketListeners() { + // WebSocket listeners } private registerControllers() { this.use(new HomeController()); } -} \ No newline at end of file +} diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index ad035b4..e6e3fb3 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -2,24 +2,24 @@ import Controller from "wms-core/Controller"; import {Request, Response} from "express"; export default class HomeController extends Controller { - routes(): void { + public routes(): void { this.get('/', this.getHome, 'home'); this.get('/about', this.getAbout, 'about'); this.get('/back', this.goBack, 'about'); } - private async getHome(req: Request, res: Response) { + protected async getHome(req: Request, res: Response): Promise { res.render('home'); } - private async getAbout(req: Request, res: Response) { + protected async getAbout(req: Request, res: Response): Promise { res.render('about'); } /** * This is to test and assert that wms-core extended types are available */ - private async goBack(req: Request, res: Response) { + protected async goBack(req: Request, res: Response): Promise { res.redirectBack(); } -} \ No newline at end of file +} diff --git a/src/main.ts b/src/main.ts index b3f32d5..76e7561 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,9 @@ +import {delimiter} from "path"; + // Load config from specified path or default + wms-core/config (default defaults) process.env['NODE_CONFIG_DIR'] = __dirname + '/../node_modules/wms-core/config/' - + require('path').delimiter + + delimiter + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); import Logger from "wms-core/Logger"; @@ -11,8 +13,8 @@ import config from "config"; (async () => { Logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); - const app = new App(config.get('port')); + const app = new App(config.get('listen_addr'), config.get('port')); await app.start(); })().catch(err => { Logger.error(err); -}); \ No newline at end of file +}); diff --git a/test/App.test.ts b/test/App.test.ts index 451f0fb..d116a22 100644 --- a/test/App.test.ts +++ b/test/App.test.ts @@ -2,4 +2,4 @@ describe('Write your tests', () => { test('Remove this when you have some tests', () => { expect(false).toBe(true); }); -}); \ No newline at end of file +}); diff --git a/tsconfig.json b/tsconfig.json index 19d375e..5ea85f7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,10 +11,11 @@ ], "typeRoots": [ "./node_modules/@types" - ] + ], + "resolveJsonModule": true }, "include": [ "src/**/*", "node_modules/wms-core/types" ] -} \ No newline at end of file +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..897a6b4 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "typeRoots": [ + "node_modules/@types", + "src/types", + "test/types" + ] + }, + "include": [ + "src/types/**/*", + "test/**/*" + ] +} \ No newline at end of file -- 2.47.0 From 292e843cd16591aa345d372016140c64bc549620 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 2 Nov 2020 18:17:55 +0100 Subject: [PATCH 34/71] Upgrade packages i.e. wms-core --- config/{default.ts => default.json5} | 2 +- config/{production.ts => production.json5} | 2 +- config/{test.ts => test.json5} | 2 +- package.json | 15 +++++++-------- src/App.ts | 6 ++++-- src/main.ts | 6 +++--- 6 files changed, 17 insertions(+), 16 deletions(-) rename config/{default.ts => default.json5} (98%) rename config/{production.ts => production.json5} (94%) rename config/{test.ts => test.json5} (90%) diff --git a/config/default.ts b/config/default.json5 similarity index 98% rename from config/default.ts rename to config/default.json5 index aed8601..1831e21 100644 --- a/config/default.ts +++ b/config/default.json5 @@ -1,4 +1,4 @@ -export default { +{ app: { name: 'Example App', contact_email: 'contact@example.net' diff --git a/config/production.ts b/config/production.json5 similarity index 94% rename from config/production.ts rename to config/production.json5 index 4143867..6993e0e 100644 --- a/config/production.ts +++ b/config/production.json5 @@ -1,4 +1,4 @@ -export default { +{ log_level: "DEBUG", db_log_level: "ERROR", public_url: "https://watch-my.stream", diff --git a/config/test.ts b/config/test.json5 similarity index 90% rename from config/test.ts rename to config/test.json5 index 61f7c4a..c184427 100644 --- a/config/test.ts +++ b/config/test.json5 @@ -1,4 +1,4 @@ -export default { +{ mysql: { host: "localhost", user: "root", diff --git a/package.json b/package.json index 04056cc..3ad46b8 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@typescript-eslint/parser": "^4.3.0", "babel-loader": "^8.1.0", "concurrently": "^5.1.0", - "css-loader": "^4.2.2", + "css-loader": "^5.0.0", "eslint": "^7.10.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", @@ -46,21 +46,20 @@ "imagemin-svgo": "^8.0.0", "img-loader": "^3.0.1", "jest": "^26.1.0", - "mini-css-extract-plugin": "^0.11.0", - "node-sass": "^4.14.0", + "mini-css-extract-plugin": "^1.2.1", + "node-sass": "^5.0.0", "nodemon": "^2.0.3", "sass-loader": "^10.0.1", - "terser-webpack-plugin": "^4.2.2", + "terser-webpack-plugin": "^5.0.3", "ts-jest": "^26.1.1", "ts-loader": "^8.0.4", "typescript": "^4.0.2", - "uglifyjs-webpack-plugin": "^2.2.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.11" + "webpack": "^5.3.2", + "webpack-cli": "^4.1.0" }, "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "wms-core": "^0.22.0-rc.24" + "wms-core": "^0.22.0" } } diff --git a/src/App.ts b/src/App.ts index c8dac6b..6633f86 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,7 +1,6 @@ import Application from "wms-core/Application"; import Migration, {MigrationType} from "wms-core/db/Migration"; import CreateMigrationsTable from "wms-core/migrations/CreateMigrationsTable"; -import CreateLogsTable from "wms-core/migrations/CreateLogsTable"; import ExpressAppComponent from "wms-core/components/ExpressAppComponent"; import NunjucksComponent from "wms-core/components/NunjucksComponent"; import MysqlComponent from "wms-core/components/MysqlComponent"; @@ -18,6 +17,8 @@ import WebSocketServerComponent from "wms-core/components/WebSocketServerCompone import HomeController from "./controllers/HomeController"; import AutoUpdateComponent from "wms-core/components/AutoUpdateComponent"; import packageJson = require('../package.json'); +import DummyMigration from "wms-core/migrations/DummyMigration"; +import DropLegacyLogsTable from "wms-core/migrations/DropLegacyLogsTable"; export default class App extends Application { public constructor( @@ -30,7 +31,8 @@ export default class App extends Application { protected getMigrations(): MigrationType[] { return [ CreateMigrationsTable, - CreateLogsTable, + DummyMigration, + DropLegacyLogsTable, ]; } diff --git a/src/main.ts b/src/main.ts index 76e7561..e243999 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,15 +6,15 @@ process.env['NODE_CONFIG_DIR'] = + delimiter + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); -import Logger from "wms-core/Logger"; +import {log} from "wms-core/Logger"; import App from "./App"; import config from "config"; (async () => { - Logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); + log.debug('Config path:', process.env['NODE_CONFIG_DIR']); const app = new App(config.get('listen_addr'), config.get('port')); await app.start(); })().catch(err => { - Logger.error(err); + log.error(err); }); -- 2.47.0 From 9e07d4bff4eeee005c4e976ef9ab0ed66b42ce38 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 2 Nov 2020 18:37:39 +0100 Subject: [PATCH 35/71] config: remove insecure default values --- config/default.json5 | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/default.json5 b/config/default.json5 index 1831e21..e0c6b9b 100644 --- a/config/default.json5 +++ b/config/default.json5 @@ -8,7 +8,6 @@ public_url: "http://localhost:4899", public_websocket_url: "ws://localhost:4899", port: 4899, - gitlab_webhook_token: 'secret', mysql: { connectionLimit: 10, host: "localhost", @@ -23,7 +22,6 @@ prefix: 'example_app' }, session: { - secret: "very_secret_not_known", cookie: { secure: false } -- 2.47.0 From a4df579937f3a0d184dadb16ba09562b8851e00a Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 3 Nov 2020 10:37:30 +0100 Subject: [PATCH 36/71] Rename "dist" task to more relevant "build" --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3ad46b8..fd6dc27 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,14 @@ "private": true, "main": "dist/main.js", "scripts": { - "test": "jest --verbose --runInBand", "dist-webpack": "webpack --mode production", - "dist": "yarn compile && yarn dist-webpack", "clean": "(test ! -d dist || rm -r dist)", "compile": "yarn clean && tsc && mv dist/src/* dist/", + "build": "yarn compile && yarn dist-webpack", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", - "start": "yarn dist && node dist/main.js", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx" + "start": "yarn build && node dist/main.js", + "test": "jest --verbose --runInBand" }, "devDependencies": { "@babel/core": "^7.9.0", -- 2.47.0 From 04f19f5a28ba90cca4adeb8125ef19cb7a258c94 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 3 Nov 2020 17:26:32 +0100 Subject: [PATCH 37/71] Fix yarn dev script --- package.json | 6 +++--- src/main.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fd6dc27..501e8f2 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,15 @@ "repository": "https://gitlab.com/ArisuOngaku/wms-boilerplate", "author": "Alice Gaudon ", "private": true, - "main": "dist/main.js", + "main": "dist/src/main.js", "scripts": { "dist-webpack": "webpack --mode production", "clean": "(test ! -d dist || rm -r dist)", - "compile": "yarn clean && tsc && mv dist/src/* dist/", + "compile": "yarn clean && tsc", "build": "yarn compile && yarn dist-webpack", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", - "start": "yarn build && node dist/main.js", + "start": "yarn build && node dist/src/main.js", "test": "jest --verbose --runInBand" }, "devDependencies": { diff --git a/src/main.ts b/src/main.ts index e243999..14be157 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,9 +2,9 @@ import {delimiter} from "path"; // Load config from specified path or default + wms-core/config (default defaults) process.env['NODE_CONFIG_DIR'] = - __dirname + '/../node_modules/wms-core/config/' + __dirname + '/../../node_modules/wms-core/config/' + delimiter - + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); + + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../../config/'); import {log} from "wms-core/Logger"; import App from "./App"; -- 2.47.0 From f16d63c74fd8e9c2437ecb2a3ac5d1ad35931eb6 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 3 Nov 2020 20:29:07 +0100 Subject: [PATCH 38/71] frontend: refactor $mobileThreshold and container media queries --- assets/sass/_vars.scss | 2 +- assets/sass/layout.scss | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/assets/sass/_vars.scss b/assets/sass/_vars.scss index f0eb1fc..31b7580 100644 --- a/assets/sass/_vars.scss +++ b/assets/sass/_vars.scss @@ -28,4 +28,4 @@ $errorText: darken($error, 30%); $errorColor: desaturate($errorText, 50%); // Responsivity -$menuLayoutSwitchTreshold: 700px; +$mobileThreshold: 632px; diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index e05bbcb..5a00bff 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -183,7 +183,7 @@ body > header { } } - @media (max-width: $menuLayoutSwitchTreshold) { + @media (max-width: $mobileThreshold) { flex-direction: row-reverse; .logo { @@ -246,7 +246,7 @@ body > header { } } - @media (min-width: $menuLayoutSwitchTreshold) { + @media (min-width: $mobileThreshold) { nav ul li { a, button, .button { @include tip; @@ -274,7 +274,7 @@ footer { main { flex: 1; - padding: 8px; + padding: 8px 0; button, .button { @include tip; @@ -649,10 +649,22 @@ button, .button { text-align: center; } -.container { +@mixin container { + width: $mobileThreshold; padding: 0 16px; - max-width: 632px; - margin: 0 auto; + + @media (min-width: $mobileThreshold) { + margin: 0 auto; + } + + @media (max-width: $mobileThreshold) { + width: 100%; + padding: 0 8px; + } +} + +.container { + @include container; } .panel { -- 2.47.0 From ba5b90a4f91df5742033afdf14c21e7752176b13 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 13 Nov 2020 10:54:35 +0100 Subject: [PATCH 39/71] swaf rename: rename project to swaf-boilerplate --- README.md | 3 +++ app.service | 11 +++++---- assets/img/logo.svg | 1 - assets/ts/forms.ts | 2 +- config/test.json5 | 2 +- package.json | 6 ++--- src/App.ts | 38 +++++++++++++++---------------- src/controllers/HomeController.ts | 4 ++-- src/main.ts | 6 ++--- tsconfig.json | 2 +- views/about.njk | 4 ++-- 11 files changed, 42 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index e69de29..96b65aa 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,3 @@ +# swaf boilerplate + +Boilerplate for a quickstart with [swaf](https://eternae.ink/arisu/swaf) diff --git a/app.service b/app.service index 32f2b99..ece8fd0 100644 --- a/app.service +++ b/app.service @@ -1,13 +1,16 @@ +# Please customize values i.e. paths, user, group, WorkingDirectory based on your environment. Do not use the same +# user and group for different applications. + [Unit] -Description=WMS website +Description=swaf based website After=network-online.target Wants=network-online.target [Service] Type=simple -User=wms -Group=wms -WorkingDirectory=/home/wms/live +User=swaf +Group=swaf +WorkingDirectory=/home/swaf/live Restart=on-success Environment=NODE_ENV=production ExecStart=/bin/node . diff --git a/assets/img/logo.svg b/assets/img/logo.svg index c33da66..4f8fb6e 100644 --- a/assets/img/logo.svg +++ b/assets/img/logo.svg @@ -19,7 +19,6 @@ id="svg6" sodipodi:docname="logo.svg" inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" - inkscape:export-filename="/r/arisu/dev/streams/wms/assets/img/logox1024.png" inkscape:export-xdpi="4096" inkscape:export-ydpi="4096"> ('input, textarea').forEach(el => { diff --git a/config/test.json5 b/config/test.json5 index c184427..cda9d47 100644 --- a/config/test.json5 +++ b/config/test.json5 @@ -3,7 +3,7 @@ host: "localhost", user: "root", password: "", - database: "wms2_test", + database: "swaf_test", create_database_automatically: true } } diff --git a/package.json b/package.json index 501e8f2..1550885 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "example-app", "version": "0.1.0", - "description": "Example App based on wms-core", - "repository": "https://gitlab.com/ArisuOngaku/wms-boilerplate", + "description": "Example App based on swaf", + "repository": "https://eternae.ink/arisu/swaf-boilerplate", "author": "Alice Gaudon ", "private": true, "main": "dist/src/main.js", @@ -60,6 +60,6 @@ "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "wms-core": "^0.22.0" + "swaf": "^0.22.5" } } diff --git a/src/App.ts b/src/App.ts index 6633f86..f645a64 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,24 +1,24 @@ -import Application from "wms-core/Application"; -import Migration, {MigrationType} from "wms-core/db/Migration"; -import CreateMigrationsTable from "wms-core/migrations/CreateMigrationsTable"; -import ExpressAppComponent from "wms-core/components/ExpressAppComponent"; -import NunjucksComponent from "wms-core/components/NunjucksComponent"; -import MysqlComponent from "wms-core/components/MysqlComponent"; -import LogRequestsComponent from "wms-core/components/LogRequestsComponent"; -import RedisComponent from "wms-core/components/RedisComponent"; -import ServeStaticDirectoryComponent from "wms-core/components/ServeStaticDirectoryComponent"; -import MaintenanceComponent from "wms-core/components/MaintenanceComponent"; -import MailComponent from "wms-core/components/MailComponent"; -import SessionComponent from "wms-core/components/SessionComponent"; -import RedirectBackComponent from "wms-core/components/RedirectBackComponent"; -import FormHelperComponent from "wms-core/components/FormHelperComponent"; -import CsrfProtectionComponent from "wms-core/components/CsrfProtectionComponent"; -import WebSocketServerComponent from "wms-core/components/WebSocketServerComponent"; +import Application from "swaf/Application"; +import Migration, {MigrationType} from "swaf/db/Migration"; +import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; +import ExpressAppComponent from "swaf/components/ExpressAppComponent"; +import NunjucksComponent from "swaf/components/NunjucksComponent"; +import MysqlComponent from "swaf/components/MysqlComponent"; +import LogRequestsComponent from "swaf/components/LogRequestsComponent"; +import RedisComponent from "swaf/components/RedisComponent"; +import ServeStaticDirectoryComponent from "swaf/components/ServeStaticDirectoryComponent"; +import MaintenanceComponent from "swaf/components/MaintenanceComponent"; +import MailComponent from "swaf/components/MailComponent"; +import SessionComponent from "swaf/components/SessionComponent"; +import RedirectBackComponent from "swaf/components/RedirectBackComponent"; +import FormHelperComponent from "swaf/components/FormHelperComponent"; +import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent"; +import WebSocketServerComponent from "swaf/components/WebSocketServerComponent"; import HomeController from "./controllers/HomeController"; -import AutoUpdateComponent from "wms-core/components/AutoUpdateComponent"; +import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; import packageJson = require('../package.json'); -import DummyMigration from "wms-core/migrations/DummyMigration"; -import DropLegacyLogsTable from "wms-core/migrations/DropLegacyLogsTable"; +import DummyMigration from "swaf/migrations/DummyMigration"; +import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; export default class App extends Application { public constructor( diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index e6e3fb3..d8a0379 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -1,4 +1,4 @@ -import Controller from "wms-core/Controller"; +import Controller from "swaf/Controller"; import {Request, Response} from "express"; export default class HomeController extends Controller { @@ -17,7 +17,7 @@ export default class HomeController extends Controller { } /** - * This is to test and assert that wms-core extended types are available + * This is to test and assert that swaf extended types are available */ protected async goBack(req: Request, res: Response): Promise { res.redirectBack(); diff --git a/src/main.ts b/src/main.ts index 14be157..0033726 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,12 @@ import {delimiter} from "path"; -// Load config from specified path or default + wms-core/config (default defaults) +// Load config from specified path or default + swaf/config (default defaults) process.env['NODE_CONFIG_DIR'] = - __dirname + '/../../node_modules/wms-core/config/' + __dirname + '/../../node_modules/swaf/config/' + delimiter + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../../config/'); -import {log} from "wms-core/Logger"; +import {log} from "swaf/Logger"; import App from "./App"; import config from "config"; diff --git a/tsconfig.json b/tsconfig.json index 5ea85f7..9034d02 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,6 @@ }, "include": [ "src/**/*", - "node_modules/wms-core/types" + "node_modules/swaf/types" ] } diff --git a/views/about.njk b/views/about.njk index dbb6047..f1e7a0a 100644 --- a/views/about.njk +++ b/views/about.njk @@ -8,7 +8,7 @@

This is us

-

And we like wms!

+

And we like swaf!

-{% endblock %} \ No newline at end of file +{% endblock %} -- 2.47.0 From 9f3a541c3e2fac185152ca8b0c839539ecb7251c Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 25 Jan 2021 11:43:36 +0100 Subject: [PATCH 40/71] Add maildev as a dev dependency --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1550885..1681a4a 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "imagemin-svgo": "^8.0.0", "img-loader": "^3.0.1", "jest": "^26.1.0", + "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", "node-sass": "^5.0.0", "nodemon": "^2.0.3", -- 2.47.0 From 5eaebd5d120372a232b7338a05e9a6e17098828f Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 25 Jan 2021 13:17:41 +0100 Subject: [PATCH 41/71] Upgrade dependencies and bump swaf to ^0.23.0 --- .gitignore | 2 ++ package.json | 18 +++++++++--------- src/App.ts | 27 +++++++++++++-------------- src/controllers/HomeController.ts | 2 +- src/main.ts | 10 +++++----- tsconfig.frontend.json | 1 + tsconfig.json | 1 + 7 files changed, 32 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 7626c60..570ee35 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules public dist yarn-error.log + +src/package.json diff --git a/package.json b/package.json index 1681a4a..2eefcc6 100644 --- a/package.json +++ b/package.json @@ -5,22 +5,22 @@ "repository": "https://eternae.ink/arisu/swaf-boilerplate", "author": "Alice Gaudon ", "private": true, - "main": "dist/src/main.js", + "main": "dist/main.js", "scripts": { - "dist-webpack": "webpack --mode production", + "test": "jest --verbose --runInBand", "clean": "(test ! -d dist || rm -r dist)", + "prepareSources": "cp package.json src/", "compile": "yarn clean && tsc", - "build": "yarn compile && yarn dist-webpack", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx", - "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", - "start": "yarn build && node dist/src/main.js", - "test": "jest --verbose --runInBand" + "build": "yarn prepareSources && yarn compile && webpack --mode production", + "dev": "yarn prepareSources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", + "start": "yarn build && node", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx" }, "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", "@fortawesome/fontawesome-free": "^5.14.0", - "@types/config": "^0.0.36", + "@types/config": "^0.0.38", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", "@types/feather-icons": "^4.7.0", @@ -61,6 +61,6 @@ "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "swaf": "^0.22.5" + "swaf": "^0.23.0" } } diff --git a/src/App.ts b/src/App.ts index f645a64..6272da0 100644 --- a/src/App.ts +++ b/src/App.ts @@ -10,15 +10,15 @@ import ServeStaticDirectoryComponent from "swaf/components/ServeStaticDirectoryC import MaintenanceComponent from "swaf/components/MaintenanceComponent"; import MailComponent from "swaf/components/MailComponent"; import SessionComponent from "swaf/components/SessionComponent"; -import RedirectBackComponent from "swaf/components/RedirectBackComponent"; import FormHelperComponent from "swaf/components/FormHelperComponent"; import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent"; import WebSocketServerComponent from "swaf/components/WebSocketServerComponent"; import HomeController from "./controllers/HomeController"; import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; -import packageJson = require('../package.json'); import DummyMigration from "swaf/migrations/DummyMigration"; import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; +import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; +import packageJson = require('./package.json'); export default class App extends Application { public constructor( @@ -43,41 +43,40 @@ export default class App extends Application { } private registerComponents() { - const redisComponent = new RedisComponent(); - const mysqlComponent = new MysqlComponent(); - - const expressAppComponent = new ExpressAppComponent(this.addr, this.port); - this.use(expressAppComponent); - this.use(new NunjucksComponent()); + // Base + this.use(new ExpressAppComponent(this.addr, this.port)); this.use(new LogRequestsComponent()); // Static files this.use(new ServeStaticDirectoryComponent('public')); this.use(new ServeStaticDirectoryComponent('node_modules/feather-icons/dist', '/icons')); + // Dynamic views and routes + this.use(new NunjucksComponent()); + this.use(new PreviousUrlComponent()); + // Maintenance this.use(new MaintenanceComponent(this, () => { - return redisComponent.canServe() && mysqlComponent.canServe(); + return this.as(RedisComponent).canServe() && this.as(MysqlComponent).canServe(); })); this.use(new AutoUpdateComponent()); // Services - this.use(mysqlComponent); + this.use(new MysqlComponent()); this.use(new MailComponent()); // Session - this.use(redisComponent); - this.use(new SessionComponent(redisComponent)); + this.use(new RedisComponent()); + this.use(new SessionComponent(this.as(RedisComponent))); // Utils - this.use(new RedirectBackComponent()); this.use(new FormHelperComponent()); // Middlewares this.use(new CsrfProtectionComponent()); // WebSocket server - this.use(new WebSocketServerComponent(this, expressAppComponent, redisComponent)); + this.use(new WebSocketServerComponent(this, this.as(ExpressAppComponent), this.as(RedisComponent))); } private registerWebSocketListeners() { diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index d8a0379..b5e1740 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -20,6 +20,6 @@ export default class HomeController extends Controller { * This is to test and assert that swaf extended types are available */ protected async goBack(req: Request, res: Response): Promise { - res.redirectBack(); + res.redirect(req.getPreviousUrl() || Controller.route('home')); } } diff --git a/src/main.ts b/src/main.ts index 0033726..babc7df 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,19 +2,19 @@ import {delimiter} from "path"; // Load config from specified path or default + swaf/config (default defaults) process.env['NODE_CONFIG_DIR'] = - __dirname + '/../../node_modules/swaf/config/' + __dirname + '/../node_modules/swaf/config/' + delimiter - + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../../config/'); + + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); -import {log} from "swaf/Logger"; +import {logger} from "swaf/Logger"; import App from "./App"; import config from "config"; (async () => { - log.debug('Config path:', process.env['NODE_CONFIG_DIR']); + logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); const app = new App(config.get('listen_addr'), config.get('port')); await app.start(); })().catch(err => { - log.error(err); + logger.error(err); }); diff --git a/tsconfig.frontend.json b/tsconfig.frontend.json index 4b5a3f5..ad74720 100644 --- a/tsconfig.frontend.json +++ b/tsconfig.frontend.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "public/js", + "rootDir": "./assets", "target": "ES6", "strict": true, "lib": [ diff --git a/tsconfig.json b/tsconfig.json index 9034d02..12eec0a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "module": "CommonJS", "esModuleInterop": true, "outDir": "dist", + "rootDir": "./src", "target": "ES6", "strict": true, "lib": [ -- 2.47.0 From 1043690a5d9d0f4fe5c760124dae9000fdd68750 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 11:37:08 +0100 Subject: [PATCH 42/71] Add bigger container max-width for desktop view --- assets/sass/_vars.scss | 1 + assets/sass/layout.scss | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/assets/sass/_vars.scss b/assets/sass/_vars.scss index 31b7580..1387331 100644 --- a/assets/sass/_vars.scss +++ b/assets/sass/_vars.scss @@ -29,3 +29,4 @@ $errorColor: desaturate($errorText, 50%); // Responsivity $mobileThreshold: 632px; +$desktopThreshold: 940px; diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 5a00bff..94508cc 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -650,16 +650,16 @@ button, .button { } @mixin container { - width: $mobileThreshold; - padding: 0 16px; + width: 100%; + padding: 0 8px; @media (min-width: $mobileThreshold) { margin: 0 auto; + padding: 0 16px; } - @media (max-width: $mobileThreshold) { - width: 100%; - padding: 0 8px; + @media (min-width: $desktopThreshold) { + width: $desktopThreshold; } } -- 2.47.0 From d2a67a12ee8dac1ca7c54f2b8907655deb0b00cf Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 11:42:24 +0100 Subject: [PATCH 43/71] Fix subpanel leaking out of their container --- assets/sass/layout.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 94508cc..5ec9874 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -688,10 +688,14 @@ button, .button { } .sub-panel { - margin: 32px -18px; + margin: 32px 0; padding: 1px 16px; border: 2px solid lighten($panelBackground, 4%); border-radius: 5px; + + form > & { + margin: 32px -18px; + } } -- 2.47.0 From 16394c0d4cfc69703e0a58adb6213443c5c14f32 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 11:43:13 +0100 Subject: [PATCH 44/71] Set icon size for titles --- assets/sass/layout.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 5ec9874..021028f 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -719,6 +719,10 @@ button, .button { stroke-linejoin: miter; fill: none; vertical-align: middle; + + h1 > &, h2 > &, h3 > & { + --icon-size: 24px; + } } // --- -- 2.47.0 From e7165edafd09e1db353b207720185cf6f5df7cbf Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 11:43:42 +0100 Subject: [PATCH 45/71] Add hover color on warning buttons --- assets/sass/layout.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 021028f..a927d89 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -584,6 +584,10 @@ button, .button { &.warning { background-color: $warningColor; + + &:hover { + background-color: lighten($warningColor, 10%); + } } &.error, &.danger { -- 2.47.0 From bda464ab1689be918219834782e2b8da0d1d8ca5 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 13:00:23 +0100 Subject: [PATCH 46/71] css: move a hover color and td.actions improvements to layout.scss --- assets/sass/layout.scss | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index a927d89..b8a5d32 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -338,7 +338,7 @@ a { text-decoration: none; &:hover { - color: lighten($secondary, 10%); + color: lighten($secondary, 30%); } .feather.feather-external-link { @@ -607,6 +607,35 @@ button, .button { } } + +// --- +// --- Tables +// --- +td.actions { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + + form { + padding: 0; + display: inline; + } + + button, .button { + margin: 0; + padding: 8px; + + .feather { + margin-right: 0; + } + } + + > *:not(:first-child) { + margin-left: 8px; + } +} + .data-table { width: 100%; text-align: left; @@ -633,6 +662,10 @@ button, .button { } } + +// --- +// --- Breadcrumb widget +// --- .breadcrumb { list-style: none; display: flex; @@ -646,6 +679,7 @@ button, .button { } } + // --- // --- Layout helpers // --- -- 2.47.0 From 8612b0f33a75ac034ca719d05397cd5e89ea33ff Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 13:00:38 +0100 Subject: [PATCH 47/71] css: move lighter theme to layout.scss and make header css mobile first --- assets/sass/_vars.scss | 7 +- assets/sass/layout.scss | 254 +++++++++++++++------------- assets/sass/responsivity_tools.scss | 19 +++ 3 files changed, 160 insertions(+), 120 deletions(-) create mode 100644 assets/sass/responsivity_tools.scss diff --git a/assets/sass/_vars.scss b/assets/sass/_vars.scss index 1387331..478fca3 100644 --- a/assets/sass/_vars.scss +++ b/assets/sass/_vars.scss @@ -6,9 +6,10 @@ $secondaryForeground: $primaryForeground; $backgroundColor: darken($primary, 4%); $defaultTextColor: #ffffff; -$headerBackground: darken($primary, 7.5%); -$footerBackground: lighten($headerBackground, 1%); -$panelBackground: lighten($headerBackground, 1%); +$headerBackground: transparent; +$headerContainer: true; +$footerBackground: transparent; +$panelBackground: darken($backgroundColor, 3.2%); $inputBackground: darken($panelBackground, 4%); $info: #4499ff; diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index b8a5d32..d086fb7 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -1,5 +1,6 @@ @import "vars"; @import 'fonts'; +@import "responsivity_tools"; * { box-sizing: border-box; @@ -69,21 +70,31 @@ body { body > header { z-index: 50; display: flex; - flex-direction: row; + flex-direction: row-reverse; justify-content: space-between; + align-items: center; $headerHeight: 64px; height: $headerHeight; line-height: $headerHeight; - background-color: $headerBackground; + background: $headerBackground; + + @if $headerContainer { + @include container; + } + + @media (max-width: $mobileThreshold) { + padding: 0; + } .logo { display: flex; flex-direction: row; + align-items: center; - padding: 0 24px 0 16px; - font-size: 32px; + padding: 0 16px 0 8px; + font-size: 24px; color: $defaultTextColor; &:hover { @@ -91,34 +102,48 @@ body > header { } img { - width: $headerHeight; - height: $headerHeight; - margin-right: 16px; + width: initial; + height: calc(#{$headerHeight} - 16px); + margin-right: 8px; + flex-shrink: 0; } } nav { - ul { + > ul { + position: fixed; + z-index: -1; + top: 0; + left: 0; + height: 100%; + transform: translateX(-100%); + transition: transform ease-out 150ms; + display: flex; - flex-direction: row; + flex-direction: column; margin: 0; - padding: 0; + padding: $headerHeight 8px 8px; font-size: 20px; + background: $panelBackground; + li { position: relative; list-style: none; + margin-top: 8px; a, button { position: relative; - height: 64px; margin: 0; - padding: 0 24px; display: flex; flex-direction: row; align-items: center; + height: auto; + padding: 8px; + + border-radius: 3px; &:hover, &:active { &:not(button) { @@ -127,13 +152,19 @@ body > header { } .feather { - --icon-size: 24px; + --icon-size: 16px; + } + + .tip { + display: block; + margin-left: 8px; + text-transform: inherit; + font-weight: inherit; } } button { - margin: 8px; - padding: 24px; + margin: 0; height: 32px; .feather { @@ -158,114 +189,121 @@ body > header { } .dropdown { - position: absolute; - z-index: -1; - top: 100%; - right: 0; - - white-space: nowrap; - background: $headerBackground; - border-radius: 0 0 3px 3px; - - a { - padding: 0 8px; - } - } - - &:hover .dropdown { + position: initial; display: block; + padding-left: 0; } } + + > li:not(:first-child) { + border-top: 1px solid transparentize($defaultTextColor, 0.8); + padding-top: 8px; + } + + &.open { + transform: translateX(0%); + box-shadow: 0 0 5px darken($panelBackground, 20%); + } } #menu-button { - display: none; - } - } + position: fixed; + top: 0; + left: 0; + display: block; + margin: 0; + padding: 0 16px; + line-height: $headerHeight; - @media (max-width: $mobileThreshold) { - flex-direction: row-reverse; + cursor: pointer; + background: transparent; + border-radius: 0; - .logo { - padding: 0 16px 0 8px; - font-size: 24px; - - img { - margin-right: 8px; + .feather { + --icon-size: 28px; + margin: 0 8px; } } - nav { - #menu-button { - display: block; - margin: 0; - padding: 0 16px; - line-height: $headerHeight; - - cursor: pointer; - background: transparent; - border-radius: 0; - - .feather { - --icon-size: 28px; - margin: 0 8px; - } - } - - > ul { - flex-direction: column; - position: absolute; - z-index: 10; - left: 0; - transform: translateX(-100%); - transition: transform ease-out 150ms; - - background-color: $headerBackground; - - &.open { - transform: translateX(0%); - } - - li { - a, button { - .tip { - display: block; - margin-left: 8px; - text-transform: inherit; - font-weight: inherit; - } - } - - .dropdown { - position: initial; - display: block; - padding-left: 32px; - } - } - } + hr { + border: 0; + border-bottom: 1px solid $defaultTextColor; + opacity: 0.2; } } @media (min-width: $mobileThreshold) { - nav ul li { - a, button, .button { - @include tip; + flex-direction: row; + + nav { + #menu-button { + display: none; } - &:last-child { - a, button, .button { - .tip { - left: unset; - right: 4px; - transform: none; + ul { + position: static; + flex-direction: row; + transform: none; + padding: 0; + background: transparent; + + li { + margin-top: 0; + margin-left: 8px; + + a, button, .button { + @include tip; } + + &:last-child { + a, button, .button { + .tip { + left: unset; + right: 4px; + transform: none; + } + } + } + + .dropdown { + position: absolute; + z-index: -1; + top: 100%; + right: 0; + display: none; + padding: 8px; + + white-space: nowrap; + background: $panelBackground; + border-radius: 0 0 3px 3px; + + box-shadow: 0 2px 2px transparentize(darken($panelBackground, 20%), 0.75); + border-top: 4px solid lighten($panelBackground, 5%); + + li { + margin-left: 0; + + &:not(:first-child) { + margin-top: 8px; + } + } + } + + &:hover .dropdown { + display: block; + } + } + + > li:not(:first-child) { + border-top: 0; + padding-top: 0; } } } } } -footer { +body > footer { padding: 8px; margin-top: 8px; text-align: center; @@ -687,24 +725,6 @@ td.actions { text-align: center; } -@mixin container { - width: 100%; - padding: 0 8px; - - @media (min-width: $mobileThreshold) { - margin: 0 auto; - padding: 0 16px; - } - - @media (min-width: $desktopThreshold) { - width: $desktopThreshold; - } -} - -.container { - @include container; -} - .panel { position: relative; margin: 16px 0 48px; diff --git a/assets/sass/responsivity_tools.scss b/assets/sass/responsivity_tools.scss new file mode 100644 index 0000000..0e3d232 --- /dev/null +++ b/assets/sass/responsivity_tools.scss @@ -0,0 +1,19 @@ +@import "vars"; + +@mixin container { + width: 100%; + padding: 0 8px; + + @media (min-width: $mobileThreshold) { + margin: 0 auto; + padding: 0 16px; + } + + @media (min-width: $desktopThreshold) { + width: $desktopThreshold; + } +} + +.container { + @include container; +} -- 2.47.0 From 145d8df70a945acc6d09b06d1b32dabbb1e02a70 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 13:37:41 +0100 Subject: [PATCH 48/71] css: move menu .tip visibility to layout.scss --- assets/sass/layout.scss | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index d086fb7..9e14352 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -156,10 +156,22 @@ body > header { } .tip { + position: static; + visibility: visible; + opacity: 1; display: block; + height: auto; margin-left: 8px; - text-transform: inherit; + padding: 0 0 0 4px; + transform: none; + + font-size: 16px; + line-height: 16px; + + color: inherit; + text-transform: uppercase; font-weight: inherit; + background: transparent; } } @@ -251,10 +263,6 @@ body > header { margin-top: 0; margin-left: 8px; - a, button, .button { - @include tip; - } - &:last-child { a, button, .button { .tip { -- 2.47.0 From 959e5ca27672c40a0b9211dca43e9f0ac505463f Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 26 Jan 2021 14:28:53 +0100 Subject: [PATCH 49/71] Remove duplicate definition of .copyable-text and improve table layout --- assets/sass/layout.scss | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 9e14352..4f4124b 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -693,6 +693,7 @@ td.actions { th { border-bottom: 1px solid #39434a; + white-space: nowrap; } tr:nth-child(even) { @@ -859,37 +860,7 @@ td.actions { } .content { - overflow: hidden; - white-space: nowrap; - padding: 8px; - } - - .copy-button { - margin: 0; - padding: 0; - border-radius: 0; - - .feather { - --icon-size: 20px; - margin: 8px; - } - } -} - -.copyable-text { - display: flex; - flex-direction: row; - margin: 8px; - - background-color: darken($backgroundColor, 2%); - border-radius: 5px; - overflow: hidden; - - .title { - padding: 8px; - } - - .content { + width: 0; flex-grow: 1; overflow: hidden; white-space: nowrap; @@ -939,3 +910,7 @@ td.actions { background: $secondary; } } + +.table-col-grow { + width: 100%; +} -- 2.47.0 From 0f83dd7ad6d3302496769f7fdc2778fe72a41aef Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 12:32:41 +0200 Subject: [PATCH 50/71] layout.scss: add pagination default style --- assets/sass/layout.scss | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 4f4124b..66e8363 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -914,3 +914,30 @@ td.actions { .table-col-grow { width: 100%; } + +.pagination { + ul { + display: flex; + flex-direction: row; + list-style: none; + padding: 8px; + + justify-content: center; + + li { + a, &.active, &.ellipsis { + display: block; + min-width: 40px; + height: 40px; + padding: 4px; + + line-height: 32px; + text-align:center; + + &:hover:not(.active):not(.ellipsis) { + background-color: #fff5; + } + } + } + } +} -- 2.47.0 From ceaa0769bcad9c03898709a41e13df3b0d7dff43 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 12:39:40 +0200 Subject: [PATCH 51/71] Upgrade dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2eefcc6..f7c65e8 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "^4.3.0", "@typescript-eslint/parser": "^4.3.0", "babel-loader": "^8.1.0", - "concurrently": "^5.1.0", + "concurrently": "^6.0.0", "css-loader": "^5.0.0", "eslint": "^7.10.0", "feather-icons": "^4.28.0", @@ -43,14 +43,14 @@ "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.0", - "imagemin-svgo": "^8.0.0", + "imagemin-svgo": "^9.0.0", "img-loader": "^3.0.1", "jest": "^26.1.0", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", "node-sass": "^5.0.0", "nodemon": "^2.0.3", - "sass-loader": "^10.0.1", + "sass-loader": "^11.0.1", "terser-webpack-plugin": "^5.0.3", "ts-jest": "^26.1.1", "ts-loader": "^8.0.4", -- 2.47.0 From 12f82f0f3dcea4d20d4e92b9f7f29069d1c385bb Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 12:44:09 +0200 Subject: [PATCH 52/71] package.json: use NodeJS scripts instead of unix commands --- .eslintrc.json | 1 + package.json | 10 +++++----- scripts/clean.js | 10 ++++++++++ scripts/prepare-sources.js | 4 ++++ 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 scripts/clean.js create mode 100644 scripts/prepare-sources.js diff --git a/.eslintrc.json b/.eslintrc.json index cdf57c6..a506e1e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -88,6 +88,7 @@ }, "ignorePatterns": [ "jest.config.js", + "scripts/**/*", "webpack.config.js", "dist/**/*", "public/**/*", diff --git a/package.json b/package.json index f7c65e8..2e8efd7 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ "main": "dist/main.js", "scripts": { "test": "jest --verbose --runInBand", - "clean": "(test ! -d dist || rm -r dist)", - "prepareSources": "cp package.json src/", + "clean": "node scripts/clean.js", + "prepare-sources": "node scripts/prepare-sources.js", "compile": "yarn clean && tsc", - "build": "yarn prepareSources && yarn compile && webpack --mode production", - "dev": "yarn prepareSources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", + "build": "yarn prepare-sources && yarn compile && webpack --mode production", + "dev": "yarn prepare-sources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", "start": "yarn build && node", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx" + "lint": "eslint ." }, "devDependencies": { "@babel/core": "^7.9.0", diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 0000000..d5ef093 --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,10 @@ +const fs = require('fs'); + +[ + 'dist', +].forEach(file => { + if (fs.existsSync(file)) { + console.log('Cleaning', file, '...'); + fs.rmSync(file, {recursive: true}); + } +}); diff --git a/scripts/prepare-sources.js b/scripts/prepare-sources.js new file mode 100644 index 0000000..a78c2f3 --- /dev/null +++ b/scripts/prepare-sources.js @@ -0,0 +1,4 @@ +const fs = require('fs'); +const path = require('path'); + +fs.copyFileSync('package.json', path.join('src', 'package.json')); -- 2.47.0 From faa728aacb3b9472ab0844215fc97560b46a3f48 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 14:27:03 +0200 Subject: [PATCH 53/71] layout.scss: allow .form-field to be hidden with .hidden --- assets/sass/layout.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 66e8363..3d791fd 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -398,7 +398,7 @@ form { padding: 8px 16px; text-align: center; - .form-field { + .form-field:not(.hidden) { display: flex; flex-direction: column; margin: 16px auto; -- 2.47.0 From d223c9c77f1b6e6f3b5da0cf2c6bb518af80ccd6 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 16:56:35 +0200 Subject: [PATCH 54/71] Update config to new swaf version --- config/default.json5 | 86 +++++++++++++++++++++-------------------- config/production.json5 | 26 ++++++------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/config/default.json5 b/config/default.json5 index e0c6b9b..0afc385 100644 --- a/config/default.json5 +++ b/config/default.json5 @@ -1,43 +1,47 @@ { - app: { - name: 'Example App', - contact_email: 'contact@example.net' - }, - log_level: "DEV", - db_log_level: "ERROR", - public_url: "http://localhost:4899", - public_websocket_url: "ws://localhost:4899", - port: 4899, - mysql: { - connectionLimit: 10, - host: "localhost", - user: "root", - password: "", - database: "example_app", - create_database_automatically: false - }, - redis: { - host: "127.0.0.1", - port: 6379, - prefix: 'example_app' - }, - session: { - cookie: { - secure: false - } - }, - mail: { - host: "127.0.0.1", - port: "1025", - secure: false, - username: "", - password: "", - allow_invalid_tls: true, - from: 'contact@example.net', - from_name: 'Example App', - }, - view: { - cache: false - }, - approval_mode: false, + app: { + name: 'Example App', + contact_email: 'contact@example.net', + }, + log_level: "DEV", + db_log_level: "ERROR", + public_url: "http://localhost:4899", + public_websocket_url: "ws://localhost:4899", + port: 4899, + mysql: { + connectionLimit: 10, + host: "localhost", + user: "root", + password: "", + database: "example_app", + create_database_automatically: false, + }, + redis: { + host: "127.0.0.1", + port: 6379, + prefix: 'example_app', + }, + session: { + cookie: { + secure: false, + }, + }, + mail: { + host: "127.0.0.1", + port: "1025", + secure: false, + username: "", + password: "", + allow_invalid_tls: true, + from: 'contact@example.net', + from_name: 'Example App', + }, + view: { + cache: false, + }, + auth: { + approval_mode: false, + // 30 days + name_change_wait_period: 2592000000, + }, } diff --git a/config/production.json5 b/config/production.json5 index 6993e0e..725329b 100644 --- a/config/production.json5 +++ b/config/production.json5 @@ -1,15 +1,15 @@ { - log_level: "DEBUG", - db_log_level: "ERROR", - public_url: "https://watch-my.stream", - public_websocket_url: "wss://watch-my.stream", - session: { - cookie: { - secure: true - } - }, - mail: { - secure: true, - allow_invalid_tls: false - } + log_level: "DEBUG", + db_log_level: "ERROR", + public_url: "https://watch-my.stream", + public_websocket_url: "wss://watch-my.stream", + session: { + cookie: { + secure: true, + }, + }, + mail: { + secure: true, + allow_invalid_tls: false, + }, } -- 2.47.0 From 00bb24cf2e1d54161d206200a3c29a9c667bf619 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 22 Apr 2021 12:30:40 +0200 Subject: [PATCH 55/71] Update repository url --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e8efd7..4557d05 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "example-app", "version": "0.1.0", "description": "Example App based on swaf", - "repository": "https://eternae.ink/arisu/swaf-boilerplate", + "repository": "https://eternae.ink/ashpie/swaf-boilerplate", "author": "Alice Gaudon ", "private": true, "main": "dist/main.js", -- 2.47.0 From 162f88410343f73a21eccdf4343de5ad8512cea0 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 22 Apr 2021 12:34:14 +0200 Subject: [PATCH 56/71] Upgrade dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4557d05..90d80b0 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eslint": "^7.10.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", - "imagemin": "^7.0.1", + "imagemin": "^8.0.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.0", @@ -53,7 +53,7 @@ "sass-loader": "^11.0.1", "terser-webpack-plugin": "^5.0.3", "ts-jest": "^26.1.1", - "ts-loader": "^8.0.4", + "ts-loader": "^9.1.0", "typescript": "^4.0.2", "webpack": "^5.3.2", "webpack-cli": "^4.1.0" -- 2.47.0 From 82439366ba8b3202d57a712fbc0410bb1ad67dd5 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 22 Apr 2021 14:06:53 +0200 Subject: [PATCH 57/71] Fix imagemin peer dependency of img-loader --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90d80b0..8ab5fd2 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eslint": "^7.10.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", - "imagemin": "^8.0.0", + "imagemin": "^7.0.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.0", -- 2.47.0 From 2cb5b6f8f9240030c959a665fe9259273344ce72 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 30 Apr 2021 11:54:50 +0200 Subject: [PATCH 58/71] Replace node-sass with sass --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ab5fd2..228fad8 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,8 @@ "jest": "^26.1.0", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", - "node-sass": "^5.0.0", "nodemon": "^2.0.3", + "sass": "^1.32.12", "sass-loader": "^11.0.1", "terser-webpack-plugin": "^5.0.3", "ts-jest": "^26.1.1", -- 2.47.0 From efbc895ba3a2973f84bd8476e33b2b29916562d0 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 30 Apr 2021 11:55:37 +0200 Subject: [PATCH 59/71] Bump @types/node --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 228fad8..291b48d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@types/formidable": "^1.0.31", "@types/jest": "^26.0.4", "@types/mysql": "^2.15.15", - "@types/node": "^14.6.3", + "@types/node": "^15.0.1", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", "@types/ws": "^7.2.6", -- 2.47.0 From 7e260ebde23ecd7ea0f5164595765a24b526a70e Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 7 Jun 2021 11:21:43 +0200 Subject: [PATCH 60/71] Upgrade dependencies, replace img-loader with image-minimizer-webpack-plugin --- package.json | 12 ++++++------ webpack.config.js | 48 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 291b48d..34cc701 100644 --- a/package.json +++ b/package.json @@ -39,20 +39,20 @@ "eslint": "^7.10.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", - "imagemin": "^7.0.0", + "image-minimizer-webpack-plugin": "^2.2.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", - "imagemin-pngquant": "^9.0.0", + "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^9.0.0", - "img-loader": "^3.0.1", - "jest": "^26.1.0", + "jest": "^27.0.4", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", "nodemon": "^2.0.3", "sass": "^1.32.12", - "sass-loader": "^11.0.1", + "sass-loader": "^12.0.0", + "svgo": "^2.3.0", "terser-webpack-plugin": "^5.0.3", - "ts-jest": "^26.1.1", + "ts-jest": "^27.0.3", "ts-loader": "^9.1.0", "typescript": "^4.0.2", "webpack": "^5.3.2", diff --git a/webpack.config.js b/webpack.config.js index 598acfd..20449a8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,7 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); +const { extendDefaultPlugins } = require("svgo"); const TerserPlugin = require('terser-webpack-plugin'); const dev = process.env.NODE_ENV === 'development'; @@ -62,19 +64,8 @@ const config = { test: /\.(png|jpe?g|gif|svg)$/i, use: [ 'file-loader?name=../img/[name].[ext]', - { - loader: 'img-loader', - options: { - enabled: !dev, - plugins: [ - require('imagemin-gifsicle')({}), - require('imagemin-mozjpeg')({}), - require('imagemin-pngquant')({}), - require('imagemin-svgo')({}), - ] - } - } - ] + ], + type: 'asset', } ], }, @@ -85,6 +76,35 @@ const config = { new MiniCssExtractPlugin({ filename: '../css/[name].css', }), + new ImageMinimizerPlugin({ + minimizerOptions: { + // Lossless optimization with custom option + // Feel free to experiment with options for better result for you + plugins: [ + ["gifsicle", {}], + ["mozjpeg", {}], + ["pngquant", {}], + // Svgo configuration here https://github.com/svg/svgo#configuration + [ + "svgo", + { + plugins: extendDefaultPlugins([ + { + name: "removeViewBox", + active: false, + }, + { + name: "addAttributesToSVGElement", + params: { + attributes: [{ xmlns: "http://www.w3.org/2000/svg" }], + }, + }, + ]), + }, + ], + ], + }, + }), ] }; @@ -97,4 +117,4 @@ if (!dev) { }; } -module.exports = config; \ No newline at end of file +module.exports = config; -- 2.47.0 From 938e8b4ebb1178f81dfea5b4ce2f9702863dcb1d Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 7 Jun 2021 11:24:52 +0200 Subject: [PATCH 61/71] Add imagemin-webp --- package.json | 1 + webpack.config.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 34cc701..b283146 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^9.0.0", + "imagemin-webp": "^6.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", diff --git a/webpack.config.js b/webpack.config.js index 20449a8..b624595 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,7 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); -const { extendDefaultPlugins } = require("svgo"); +const {extendDefaultPlugins} = require("svgo"); const TerserPlugin = require('terser-webpack-plugin'); const dev = process.env.NODE_ENV === 'development'; @@ -84,6 +84,7 @@ const config = { ["gifsicle", {}], ["mozjpeg", {}], ["pngquant", {}], + ["webp", {quality: 90}], // Svgo configuration here https://github.com/svg/svgo#configuration [ "svgo", @@ -96,7 +97,7 @@ const config = { { name: "addAttributesToSVGElement", params: { - attributes: [{ xmlns: "http://www.w3.org/2000/svg" }], + attributes: [{xmlns: "http://www.w3.org/2000/svg"}], }, }, ]), -- 2.47.0 From 569a50e43a9af7907b96f848e7350b7afe2f9e3e Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 20 Nov 2021 19:54:59 +0100 Subject: [PATCH 62/71] Upgrade swaf and dependencies --- .gitignore | 3 + assets/config.json | 10 -- assets/ts/font-awesome.ts | 4 - package.json | 40 +++--- scripts/_functions.js | 22 ++++ scripts/clean.js | 2 + scripts/dist.js | 22 ++++ scripts/prepare-sources.js | 26 +++- src/App.ts | 34 +++-- {assets => src/assets}/img/logo.svg | 0 {assets => src/assets}/img/logox1024.png | Bin {assets => src/assets}/img/logox128.png | Bin src/assets/package.json | 3 + {assets => src/assets}/sass/_fonts.scss | 0 {assets => src/assets}/sass/_vars.scss | 0 {assets => src/assets}/sass/app.scss | 0 {assets => src/assets}/sass/error.scss | 0 {assets => src/assets}/sass/layout.scss | 100 --------------- .../assets}/sass/responsivity_tools.scss | 0 .../assets}/ts/PersistentWebSocket.ts | 0 {assets => src/assets}/ts/app.ts | 0 {assets => src/assets}/ts/copyable_text.ts | 0 {assets => src/assets}/ts/external_links.ts | 0 src/assets/ts/font-awesome.ts | 4 + {assets => src/assets}/ts/forms.ts | 0 {assets => src/assets}/ts/main_menu.ts | 0 {assets => src/assets}/ts/message_icons.ts | 0 .../assets}/ts/tooltips-and-dropdowns.ts | 0 src/assets/ts/tsconfig.eslint.json | 6 + src/assets/ts/tsconfig.json | 27 ++++ {views => src/assets/views}/about.njk | 0 {views => src/assets/views}/home.njk | 0 {views => src/assets/views}/layouts/base.njk | 0 src/assets/views/tsconfig.json | 15 +++ src/common/dummy.ts | 1 + src/common/package.json | 3 + src/common/tsconfig.json | 20 +++ src/controllers/HomeController.ts | 3 +- src/main.ts | 9 +- src/tsconfig.json | 30 +++++ {public => src/types}/.gitkeep | 0 tsconfig.frontend.json | 19 --- tsconfig.json | 47 +++++-- tsconfig.test.json | 2 +- webpack.config.js | 121 ------------------ 45 files changed, 276 insertions(+), 297 deletions(-) delete mode 100644 assets/config.json delete mode 100644 assets/ts/font-awesome.ts create mode 100644 scripts/_functions.js create mode 100644 scripts/dist.js rename {assets => src/assets}/img/logo.svg (100%) rename {assets => src/assets}/img/logox1024.png (100%) rename {assets => src/assets}/img/logox128.png (100%) create mode 100644 src/assets/package.json rename {assets => src/assets}/sass/_fonts.scss (100%) rename {assets => src/assets}/sass/_vars.scss (100%) rename {assets => src/assets}/sass/app.scss (100%) rename {assets => src/assets}/sass/error.scss (100%) rename {assets => src/assets}/sass/layout.scss (89%) rename {assets => src/assets}/sass/responsivity_tools.scss (100%) rename {assets => src/assets}/ts/PersistentWebSocket.ts (100%) rename {assets => src/assets}/ts/app.ts (100%) rename {assets => src/assets}/ts/copyable_text.ts (100%) rename {assets => src/assets}/ts/external_links.ts (100%) create mode 100644 src/assets/ts/font-awesome.ts rename {assets => src/assets}/ts/forms.ts (100%) rename {assets => src/assets}/ts/main_menu.ts (100%) rename {assets => src/assets}/ts/message_icons.ts (100%) rename {assets => src/assets}/ts/tooltips-and-dropdowns.ts (100%) create mode 100644 src/assets/ts/tsconfig.eslint.json create mode 100644 src/assets/ts/tsconfig.json rename {views => src/assets/views}/about.njk (100%) rename {views => src/assets/views}/home.njk (100%) rename {views => src/assets/views}/layouts/base.njk (100%) create mode 100644 src/assets/views/tsconfig.json create mode 100644 src/common/dummy.ts create mode 100644 src/common/package.json create mode 100644 src/common/tsconfig.json create mode 100644 src/tsconfig.json rename {public => src/types}/.gitkeep (100%) delete mode 100644 tsconfig.frontend.json delete mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index 570ee35..873a5d8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ dist yarn-error.log src/package.json + +intermediates/ +dist/ \ No newline at end of file diff --git a/assets/config.json b/assets/config.json deleted file mode 100644 index 6bcf54c..0000000 --- a/assets/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "bundles": { - "app": "ts/app.ts", - "layout": "sass/layout.scss", - "error": "sass/error.scss", - "logo": "img/logo.svg", - "logo_png": "img/logox128.png", - "logo_png_xxl": "img/logox1024.png" - } -} \ No newline at end of file diff --git a/assets/ts/font-awesome.ts b/assets/ts/font-awesome.ts deleted file mode 100644 index 5ce65ff..0000000 --- a/assets/ts/font-awesome.ts +++ /dev/null @@ -1,4 +0,0 @@ -import '../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss'; -import '../../node_modules/@fortawesome/fontawesome-free/scss/regular.scss'; -import '../../node_modules/@fortawesome/fontawesome-free/scss/solid.scss'; -import '../../node_modules/@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/package.json b/package.json index b283146..b74ecdc 100644 --- a/package.json +++ b/package.json @@ -10,47 +10,53 @@ "test": "jest --verbose --runInBand", "clean": "node scripts/clean.js", "prepare-sources": "node scripts/prepare-sources.js", - "compile": "yarn clean && tsc", - "build": "yarn prepare-sources && yarn compile && webpack --mode production", - "dev": "yarn prepare-sources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", - "start": "yarn build && node", - "lint": "eslint ." + "compile": "yarn clean && yarn prepare-sources && tsc --build", + "build": "yarn compile && node . pre-compile-views && node scripts/dist.js", + "build-production": "NODE_ENV=production yarn build", + "dev": "yarn compile && concurrently -k -n \"Maildev,Typescript,ViewPreCompile,Node\" -p \"[{name}]\" -c \"yellow,blue,red,green\" \"maildev\" \"tsc --build --watch --preserveWatchOutput\" \"nodemon -i public -i intermediates -- pre-compile-views --watch\" \"nodemon -i public -i intermediates\"", + "lint": "eslint .", + "start": "yarn build-production && node ." }, "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", "@fortawesome/fontawesome-free": "^5.14.0", - "@types/config": "^0.0.38", + "@tsconfig/svelte": "^2.0.1", + "@types/config": "^0.0.40", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", "@types/feather-icons": "^4.7.0", - "@types/formidable": "^1.0.31", - "@types/jest": "^26.0.4", + "@types/formidable": "^2.0.0", + "@types/jest": "^27.0.3", "@types/mysql": "^2.15.15", - "@types/node": "^15.0.1", + "@types/node": "^16.11.9", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", - "@types/ws": "^7.2.6", - "@typescript-eslint/eslint-plugin": "^4.3.0", - "@typescript-eslint/parser": "^4.3.0", + "@types/ws": "^8.2.0", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", "babel-loader": "^8.1.0", + "clear-module": "^4.1.2", "concurrently": "^6.0.0", - "css-loader": "^5.0.0", - "eslint": "^7.10.0", + "css-loader": "^6.5.1", + "eslint": "^8.2.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", "image-minimizer-webpack-plugin": "^2.2.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", - "imagemin-svgo": "^9.0.0", + "imagemin-svgo": "^10.0.0", "imagemin-webp": "^6.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", - "mini-css-extract-plugin": "^1.2.1", + "mini-css-extract-plugin": "^2.4.5", "nodemon": "^2.0.3", + "normalize.css": "^8.0.1", "sass": "^1.32.12", "sass-loader": "^12.0.0", + "svelte": "^3.44.2", + "svelte-preprocess": "^4.9.8", "svgo": "^2.3.0", "terser-webpack-plugin": "^5.0.3", "ts-jest": "^27.0.3", @@ -62,6 +68,6 @@ "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "swaf": "^0.23.0" + "swaf": "^0.24.4" } } diff --git a/scripts/_functions.js b/scripts/_functions.js new file mode 100644 index 0000000..0fea1c4 --- /dev/null +++ b/scripts/_functions.js @@ -0,0 +1,22 @@ +const fs = require('fs'); +const path = require('path'); + +function copyRecursively(file, destination) { + const target = path.join(destination, path.basename(file)); + if (fs.statSync(file).isDirectory()) { + console.log('mkdir', target); + + fs.mkdirSync(target, {recursive: true}); + fs.readdirSync(file).forEach(f => { + copyRecursively(path.join(file, f), target); + }); + } else { + console.log('> cp ', target); + + fs.copyFileSync(file, target); + } +} + +module.exports = { + copyRecursively, +}; \ No newline at end of file diff --git a/scripts/clean.js b/scripts/clean.js index d5ef093..32ebb24 100644 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -1,7 +1,9 @@ const fs = require('fs'); [ + 'intermediates', 'dist', + 'public', ].forEach(file => { if (fs.existsSync(file)) { console.log('Cleaning', file, '...'); diff --git a/scripts/dist.js b/scripts/dist.js new file mode 100644 index 0000000..a0ead2a --- /dev/null +++ b/scripts/dist.js @@ -0,0 +1,22 @@ +const fs = require('fs'); +const path = require('path'); +const {copyRecursively} = require('./_functions.js'); + + +[ + 'yarn.lock', + 'README.md', + 'config/', +].forEach(file => { + copyRecursively(file, 'dist'); +}); + +fs.mkdirSync('dist/types', {recursive: true}); + +fs.readdirSync('src/types').forEach(file => { + copyRecursively(path.join('src/types', file), 'dist/types'); +}); + +fs.readdirSync('src/assets').forEach(file => { + copyRecursively(path.join('src/assets', file), 'dist/assets'); +}); diff --git a/scripts/prepare-sources.js b/scripts/prepare-sources.js index a78c2f3..c8ee7b9 100644 --- a/scripts/prepare-sources.js +++ b/scripts/prepare-sources.js @@ -1,4 +1,28 @@ const fs = require('fs'); const path = require('path'); -fs.copyFileSync('package.json', path.join('src', 'package.json')); +// These folders must exist for nodemon not to loop indefinitely. +[ + 'public', + 'dist', + 'intermediates', + 'intermediates/assets', +].forEach(dir => { + if (!fs.existsSync(dir)) fs.mkdirSync(dir); +}); + +// Symlink to build/common +const commonLocalSymlink = path.resolve('intermediates/common-local'); +if (!fs.existsSync(commonLocalSymlink)) { + const target = path.resolve('dist/common-local'); + fs.symlinkSync(target, commonLocalSymlink); +} + +const commonSymlink = path.resolve('intermediates/common'); +if (!fs.existsSync(commonSymlink)) { + const target = path.resolve('node_modules/swaf/common'); + fs.symlinkSync(target, commonSymlink); +} + +// Copy package.json +fs.copyFileSync('package.json', 'dist/package.json'); diff --git a/src/App.ts b/src/App.ts index 6272da0..768d322 100644 --- a/src/App.ts +++ b/src/App.ts @@ -2,7 +2,6 @@ import Application from "swaf/Application"; import Migration, {MigrationType} from "swaf/db/Migration"; import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; import ExpressAppComponent from "swaf/components/ExpressAppComponent"; -import NunjucksComponent from "swaf/components/NunjucksComponent"; import MysqlComponent from "swaf/components/MysqlComponent"; import LogRequestsComponent from "swaf/components/LogRequestsComponent"; import RedisComponent from "swaf/components/RedisComponent"; @@ -18,14 +17,22 @@ import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; import DummyMigration from "swaf/migrations/DummyMigration"; import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; -import packageJson = require('./package.json'); +import MailViewEngine from "swaf/frontend/MailViewEngine"; +import AssetCompiler from "swaf/frontend/AssetCompiler"; +import FrontendToolsComponent from "swaf/components/FrontendToolsComponent"; +import CopyAssetPreCompiler from "swaf/frontend/CopyAssetPreCompiler"; +import ScssAssetPreCompiler from "swaf/frontend/ScssAssetPreCompiler"; +import TypeScriptPreCompiler from "swaf/frontend/TypeScriptPreCompiler"; +import SvelteViewEngine from "swaf/frontend/SvelteViewEngine"; +import NunjucksViewEngine from "swaf/frontend/NunjucksViewEngine"; export default class App extends Application { public constructor( + version: string, private readonly addr: string, private readonly port: number, ) { - super(packageJson.version); + super(version); } protected getMigrations(): MigrationType[] { @@ -52,18 +59,27 @@ export default class App extends Application { this.use(new ServeStaticDirectoryComponent('node_modules/feather-icons/dist', '/icons')); // Dynamic views and routes - this.use(new NunjucksComponent()); + const intermediateDirectory = 'intermediates/assets'; + const assetCompiler = new AssetCompiler(intermediateDirectory, 'public'); + const additionalViewPaths = ['test/assets']; + this.use(new FrontendToolsComponent( + assetCompiler, + new CopyAssetPreCompiler(intermediateDirectory, '', 'json', additionalViewPaths, false), + new ScssAssetPreCompiler(intermediateDirectory, assetCompiler.targetDir, 'scss', additionalViewPaths), + new CopyAssetPreCompiler(intermediateDirectory, 'img', 'svg', additionalViewPaths, true), + new TypeScriptPreCompiler(intermediateDirectory, additionalViewPaths), + new SvelteViewEngine(intermediateDirectory, ...additionalViewPaths), + new NunjucksViewEngine(intermediateDirectory, ...additionalViewPaths), + )); this.use(new PreviousUrlComponent()); // Maintenance - this.use(new MaintenanceComponent(this, () => { - return this.as(RedisComponent).canServe() && this.as(MysqlComponent).canServe(); - })); + this.use(new MaintenanceComponent()); this.use(new AutoUpdateComponent()); // Services this.use(new MysqlComponent()); - this.use(new MailComponent()); + this.use(new MailComponent(new MailViewEngine(intermediateDirectory, ...additionalViewPaths))); // Session this.use(new RedisComponent()); @@ -76,7 +92,7 @@ export default class App extends Application { this.use(new CsrfProtectionComponent()); // WebSocket server - this.use(new WebSocketServerComponent(this, this.as(ExpressAppComponent), this.as(RedisComponent))); + this.use(new WebSocketServerComponent()); } private registerWebSocketListeners() { diff --git a/assets/img/logo.svg b/src/assets/img/logo.svg similarity index 100% rename from assets/img/logo.svg rename to src/assets/img/logo.svg diff --git a/assets/img/logox1024.png b/src/assets/img/logox1024.png similarity index 100% rename from assets/img/logox1024.png rename to src/assets/img/logox1024.png diff --git a/assets/img/logox128.png b/src/assets/img/logox128.png similarity index 100% rename from assets/img/logox128.png rename to src/assets/img/logox128.png diff --git a/src/assets/package.json b/src/assets/package.json new file mode 100644 index 0000000..1cd945a --- /dev/null +++ b/src/assets/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/assets/sass/_fonts.scss b/src/assets/sass/_fonts.scss similarity index 100% rename from assets/sass/_fonts.scss rename to src/assets/sass/_fonts.scss diff --git a/assets/sass/_vars.scss b/src/assets/sass/_vars.scss similarity index 100% rename from assets/sass/_vars.scss rename to src/assets/sass/_vars.scss diff --git a/assets/sass/app.scss b/src/assets/sass/app.scss similarity index 100% rename from assets/sass/app.scss rename to src/assets/sass/app.scss diff --git a/assets/sass/error.scss b/src/assets/sass/error.scss similarity index 100% rename from assets/sass/error.scss rename to src/assets/sass/error.scss diff --git a/assets/sass/layout.scss b/src/assets/sass/layout.scss similarity index 89% rename from assets/sass/layout.scss rename to src/assets/sass/layout.scss index 3d791fd..cf1f7c1 100644 --- a/assets/sass/layout.scss +++ b/src/assets/sass/layout.scss @@ -682,33 +682,6 @@ td.actions { } } -.data-table { - width: 100%; - text-align: left; - border-collapse: collapse; - - th, td { - padding: 8px; - } - - th { - border-bottom: 1px solid #39434a; - white-space: nowrap; - } - - tr:nth-child(even) { - background-color: rgba(255, 255, 255, 0.03); - } - - tr:hover { - background-color: rgba(255, 255, 255, 0.09); - } - - thead tr:hover { - background-color: transparent; - } -} - // --- // --- Breadcrumb widget @@ -766,82 +739,9 @@ td.actions { } -// --- -// --- Feather -// --- -.feather { - display: inline-flex; - justify-content: center; - align-items: center; - - flex-shrink: 0; - width: var(--icon-size); - height: var(--icon-size); - - --icon-size: 16px; - font-size: var(--icon-size); - stroke: currentColor; - stroke-width: 2; - stroke-linecap: square; - stroke-linejoin: miter; - fill: none; - vertical-align: middle; - - h1 > &, h2 > &, h3 > & { - --icon-size: 24px; - } -} - // --- // --- Helper classes // --- -.message { - display: flex; - flex-direction: row; - align-items: center; - - padding: 8px 16px; - - border-radius: 5px; - - .feather { - --icon-size: 24px; - margin-right: 8px; - } - - &:not(&-discreet) { - background-color: rgba(255, 255, 255, 0.33); - - &[data-type=info], &[data-type=question] { - background-color: $infoColor; - } - - &[data-type=success] { - background-color: $successColor; - } - - &[data-type=warning] { - background-color: $warningColor; - } - - &[data-type=error] { - background-color: $errorColor; - } - } - - &-discreet { - color: mix($panelBackground, #fff, 35%); - - .feather { - --icon-size: 20px; - } - } -} - -.messages .message:not(:last-child) { - margin-bottom: 8px; -} - .container > .messages:first-child { margin-top: 16px; } diff --git a/assets/sass/responsivity_tools.scss b/src/assets/sass/responsivity_tools.scss similarity index 100% rename from assets/sass/responsivity_tools.scss rename to src/assets/sass/responsivity_tools.scss diff --git a/assets/ts/PersistentWebSocket.ts b/src/assets/ts/PersistentWebSocket.ts similarity index 100% rename from assets/ts/PersistentWebSocket.ts rename to src/assets/ts/PersistentWebSocket.ts diff --git a/assets/ts/app.ts b/src/assets/ts/app.ts similarity index 100% rename from assets/ts/app.ts rename to src/assets/ts/app.ts diff --git a/assets/ts/copyable_text.ts b/src/assets/ts/copyable_text.ts similarity index 100% rename from assets/ts/copyable_text.ts rename to src/assets/ts/copyable_text.ts diff --git a/assets/ts/external_links.ts b/src/assets/ts/external_links.ts similarity index 100% rename from assets/ts/external_links.ts rename to src/assets/ts/external_links.ts diff --git a/src/assets/ts/font-awesome.ts b/src/assets/ts/font-awesome.ts new file mode 100644 index 0000000..0409cfe --- /dev/null +++ b/src/assets/ts/font-awesome.ts @@ -0,0 +1,4 @@ +import '@fortawesome/fontawesome-free/scss/fontawesome.scss'; +import '@fortawesome/fontawesome-free/scss/regular.scss'; +import '@fortawesome/fontawesome-free/scss/solid.scss'; +import '@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/assets/ts/forms.ts b/src/assets/ts/forms.ts similarity index 100% rename from assets/ts/forms.ts rename to src/assets/ts/forms.ts diff --git a/assets/ts/main_menu.ts b/src/assets/ts/main_menu.ts similarity index 100% rename from assets/ts/main_menu.ts rename to src/assets/ts/main_menu.ts diff --git a/assets/ts/message_icons.ts b/src/assets/ts/message_icons.ts similarity index 100% rename from assets/ts/message_icons.ts rename to src/assets/ts/message_icons.ts diff --git a/assets/ts/tooltips-and-dropdowns.ts b/src/assets/ts/tooltips-and-dropdowns.ts similarity index 100% rename from assets/ts/tooltips-and-dropdowns.ts rename to src/assets/ts/tooltips-and-dropdowns.ts diff --git a/src/assets/ts/tsconfig.eslint.json b/src/assets/ts/tsconfig.eslint.json new file mode 100644 index 0000000..a12ab8a --- /dev/null +++ b/src/assets/ts/tsconfig.eslint.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "./**/*" + ] +} diff --git a/src/assets/ts/tsconfig.json b/src/assets/ts/tsconfig.json new file mode 100644 index 0000000..a9dfc8d --- /dev/null +++ b/src/assets/ts/tsconfig.json @@ -0,0 +1,27 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "module": "CommonJS", + "baseUrl": "../../../intermediates/assets", + "rootDir": "../../../intermediates/assets/ts-source", + "sourceRoot": "../../../intermediates/assets/ts-source", + "outDir": "../../../intermediates/assets/ts", + "declaration": false, + + "typeRoots": [], + "resolveJsonModule": false, + "lib": [ + "es2020", + "DOM" + ] + }, + "include": [ + "../../../intermediates/assets/ts-source/**/*" + ], + "references": [ + { + "path": "../../common" + } + ] +} diff --git a/views/about.njk b/src/assets/views/about.njk similarity index 100% rename from views/about.njk rename to src/assets/views/about.njk diff --git a/views/home.njk b/src/assets/views/home.njk similarity index 100% rename from views/home.njk rename to src/assets/views/home.njk diff --git a/views/layouts/base.njk b/src/assets/views/layouts/base.njk similarity index 100% rename from views/layouts/base.njk rename to src/assets/views/layouts/base.njk diff --git a/src/assets/views/tsconfig.json b/src/assets/views/tsconfig.json new file mode 100644 index 0000000..bc808e8 --- /dev/null +++ b/src/assets/views/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "outDir": "public/js", + "rootDir": "../../../intermediates/assets", + }, + "include": [ + "src/assets/ts/**/*" + ], + "references": [ + { + "path": "../../common" + } + ] +} diff --git a/src/common/dummy.ts b/src/common/dummy.ts new file mode 100644 index 0000000..c58f5a5 --- /dev/null +++ b/src/common/dummy.ts @@ -0,0 +1 @@ +console.log('common code between back and front'); \ No newline at end of file diff --git a/src/common/package.json b/src/common/package.json new file mode 100644 index 0000000..1cd945a --- /dev/null +++ b/src/common/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/src/common/tsconfig.json b/src/common/tsconfig.json new file mode 100644 index 0000000..60705a9 --- /dev/null +++ b/src/common/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + + "module": "CommonJS", + + "baseUrl": "../../dist/common-local", + "rootDir": "./", + "sourceRoot": "./", + "outDir": "../../dist/common-local", + + "typeRoots": [ + "src/types" + ], + }, + "include": [ + "./**/*" + ] +} diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index b5e1740..027d83d 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -1,5 +1,6 @@ import Controller from "swaf/Controller"; import {Request, Response} from "express"; +import {route} from "swaf/common/Routing"; export default class HomeController extends Controller { public routes(): void { @@ -20,6 +21,6 @@ export default class HomeController extends Controller { * This is to test and assert that swaf extended types are available */ protected async goBack(req: Request, res: Response): Promise { - res.redirect(req.getPreviousUrl() || Controller.route('home')); + res.redirect(req.getPreviousUrl() || route('home')); } } diff --git a/src/main.ts b/src/main.ts index babc7df..ff2f443 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,11 +9,18 @@ process.env['NODE_CONFIG_DIR'] = import {logger} from "swaf/Logger"; import App from "./App"; import config from "config"; +import {promises as fs} from "fs"; (async () => { logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); - const app = new App(config.get('listen_addr'), config.get('port')); + const packageJson = JSON.parse((await fs.readFile('package.json')).toString()); + + const app = new App( + packageJson.version, + config.get('app.listen_addr'), + config.get('app.port'), + ); await app.start(); })().catch(err => { logger.error(err); diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..890991d --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "composite": true, + + "module": "CommonJS", + + "baseUrl": "../dist", + "rootDir": "./", + "sourceRoot": "./", + "outDir": "../dist", + + "typeRoots": [ + "src/types" + ] + }, + "include": [ + "./**/*", + "../node_modules/swaf/types" + ], + "exclude": [ + "./assets/**/*", + "./common/**/*" + ], + "references": [ + { + "path": "./common" + } + ] +} diff --git a/public/.gitkeep b/src/types/.gitkeep similarity index 100% rename from public/.gitkeep rename to src/types/.gitkeep diff --git a/tsconfig.frontend.json b/tsconfig.frontend.json deleted file mode 100644 index ad74720..0000000 --- a/tsconfig.frontend.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "public/js", - "rootDir": "./assets", - "target": "ES6", - "strict": true, - "lib": [ - "es2020", - "DOM" - ], - "typeRoots": [ - "./node_modules/@types" - ] - }, - "include": [ - "assets/ts/**/*" - ] -} diff --git a/tsconfig.json b/tsconfig.json index 12eec0a..6a82f14 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,43 @@ { "compilerOptions": { - "module": "CommonJS", - "esModuleInterop": true, - "outDir": "dist", - "rootDir": "./src", - "target": "ES6", + "target": "ESNext", + "module": "ESNext", + "declaration": true, + "stripInternal": true, + "strict": true, + "allowSyntheticDefaultImports": true, + "strictNullChecks": true, + + "moduleResolution": "Node", + "esModuleInterop": true, + "baseUrl": "dist", + "inlineSourceMap": true, + "inlineSources": true, + "outDir": "dist", + + "typeRoots": [ + "node_modules/@types", + "src/types" + ], "lib": [ "es2020", - "DOM" + "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], - "resolveJsonModule": true + "resolveJsonModule": true, + "skipLibCheck": true, + "allowJs": true }, - "include": [ - "src/**/*", - "node_modules/swaf/types" + "include": [], + "references": [ + { + "path": "src", + }, + { + "path": "src/assets/ts", + }, + { + "path": "src/assets/views", + } ] } diff --git a/tsconfig.test.json b/tsconfig.test.json index 897a6b4..fce2399 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -11,4 +11,4 @@ "src/types/**/*", "test/**/*" ] -} \ No newline at end of file +} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index b624595..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,121 +0,0 @@ -const path = require('path'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); -const {extendDefaultPlugins} = require("svgo"); -const TerserPlugin = require('terser-webpack-plugin'); - -const dev = process.env.NODE_ENV === 'development'; - -const userConfig = require('./assets/config.json'); -for (const b in userConfig.bundles) { - if (userConfig.bundles.hasOwnProperty(b)) { - userConfig.bundles[b] = `./assets/${userConfig.bundles[b]}`; - } -} - -const config = { - entry: userConfig.bundles, - output: { - path: path.resolve(__dirname, 'public/js'), - filename: '[name].js' - }, - devtool: dev ? 'eval-source-map' : undefined, - module: { - rules: [ - { - test: /\.js$/i, - use: [ - { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env'], - } - } - ] - }, - { - test: /\.s[ac]ss$/i, - use: [ - { - loader: MiniCssExtractPlugin.loader, - options: { - publicPath: '/', - } - }, - 'css-loader', - 'sass-loader', - ] - }, - { - test: /\.(woff2?|eot|ttf|otf)$/i, - use: 'file-loader?name=../fonts/[name].[ext]', - }, - { - test: /\.tsx?$/i, - use: { - loader: 'ts-loader', - options: { - configFile: 'tsconfig.frontend.json', - } - }, - exclude: '/node_modules/' - }, - { - test: /\.(png|jpe?g|gif|svg)$/i, - use: [ - 'file-loader?name=../img/[name].[ext]', - ], - type: 'asset', - } - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: '../css/[name].css', - }), - new ImageMinimizerPlugin({ - minimizerOptions: { - // Lossless optimization with custom option - // Feel free to experiment with options for better result for you - plugins: [ - ["gifsicle", {}], - ["mozjpeg", {}], - ["pngquant", {}], - ["webp", {quality: 90}], - // Svgo configuration here https://github.com/svg/svgo#configuration - [ - "svgo", - { - plugins: extendDefaultPlugins([ - { - name: "removeViewBox", - active: false, - }, - { - name: "addAttributesToSVGElement", - params: { - attributes: [{xmlns: "http://www.w3.org/2000/svg"}], - }, - }, - ]), - }, - ], - ], - }, - }), - ] -}; - -if (!dev) { - config.optimization = { - minimize: true, - minimizer: [ - new TerserPlugin(), - ] - }; -} - -module.exports = config; -- 2.47.0 From 257a407faf0d6cb9b4def3651f32817d7ea040db Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 20 Nov 2021 22:26:22 +0100 Subject: [PATCH 63/71] Remove unused old assets --- package.json | 1 - src/assets/sass/.gitkeep | 0 src/assets/sass/_fonts.scss | 81 --- src/assets/sass/_vars.scss | 33 - src/assets/sass/app.scss | 1 - src/assets/sass/error.scss | 90 --- src/assets/sass/layout.scss | 843 ------------------------ src/assets/sass/responsivity_tools.scss | 19 - src/assets/ts/PersistentWebSocket.ts | 39 -- src/assets/ts/app.ts | 10 - src/assets/ts/copyable_text.ts | 15 - src/assets/ts/external_links.ts | 11 - src/assets/ts/font-awesome.ts | 4 - src/assets/ts/forms.ts | 43 -- src/assets/ts/main_menu.ts | 21 - src/assets/ts/message_icons.ts | 26 - src/assets/ts/tooltips-and-dropdowns.ts | 31 - src/assets/views/about.njk | 14 - src/assets/views/home.njk | 7 - src/assets/views/layouts/base.njk | 41 -- 20 files changed, 1330 deletions(-) create mode 100644 src/assets/sass/.gitkeep delete mode 100644 src/assets/sass/_fonts.scss delete mode 100644 src/assets/sass/_vars.scss delete mode 100644 src/assets/sass/app.scss delete mode 100644 src/assets/sass/error.scss delete mode 100644 src/assets/sass/layout.scss delete mode 100644 src/assets/sass/responsivity_tools.scss delete mode 100644 src/assets/ts/PersistentWebSocket.ts delete mode 100644 src/assets/ts/app.ts delete mode 100644 src/assets/ts/copyable_text.ts delete mode 100644 src/assets/ts/external_links.ts delete mode 100644 src/assets/ts/font-awesome.ts delete mode 100644 src/assets/ts/forms.ts delete mode 100644 src/assets/ts/main_menu.ts delete mode 100644 src/assets/ts/message_icons.ts delete mode 100644 src/assets/ts/tooltips-and-dropdowns.ts delete mode 100644 src/assets/views/about.njk delete mode 100644 src/assets/views/home.njk delete mode 100644 src/assets/views/layouts/base.njk diff --git a/package.json b/package.json index b74ecdc..b83dc74 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", - "@fortawesome/fontawesome-free": "^5.14.0", "@tsconfig/svelte": "^2.0.1", "@types/config": "^0.0.40", "@types/express": "^4.17.6", diff --git a/src/assets/sass/.gitkeep b/src/assets/sass/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/sass/_fonts.scss b/src/assets/sass/_fonts.scss deleted file mode 100644 index 6c26b55..0000000 --- a/src/assets/sass/_fonts.scss +++ /dev/null @@ -1,81 +0,0 @@ -/* vietnamese */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5iU1EQVg.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5jU1EQVg.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5tU1E.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* vietnamese */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8cceyI9tScg.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8ccezI9tScg.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8cce9I9s.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* vietnamese */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5iU1EQVg.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5jU1EQVg.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5tU1E.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} diff --git a/src/assets/sass/_vars.scss b/src/assets/sass/_vars.scss deleted file mode 100644 index 478fca3..0000000 --- a/src/assets/sass/_vars.scss +++ /dev/null @@ -1,33 +0,0 @@ -$primary: darken(#242b33, 2%); -$primaryForeground: #f0f0f0; -$secondary: lighten(#00766c, 10%); -$secondaryForeground: $primaryForeground; - -$backgroundColor: darken($primary, 4%); -$defaultTextColor: #ffffff; - -$headerBackground: transparent; -$headerContainer: true; -$footerBackground: transparent; -$panelBackground: darken($backgroundColor, 3.2%); -$inputBackground: darken($panelBackground, 4%); - -$info: #4499ff; -$infoText: darken($info, 42%); -$infoColor: desaturate($infoText, 50%); - -$success: #55ff55; -$successText: darken($success, 45%); -$successColor: desaturate($successText, 50%); - -$warning: #ffcc00; -$warningText: darken($warning, 30%); -$warningColor: desaturate($warningText, 50%); - -$error: #ff0000; -$errorText: darken($error, 30%); -$errorColor: desaturate($errorText, 50%); - -// Responsivity -$mobileThreshold: 632px; -$desktopThreshold: 940px; diff --git a/src/assets/sass/app.scss b/src/assets/sass/app.scss deleted file mode 100644 index 933fea1..0000000 --- a/src/assets/sass/app.scss +++ /dev/null @@ -1 +0,0 @@ -@import "layout"; \ No newline at end of file diff --git a/src/assets/sass/error.scss b/src/assets/sass/error.scss deleted file mode 100644 index d36ad0b..0000000 --- a/src/assets/sass/error.scss +++ /dev/null @@ -1,90 +0,0 @@ -@import "layout"; - -header, footer { - margin: 0; - padding: 0; - height: 0; -} - -main { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - .messages { - margin-bottom: 32px; - } - - .error-code { - font-size: 36px; - } - - .error-message { - font-size: 32px; - } - - .error-instructions { - margin-top: 32px; - font-size: 20px; - } - - nav { - margin-top: 32px; - } - - &::before { - content: "Oops"; - position: absolute; - z-index: -1; - - font-size: #{'min(50vh, 40vw)'}; - opacity: 0.025; - } -} - -.contact { - text-align: center; - padding: 8px; -} - -.logo { - position: absolute; - top: 0; - left: 0; - width: 100%; - margin-top: 24px; - text-align: center; - - a { - position: relative; - padding: 16px; - - color: $defaultTextColor; - - &:hover { - color: #fff; - - &::before { - opacity: 0.2; - } - } - - &::before { - content: ""; - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - - background-image: url(../img/logo.svg); - background-repeat: no-repeat; - background-position: center; - background-size: 64px; - - opacity: 0.075; - filter: contrast(0); - } - } -} \ No newline at end of file diff --git a/src/assets/sass/layout.scss b/src/assets/sass/layout.scss deleted file mode 100644 index cf1f7c1..0000000 --- a/src/assets/sass/layout.scss +++ /dev/null @@ -1,843 +0,0 @@ -@import "vars"; -@import 'fonts'; -@import "responsivity_tools"; - -* { - box-sizing: border-box; -} - -html, body { - height: 100%; -} - -body { - display: flex; - flex-direction: column; - - margin: 0; - font-family: "Nunito Sans", sans-serif; - font-size: 16px; - - color: $defaultTextColor; - background-color: $backgroundColor; -} - -@mixin tip { - position: relative; - - .tip { - visibility: hidden; - position: absolute; - z-index: 10000; - pointer-events: none; - display: block; - width: max-content; - height: 30px; - padding: 4px 8px; - line-height: 22px; - top: calc(100% + 8px); - left: 50%; - transform: translateX(-50%); - - text-align: center; - font-size: 18px; - color: $defaultTextColor; - opacity: 0; - transition: opacity ease-out 100ms, visibility step-end 150ms; - transition-delay: 0ms; - background-color: #000; - border-radius: 5px; - - text-transform: initial; - font-weight: initial; - - &.top { - top: auto; - bottom: calc(100% + 8px); - } - } - - &:hover, &:active { - .tip { - visibility: visible; - opacity: 1; - transition: opacity ease-out 100ms; - transition-delay: 150ms; - } - } -} - -body > header { - z-index: 50; - display: flex; - flex-direction: row-reverse; - justify-content: space-between; - align-items: center; - - $headerHeight: 64px; - height: $headerHeight; - line-height: $headerHeight; - - background: $headerBackground; - - @if $headerContainer { - @include container; - } - - @media (max-width: $mobileThreshold) { - padding: 0; - } - - .logo { - display: flex; - flex-direction: row; - align-items: center; - - padding: 0 16px 0 8px; - font-size: 24px; - color: $defaultTextColor; - - &:hover { - color: lighten($defaultTextColor, 10%); - } - - img { - width: initial; - height: calc(#{$headerHeight} - 16px); - margin-right: 8px; - flex-shrink: 0; - } - } - - nav { - > ul { - position: fixed; - z-index: -1; - top: 0; - left: 0; - height: 100%; - transform: translateX(-100%); - transition: transform ease-out 150ms; - - display: flex; - flex-direction: column; - margin: 0; - padding: $headerHeight 8px 8px; - - font-size: 20px; - - background: $panelBackground; - - li { - position: relative; - list-style: none; - margin-top: 8px; - - a, button { - position: relative; - margin: 0; - - display: flex; - flex-direction: row; - align-items: center; - height: auto; - padding: 8px; - - border-radius: 3px; - - &:hover, &:active { - &:not(button) { - background-color: rgba(255, 255, 255, 0.07); - } - } - - .feather { - --icon-size: 16px; - } - - .tip { - position: static; - visibility: visible; - opacity: 1; - display: block; - height: auto; - margin-left: 8px; - padding: 0 0 0 4px; - transform: none; - - font-size: 16px; - line-height: 16px; - - color: inherit; - text-transform: uppercase; - font-weight: inherit; - background: transparent; - } - } - - button { - margin: 0; - height: 32px; - - .feather { - margin-right: 0; - } - } - - form { - display: flex; - justify-content: center; - align-items: center; - padding: 0; - } - - &.auth-user { - img { - width: 48px; - height: 48px; - border-radius: 3px; - margin-right: 8px; - } - } - - .dropdown { - position: initial; - display: block; - padding-left: 0; - } - } - - > li:not(:first-child) { - border-top: 1px solid transparentize($defaultTextColor, 0.8); - padding-top: 8px; - } - - &.open { - transform: translateX(0%); - box-shadow: 0 0 5px darken($panelBackground, 20%); - } - } - - #menu-button { - position: fixed; - top: 0; - left: 0; - display: block; - margin: 0; - padding: 0 16px; - line-height: $headerHeight; - - cursor: pointer; - background: transparent; - border-radius: 0; - - .feather { - --icon-size: 28px; - margin: 0 8px; - } - } - - hr { - border: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; - } - } - - @media (min-width: $mobileThreshold) { - flex-direction: row; - - nav { - #menu-button { - display: none; - } - - ul { - position: static; - flex-direction: row; - transform: none; - padding: 0; - background: transparent; - - li { - margin-top: 0; - margin-left: 8px; - - &:last-child { - a, button, .button { - .tip { - left: unset; - right: 4px; - transform: none; - } - } - } - - .dropdown { - position: absolute; - z-index: -1; - top: 100%; - right: 0; - display: none; - padding: 8px; - - white-space: nowrap; - background: $panelBackground; - border-radius: 0 0 3px 3px; - - box-shadow: 0 2px 2px transparentize(darken($panelBackground, 20%), 0.75); - border-top: 4px solid lighten($panelBackground, 5%); - - li { - margin-left: 0; - - &:not(:first-child) { - margin-top: 8px; - } - } - } - - &:hover .dropdown { - display: block; - } - } - - > li:not(:first-child) { - border-top: 0; - padding-top: 0; - } - } - } - } -} - -body > footer { - padding: 8px; - margin-top: 8px; - text-align: center; - background-color: $footerBackground; -} - -main { - flex: 1; - padding: 8px 0; - - button, .button { - @include tip; - } -} - -h1 { - text-align: center; - font-size: 32px; - - & + p { - text-align: center; - font-size: 20px; - } -} - -h1, h2 { - font-weight: 100; -} - -h3, h4 { - font-weight: 300; -} - -section > h2, .panel > h2 { - display: flex; - flex-direction: row; - align-items: center; - position: relative; - text-align: center; - margin-top: 4px; - - font-size: 24px; - line-height: 1; - - .feather { - margin: 0 16px 0 0; - opacity: 0.1; - } - - &::after { - content: ""; - flex: 1; - margin: 0 16px; - height: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.1; - } -} - -section > hr, .panel > hr { - border: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; - - margin: 8px 32px; -} - -a { - color: $secondary; - text-decoration: none; - - &:hover { - color: lighten($secondary, 30%); - } - - .feather.feather-external-link { - --icon-size: 16px; - margin-left: 4px; - margin-top: -3px; - } -} - -form { - padding: 8px 16px; - text-align: center; - - .form-field:not(.hidden) { - display: flex; - flex-direction: column; - margin: 16px auto; - - .control { - position: relative; - background: $inputBackground; - border-radius: 5px; - } - - .feather.icon { - position: absolute; - top: 50%; - right: 8px; - transform: translateY(-50%); - z-index: 0; - - --icon-size: 24px; - opacity: 0.75; - } - - label { - position: absolute; - left: 8px; - top: 20px; - user-select: none; - font-size: 16px; - opacity: 0.75; - - transition-property: top, font-size; - transition-duration: 150ms; - transition-timing-function: ease-out; - - cursor: text; - } - - [disabled] { - opacity: 0.5; - - & ~ label { - opacity: 0.5; - cursor: default; - } - } - - input, select, textarea, .input-group { - z-index: 1; - border: 0; - color: $defaultTextColor; - background: transparent; - font-size: 16px; - - &:focus, &:not([value=""]), &[type="file"] { - ~ label { - top: 8px; - font-size: 14px; - } - } - } - - input, select, textarea, .form-display { - display: block; - padding: 32px 8px 8px 8px; - width: 100%; - height: 60px; - } - - select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - - &::-ms-expand { - display: none; - } - - & + .feather { - position: absolute; - pointer-events: none; - right: 8px; - top: 30px; - - transition: transform 150ms ease-out; - } - - // Temporary - &:focus + .feather { - transform: rotateX(180deg); - } - } - - textarea { - resize: vertical; - min-height: 100px; - font-family: inherit; - } - - input[type=color] { - height: calc(32px + 8px + 32px); - } - - &.inline { - display: flex; - flex-direction: row; - - .control { - display: flex; - flex-direction: row; - align-items: center; - flex-grow: 1; - - input[type=checkbox] { - width: min-content; - height: min-content; - margin: 8px; - text-align: left; - - & ~ label { - position: static; - flex-grow: 1; - display: inline; - padding: 8px; - - font-size: 16px; - text-align: left; - } - } - } - } - - .input-group { - display: flex; - flex-grow: 1; - flex-direction: row; - - div { - position: relative; - flex: 1; - - input { - width: 100%; - border: 0; - background: transparent; - } - } - } - } - - .inline-fields { - display: flex; - flex-direction: row; - align-items: start; - margin: 16px auto; - - .form-field { - flex: 1; - margin: 0; - } - - > :not(.form-field) { - padding: 32px 8px 8px 8px; - } - - + { - .error, .hint { - margin-top: -16px; - margin-bottom: 16px; - } - } - } - - .form-field, .inline-fields + { - .error, .hint { - padding: 2px; - text-align: left; - font-size: 14px; - - .feather { - --icon-size: 14px; - } - } - - .error { - color: $error; - } - } -} - -button, .button { - display: inline-flex; - margin: 8px; - padding: 12px 16px; - border: 0; - border-radius: 5px; - cursor: pointer; - - text-transform: uppercase; - font-size: 16px; - font-weight: bolder; - - line-height: 16px; - - .feather { - --icon-size: 16px; - margin-right: 8px; - } - - .feather.last { - margin-right: 0; - margin-left: 8px; - } - - &, &.primary { - color: $primaryForeground; - background-color: darken($secondary, 10%); - - &:hover { - background-color: $secondary; - } - } - - &.info { - background-color: $infoColor; - } - - &.success { - background-color: $successColor; - } - - &.warning { - background-color: $warningColor; - - &:hover { - background-color: lighten($warningColor, 10%); - } - } - - &.error, &.danger { - background-color: $errorColor; - - &:hover { - background-color: lighten($errorColor, 10%); - } - } - - &.transparent { - background-color: transparent; - } - - &:hover { - color: $primaryForeground; - } -} - - -// --- -// --- Tables -// --- -td.actions { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - - form { - padding: 0; - display: inline; - } - - button, .button { - margin: 0; - padding: 8px; - - .feather { - margin-right: 0; - } - } - - > *:not(:first-child) { - margin-left: 8px; - } -} - - -// --- -// --- Breadcrumb widget -// --- -.breadcrumb { - list-style: none; - display: flex; - flex-direction: row; - margin: 0; - padding: 8px; - - > *:not(:first-child)::before { - content: '›'; - padding: 0 8px; - } -} - - -// --- -// --- Layout helpers -// --- -.center { - text-align: center; -} - -.panel { - position: relative; - margin: 16px 0 48px; - padding: 8px; - background-color: $panelBackground; - border-radius: 5px; - - p { - margin: 16px 8px; - } - - > .feather:first-child { - position: absolute; - --icon-size: 24px; - opacity: 0.1; - top: 8px; - left: 8px; - } -} - -.sub-panel { - margin: 32px 0; - padding: 1px 16px; - border: 2px solid lighten($panelBackground, 4%); - border-radius: 5px; - - form > & { - margin: 32px -18px; - } -} - - -// --- -// --- Helper classes -// --- -.container > .messages:first-child { - margin-top: 16px; -} - -.copyable-text { - display: flex; - flex-direction: row; - margin: 8px; - - background-color: darken($backgroundColor, 2%); - border-radius: 5px; - overflow: hidden; - - .title { - padding: 8px; - } - - .content { - width: 0; - flex-grow: 1; - overflow: hidden; - white-space: nowrap; - padding: 8px; - } - - .copy-button { - margin: 0; - padding: 0; - border-radius: 0; - - .feather { - --icon-size: 20px; - margin: 8px; - } - } -} - -.hidden { - display: none; -} - -.progress-bar { - position: relative; - display: block; - margin: 8px; - padding: 4px; - background: #fff1; - border-radius: 5px; - overflow: hidden; - text-align: center; - - .content { - position: relative; - } - - &::before { - content: ""; - display: block; - position: absolute; - left: 0; - top: 0; - width: var(--progress); - height: 100%; - transition: width ease-out 150ms; - - background: $secondary; - } -} - -.table-col-grow { - width: 100%; -} - -.pagination { - ul { - display: flex; - flex-direction: row; - list-style: none; - padding: 8px; - - justify-content: center; - - li { - a, &.active, &.ellipsis { - display: block; - min-width: 40px; - height: 40px; - padding: 4px; - - line-height: 32px; - text-align:center; - - &:hover:not(.active):not(.ellipsis) { - background-color: #fff5; - } - } - } - } -} diff --git a/src/assets/sass/responsivity_tools.scss b/src/assets/sass/responsivity_tools.scss deleted file mode 100644 index 0e3d232..0000000 --- a/src/assets/sass/responsivity_tools.scss +++ /dev/null @@ -1,19 +0,0 @@ -@import "vars"; - -@mixin container { - width: 100%; - padding: 0 8px; - - @media (min-width: $mobileThreshold) { - margin: 0 auto; - padding: 0 16px; - } - - @media (min-width: $desktopThreshold) { - width: $desktopThreshold; - } -} - -.container { - @include container; -} diff --git a/src/assets/ts/PersistentWebSocket.ts b/src/assets/ts/PersistentWebSocket.ts deleted file mode 100644 index 98e474f..0000000 --- a/src/assets/ts/PersistentWebSocket.ts +++ /dev/null @@ -1,39 +0,0 @@ -export default class PersistentWebsocket { - private webSocket?: WebSocket; - - public constructor( - protected readonly url: string, - private readonly handler: MessageHandler, - protected readonly reconnectOnClose: boolean = true, - ) { - } - - public run(): void { - const _webSocket = this.webSocket = new WebSocket(this.url); - this.webSocket.addEventListener('open', () => { - console.debug('Websocket connected'); - }); - this.webSocket.addEventListener('message', (e) => { - this.handler(_webSocket, e); - }); - this.webSocket.addEventListener('error', (e) => { - console.error('Websocket error', e); - }); - this.webSocket.addEventListener('close', (e) => { - this.webSocket = undefined; - console.debug('Websocket closed', e.code, e.reason); - - if (this.reconnectOnClose) { - setTimeout(() => this.run(), 1000); - } - }); - } - - public send(data: string): void { - if (!this.webSocket) throw new Error('WebSocket not connected'); - - this.webSocket.send(data); - } -} - -export type MessageHandler = (webSocket: WebSocket, e: MessageEvent) => void; diff --git a/src/assets/ts/app.ts b/src/assets/ts/app.ts deleted file mode 100644 index 8594552..0000000 --- a/src/assets/ts/app.ts +++ /dev/null @@ -1,10 +0,0 @@ -import './external_links'; -import './message_icons'; -import './forms'; -import './copyable_text'; -import './tooltips-and-dropdowns'; -import './main_menu'; -import './font-awesome'; - -// css -import '../sass/app.scss'; diff --git a/src/assets/ts/copyable_text.ts b/src/assets/ts/copyable_text.ts deleted file mode 100644 index 60d58ab..0000000 --- a/src/assets/ts/copyable_text.ts +++ /dev/null @@ -1,15 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - document.querySelectorAll('.copyable-text').forEach(el => { - const contentEl = el.querySelector('.content'); - const selection = window.getSelection(); - if (contentEl && selection) { - contentEl.addEventListener('click', () => { - selection.selectAllChildren(contentEl); - }); - el.querySelector('.copy-button')?.addEventListener('click', () => { - selection.selectAllChildren(contentEl); - document.execCommand('copy'); - }); - } - }); -}); diff --git a/src/assets/ts/external_links.ts b/src/assets/ts/external_links.ts deleted file mode 100644 index bc9ba26..0000000 --- a/src/assets/ts/external_links.ts +++ /dev/null @@ -1,11 +0,0 @@ -import feather from "feather-icons"; - -document.addEventListener('DOMContentLoaded', () => { - document.querySelectorAll('a[target="_blank"]').forEach(el => { - if (!el.classList.contains('no-icon')) { - el.innerHTML += ``; - } - }); - - feather.replace(); -}); diff --git a/src/assets/ts/font-awesome.ts b/src/assets/ts/font-awesome.ts deleted file mode 100644 index 0409cfe..0000000 --- a/src/assets/ts/font-awesome.ts +++ /dev/null @@ -1,4 +0,0 @@ -import '@fortawesome/fontawesome-free/scss/fontawesome.scss'; -import '@fortawesome/fontawesome-free/scss/regular.scss'; -import '@fortawesome/fontawesome-free/scss/solid.scss'; -import '@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/src/assets/ts/forms.ts b/src/assets/ts/forms.ts deleted file mode 100644 index ece465d..0000000 --- a/src/assets/ts/forms.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * For labels to update their state (css selectors based on the value attribute) - */ -import {ValidationError} from "swaf/db/Validator"; - -export function updateInputs(): void { - document.querySelectorAll('input, textarea').forEach(el => { - if (!el.dataset.inputSetup) { - el.dataset.inputSetup = 'true'; - if (el.type !== 'checkbox') { - el.setAttribute('value', el.value); - el.addEventListener('change', () => { - el.setAttribute('value', el.value); - }); - } - } - }); -} - -document.addEventListener('DOMContentLoaded', () => { - updateInputs(); -}); - -export function applyFormMessages( - formElement: HTMLFormElement, - messages: { [p: string]: ValidationError }, -): void { - for (const fieldName of Object.keys(messages)) { - const field = formElement.querySelector('#field-' + fieldName); - if (!field) continue; - - let parent = field.parentElement; - while (parent && !parent.classList.contains('form-field')) parent = parent.parentElement; - - let err = field.querySelector('.error'); - if (!err) { - err = document.createElement('div'); - err.classList.add('error'); - parent?.insertBefore(err, parent.querySelector('.hint') || parent); - } - err.innerHTML = ` ${messages[fieldName].message}`; - } -} diff --git a/src/assets/ts/main_menu.ts b/src/assets/ts/main_menu.ts deleted file mode 100644 index 4e19e40..0000000 --- a/src/assets/ts/main_menu.ts +++ /dev/null @@ -1,21 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const menuButton = document.getElementById('menu-button'); - const mainMenu = document.getElementById('main-menu'); - - if (menuButton) { - menuButton.addEventListener('click', (e) => { - e.stopPropagation(); - mainMenu?.classList.toggle('open'); - }); - } - - if (mainMenu) { - mainMenu.addEventListener('click', (e) => { - e.stopPropagation(); - }); - - document.addEventListener('click', () => { - mainMenu.classList.remove('open'); - }); - } -}); diff --git a/src/assets/ts/message_icons.ts b/src/assets/ts/message_icons.ts deleted file mode 100644 index b737de3..0000000 --- a/src/assets/ts/message_icons.ts +++ /dev/null @@ -1,26 +0,0 @@ -import feather from "feather-icons"; - -document.addEventListener('DOMContentLoaded', () => { - const messageTypeToIcon: { [p: string]: string } = { - info: 'info', - success: 'check', - warning: 'alert-triangle', - error: 'x-circle', - question: 'help-circle', - }; - - document.querySelectorAll('.message').forEach(el => { - const icon = el.querySelector('.icon'); - const type = el.dataset['type']; - if (!icon || !type) return; - if (!messageTypeToIcon[type]) throw new Error(`No icon for type ${type}`); - - const svgContainer = document.createElement('div'); - svgContainer.innerHTML = feather.icons[messageTypeToIcon[type]].toSvg(); - - if (svgContainer.firstChild) el.insertBefore(svgContainer.firstChild, icon); - icon.remove(); - }); - - feather.replace(); -}); diff --git a/src/assets/ts/tooltips-and-dropdowns.ts b/src/assets/ts/tooltips-and-dropdowns.ts deleted file mode 100644 index 069b405..0000000 --- a/src/assets/ts/tooltips-and-dropdowns.ts +++ /dev/null @@ -1,31 +0,0 @@ -export function updateTooltips(): void { - console.debug('Updating tooltips'); - const elements = document.querySelectorAll('.tip, .dropdown'); - - // Calculate max potential displacement - let max = 0; - elements.forEach(el => { - const box = el.getBoundingClientRect(); - if (max < box.height) max = box.height; - }); - - // Prevent displacement - elements.forEach(el => { - if (!el.dataset.tooltipSetup) { - el.dataset.tooltipSetup = 'true'; - const box = el.getBoundingClientRect(); - if (box.bottom >= document.body.clientHeight - (max + 32)) { - el.classList.add('top'); - } - } - }); -} - -document.addEventListener('DOMContentLoaded', () => { - window.addEventListener('popstate', () => { - updateTooltips(); - }); - window.requestAnimationFrame(() => { - updateTooltips(); - }); -}); diff --git a/src/assets/views/about.njk b/src/assets/views/about.njk deleted file mode 100644 index f1e7a0a..0000000 --- a/src/assets/views/about.njk +++ /dev/null @@ -1,14 +0,0 @@ -{% extends 'layouts/base.njk' %} - -{% set title = app.name + ' - About us' %} - -{% block body %} -

Very interesting

- -
-
-

This is us

-

And we like swaf!

-
-
-{% endblock %} diff --git a/src/assets/views/home.njk b/src/assets/views/home.njk deleted file mode 100644 index 09adf33..0000000 --- a/src/assets/views/home.njk +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'layouts/base.njk' %} - -{% set title = app.name + ' - Hello world!' %} - -{% block body %} -

Hello world!

-{% endblock %} \ No newline at end of file diff --git a/src/assets/views/layouts/base.njk b/src/assets/views/layouts/base.njk deleted file mode 100644 index f350e8e..0000000 --- a/src/assets/views/layouts/base.njk +++ /dev/null @@ -1,41 +0,0 @@ -{% extends 'layouts/barebone.njk' %} -{% import 'macros.njk' as macros %} - -{% block _stylesheets %} - {{ super() }} - - {% block stylesheets %}{% endblock %} -{% endblock %} -{% block _scripts %} - {{ super() }} - {% block scripts %}{% endblock %} -{% endblock %} - -{% block header %} - - -{% endblock %} - -{% block _body %} -
- {{ macros.messages(flash) }} -
- -
- {% if h1 %} -

{{ h1 }}

- {% endif %} - {% if subtitle %} -

{{ subtitle }}

- {% endif %} - - {% block body %}{% endblock %} -
-{% endblock %} - -{% block footer %}{{ app.name }} v{{ app_version }} - all rights reserved.{% endblock %} \ No newline at end of file -- 2.47.0 From 6002ad529090147f838542b0b7354ff834798702 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 16:59:06 +0100 Subject: [PATCH 64/71] Remove webpack and unused dependencies --- package.json | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index b83dc74..2ddb61c 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,6 @@ "start": "yarn build-production && node ." }, "devDependencies": { - "@babel/core": "^7.9.0", - "@babel/preset-env": "^7.9.5", "@tsconfig/svelte": "^2.0.1", "@types/config": "^0.0.40", "@types/express": "^4.17.6", @@ -34,14 +32,9 @@ "@types/ws": "^8.2.0", "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", - "babel-loader": "^8.1.0", - "clear-module": "^4.1.2", "concurrently": "^6.0.0", - "css-loader": "^6.5.1", "eslint": "^8.2.0", "feather-icons": "^4.28.0", - "file-loader": "^6.0.0", - "image-minimizer-webpack-plugin": "^2.2.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", @@ -49,24 +42,15 @@ "imagemin-webp": "^6.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", - "mini-css-extract-plugin": "^2.4.5", "nodemon": "^2.0.3", - "normalize.css": "^8.0.1", "sass": "^1.32.12", - "sass-loader": "^12.0.0", - "svelte": "^3.44.2", - "svelte-preprocess": "^4.9.8", "svgo": "^2.3.0", - "terser-webpack-plugin": "^5.0.3", "ts-jest": "^27.0.3", - "ts-loader": "^9.1.0", - "typescript": "^4.0.2", - "webpack": "^5.3.2", - "webpack-cli": "^4.1.0" + "typescript": "^4.0.2" }, "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "swaf": "^0.24.4" + "swaf": "^0.24.7" } } -- 2.47.0 From 8c1230d5017a3c396fe2967a736c6e16ff161c82 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 17:41:48 +0100 Subject: [PATCH 65/71] Remove reference to deleted tsconfig.frontend.json from eslint config --- .eslintrc.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index a506e1e..8b0a7b4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,8 +7,7 @@ "parserOptions": { "project": [ "./tsconfig.json", - "./tsconfig.test.json", - "./tsconfig.frontend.json" + "./tsconfig.test.json" ] }, "extends": [ -- 2.47.0 From f2f34dd00f2c4f29d7acc829d2395b9d9f891bbc Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 17:44:12 +0100 Subject: [PATCH 66/71] Update eslint config with swaf --- .eslintrc.cjs | 135 +++++++++++++++++++++++++++++++++++++++++++++++++ .eslintrc.json | 114 ----------------------------------------- 2 files changed, 135 insertions(+), 114 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..4910a0e --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,135 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: [ + 'svelte3', + '@typescript-eslint', + 'import', + 'simple-import-sort', + ], + parserOptions: { + tsconfigRootDir: __dirname, + project: [ + './tsconfig.test.json', + './src/tsconfig.json', + './src/common/tsconfig.json', + './src/assets/ts/tsconfig.eslint.json', + './src/assets/views/tsconfig.json', + ] + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + ], + rules: { + indent: [ + 'error', + 4, + { + SwitchCase: 1 + } + ], + 'no-trailing-spaces': 'error', + 'max-len': [ + 'error', + { + code: 120, + ignoreTemplateLiterals: true, + ignoreRegExpLiterals: true + } + ], + semi: 'off', + '@typescript-eslint/semi': [ + 'error' + ], + 'no-extra-semi': 'error', + 'eol-last': 'error', + 'comma-dangle': 'off', + 'simple-import-sort/imports': 'error', + 'no-extra-parens': 'off', + 'no-nested-ternary': 'error', + 'no-return-await': 'off', + 'no-useless-return': 'error', + 'no-useless-constructor': 'off', + 'import/extensions': ['error', 'ignorePackages'], + '@typescript-eslint/comma-dangle': [ + 'error', + { + arrays: 'always-multiline', + objects: 'always-multiline', + imports: 'always-multiline', + exports: 'always-multiline', + functions: 'always-multiline', + enums: 'always-multiline', + generics: 'always-multiline', + tuples: 'always-multiline' + } + ], + '@typescript-eslint/no-extra-parens': [ + 'error' + ], + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'error', + '@typescript-eslint/no-unnecessary-condition': 'error', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_' + } + ], + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-useless-constructor': [ + 'error' + ], + '@typescript-eslint/return-await': [ + 'error', + 'always' + ], + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { + accessibility: 'explicit' + } + ], + '@typescript-eslint/no-floating-promises': 'error', + }, + ignorePatterns: [ + '.eslintrc.js', + 'rollup.config.js', + 'jest.config.js', + 'dist/**/*', + 'config/**/*', + 'intermediates/**/*', + 'public/**/*', + 'scripts/**/*', + 'src/frontend/register_svelte/register_svelte.js', + ], + overrides: [ + { + files: [ + 'test/**/*' + ], + rules: { + 'max-len': [ + 'error', + { + code: 120, + ignoreTemplateLiterals: true, + ignoreRegExpLiterals: true, + ignoreStrings: true + } + ] + } + }, + { + files: ['*.svelte'], + processor: 'svelte3/svelte3' + } + ], + settings: { + 'svelte3/typescript': require('typescript'), + 'svelte3/ignore-styles': function (attributes) { + return !!(attributes['lang'] && attributes['lang'] !== 'css'); + } + }, +} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 8b0a7b4..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "parserOptions": { - "project": [ - "./tsconfig.json", - "./tsconfig.test.json" - ] - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "indent": [ - "error", - 4, - { - "SwitchCase": 1 - } - ], - "no-trailing-spaces": "error", - "max-len": [ - "error", - { - "code": 120, - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreRegExpLiterals": true - } - ], - "semi": "off", - "@typescript-eslint/semi": [ - "error" - ], - "no-extra-semi": "error", - "eol-last": "error", - "comma-dangle": "off", - "@typescript-eslint/comma-dangle": [ - "error", - { - "arrays": "always-multiline", - "objects": "always-multiline", - "imports": "always-multiline", - "exports": "always-multiline", - "functions": "always-multiline", - "enums": "always-multiline", - "generics": "always-multiline", - "tuples": "always-multiline" - } - ], - "no-extra-parens": "off", - "@typescript-eslint/no-extra-parens": [ - "error" - ], - "no-nested-ternary": "error", - "@typescript-eslint/no-inferrable-types": "off", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-unnecessary-condition": "error", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_" - } - ], - "@typescript-eslint/no-non-null-assertion": "error", - "no-useless-return": "error", - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": [ - "error" - ], - "no-return-await": "off", - "@typescript-eslint/return-await": [ - "error", - "always" - ], - "@typescript-eslint/explicit-member-accessibility": [ - "error", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/no-floating-promises": "error" - }, - "ignorePatterns": [ - "jest.config.js", - "scripts/**/*", - "webpack.config.js", - "dist/**/*", - "public/**/*", - "config/**/*" - ], - "overrides": [ - { - "files": [ - "test/**/*" - ], - "rules": { - "max-len": [ - "error", - { - "code": 120, - "ignoreTemplateLiterals": true, - "ignoreRegExpLiterals": true, - "ignoreStrings": true - } - ] - } - } - ] -} -- 2.47.0 From eb0364a2f7e632a7e10c24702a75752bbe7eb6a8 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 17:52:56 +0100 Subject: [PATCH 67/71] Fix eslint and fix linting issues --- package.json | 6 +++++- src/App.ts | 35 ++++++++++++++++--------------- src/common/dummy.ts | 2 +- src/controllers/HomeController.ts | 2 +- src/main.ts | 5 +++-- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 2ddb61c..5057cc4 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,10 @@ "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", "concurrently": "^6.0.0", - "eslint": "^8.2.0", + "eslint": "^8.3.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-simple-import-sort": "^7.0.0", + "eslint-plugin-svelte3": "^3.2.1", "feather-icons": "^4.28.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", @@ -44,6 +47,7 @@ "maildev": "^1.1.0", "nodemon": "^2.0.3", "sass": "^1.32.12", + "svelte": "^3.44.2", "svgo": "^2.3.0", "ts-jest": "^27.0.3", "typescript": "^4.0.2" diff --git a/src/App.ts b/src/App.ts index 768d322..09ffde9 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,30 +1,31 @@ import Application from "swaf/Application"; -import Migration, {MigrationType} from "swaf/db/Migration"; -import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; +import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; +import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent"; import ExpressAppComponent from "swaf/components/ExpressAppComponent"; -import MysqlComponent from "swaf/components/MysqlComponent"; +import FormHelperComponent from "swaf/components/FormHelperComponent"; +import FrontendToolsComponent from "swaf/components/FrontendToolsComponent"; import LogRequestsComponent from "swaf/components/LogRequestsComponent"; +import MailComponent from "swaf/components/MailComponent"; +import MaintenanceComponent from "swaf/components/MaintenanceComponent"; +import MysqlComponent from "swaf/components/MysqlComponent"; +import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; import RedisComponent from "swaf/components/RedisComponent"; import ServeStaticDirectoryComponent from "swaf/components/ServeStaticDirectoryComponent"; -import MaintenanceComponent from "swaf/components/MaintenanceComponent"; -import MailComponent from "swaf/components/MailComponent"; import SessionComponent from "swaf/components/SessionComponent"; -import FormHelperComponent from "swaf/components/FormHelperComponent"; -import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent"; import WebSocketServerComponent from "swaf/components/WebSocketServerComponent"; -import HomeController from "./controllers/HomeController"; -import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; -import DummyMigration from "swaf/migrations/DummyMigration"; -import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; -import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; -import MailViewEngine from "swaf/frontend/MailViewEngine"; +import Migration, {MigrationType} from "swaf/db/Migration"; import AssetCompiler from "swaf/frontend/AssetCompiler"; -import FrontendToolsComponent from "swaf/components/FrontendToolsComponent"; import CopyAssetPreCompiler from "swaf/frontend/CopyAssetPreCompiler"; -import ScssAssetPreCompiler from "swaf/frontend/ScssAssetPreCompiler"; -import TypeScriptPreCompiler from "swaf/frontend/TypeScriptPreCompiler"; -import SvelteViewEngine from "swaf/frontend/SvelteViewEngine"; +import MailViewEngine from "swaf/frontend/MailViewEngine"; import NunjucksViewEngine from "swaf/frontend/NunjucksViewEngine"; +import ScssAssetPreCompiler from "swaf/frontend/ScssAssetPreCompiler"; +import SvelteViewEngine from "swaf/frontend/SvelteViewEngine"; +import TypeScriptPreCompiler from "swaf/frontend/TypeScriptPreCompiler"; +import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; +import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; +import DummyMigration from "swaf/migrations/DummyMigration"; + +import HomeController from "./controllers/HomeController.js"; export default class App extends Application { public constructor( diff --git a/src/common/dummy.ts b/src/common/dummy.ts index c58f5a5..4f6d24e 100644 --- a/src/common/dummy.ts +++ b/src/common/dummy.ts @@ -1 +1 @@ -console.log('common code between back and front'); \ No newline at end of file +console.log('common code between back and front'); diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index 027d83d..825b619 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -1,6 +1,6 @@ -import Controller from "swaf/Controller"; import {Request, Response} from "express"; import {route} from "swaf/common/Routing"; +import Controller from "swaf/Controller"; export default class HomeController extends Controller { public routes(): void { diff --git a/src/main.ts b/src/main.ts index ff2f443..8bf4ab4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,10 +6,11 @@ process.env['NODE_CONFIG_DIR'] = + delimiter + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); -import {logger} from "swaf/Logger"; -import App from "./App"; import config from "config"; import {promises as fs} from "fs"; +import {logger} from "swaf/Logger"; + +import App from "./App.js"; (async () => { logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); -- 2.47.0 From 5f5275ceb116a77dbc355ada1de05773c370ee90 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 24 Dec 2021 15:18:09 +0100 Subject: [PATCH 68/71] upgrade dependencies --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5057cc4..d5a0877 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "start": "yarn build-production && node ." }, "devDependencies": { - "@tsconfig/svelte": "^2.0.1", + "@tsconfig/svelte": "^3.0.0", "@types/config": "^0.0.40", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", @@ -26,7 +26,7 @@ "@types/formidable": "^2.0.0", "@types/jest": "^27.0.3", "@types/mysql": "^2.15.15", - "@types/node": "^16.11.9", + "@types/node": "^17.0.4", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", "@types/ws": "^8.2.0", @@ -39,10 +39,10 @@ "eslint-plugin-svelte3": "^3.2.1", "feather-icons": "^4.28.0", "imagemin-gifsicle": "^7.0.0", - "imagemin-mozjpeg": "^9.0.0", + "imagemin-mozjpeg": "^10.0.0", "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^10.0.0", - "imagemin-webp": "^6.0.0", + "imagemin-webp": "^7.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", "nodemon": "^2.0.3", -- 2.47.0 From 47156c9a779909c86c770889292290e2ecb117ea Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 1 Mar 2022 10:50:14 +0100 Subject: [PATCH 69/71] Remove feather icons in favor of lucide icons (included with swaf) --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index 5057cc4..3402319 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "@types/config": "^0.0.40", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", - "@types/feather-icons": "^4.7.0", "@types/formidable": "^2.0.0", "@types/jest": "^27.0.3", "@types/mysql": "^2.15.15", @@ -37,7 +36,6 @@ "eslint-plugin-import": "^2.25.3", "eslint-plugin-simple-import-sort": "^7.0.0", "eslint-plugin-svelte3": "^3.2.1", - "feather-icons": "^4.28.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", -- 2.47.0 From 11fccbfc0d818f6b3420cc99ea8babde303d4d06 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 2 Mar 2022 11:11:57 +0100 Subject: [PATCH 70/71] fix sass->scss asset dir name --- src/assets/{sass => scss}/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/assets/{sass => scss}/.gitkeep (100%) diff --git a/src/assets/sass/.gitkeep b/src/assets/scss/.gitkeep similarity index 100% rename from src/assets/sass/.gitkeep rename to src/assets/scss/.gitkeep -- 2.47.0 From a5b7cf9268300295b1e867e22be0541dd535c7a2 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 7 Mar 2022 19:04:29 +0100 Subject: [PATCH 71/71] upgrade dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a677811..a6aaa04 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "devDependencies": { "@tsconfig/svelte": "^3.0.0", - "@types/config": "^0.0.40", + "@types/config": "^0.0.41", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", "@types/formidable": "^2.0.0", @@ -31,7 +31,7 @@ "@types/ws": "^8.2.0", "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", - "concurrently": "^6.0.0", + "concurrently": "^7.0.0", "eslint": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-simple-import-sort": "^7.0.0", @@ -53,6 +53,6 @@ "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "swaf": "^0.24.7" + "swaf": "^0.25.1" } } -- 2.47.0