Merge pull request #6 from IT4Change/more-github-workflows

feat(frontend): stylelint & workflow build storybook
This commit is contained in:
Ulf Gebhardt 2023-11-20 21:46:38 +01:00 committed by GitHub
commit bdec96c9ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1370 additions and 51 deletions

View File

@ -10,4 +10,8 @@ frontend-test-build-code: &frontend-test-build-code
- '**/*' - '**/*'
frontend-test-build-docs: &frontend-test-build-docs frontend-test-build-docs: &frontend-test-build-docs
- '**/*.md' - '**/*.md'
- '.vuepress/'
frontend-test-build-storybook: &frontend-test-build-storybook
- '**/*'

View File

@ -1,4 +1,4 @@
name: "deploy:docs to github" name: "frontend:deploy:docs to github"
on: on:
push: push:
branches: branches:

View File

@ -1,4 +1,4 @@
name: "test:build test code" name: "frontend:test:build test code"
on: push on: push

View File

@ -1,4 +1,4 @@
name: "test:build test docs" name: "frontend:test:build test docs"
on: push on: push
@ -30,5 +30,5 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Frontend | Build - name: Frontend | Build Docs
run: npm install && npm run docs:build run: npm install && npm run docs:build

View File

@ -0,0 +1,34 @@
name: "frontend:test:build test storybook"
on: push
jobs:
# only (but most important) job from this workflow required for pull requests
# check results serve as run conditions for all other jobs here
files-changed:
name: Detect File Changes - frontend-test-build-storybook
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.frontend-test-build-storybook }}
steps:
- uses: actions/checkout@v3.3.0
- name: Check for frontend file changes
uses: dorny/paths-filter@v2.11.1
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
storybook:
if: needs.files-changed.outputs.changes == 'true'
name: Build Storybook - Frontend
needs: files-changed
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Frontend | Build Storybook
run: npm install && npm run storybook:build

View File

@ -1,4 +1,4 @@
name: "test:lint code with defined linters" name: "frontend:test:lint code with defined linters"
on: push on: push

View File

@ -1,4 +1,4 @@
name: "test:unit test code with defined suites" name: "frontend:test:unit test code with defined suites"
on: push on: push

View File

@ -9,7 +9,7 @@ on:
permissions: permissions:
pull-requests: write pull-requests: write
actions: write statuses: write
jobs: jobs:
main: main:
@ -29,6 +29,7 @@ jobs:
# Configure which scopes are allowed (newline delimited). # Configure which scopes are allowed (newline delimited).
# Append a scope for each service here # Append a scope for each service here
scopes: | scopes: |
frontend
docker docker
release release
workflow workflow

9
.stylelintrc.json Normal file
View File

@ -0,0 +1,9 @@
{
"extends": [
"stylelint-config-standard",
"stylelint-config-standard-scss",
"stylelint-config-recommended-vue",
"stylelint-config-recess-order",
"stylelint-config-css-modules"
]
}

View File

@ -9,6 +9,7 @@
[![vue-i18n][badge-vue-i18n-img]][badge-vue-i18n-href] [![vue-i18n][badge-vue-i18n-img]][badge-vue-i18n-href]
[![eslint][badge-eslint-img]][badge-eslint-href] [![eslint][badge-eslint-img]][badge-eslint-href]
[![remark-cli][badge-remark-cli-img]][badge-remark-cli-href] [![remark-cli][badge-remark-cli-img]][badge-remark-cli-href]
[![stylelint][badge-stylelint-img]][badge-stylelint-href]
[![vitest][badge-vitest-img]][badge-vitest-href] [![vitest][badge-vitest-img]][badge-vitest-href]
[![storybook][badge-storybook-img]][badge-storybook-href] [![storybook][badge-storybook-img]][badge-storybook-href]
[![vuepress][badge-vuepress-img]][badge-vuepress-href] [![vuepress][badge-vuepress-img]][badge-vuepress-href]
@ -21,7 +22,7 @@ To be able to build this project you need `nodejs`, `npm` and optional `docker`.
The project uses `vite` as builder, `vike` to do the SSR. The design framework is `vuetify` which requires the frontend framework `vue3`. For localization `vue-i18n` is used; Session storage is handled with `pinia`. The project uses `vite` as builder, `vike` to do the SSR. The design framework is `vuetify` which requires the frontend framework `vue3`. For localization `vue-i18n` is used; Session storage is handled with `pinia`.
Testing is done with `vitest` and code style is enforced with `eslint` and `remark-cli`. Testing is done with `vitest` and code style is enforced with `eslint`, `remark-cli` and `stylelint`.
This projects utilizes `storybook` to develop frontend components and `vuepress` for static documentation generation. This projects utilizes `storybook` to develop frontend components and `vuepress` for static documentation generation.
@ -41,6 +42,7 @@ The following commands are available:
| `npm run test:lint` | Run all linters | | `npm run test:lint` | Run all linters |
| `npm run test:lint:eslint` | Run linter eslint | | `npm run test:lint:eslint` | Run linter eslint |
| `npm run test:lint:remark` | Run linter remark | | `npm run test:lint:remark` | Run linter remark |
| `npm run test:lint:style` | Run linter stylelint |
| `npm run test:unit` | Run all unit tests and generate coverage report | | `npm run test:unit` | Run all unit tests and generate coverage report |
| `npm run test:unit:dev` | Run all unit tests in watch mode | | `npm run test:unit:dev` | Run all unit tests in watch mode |
| `npm test` | Run all tests & linters | | `npm test` | Run all tests & linters |
@ -122,6 +124,9 @@ Currently none
[badge-remark-cli-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies%5B%27remark-cli%27%5D&label=remark-cli&color=yellow [badge-remark-cli-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies%5B%27remark-cli%27%5D&label=remark-cli&color=yellow
[badge-remark-cli-href]: https://remark.js.org/ [badge-remark-cli-href]: https://remark.js.org/
[badge-stylelint-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.stylelint&label=stylelint&color=yellow
[badge-stylelint-href]: https://stylelint.io/
[badge-vitest-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.vitest&label=vitest&color=yellow [badge-vitest-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.vitest&label=vitest&color=yellow
[badge-vitest-href]: https://vitest.dev/ [badge-vitest-href]: https://vitest.dev/

1243
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -40,9 +40,10 @@
"storybook": "storybook dev -p 6006", "storybook": "storybook dev -p 6006",
"storybook:build": "storybook build -o build/storybook", "storybook:build": "storybook build -o build/storybook",
"storybook:test": "test-storybook", "storybook:test": "test-storybook",
"test:lint": "npm run test:lint:eslint && npm run test:lint:remark", "test:lint": "npm run test:lint:eslint && npm run test:lint:remark && npm run test:lint:style",
"test:lint:eslint": "eslint --ext .vue,.ts,.tsx,.js,.jsx,.json,.yml,.yaml --max-warnings 0 --ignore-path .gitignore .", "test:lint:eslint": "eslint --ext .vue,.ts,.tsx,.js,.jsx,.json,.yml,.yaml --max-warnings 0 --ignore-path .gitignore .",
"test:lint:remark": "remark . --quiet --frail", "test:lint:remark": "remark . --quiet --frail",
"test:lint:style": "stylelint --max-warnings 0 --ignore-path .gitignore \"**/*.{css,scss,vue,vuex}\"",
"test:unit": "npm run test:unit:dev -- run --coverage", "test:unit": "npm run test:unit:dev -- run --coverage",
"test:unit:dev": "vitest", "test:unit:dev": "vitest",
"test": "npm run test:lint && npm run test:unit", "test": "npm run test:lint && npm run test:unit",
@ -112,6 +113,12 @@
"remark-preset-lint-markdown-style-guide": "^5.1.3", "remark-preset-lint-markdown-style-guide": "^5.1.3",
"remark-preset-lint-recommended": "^6.1.3", "remark-preset-lint-recommended": "^6.1.3",
"storybook": "^7.5.3", "storybook": "^7.5.3",
"stylelint": "^15.11.0",
"stylelint-config-css-modules": "^4.3.0",
"stylelint-config-recess-order": "^4.4.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-config-standard-scss": "^11.1.0",
"vitest": "^0.34.6", "vitest": "^0.34.6",
"vuepress": "^2.0.0-rc.0" "vuepress": "^2.0.0-rc.0"
} }

View File

@ -24,9 +24,11 @@ body {
margin: 0; margin: 0;
font-family: sans-serif; font-family: sans-serif;
} }
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
a { a {
text-decoration: none; text-decoration: none;
} }
@ -38,20 +40,23 @@ a {
max-width: 900px; max-width: 900px;
margin: auto; margin: auto;
} }
.content { .content {
padding: 20px;
border-left: 2px solid #eee;
padding-bottom: 50px;
min-height: 100vh; min-height: 100vh;
}
.navigation {
padding: 20px; padding: 20px;
flex-shrink: 0; padding-bottom: 50px;
border-left: 2px solid #eee;
}
.navigation {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-shrink: 0;
align-items: center; align-items: center;
padding: 20px;
line-height: 1.8em; line-height: 1.8em;
} }
.logo { .logo {
margin-top: 20px; margin-top: 20px;
margin-bottom: 10px; margin-bottom: 10px;

View File

@ -12,6 +12,7 @@ const pageContext = usePageContext()
a { a {
padding: 3px 10px; padding: 3px 10px;
} }
a.active { a.active {
background-color: #eee; background-color: #eee;
} }

View File

@ -5,9 +5,9 @@
<style> <style>
code { code {
padding: 3px 5px;
font-family: monospace; font-family: monospace;
background-color: #eaeaea; background-color: #eaeaea;
padding: 3px 5px;
border-radius: 4px; border-radius: 4px;
} }
</style> </style>

View File

@ -1,30 +1,40 @@
.storybook-button { .storybook-button {
display: inline-block;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 700; font-weight: 700;
line-height: 1;
cursor: pointer;
border: 0; border: 0;
border-radius: 3em; border-radius: 3em;
cursor: pointer;
display: inline-block;
line-height: 1;
} }
/* stylelint-disable-next-line selector-class-pattern */
.storybook-button--primary { .storybook-button--primary {
color: white; color: white;
background-color: #1ea7fd; background-color: #1ea7fd;
} }
/* stylelint-disable-next-line selector-class-pattern */
.storybook-button--secondary { .storybook-button--secondary {
color: #333; color: #333;
background-color: transparent; background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; box-shadow: rgb(0 0 0 / 15%) 0 0 0 1px inset;
} }
/* stylelint-disable-next-line selector-class-pattern */
.storybook-button--small { .storybook-button--small {
font-size: 12px;
padding: 10px 16px; padding: 10px 16px;
font-size: 12px;
} }
/* stylelint-disable-next-line selector-class-pattern */
.storybook-button--medium { .storybook-button--medium {
font-size: 14px;
padding: 11px 20px; padding: 11px 20px;
font-size: 14px;
} }
/* stylelint-disable-next-line selector-class-pattern */
.storybook-button--large { .storybook-button--large {
font-size: 16px;
padding: 12px 24px; padding: 12px 24px;
font-size: 16px;
} }

View File

@ -1,10 +1,10 @@
.storybook-header { .storybook-header {
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 15px 20px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 15px 20px;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
border-bottom: 1px solid rgb(0 0 0 / 10%);
} }
.storybook-header svg { .storybook-header svg {
@ -13,11 +13,11 @@
} }
.storybook-header h1 { .storybook-header h1 {
font-weight: 700;
font-size: 20px;
line-height: 1;
margin: 6px 0 6px 10px;
display: inline-block; display: inline-block;
margin: 6px 0 6px 10px;
font-size: 20px;
font-weight: 700;
line-height: 1;
vertical-align: top; vertical-align: top;
} }
@ -26,7 +26,7 @@
} }
.storybook-header .welcome { .storybook-header .welcome {
color: #333;
font-size: 14px;
margin-right: 10px; margin-right: 10px;
font-size: 14px;
color: #333;
} }

View File

@ -1,19 +1,19 @@
.storybook-page { .storybook-page {
max-width: 600px;
padding: 48px 20px;
margin: 0 auto;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px; font-size: 14px;
line-height: 24px; line-height: 24px;
padding: 48px 20px;
margin: 0 auto;
max-width: 600px;
color: #333; color: #333;
} }
.storybook-page h2 { .storybook-page h2 {
font-weight: 700;
font-size: 32px;
line-height: 1;
margin: 0 0 4px;
display: inline-block; display: inline-block;
margin: 0 0 4px;
font-size: 32px;
font-weight: 700;
line-height: 1;
vertical-align: top; vertical-align: top;
} }
@ -22,8 +22,8 @@
} }
.storybook-page a { .storybook-page a {
text-decoration: none;
color: #1ea7fd; color: #1ea7fd;
text-decoration: none;
} }
.storybook-page ul { .storybook-page ul {
@ -37,31 +37,31 @@
.storybook-page .tip { .storybook-page .tip {
display: inline-block; display: inline-block;
border-radius: 1em;
font-size: 11px;
line-height: 12px;
font-weight: 700;
background: #e7fdd8;
color: #66bf3c;
padding: 4px 12px; padding: 4px 12px;
margin-right: 10px; margin-right: 10px;
font-size: 11px;
font-weight: 700;
line-height: 12px;
color: #66bf3c;
vertical-align: top; vertical-align: top;
background: #e7fdd8;
border-radius: 1em;
} }
.storybook-page .tip-wrapper { .storybook-page .tip-wrapper {
font-size: 13px;
line-height: 20px;
margin-top: 40px; margin-top: 40px;
margin-bottom: 40px; margin-bottom: 40px;
font-size: 13px;
line-height: 20px;
} }
.storybook-page .tip-wrapper svg { .storybook-page .tip-wrapper svg {
display: inline-block; display: inline-block;
height: 12px;
width: 12px; width: 12px;
height: 12px;
margin-top: 3px;
margin-right: 4px; margin-right: 4px;
vertical-align: top; vertical-align: top;
margin-top: 3px;
} }
.storybook-page .tip-wrapper svg path { .storybook-page .tip-wrapper svg path {