mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-01-20 20:01:25 +00:00
Merge branch 'master' into refactor-chat-module
This commit is contained in:
commit
2548998554
26
.github/dependabot.yml
vendored
26
.github/dependabot.yml
vendored
@ -66,3 +66,29 @@ updates:
|
||||
day: "saturday"
|
||||
timezone: "Europe/Berlin"
|
||||
time: "03:00"
|
||||
|
||||
# frontend
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/frontend"
|
||||
rebase-strategy: "disabled"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "saturday"
|
||||
timezone: "Europe/Berlin"
|
||||
time: "03:00"
|
||||
- package-ecosystem: npm
|
||||
directory: "/frontend"
|
||||
rebase-strategy: "disabled"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "saturday"
|
||||
timezone: "Europe/Berlin"
|
||||
time: "03:00"
|
||||
- package-ecosystem: docker
|
||||
directory: "/frontend"
|
||||
rebase-strategy: "disabled"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "saturday"
|
||||
timezone: "Europe/Berlin"
|
||||
time: "03:00"
|
||||
39
.github/file-filters.yml
vendored
39
.github/file-filters.yml
vendored
@ -1,3 +1,5 @@
|
||||
# These file filter patterns are used by the action https://github.com/dorny/paths-filter
|
||||
|
||||
backend: &backend
|
||||
- '.github/workflows/test-backend.yml'
|
||||
- 'backend/**/*'
|
||||
@ -12,5 +14,40 @@ webapp: &webapp
|
||||
- 'webapp/**/*'
|
||||
- 'package.json'
|
||||
|
||||
markdown-files: &markdown-files
|
||||
docs-check: &docs-check
|
||||
- '.github/workflows/check-documentation.yml'
|
||||
|
||||
markdown: &markdown
|
||||
- *docs-check
|
||||
- '**/*.md'
|
||||
- '.github/workflows/mlc_config.json'
|
||||
|
||||
vuepress: &vuepress
|
||||
- *docs-check
|
||||
- '.github/workflows/deploy-documentation.yml'
|
||||
- '.vuepress/**/*'
|
||||
- 'package.json'
|
||||
|
||||
documentation: &documentation
|
||||
- *vuepress
|
||||
- *markdown
|
||||
|
||||
# frontend
|
||||
frontend-test-lint-code: &frontend-test-lint-code
|
||||
- 'frontend/**/*'
|
||||
|
||||
frontend-test-unit-code: &frontend-test-unit-code
|
||||
- 'frontend/**/*'
|
||||
|
||||
frontend-test-build-code: &frontend-test-build-code
|
||||
- 'frontend/**/*'
|
||||
|
||||
frontend-test-build-docker: &frontend-test-build-docker
|
||||
- 'frontend/**/*'
|
||||
|
||||
frontend-test-build-docs: &frontend-test-build-docs
|
||||
- 'frontend/**/*.md'
|
||||
- 'frontend/.vuepress/*'
|
||||
|
||||
frontend-test-build-storybook: &frontend-test-build-storybook
|
||||
- 'frontend/**/*'
|
||||
56
.github/workflows/check-documentation.yml
vendored
56
.github/workflows/check-documentation.yml
vendored
@ -7,13 +7,14 @@ jobs:
|
||||
name: Detect File Changes - Markdown files
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
markdown-files: ${{ steps.changes.outputs.markdown-files }}
|
||||
markdown: ${{ steps.changes.outputs.markdown }}
|
||||
documentation: ${{ steps.changes.outputs.documentation }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Check for markdown file changes
|
||||
uses: dorny/paths-filter@v2.11.1
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
@ -22,20 +23,43 @@ jobs:
|
||||
|
||||
check-markdown-links:
|
||||
name: Check Markdown links
|
||||
if: needs.files-changed.outputs.markdown-files == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
if: needs.files-changed.outputs.markdown == 'true'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
- name: Remove old documentation files
|
||||
run: rm -rf ./deployment/src/old/ # workaround until https://github.com/gaurav-nelson/github-action-markdown-link-check/pull/183 has been done
|
||||
- name: Check Markdown Links
|
||||
uses: gaurav-nelson/github-action-markdown-link-check@master
|
||||
with:
|
||||
use-quiet-mode: 'yes'
|
||||
use-verbose-mode: 'no'
|
||||
check-modified-files-only: 'no'
|
||||
config-file: '.github/workflows/mlc_config.json'
|
||||
base-branch: 'master'
|
||||
folder-path: '.'
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Remove old documentation files
|
||||
run: rm -rf ./deployment/src/old/ ./CHANGELOG.md # workaround until https://github.com/gaurav-nelson/github-action-markdown-link-check/pull/183 has been done
|
||||
|
||||
- name: Check Markdown Links
|
||||
uses: gaurav-nelson/github-action-markdown-link-check@master
|
||||
with:
|
||||
use-quiet-mode: 'yes'
|
||||
use-verbose-mode: 'no'
|
||||
# at any .md file change take the chance to check the links in all .md files
|
||||
check-modified-files-only: 'no'
|
||||
config-file: '.github/workflows/mlc_config.json'
|
||||
base-branch: 'master'
|
||||
folder-path: '.'
|
||||
|
||||
test-vuepress-build:
|
||||
name: Test Vuepress build
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
if: needs.files-changed.outputs.documentation == 'true'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Setup Node 20
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: npm-install
|
||||
run: npm install
|
||||
|
||||
- name: npm-docs:build
|
||||
run: npm run docs:build
|
||||
|
||||
48
.github/workflows/deploy-documentation.yml
vendored
Normal file
48
.github/workflows/deploy-documentation.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
name: ocelot.social deploy documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
name: Detect File Changes - Markdown and Vuepress files
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
documentation: ${{ steps.changes.outputs.documentation }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Check for file changes
|
||||
uses: dorny/paths-filter@master
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-filters.yml
|
||||
list-files: shell
|
||||
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Setup Node 20
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Build Vuepress Pages
|
||||
run: npm install && npm run docs:build
|
||||
|
||||
- name: Deploy Vuepress to Github Pages
|
||||
uses: crazy-max/ghaction-github-pages@v4
|
||||
with:
|
||||
target_branch: gh-pages
|
||||
build_dir: .vuepress/dist
|
||||
author: Wolfgang Huß <vorstand@busfaktor.org>
|
||||
fqdn: docs.ocelot.social
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
21
.github/workflows/frontend.deploy.chromatic.yml
vendored
Normal file
21
.github/workflows/frontend.deploy.chromatic.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: "frontend:deploy:chromatic"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
name: Chromatic - Frontend
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Frontend | Build
|
||||
run: npm install && npm run chromatic -- --exit-zero-on-changes
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
37
.github/workflows/frontend.test.build.code.yml
vendored
Normal file
37
.github/workflows/frontend.test.build.code.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: "frontend:test:build test code"
|
||||
|
||||
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-code
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
changes: ${{ steps.changes.outputs.frontend-test-build-code }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-filters.yml
|
||||
list-files: shell
|
||||
|
||||
build:
|
||||
if: needs.files-changed.outputs.changes == 'true'
|
||||
name: Build - Frontend
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Build
|
||||
run: npm install && npm run build
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
52
.github/workflows/frontend.test.build.docker.yml
vendored
Normal file
52
.github/workflows/frontend.test.build.docker.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
name: "frontend:test:build test docker"
|
||||
|
||||
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-docker
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
changes: ${{ steps.changes.outputs.frontend-test-build-docker }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-filters.yml
|
||||
list-files: shell
|
||||
|
||||
build-production:
|
||||
if: needs.files-changed.outputs.changes == 'true'
|
||||
name: Build Docker Production - Frontend
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Build Docker Production
|
||||
run: docker compose -f docker-compose.yml build
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
|
||||
build-development:
|
||||
if: needs.files-changed.outputs.changes == 'true'
|
||||
name: Build Docker Development - Frontend
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Build Docker Development
|
||||
run: docker compose build
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
37
.github/workflows/frontend.test.build.docs.yml
vendored
Normal file
37
.github/workflows/frontend.test.build.docs.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: "frontend:test:build test docs"
|
||||
|
||||
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-docs
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
changes: ${{ steps.changes.outputs.frontend-test-build-docs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-filters.yml
|
||||
list-files: shell
|
||||
|
||||
build:
|
||||
if: needs.files-changed.outputs.changes == 'true'
|
||||
name: Build Docs - Frontend
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Build Docs
|
||||
run: npm install && npm run docs:build
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
37
.github/workflows/frontend.test.build.storybook.yml
vendored
Normal file
37
.github/workflows/frontend.test.build.storybook.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
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@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v3.0.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
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Build Storybook
|
||||
run: npm install && npm run storybook:build
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
37
.github/workflows/frontend.test.lint.code.yml
vendored
Normal file
37
.github/workflows/frontend.test.lint.code.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: "frontend:test:lint code with defined linters"
|
||||
|
||||
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-lint-code
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
changes: ${{ steps.changes.outputs.frontend-test-lint-code }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-filters.yml
|
||||
list-files: shell
|
||||
|
||||
lint:
|
||||
if: needs.files-changed.outputs.changes == 'true'
|
||||
name: Lint - Frontend
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Lint
|
||||
run: npm install && npm run test:lint
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
37
.github/workflows/frontend.test.unit.code.yml
vendored
Normal file
37
.github/workflows/frontend.test.unit.code.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: "frontend:test:unit test code with defined suites"
|
||||
|
||||
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-unit-code
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
changes: ${{ steps.changes.outputs.frontend-test-unit-code }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-filters.yml
|
||||
list-files: shell
|
||||
|
||||
unit:
|
||||
if: needs.files-changed.outputs.changes == 'true'
|
||||
name: Unit - Frontend
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
WORKING_DIRECTORY: ./frontend
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Frontend | Unit
|
||||
run: npm install && npm run test:unit
|
||||
working-directory: ${{env.WORKING_DIRECTORY}}
|
||||
2
.github/workflows/mlc_config.json
vendored
2
.github/workflows/mlc_config.json
vendored
@ -6,7 +6,7 @@
|
||||
"aliveStatusCodes": [200, 206, 303, 403],
|
||||
"ignorePatterns": [
|
||||
{
|
||||
"pattern": "^(https:\/\/github.com\/Ocelot-Social-Community\/Ocelot-Social\/pull\/|http:\/\/localhost)"
|
||||
"pattern": "^(https:\/\/github.com\/Ocelot-Social-Community\/Ocelot-Social\/(pull|deployment\/src\/old)\/|http:\/\/localhost)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
60
.github/workflows/publish.yml
vendored
60
.github/workflows/publish.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
- name: Neo4J | Save docker image
|
||||
run: docker save "ocelotsocialnetwork/neo4j-community" > /tmp/neo4j.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-neo4j-community
|
||||
path: /tmp/neo4j.tar
|
||||
@ -83,7 +83,7 @@ jobs:
|
||||
- name: Backend | Save docker image
|
||||
run: docker save "ocelotsocialnetwork/backend" > /tmp/backend.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-backend-production
|
||||
path: /tmp/backend.tar
|
||||
@ -132,7 +132,7 @@ jobs:
|
||||
- name: Webapp | Save docker image
|
||||
run: docker save "ocelotsocialnetwork/webapp" > /tmp/webapp.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-webapp-production
|
||||
path: /tmp/webapp.tar
|
||||
@ -184,7 +184,7 @@ jobs:
|
||||
- name: Maintenance | Save docker image
|
||||
run: docker save "ocelotsocialnetwork/maintenance" > /tmp/maintenance.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-maintenance-production
|
||||
path: /tmp/maintenance.tar
|
||||
@ -201,25 +201,25 @@ jobs:
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
steps:
|
||||
- name: Download Docker Image (Neo4J)
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docker-neo4j-community
|
||||
path: /tmp
|
||||
- run: docker load < /tmp/neo4j.tar
|
||||
- name: Download Docker Image (Backend)
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docker-backend-production
|
||||
path: /tmp
|
||||
- run: docker load < /tmp/backend.tar
|
||||
- name: Download Docker Image (WebApp)
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docker-webapp-production
|
||||
path: /tmp
|
||||
- run: docker load < /tmp/webapp.tar
|
||||
- name: Download Docker Image (Maintenance)
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docker-maintenance-production
|
||||
path: /tmp
|
||||
@ -253,45 +253,17 @@ jobs:
|
||||
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
|
||||
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
|
||||
- name: package-version-to-git-tag + build number
|
||||
uses: pkgdeps/git-tag-action@v2
|
||||
uses: pkgdeps/git-tag-action@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_repo: ${{ github.repository }}
|
||||
version: ${{ env.BUILD_VERSION }}
|
||||
git_commit_sha: ${{ github.sha }}
|
||||
git_tag_prefix: "b"
|
||||
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
uses: mikepenz/release-changelog-builder-action@v4
|
||||
with:
|
||||
configurationJson: |
|
||||
{
|
||||
"pr_template": "- ##{{NUMBER}} #{{TITLE}} #{{ASSIGNEES}}",
|
||||
"categories": [
|
||||
{
|
||||
"title": "### 🚀 Features",
|
||||
"labels": ["feat"]
|
||||
},
|
||||
{
|
||||
"title": "### 🐛 Fixes",
|
||||
"labels": ["fix"]
|
||||
},
|
||||
{
|
||||
"title": "### 💬 Refactoring, Documentation & Other",
|
||||
"labels": ["chore","ci","docs","refactor"]
|
||||
},
|
||||
{
|
||||
"title": "### 📦 Build & Dependencies",
|
||||
"labels": ["build","bump"]
|
||||
}
|
||||
],
|
||||
"max_pull_requests": 1000,
|
||||
"max_back_track_time_days": 1000
|
||||
}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
run: |
|
||||
yarn install
|
||||
yarn auto-changelog --latest-version ${{ env.VERSION }} --unreleased-only
|
||||
- name: package-version-to-git-release
|
||||
continue-on-error: true # Will fail if tag exists
|
||||
id: create_release
|
||||
@ -301,7 +273,7 @@ jobs:
|
||||
with:
|
||||
tag_name: ${{ env.VERSION }}
|
||||
release_name: ${{ env.VERSION }}
|
||||
body: ${{steps.changelog.outputs.changelog}}
|
||||
body_path: ./CHANGELOG.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
@ -321,7 +293,7 @@ jobs:
|
||||
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
|
||||
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
|
||||
#- name: Repository Dispatch
|
||||
# uses: peter-evans/repository-dispatch@v2
|
||||
# uses: peter-evans/repository-dispatch@v3
|
||||
# with:
|
||||
# token: ${{ github.token }}
|
||||
# event-type: trigger-ocelot-build-success
|
||||
@ -329,7 +301,7 @@ jobs:
|
||||
# client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "VERSION": "${VERSION}", "BUILD_DATE": "${BUILD_DATE}", "BUILD_COMMIT": "${BUILD_COMMIT}", "BUILD_VERSION": "${BUILD_VERSION}"}'
|
||||
|
||||
- name: Repository Dispatch stage.ocelot.social
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
with:
|
||||
token: ${{ secrets.OCELOT_PUBLISH_EVENT_PAT }} # this token is required to access the other repository
|
||||
event-type: trigger-ocelot-build-success
|
||||
@ -337,7 +309,7 @@ jobs:
|
||||
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "GITHUB_RUN_NUMBER": "${{ env.GITHUB_RUN_NUMBER }}", "VERSION": "${VERSION}", "BUILD_DATE": "${BUILD_DATE}", "BUILD_COMMIT": "${BUILD_COMMIT}", "BUILD_VERSION": "${BUILD_VERSION}"}'
|
||||
|
||||
- name: Repository Dispatch stage.yunite.me
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
with:
|
||||
token: ${{ secrets.OCELOT_PUBLISH_EVENT_PAT }} # this token is required to access the other repository
|
||||
event-type: trigger-ocelot-build-success
|
||||
|
||||
11
.github/workflows/test-backend.yml
vendored
11
.github/workflows/test-backend.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for backend file changes
|
||||
uses: dorny/paths-filter@v2.11.1
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
|
||||
- name: Cache docker images
|
||||
id: cache-neo4j
|
||||
uses: actions/cache/save@v3.3.2
|
||||
uses: actions/cache/save@v4.0.1
|
||||
with:
|
||||
path: /tmp/neo4j.tar
|
||||
key: ${{ github.run_id }}-backend-neo4j-cache
|
||||
@ -58,7 +58,7 @@ jobs:
|
||||
|
||||
- name: Cache docker images
|
||||
id: cache-backend
|
||||
uses: actions/cache/save@v3.3.2
|
||||
uses: actions/cache/save@v4.0.1
|
||||
with:
|
||||
path: /tmp/backend.tar
|
||||
key: ${{ github.run_id }}-backend-cache
|
||||
@ -87,14 +87,14 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Restore Neo4J cache
|
||||
uses: actions/cache/restore@v3.3.2
|
||||
uses: actions/cache/restore@v4.0.1
|
||||
with:
|
||||
path: /tmp/neo4j.tar
|
||||
key: ${{ github.run_id }}-backend-neo4j-cache
|
||||
fail-on-cache-miss: true
|
||||
|
||||
- name: Restore Backend cache
|
||||
uses: actions/cache/restore@v3.3.2
|
||||
uses: actions/cache/restore@v4.0.1
|
||||
with:
|
||||
path: /tmp/backend.tar
|
||||
key: ${{ github.run_id }}-backend-cache
|
||||
@ -108,6 +108,7 @@ jobs:
|
||||
- name: backend | copy env files
|
||||
run: |
|
||||
cp webapp/.env.template webapp/.env
|
||||
cp frontend/.env.dist frontend/.env
|
||||
cp backend/.env.template backend/.env
|
||||
|
||||
- name: backend | docker-compose
|
||||
|
||||
7
.github/workflows/test-e2e.yml
vendored
7
.github/workflows/test-e2e.yml
vendored
@ -13,6 +13,7 @@ jobs:
|
||||
- name: Copy env files
|
||||
run: |
|
||||
cp webapp/.env.template webapp/.env
|
||||
cp frontend/.env.dist frontend/.env
|
||||
cp backend/.env.template backend/.env
|
||||
|
||||
- name: Build docker images
|
||||
@ -36,7 +37,7 @@ jobs:
|
||||
|
||||
- name: Cache docker images
|
||||
id: cache
|
||||
uses: actions/cache/save@v3.3.2
|
||||
uses: actions/cache/save@v4.0.1
|
||||
with:
|
||||
path: |
|
||||
/opt/cucumber-json-formatter
|
||||
@ -58,7 +59,7 @@ jobs:
|
||||
job: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
steps:
|
||||
- name: Restore cache
|
||||
uses: actions/cache/restore@v3.3.2
|
||||
uses: actions/cache/restore@v4.0.1
|
||||
id: cache
|
||||
with:
|
||||
path: |
|
||||
@ -92,7 +93,7 @@ jobs:
|
||||
- name: Full stack tests | if tests failed, upload report
|
||||
id: e2e-report
|
||||
if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }}
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ocelot-e2e-test-report-pr${{ needs.docker_preparation.outputs.pr-number }}
|
||||
path: /home/runner/work/Ocelot-Social/Ocelot-Social/cypress/reports/cucumber_html_report
|
||||
|
||||
7
.github/workflows/test-webapp.yml
vendored
7
.github/workflows/test-webapp.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for frontend file changes
|
||||
uses: dorny/paths-filter@v2.11.1
|
||||
uses: dorny/paths-filter@v3.0.1
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
@ -50,7 +50,7 @@ jobs:
|
||||
docker save "ocelotsocialnetwork/webapp:test" > /tmp/webapp.tar
|
||||
|
||||
- name: Cache docker image
|
||||
uses: actions/cache/save@v3.3.2
|
||||
uses: actions/cache/save@v4.0.1
|
||||
with:
|
||||
path: /tmp/webapp.tar
|
||||
key: ${{ github.run_id }}-webapp-cache
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Restore webapp cache
|
||||
uses: actions/cache/restore@v3.3.2
|
||||
uses: actions/cache/restore@v4.0.1
|
||||
with:
|
||||
path: /tmp/webapp.tar
|
||||
key: ${{ github.run_id }}-webapp-cache
|
||||
@ -90,6 +90,7 @@ jobs:
|
||||
- name: Copy env files
|
||||
run: |
|
||||
cp webapp/.env.template webapp/.env
|
||||
cp frontend/.env.dist frontend/.env
|
||||
cp backend/.env.template backend/.env
|
||||
|
||||
- name: backend | docker-compose
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
name: "ocelot.social lint pull request CI"
|
||||
name: "test:lint pull request CI"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
@ -7,6 +7,10 @@ on:
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR title
|
||||
@ -26,8 +30,12 @@ jobs:
|
||||
scopes: |
|
||||
backend
|
||||
webapp
|
||||
frontend
|
||||
database
|
||||
docu
|
||||
docker
|
||||
release
|
||||
workflow
|
||||
other
|
||||
# Configure that a scope must always be provided.
|
||||
requireScope: true
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@ -8,14 +8,20 @@ yarn-error.log*
|
||||
.yarn-integrity
|
||||
.eslintcache
|
||||
kubeconfig.yaml
|
||||
backup-cron-job.log
|
||||
|
||||
node_modules/
|
||||
cypress/videos
|
||||
cypress/screenshots/
|
||||
cypress.env.json
|
||||
|
||||
.vuepress/.cache/
|
||||
.vuepress/.temp/
|
||||
.vuepress/dist/
|
||||
|
||||
|
||||
!.gitkeep
|
||||
**/coverage
|
||||
|
||||
release/
|
||||
*~
|
||||
*~
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { viteBundler } from '@vuepress/bundler-vite'
|
||||
|
||||
import meta from './config/meta'
|
||||
import theme from './config/theme'
|
||||
import plugins from './config/plugins'
|
||||
|
||||
export default defineUserConfig({
|
||||
pagePatterns: ['**/*.md', '!.vuepress', '!node_modules', '!backend/node_modules', '!webapp/node_modules', '!deployment/src/old'],
|
||||
bundler: viteBundler(),
|
||||
...meta,
|
||||
theme,
|
||||
plugins,
|
||||
})
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
import { searchProPlugin } from 'vuepress-plugin-search-pro'
|
||||
|
||||
export default [
|
||||
searchProPlugin({
|
||||
indexContent: true,
|
||||
autoSuggestions: true,
|
||||
customFields: [
|
||||
{
|
||||
getter: (page) => page.frontmatter.category,
|
||||
formatter: "Category: $content",
|
||||
},
|
||||
{
|
||||
getter: (page) => page.frontmatter.tag,
|
||||
formatter: "Tag: $content",
|
||||
},
|
||||
],
|
||||
})
|
||||
]
|
||||
@ -4,31 +4,63 @@ import { hopeTheme } from 'vuepress-theme-hope'
|
||||
|
||||
export default hopeTheme({
|
||||
favicon: 'favicon.ico',
|
||||
logo: '/logo.svg',
|
||||
docsRepo: 'https://github.com/Ocelot-Social-Community/Ocelot-Social',
|
||||
docsBranch: 'master',
|
||||
docsDir: '.',
|
||||
editLink: true,
|
||||
lastUpdated: false,
|
||||
contributors: false,
|
||||
print: false,
|
||||
pure: true,
|
||||
displayFooter: true,
|
||||
footer: 'CC BY busFaktor() e.V. & Authors',
|
||||
sidebar: generateSidebar('../../SUMMARY.md'),
|
||||
navbar: [
|
||||
{ text: 'Home', link: '/' },
|
||||
{
|
||||
text: 'Github',
|
||||
link: 'https://github.com/Ocelot-Social-Community/Ocelot-Social'
|
||||
},
|
||||
],
|
||||
plugins: {
|
||||
mdEnhance: {
|
||||
tabs: true,
|
||||
imgSize: true
|
||||
}
|
||||
logo: '/logo.svg',
|
||||
docsRepo: 'https://github.com/Ocelot-Social-Community/Ocelot-Social',
|
||||
docsBranch: 'master',
|
||||
docsDir: '.',
|
||||
editLink: true,
|
||||
lastUpdated: false,
|
||||
contributors: false,
|
||||
print: false,
|
||||
pure: true,
|
||||
navbarLayout: {
|
||||
start: ['Brand'],
|
||||
center: ['Links'],
|
||||
end: ['Repo', 'Outlook', 'Search'],
|
||||
},
|
||||
repo: 'Ocelot-Social-Community/Ocelot-Social',
|
||||
repoLabel: 'GitHub',
|
||||
repoDisplay: true,
|
||||
|
||||
|
||||
displayFooter: true,
|
||||
copyright: '© by <a href="https://busfaktor.org" target="_blank">busFaktor() e.V.</a> & Authors | <a href="https://ocelot.social/en/impressum/">Imprint</a>',
|
||||
footer: 'Released under the <a class="vt-link link link" href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer"><!--[-->MIT License<!--]--><!----></a>.',
|
||||
sidebar: generateSidebar('../../SUMMARY.md'),
|
||||
navbar: [
|
||||
{
|
||||
text: 'Demo',
|
||||
link: 'https://stage.ocelot.social/',
|
||||
target: '_self',
|
||||
},
|
||||
],
|
||||
plugins: {
|
||||
mdEnhance: {
|
||||
align: true,
|
||||
demo: true,
|
||||
imgLazyload: true,
|
||||
imgMark: true,
|
||||
imgSize: true,
|
||||
sub: true,
|
||||
sup: true,
|
||||
tabs: true,
|
||||
vPre: true,
|
||||
},
|
||||
searchPro: {
|
||||
indexContent: true,
|
||||
autoSuggestions: true,
|
||||
customFields: [
|
||||
{
|
||||
getter: (page) => page.frontmatter.category,
|
||||
formatter: "Category: $content",
|
||||
},
|
||||
{
|
||||
getter: (page) => page.frontmatter.tag,
|
||||
formatter: "Tag: $content",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function generateSidebar(summaryFileName) {
|
||||
|
||||
1
.vuepress/styles/palette.scss
Normal file
1
.vuepress/styles/palette.scss
Normal file
@ -0,0 +1 @@
|
||||
$theme-color: #17b53f;
|
||||
168
CHANGELOG.md
168
CHANGELOG.md
@ -4,10 +4,176 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [3.1.2](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.1.0...3.1.2)
|
||||
#### [3.2.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.1.2...3.2.0)
|
||||
|
||||
- feat(webapp): implement config for `date-time` format [`#6985`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6985)
|
||||
- build(other): bump eslint-plugin-n from 15.7.0 to 16.6.2 in /backend [`#6962`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6962)
|
||||
- feat(other): frontend workflows & test suites [`#6987`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6987)
|
||||
- feat(other): new frontend [`#6970`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6970)
|
||||
- feat(webapp): redesign post teaser date [`#6978`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6978)
|
||||
- Bump cypress from 13.6.3 to 13.6.4 [`#6984`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6984)
|
||||
- build(other): bump multiple-cucumber-html-reporter from 3.6.0 to 3.6.1 [`#6983`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6983)
|
||||
- fix(webapp): fix wrong content menu position on group profile page [`#6956`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6956)
|
||||
- fix(other): revert "remove temporarily some *.ocelot.social link from the readmes…" [`#6972`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6972)
|
||||
- fix(other): update and fix vuepress [`#6974`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6974)
|
||||
- docs(other): add description for a 1-click install and usage of kubernetes dashboard [`#6957`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6957)
|
||||
- fix(webapp): fix footer links [`#6971`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6971)
|
||||
- feat(frontend): per page title [`#69`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/69)
|
||||
- Bump dorny/paths-filter from 2.11.1 to 3.0.0 [`#62`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/62)
|
||||
- chore(frontend): update packages 28.01 [`#68`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/68)
|
||||
- Bump @babel/preset-env from 7.23.6 to 7.23.9 [`#6968`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6968)
|
||||
- Bump @faker-js/faker from 8.3.1 to 8.4.0 [`#6969`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6969)
|
||||
- Bump cypress from 13.6.2 to 13.6.3 [`#6967`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6967)
|
||||
- Bump pkgdeps/git-tag-action from 2 to 3 [`#6965`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6965)
|
||||
- Bump dorny/paths-filter from 2.11.1 to 3.0.0 [`#6964`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6964)
|
||||
- feat(webapp): add chat item to avatar navigation menu and change title of notification by removing `All …` [`#6953`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6953)
|
||||
- refactor(other): fix build command in docs deploy workflow [`#6955`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6955)
|
||||
- chore(other): revert pr - improve structure and readability of auto-generated changelog [`#6954`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6954)
|
||||
- feat(other): add documentation deployment [`#6863`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6863)
|
||||
- refactor(other): fix broken links in documentation [`#6825`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6825)
|
||||
- docs(other): add new neo4j env for default database name to readmes [`#6940`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6940)
|
||||
- Bump vue-advanced-chat from 2.0.7 to 2.0.10 in /webapp [`#6947`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6947)
|
||||
- chore(frontend): update packages 20 01 2024 [`#61`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/61)
|
||||
- Bump @babel/plugin-proposal-throw-expressions from 7.22.5 to 7.23.3 in /backend [`#6944`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6944)
|
||||
- Bump eslint-plugin-import from 2.29.0 to 2.29.1 in /backend [`#6946`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6946)
|
||||
- Bump @babel/preset-env from 7.22.20 to 7.23.8 in /backend [`#6945`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6945)
|
||||
- Bump @cucumber/cucumber from 10.1.0 to 10.3.1 [`#6943`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6943)
|
||||
- Bump @badeball/cypress-cucumber-preprocessor from 20.0.0 to 20.0.1 [`#6942`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6942)
|
||||
- Bump actions/cache from 3.3.3 to 4.0.0 [`#6941`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6941)
|
||||
- feat(webapp): improve registration slide nonce text [`#6850`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6850)
|
||||
- build(other): bump @babel/core from 7.23.6 to 7.23.7 [`#6920`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6920)
|
||||
- Bump linkify-it from 3.0.2 to 5.0.0 in /webapp [`#6932`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6932)
|
||||
- Bump ts-node from 10.9.1 to 10.9.2 in /backend [`#6926`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6926)
|
||||
- Bump @typescript-eslint/eslint-plugin from 5.60.0 to 5.62.0 in /backend [`#6929`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6929)
|
||||
- Bump eslint-config-prettier from 9.0.0 to 9.1.0 in /backend [`#6927`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6927)
|
||||
- Bump vuepress-theme-hope from 2.0.0-rc.6 to 2.0.0-rc.11 [`#6936`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6936)
|
||||
- Bump actions/cache from 3.3.2 to 3.3.3 [`#6937`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6937)
|
||||
- docs(frontend): fix readme [`#55`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/55)
|
||||
- feat(frontend): stories [`#54`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/54)
|
||||
- chore(frontend): update packages 13 01 2024 [`#53`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/53)
|
||||
- chore(other): add deployment script 'clusters.cron-backups.sh' [`#6813`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6813)
|
||||
- feat(frontend): snapshot tests [`#47`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/47)
|
||||
- refactor(other): ignore changelog file in markdown link checker [`#6933`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6933)
|
||||
- feat(frontend): test vike button [`#46`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/46)
|
||||
- feat(frontend): build server [`#45`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/45)
|
||||
- feat(frontend): utilize vike-navigate [`#44`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/44)
|
||||
- chore(frontend): update packages [`#43`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/43)
|
||||
- feat(other): change group description length min [`#6924`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6924)
|
||||
- Bump multiple-cucumber-html-reporter from 3.5.0 to 3.6.0 [`#6922`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6922)
|
||||
- Bump cypress from 13.6.1 to 13.6.2 [`#6919`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6919)
|
||||
- fix(frontend): deleted unused debug handlers [`#35`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/35)
|
||||
- Bump actions/checkout from 3 to 4 [`#33`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/33)
|
||||
- chore(workflow): dependabot support [`#32`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/32)
|
||||
- chore(frontend): apply vike fix [`#31`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/31)
|
||||
- chore(frontend): package updates [`#30`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/30)
|
||||
- fix(frontend): optimization [`#29`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/29)
|
||||
- Bump jest-environment-jsdom from 29.4.2 to 29.7.0 in /webapp [`#6907`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6907)
|
||||
- Bump vuepress-plugin-search-pro from 2.0.0-rc.4 to 2.0.0-rc.6 [`#6914`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6914)
|
||||
- Bump vuepress-theme-hope from 2.0.0-rc.4 to 2.0.0-rc.6 [`#6913`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6913)
|
||||
- Bump @badeball/cypress-cucumber-preprocessor from 19.2.0 to 20.0.0 [`#6911`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6911)
|
||||
- Bump @cucumber/cucumber from 10.0.1 to 10.1.0 [`#6912`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6912)
|
||||
- Bump @mapbox/mapbox-gl-geocoder from 5.0.1 to 5.0.2 in /webapp [`#6900`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6900)
|
||||
- Bump @vue/vue2-jest from 29.2.4 to 29.2.6 in /webapp [`#6899`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6899)
|
||||
- Bump @babel/preset-env from 7.23.5 to 7.23.6 [`#6895`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6895)
|
||||
- Bump @babel/core from 7.23.5 to 7.23.6 [`#6896`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6896)
|
||||
- Bump actions/download-artifact from 3 to 4 [`#6897`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6897)
|
||||
- Bump actions/upload-artifact from 3 to 4 [`#6898`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6898)
|
||||
- refactor(frontend): import order + sbcomp + some types [`#28`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/28)
|
||||
- feat(frontend): typechecks & type cleanups [`#27`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/27)
|
||||
- 6812 script auto backups for kubernetes servers database name as variable [`#6893`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6893)
|
||||
- fix(frontend): eslint relativ eparsing [`#26`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/26)
|
||||
- fix(other): eslint typescript strict [`#25`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/25)
|
||||
- build(other): bump eslint-plugin-vue from 6.2.2 to 9.19.2 in /webapp [`#6891`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6891)
|
||||
- ci(other): improve structure and readability of auto-generated changelog [`#6654`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6654)
|
||||
- fix(frontend): tests from dreammall [`#24`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/24)
|
||||
- Bump vuepress-theme-hope from 2.0.0-rc.1 to 2.0.0-rc.4 [`#6889`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6889)
|
||||
- Bump vuepress-plugin-search-pro from 2.0.0-rc.0 to 2.0.0-rc.4 [`#6888`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6888)
|
||||
- Bump @babel/preset-env from 7.23.3 to 7.23.5 [`#6883`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6883)
|
||||
- Bump @babel/core from 7.23.3 to 7.23.5 [`#6884`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6884)
|
||||
- Bump cypress from 13.6.0 to 13.6.1 [`#6881`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6881)
|
||||
- feat(frontend): test store [`#23`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/23)
|
||||
- Bump migrate from 2.0.0 to 2.0.1 in /backend [`#6876`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6876)
|
||||
- Bump vuepress-theme-hope from 2.0.0-rc.0 to 2.0.0-rc.1 [`#6871`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6871)
|
||||
- Bump @badeball/cypress-cucumber-preprocessor from 19.1.0 to 19.2.0 [`#6873`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6873)
|
||||
- fix(docu): include LICENSE file in docu build [`#22`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/22)
|
||||
- fix(docu): fix type error vuepress base [`#21`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/21)
|
||||
- fix(workflow): docs base configurable [`#20`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/20)
|
||||
- chore(other): upgrade cert-manager version [`#6848`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6848)
|
||||
- feat(other): include working vuepress for documentation automation [`#6836`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6836)
|
||||
- docs(other): remove temp `*.ocelot.social` links [`#6867`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6867)
|
||||
- Bump eslint-plugin-import from 2.27.5 to 2.29.0 in /backend [`#6860`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6860)
|
||||
- refactor(other): remove unused packages and scripts [`#6857`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6857)
|
||||
- Bump cypress from 13.5.1 to 13.6.0 [`#6859`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6859)
|
||||
- build(other): fix cucumber dependency deprecation [`#6856`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6856)
|
||||
- fix(backend): expired jwt in unit test [`#6864`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6864)
|
||||
- fix(docu): added docu for commit after subtree pull [`#19`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/19)
|
||||
- fix(docu): document how to update the subtree [`#18`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/18)
|
||||
- feat(other): document how to use as git subtree [`#17`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/17)
|
||||
- fix(frontend): cleanup [`#16`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/16)
|
||||
- feat(frontend): switch TopBar from DefaultLayout to PageShell [`#15`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/15)
|
||||
- feat(frontend): package updates [`#14`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/14)
|
||||
- feat(frontend): boilerplate function & layout [`#13`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/13)
|
||||
- docs(frontend): chromatic readme [`#11`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/11)
|
||||
- feat(frontend): chromatic + workflow [`#10`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/10)
|
||||
- refactor(frontend): clean structure & introduce aliases [`#9`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/9)
|
||||
- fix(workflow): lint & docu fixes [`#8`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/8)
|
||||
- feat(frontend): lint locales [`#7`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/7)
|
||||
- feat(frontend): stylelint & workflow build storybook [`#6`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6)
|
||||
- feat(workflow): deploy docs to github - workflow [`#5`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5)
|
||||
- feat(workflow): build test workflow [`#4`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4)
|
||||
- feat(workflow): test:unit workflow [`#3`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3)
|
||||
- feat(workflow): test:lint code - workflow [`#2`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/2)
|
||||
- Bump cropperjs from 1.5.6 to 1.6.1 in /webapp [`#6772`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6772)
|
||||
- Bump @faker-js/faker from 8.2.0 to 8.3.1 [`#6841`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6841)
|
||||
- build(other): bump sanitize-html from 1.22.1 to 2.11.0 in /backend [`#6819`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6819)
|
||||
- build(other): bump cypress from 13.5.0 to 13.5.1 [`#6840`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6840)
|
||||
- build(other): bump @badeball/cypress-cucumber-preprocessor from 19.1.0 to 19.1.1 [`#6842`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6842)
|
||||
- Bump wait-on from 7.1.0 to 7.2.0 [`#6839`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6839)
|
||||
- build(other): bump wait-on from 7.0.1 to 7.1.0 [`#6817`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6817)
|
||||
- build(other): bump dotenv from 8.2.0 to 16.3.1 in /backend [`#6827`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6827)
|
||||
- build(other): bump @babel/preset-env from 7.23.2 to 7.23.3 [`#6831`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6831)
|
||||
- build(other): bump @babel/core from 7.23.2 to 7.23.3 [`#6830`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6830)
|
||||
- build(other): bump cypress from 13.4.0 to 13.5.0 [`#6829`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6829)
|
||||
- Bump @badeball/cypress-cucumber-preprocessor from 19.0.0 to 19.1.0 [`#6832`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6832)
|
||||
- feat(other): add documentation check to CI [`#6824`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6824)
|
||||
- build(other): bump cypress from 13.3.1 to 13.4.0 [`#6820`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6820)
|
||||
- build(other): bump @badeball/cypress-cucumber-preprocessor from 18.0.6 to 19.0.0 [`#6818`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6818)
|
||||
- feat(backend): coverage backend to 90% [`#6814`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6814)
|
||||
- build(other): bump validator from 13.9.0 to 13.11.0 in /backend [`#6771`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6771)
|
||||
- build(other): bump eslint-import-resolver-typescript from 3.5.5 to 3.6.1 in /backend [`#6769`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6769)
|
||||
- fix(webapp): event date format [`#6784`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6784)
|
||||
- build(other): bump @babel/preset-env from 7.22.20 to 7.23.2 [`#6788`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6788)
|
||||
- build(other): bump @babel/core from 7.23.0 to 7.23.2 [`#6790`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6790)
|
||||
- build(other): bump @faker-js/faker from 8.1.0 to 8.2.0 [`#6799`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6799)
|
||||
- docs(other): fix divers links in readmes [`#6802`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6802)
|
||||
- chore(other): add script to set neo4j in offline-mode and back in online-mode [`#6182`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6182)
|
||||
- fix(other): fix and refine docs and add kubernetes cluster installation script [`#6796`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6796)
|
||||
- refactor(webapp): replace deprecated jest methods in webapp unit tests [`#6808`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6808)
|
||||
- fix(webapp): make filter menu visible if categories are inactive [`#6807`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6807)
|
||||
- fix(other): increase cypress timeouts [`#6809`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6809)
|
||||
- docs(other): refine deployments `docker-compose.yml` in deployment and main folder [`#6786`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6786)
|
||||
- fix(other): fix link in `deployment/TODO-next-update.md` to `deployment/deployment-values.md` [`#6729`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6729)
|
||||
- Bump cypress from 13.2.0 to 13.3.1 [`#6789`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6789)
|
||||
- fix(other): remove buggy space in filename 'neo4j-data-snapshot.yaml ' to 'neo4j-data-snapshot.yaml' [`#6777`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6777)
|
||||
- storybook tests [`ff7a1c5`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/ff7a1c548405c3a60341844679e70d93aebb2e3c)
|
||||
- update vuepress [`cbf7bdc`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/cbf7bdc84ccf02c9658748b945dac7ebc405e5b2)
|
||||
- update storybook [`a0b77d7`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/a0b77d78a3e7a483d204337e3d42dd9dd56ad69a)
|
||||
|
||||
#### [3.1.2](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.1.1...3.1.2)
|
||||
|
||||
> 3 October 2023
|
||||
|
||||
- chore(release): release v3.1.2 - fix kubernetes deployment by degrade Node version from v20.7.0 to v20.2.0 [`#6782`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6782)
|
||||
- fix(other): kubernetes error by degrading node version from v20.7.0 to v20.2.0 [`#6779`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6779)
|
||||
- fix(backend): cypher statement in user locales unit test [`#6780`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6780)
|
||||
- Release v3.1.2 - Fix Kubernetes Deployment by degrade Node version from v20.7.0 to v20.2.0 [`aa2d27e`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/aa2d27e8caefeac578fb30fc5b426dbd51e84b34)
|
||||
- Fix Dockerfile labels [`5d2c41d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5d2c41d12ec9c892a38d8f8e2325194618fc35e4)
|
||||
- Degrade Node version from v20.7.0 to v20.2.0 [`988e874`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/988e874934dcf0caa060600e843138664fb367c5)
|
||||
|
||||
#### [3.1.1](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.1.0...3.1.1)
|
||||
|
||||
> 27 September 2023
|
||||
|
||||
- chore(release): release v3.1.1 – move dkim to secrets and fix search etc. [`#6763`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6763)
|
||||
- chore(other): move kubrnetes dkim from confmap to secret yaml [`#6761`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6761)
|
||||
- build(other): bump @babel/preset-env from 7.22.9 to 7.22.20 in /backend [`#6741`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6741)
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
# CONTRIBUTING
|
||||
|
||||
Thank you so much for thinking of contributing to the <!-- [ -->ocelot.social<!-- ](https://ocelot.social) --> project! It's awesome you're here, we really appreciate it. :-\)
|
||||
Thank you so much for thinking of contributing to the [ocelot.social](https://ocelot.social) project! It's awesome you're here, we really appreciate it. :-\)
|
||||
|
||||
## Getting Set Up
|
||||
|
||||
Instructions for how to install all the necessary software and some code guidelines can be found in our main [Readme](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md) or in our [documentation](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/SUMMARY.md).
|
||||
Instructions for how to install all the necessary software and some code guidelines can be found in our main [Readme](./README.md) or in our [documentation](./SUMMARY.md).
|
||||
|
||||
To get you started we recommend that you join forces with a regular contributor. Please join [our Discord instance](https://discord.gg/AJSX9DCSUA) to chat with developers or just get in touch directly on an issue on either [Github](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues) or [Zenhub](https://app.zenhub.com/workspaces/ocelotsocial-5fb21ff922cb410015dd6535/board?filterLogic=any&repos=301151089):
|
||||
|
||||
@ -36,7 +36,7 @@ Every pull request needs to:
|
||||
|
||||
## Contribution Flow For Open Source Contributors
|
||||
|
||||
See [contributing in main README.md](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md#contributing)
|
||||
See [contributing in main README.md](./README.md#contributing)
|
||||
|
||||
## The Team
|
||||
|
||||
@ -171,11 +171,11 @@ Please copy and paste the following quotes for the languages:
|
||||
|
||||
## Docker – More Closely
|
||||
|
||||
### Apple M1 Platform
|
||||
### Apple Silicon Platform
|
||||
|
||||
***Attention:** For using Docker commands in Apple M1 environments!*
|
||||
***ATTENTION:** For using Docker commands in Apple Silicon environments!*
|
||||
|
||||
#### Environment Variable For Apple M1 Platform
|
||||
#### Environment Variable For Apple Silicon Platform (M1, M2 Chips)
|
||||
|
||||
If you encounter trouble building the docker containers on an Apple M1 chip you can try to explicitly define the target platform docker builds and pulls images for:
|
||||
|
||||
|
||||
25
README.md
25
README.md
@ -1,18 +1,19 @@
|
||||
# Ocelot.Social
|
||||
|
||||
[](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions)
|
||||
[](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions/workflows/test-backend.yml)
|
||||
[](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions/workflows/test-webapp.yml)
|
||||
[](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions/workflows/test-e2e.yml)
|
||||
[](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions)
|
||||
[](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/LICENSE.md)
|
||||
[](https://discord.gg/AJSX9DCSUA)
|
||||
[](https://www.codetriage.com/ocelot-social-community/ocelot-social)
|
||||
|
||||
<!-- [ -->Ocelot.social<!-- ](<https://ocelot.social>) --> is free and open source software program code to run social networks. Its development is supported by a community of programmers and interested network operators.
|
||||
[Ocelot.social](https://ocelot.social) is free and open source software program code to run social networks. Its development is supported by a community of programmers and interested network operators.
|
||||
|
||||
<!-- markdownlint-disable MD033 -->
|
||||
<p align="center">
|
||||
<!-- <a href="https://ocelot.social" target="_blank"> -->
|
||||
<img src="https://raw.githubusercontent.com/Ocelot-Social-Community/Ocelot-Social/master/webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%">
|
||||
<!-- </a> -->
|
||||
<!-- <p align="center"> -->
|
||||
<p style="text-align: center;">
|
||||
<a href="https://ocelot.social" target="_blank"><img src="https://raw.githubusercontent.com/Ocelot-Social-Community/Ocelot-Social/master/webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%"></a>
|
||||
</p>
|
||||
<!-- markdownlint-enable MD033 -->
|
||||
|
||||
@ -69,7 +70,7 @@ Try out our live demo network, see [here](#live-demo-and-developer-logins).
|
||||
If you're wondering how you could help, there are plenty of ways, e.g.:
|
||||
|
||||
- Spread the good word about ocelot.social to make it more popular:
|
||||
- Add the link <!-- [ -->ocelot.social<!-- ](https://ocelot.social)--> to your website.
|
||||
- Add the link [ocelot.social](https://ocelot.social) to your website.
|
||||
- Give ocelot.social a Like at <https://alternativeto.net/software/ocelot-social/>.
|
||||
- Star our project on GitHub at <https://github.com/Ocelot-Social-Community/Ocelot-Social/>.
|
||||
- Promote it on your social networks.
|
||||
@ -140,11 +141,11 @@ $ cd Ocelot-Social
|
||||
|
||||
### Live Demo and Developer Logins
|
||||
|
||||
**Try out our deployed <!-- [ -->development environment<!--](https://stage.ocelot.social)-->.**
|
||||
**Try out our deployed [development environment](https://stage.ocelot.social).**
|
||||
|
||||
Visit our staging networks:
|
||||
|
||||
- central staging network: <!-- [ -->stage.ocelot.social<!-- ](https://stage.ocelot.social)-->
|
||||
- central staging network: [stage.ocelot.social](https://stage.ocelot.social)
|
||||
<!-- - rebranded staging network: [rebrand.ocelot.social](https://stage.ocelot.social). -->
|
||||
|
||||
#### Login
|
||||
@ -173,7 +174,9 @@ Check the correct Docker installation by checking the version before proceeding.
|
||||
$ docker --version
|
||||
```
|
||||
|
||||
##### Start Ocelot-Social via Docker-Compose
|
||||
##### Start Ocelot-Social via Docker Compose
|
||||
|
||||
***ATTENTION:** For using Docker commands in Apple Silicon environments see [here](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/CONTRIBUTING.md#apple-silicon-platform).*
|
||||
|
||||
Prepare ENVs once beforehand:
|
||||
|
||||
@ -234,7 +237,7 @@ We are happy if you fork our repository, but we don't recommend it for developme
|
||||
|
||||
Clone this repository locally as [described above](#clone-the-repository), create your branch named `<issue-number>-<description>`, add your code and push your branch direct to this repository. Then create a PR by comparing it to our `master`.
|
||||
|
||||
**_!!! Be aware:_** Please don't compare from a fork, because the tests are breaking caused by credential problems.
|
||||
***!!! Be aware:*** Please don't compare from a fork, because the tests are breaking caused by credential problems.
|
||||
|
||||
Please run the following commands before you push:
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ocelot-social-backend",
|
||||
"version": "3.1.2",
|
||||
"version": "3.2.0",
|
||||
"description": "GraphQL Backend for ocelot.social",
|
||||
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
|
||||
"author": "ocelot.social Community",
|
||||
@ -24,10 +24,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/cli": "~7.8.4",
|
||||
"@babel/core": "~7.9.0",
|
||||
"@babel/core": "^7.23.7",
|
||||
"@babel/node": "~7.8.7",
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.22.5",
|
||||
"@babel/preset-env": "~7.22.20",
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.23.3",
|
||||
"@babel/preset-env": "~7.23.8",
|
||||
"@babel/register": "^7.9.0",
|
||||
"@sentry/node": "^5.15.4",
|
||||
"apollo-cache-inmemory": "~1.6.5",
|
||||
@ -39,7 +39,7 @@
|
||||
"aws-sdk": "^2.1425.0",
|
||||
"babel-core": "~7.0.0-0",
|
||||
"babel-eslint": "~10.1.0",
|
||||
"babel-jest": "~25.2.6",
|
||||
"babel-jest": "~29.7.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"bcryptjs": "~2.4.3",
|
||||
"cheerio": "~1.0.0-rc.3",
|
||||
@ -81,7 +81,7 @@
|
||||
"neo4j-driver": "^4.0.2",
|
||||
"neo4j-graphql-js": "^2.11.5",
|
||||
"neode": "^0.4.9",
|
||||
"node-fetch": "~2.6.1",
|
||||
"node-fetch": "^2.7.0",
|
||||
"nodemailer": "^6.4.4",
|
||||
"nodemailer-html-to-text": "^3.2.0",
|
||||
"request": "~2.88.2",
|
||||
@ -97,16 +97,16 @@
|
||||
"@faker-js/faker": "7.6.0",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^20.2.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"apollo-server-testing": "~2.11.0",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard": "^17.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"eslint-plugin-n": "^15.7.0",
|
||||
"eslint-plugin-n": "^16.6.2",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-security": "^1.7.1",
|
||||
@ -115,7 +115,7 @@
|
||||
"prettier": "^2.8.7",
|
||||
"rosie": "^2.0.1",
|
||||
"ts-jest": "^27.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"resolutions": {
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
// this file is duplicated in `backend/src/constants/group` and `webapp/constants/group.js`
|
||||
export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 50 // with removed HTML tags
|
||||
export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 3 // with removed HTML tags
|
||||
export const DESCRIPTION_EXCERPT_HTML_LENGTH = 250 // with removed HTML tags
|
||||
|
||||
@ -328,15 +328,15 @@ describe('in mode', () => {
|
||||
|
||||
describe('description', () => {
|
||||
describe('length without HTML', () => {
|
||||
describe('less then 100 chars', () => {
|
||||
describe('less then 3 chars', () => {
|
||||
it('throws error: "Description too short!"', async () => {
|
||||
const { errors } = await mutate({
|
||||
mutation: createGroupMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
description:
|
||||
'0123456789' +
|
||||
'<a href="https://domain.org/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">0123456789</a>',
|
||||
'0' +
|
||||
'<a href="https://domain.org/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">0</a>',
|
||||
},
|
||||
})
|
||||
expect(errors![0]).toHaveProperty('message', 'Description too short!')
|
||||
@ -2850,15 +2850,15 @@ describe('in mode', () => {
|
||||
|
||||
describe('description', () => {
|
||||
describe('length without HTML', () => {
|
||||
describe('less then 100 chars', () => {
|
||||
describe('less then 3 chars', () => {
|
||||
it('throws error: "Description too short!"', async () => {
|
||||
const { errors } = await mutate({
|
||||
mutation: updateGroupMutation(),
|
||||
variables: {
|
||||
id: 'my-group',
|
||||
description:
|
||||
'0123456789' +
|
||||
'<a href="https://domain.org/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">0123456789</a>',
|
||||
'0' +
|
||||
'<a href="https://domain.org/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">0</a>',
|
||||
},
|
||||
})
|
||||
expect(errors![0]).toHaveProperty('message', 'Description too short!')
|
||||
|
||||
1817
backend/yarn.lock
1817
backend/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,8 @@ module.exports = defineConfig({
|
||||
supportFile: "cypress/support/e2e.js",
|
||||
retries: 0,
|
||||
video: false,
|
||||
viewportHeight: 720,
|
||||
viewportWidth: 1290,
|
||||
setupNodeEvents,
|
||||
},
|
||||
env: parsed
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { Then } from "@badeball/cypress-cucumber-preprocessor";
|
||||
import 'cypress-network-idle';
|
||||
|
||||
Then("I click the checkbox show donations progress bar and save", () => {
|
||||
cy.get("#showDonations").click()
|
||||
cy.get(".donations-info-button").click()
|
||||
cy.waitForNetworkIdle(2000)
|
||||
})
|
||||
|
||||
@ -1 +1,7 @@
|
||||
CONFIGURATION=example
|
||||
# branding folder used for "docker compose up" run in deployment folder
|
||||
CONFIGURATION=stage.ocelot.social
|
||||
|
||||
# used in "scripts/clusters.backup-multiple-servers.sh"
|
||||
BACKUP_CONFIGURATIONS="stage.ocelot.social stage.wir.social"
|
||||
# if '<= 0' no backups will be deleted
|
||||
BACKUP_SAVED_BACKUPS_NUMBER=7
|
||||
@ -22,4 +22,4 @@ For example:
|
||||
$ minikube service webapp --namespace=ocelotsocialnetwork
|
||||
# optionally
|
||||
$ minikube service backend --namespace=ocelotsocialnetwork
|
||||
```
|
||||
```
|
||||
|
||||
@ -9,20 +9,18 @@ This repository is an in use template to rebrand, configure, and deploy [ocelot.
|
||||
The forked original repository is [stage.ocelot.social](https://github.com/Ocelot-Social-Community/stage.ocelot.social).
|
||||
|
||||
<!-- markdownlint-disable MD033 -->
|
||||
<p align="center">
|
||||
<!-- <a href="https://ocelot.social" target="_blank"> -->
|
||||
<img src="../webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%">
|
||||
<!-- </a> -->
|
||||
<p style="text-align: center;">
|
||||
<a href="https://ocelot.social" target="_blank"><img src="https://raw.githubusercontent.com/Ocelot-Social-Community/Ocelot-Social/master/webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%"></a>
|
||||
</p>
|
||||
<!-- markdownlint-enable MD033 -->
|
||||
|
||||
## Live demo
|
||||
|
||||
__Try out our deployed <!-- [ -->development environment<!-- ](https://stage.ocelot.social)-->.__
|
||||
__Try out our deployed [development environment](https://stage.ocelot.social).__
|
||||
|
||||
Visit our staging networks:
|
||||
|
||||
- central staging network: <!-- [ -->stage.ocelot.social<!-- ](https://stage.ocelot.social)-->
|
||||
- central staging network: [stage.ocelot.social](https://stage.ocelot.social)
|
||||
<!-- - rebranded staging network: [rebrand.ocelot.social](https://stage.ocelot.social). -->
|
||||
|
||||
Logins:
|
||||
@ -137,5 +135,4 @@ Browser compatibility testing with [BrowserStack](https://www.browserstack.com/)
|
||||
|
||||
See the [LICENSE](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/LICENSE.md) file for license rights and limitations (MIT).
|
||||
|
||||
|
||||
We need `DOCKER_BUILDKIT=0` for this to work.
|
||||
We need `DOCKER_BUILDKIT=0` for this to work.
|
||||
|
||||
@ -2,9 +2,26 @@
|
||||
|
||||
When you introduce a new version and branding and deploy it on your network, you need to consider the following changes and actions:
|
||||
|
||||
## Version >= 3.3.0 with 'ocelotDockerVersionTag' 3.3.0-XXX
|
||||
## Version >= 3.2.0 with 'ocelotDockerVersionTag' 3.2.0-XXX
|
||||
|
||||
- We have the new option to configure DKIM for sent e-mails in environment variables (`.env` or `values.yaml`), see [deployment-values.md](deployment-values.md):
|
||||
### Backend and Kubernetes Config `DBMS_DEFAULT_DATABASE`
|
||||
|
||||
- We have the new option to configure the default name of the Neo4j database to be used for operations and commands in environment variables (`.env`, `docker-compose.yml` or `values.yaml`).
|
||||
For more details see [deployment-values.md](deployment-values.md):
|
||||
|
||||
```yaml
|
||||
DBMS_DEFAULT_DATABASE: "graph.db"
|
||||
```
|
||||
|
||||
The default value is `neo4j` if it is not set.
|
||||
|
||||
### Webapp Config `dateTime`
|
||||
|
||||
- You can set `RELATIVE_DATETIME` and `ABSOLUT_DATETIME_FORMAT` in `branding/constants/dateTime.js` originally in main code file `webapp/constants/dateTime.js` to your preferred values.
|
||||
|
||||
## Version >= 3.1.0 with 'ocelotDockerVersionTag' 3.1.0-555
|
||||
|
||||
- We have the new option to configure DKIM for sent e-mails in environment variables (`.env`, `docker-compose.yml` or `values.yaml`), see [deployment-values.md](deployment-values.md):
|
||||
- `SMTP_DKIM_DOMAINNAME=`
|
||||
- `SMTP_DKIM_KEYSELECTOR=`
|
||||
- `SMTP_DKIM_PRIVATKEY=`
|
||||
@ -15,7 +32,7 @@ When you introduce a new version and branding and deploy it on your network, you
|
||||
|
||||
## Version >= 2.4.0 with 'ocelotDockerVersionTag' 2.4.0-298
|
||||
|
||||
- You have to set `SHOW_CONTENT_FILTER_HEADER_MENU` and `SHOW_CONTENT_FILTER_MASONRY_GRID` in `branding/constants/filter.js` originally in main code file `webapp/constants/filter.js` to your preferred value.
|
||||
- You have to set `SHOW_CONTENT_FILTER_HEADER_MENU` and `SHOW_CONTENT_FILTER_MASONRY_GRID` in `branding/constants/filter.js` originally in main code file `webapp/constants/filter.js` to your preferred values.
|
||||
|
||||
### Main Code PR – feat(webapp): map #5843
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit a930f11d8f2d0c11136ff0bf9188aaab9cabc5d1
|
||||
Subproject commit fdc2e52fa444b300e1c4736600bc0e9ae3314222
|
||||
@ -3,6 +3,21 @@
|
||||
For each deployment, you need to set the environment variables and configurations.
|
||||
Here is some specific information on how to set the values.
|
||||
|
||||
## Webapp
|
||||
|
||||
We have several configuration possibilities just in the frontend.
|
||||
|
||||
### Date Time
|
||||
|
||||
In file `branding/constants/dateTime.js`.
|
||||
|
||||
- `RELATIVE_DATETIME`
|
||||
- `true` (default) or `false`
|
||||
- `ABSOLUT_DATETIME_FORMAT`
|
||||
- definition see [date-fns, format](https://date-fns.org/v3.3.1/docs/format):
|
||||
- `P`: just localized date
|
||||
- `Pp`: just localized date and time
|
||||
|
||||
## E-Mails
|
||||
|
||||
You need to set environment variables to send registration and invitation information or notifications to users, for example.
|
||||
@ -17,7 +32,7 @@ Sometimes it is enough to create an SPF record in your DNS.
|
||||
|
||||
### DKIM
|
||||
|
||||
However, if you need DKIM authorization and verification, you must set the appropriate environment variables:
|
||||
However, if you need DKIM authorization and verification, you must set the appropriate environment variables in: `.env`, `docker-compose.yml` or Helm script `values.yaml`:
|
||||
|
||||
```bash
|
||||
SMTP_DKIM_DOMAINNAME=<your e-mail sender domain>
|
||||
@ -36,3 +51,23 @@ To create the private and public DKIM key, see here:
|
||||
Information about the required PEM format can be found here:
|
||||
|
||||
<https://docs.progress.com/bundle/datadirect-hybrid-data-pipeline-installation-46/page/PEM-file-format.html>
|
||||
|
||||
## Neo4j Database
|
||||
|
||||
We have several configuration options for our Neo4j database.
|
||||
|
||||
### DBMS_DEFAULT_DATABASE – Default Database Name to be Used
|
||||
|
||||
If you need to set the default database name in Neo4j to be used for all operations and terminal commands like our backup scripts, you must set the appropriate environment variable in: `.env`, `docker-compose.yml` or Helm script `values.yaml`:
|
||||
|
||||
```yaml
|
||||
DBMS_DEFAULT_DATABASE: "graph.db"
|
||||
```
|
||||
|
||||
The default value is `neo4j` if it is not set.
|
||||
|
||||
As example see files:
|
||||
|
||||
- `neo4j/.env.template`
|
||||
- `deployment/docker-compose.yml`
|
||||
- `deployment/configurations/stage.ocelot.social/kubernetes/values.yaml.template`
|
||||
|
||||
@ -22,15 +22,15 @@ After the first deployment of the new network on your server, the database is in
|
||||
|
||||
***ATTENTION:*** When you are logged in for the first time, please change your (the admin's) e-mail to an existing one and change your password to a secure one !!!
|
||||
|
||||
## Use the Scripts
|
||||
## Using the Scripts
|
||||
|
||||
To use all the scripts you have to set the variable `CONFIGURATION` in your terminal by entering:
|
||||
To use most of the scripts you have to set the variable `CONFIGURATION` in your terminal by entering:
|
||||
|
||||
```bash
|
||||
# in deployment folder
|
||||
|
||||
# set configuration name to folder name in 'configurations' folder (network name)
|
||||
$ export CONFIGURATION=`<your-configuration-name>`
|
||||
$ export CONFIGURATION=<your-configuration-name>
|
||||
# to check this
|
||||
$ echo $CONFIGURATION
|
||||
```
|
||||
@ -64,9 +64,13 @@ $ scripts/cluster.maintenance.sh on
|
||||
$ scripts/cluster.maintenance.sh off
|
||||
```
|
||||
|
||||
### Backup Script
|
||||
### Backup Scripts
|
||||
|
||||
To save a locale backup of the database and uploaded images:
|
||||
Save backups.
|
||||
|
||||
#### Single Backup
|
||||
|
||||
To save a local backup of the database and uploaded images:
|
||||
|
||||
```bash
|
||||
# in deployment folder
|
||||
@ -76,3 +80,58 @@ $ scripts/cluster.backup.sh
|
||||
```
|
||||
|
||||
The backup will be saved into your network folders `backup` folder in a new folder with the date and time.
|
||||
|
||||
#### Multiple Networks Backup
|
||||
|
||||
In order to save several network backups locally, you must define the configuration names of all networks in `.env`. The template for this is `deployment/.env.dist`:
|
||||
|
||||
```bash
|
||||
# in the deployment folders '.env' set as example
|
||||
BACKUP_CONFIGURATIONS="stage.ocelot.social stage.wir.social"
|
||||
BACKUP_SAVED_BACKUPS_NUMBER=7
|
||||
```
|
||||
|
||||
If `BACKUP_SAVED_BACKUPS_NUMBER <= 0` then no backups will be deleted.
|
||||
|
||||
To actually save all the backups run:
|
||||
|
||||
```bash
|
||||
# in deployment folder
|
||||
|
||||
# save all backups listed in 'BACKUP_CONFIGURATIONS'
|
||||
# delete all backups older then the 'BACKUP_SAVED_BACKUPS_NUMBER' newest ones
|
||||
$ scripts/clusters.backup-multiple-servers.sh
|
||||
```
|
||||
|
||||
The backups will be saved into your networks folders `backup` folder in a new folder with the date and time.
|
||||
|
||||
#### Automated Backups
|
||||
|
||||
⚠️ *Attention: Please check carefully whether really the oldest backups have been deleted. As shells on different systems behave differently with regard to the commands used in this script.*
|
||||
|
||||
Install automated backups by a [cron job](https://en.wikipedia.org/wiki/Cron).
|
||||
Be aware of having the bash shell installed to run the script.
|
||||
The environment variables for the automated backups are described above.
|
||||
|
||||
Installing a cron job by editing the cron table file:
|
||||
|
||||
```bash
|
||||
# edit cron job table
|
||||
$ crontab -e
|
||||
```
|
||||
|
||||
In the editor add the line:
|
||||
|
||||
```bash
|
||||
# in cron job table file
|
||||
|
||||
# set a cron job every night at 04am server time
|
||||
# min hour day month weekday command
|
||||
00 04 * * * /root/Ocelot-Social/deployment/scripts/clusters.backup-multiple-servers.sh >> /root/Ocelot-Social/deployment/backup-cron-job.log
|
||||
```
|
||||
|
||||
This way the terminal output is written into a log file named `backup-cron-job.log` located in the deployment folder.
|
||||
|
||||
Be aware that the server datetime can differ from your local time.
|
||||
Especially by the change between summer and winter time, because servers usually have UTC.
|
||||
Find out the actual difference by running the command `date` on your server.
|
||||
|
||||
@ -168,6 +168,9 @@ services:
|
||||
# Uncomment following line for Neo4j Enterprise version instead of Community version
|
||||
# TODO: clarify if that is the only thing needed to unlock the Enterprise version
|
||||
# - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
|
||||
# set the name of the database to be used
|
||||
# - NEO4J_dbms_default__database=graph.db
|
||||
# - NEO4J_dbms_default__database=neo4j
|
||||
# TODO: Remove the playground from production
|
||||
# bring the database in offline mode to export or load dumps
|
||||
# command: ["tail", "-f", "/dev/null"]
|
||||
|
||||
@ -1,34 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
# time stamp
|
||||
printf "Backup started at:\n "
|
||||
date
|
||||
|
||||
# base setup
|
||||
SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
|
||||
# check CONFIGURATION
|
||||
if [ -z ${CONFIGURATION} ]; then
|
||||
echo "You must provide a `CONFIGURATION` via environment variable"
|
||||
if [[ -z "$CONFIGURATION" ]]; then
|
||||
echo "!!! You must provide a CONFIGURATION via environment variable !!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf " Cluster: %s\n" $CONFIGURATION
|
||||
|
||||
# configuration
|
||||
KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml}
|
||||
BACKUP_DATE=$(date "+%F_%H-%M-%S")
|
||||
BACKUP_FOLDER=${BACKUP_FOLDER:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/backup/${BACKUP_DATE}}
|
||||
|
||||
# create backup fodler
|
||||
printf "Backup folder name: %s\n" $BACKUP_DATE
|
||||
# create backup folder
|
||||
mkdir -p ${BACKUP_FOLDER}
|
||||
|
||||
# cluster maintenance mode on && Neo4j maintenance mode on
|
||||
${SCRIPT_DIR}/cluster.neo4j.sh maintenance on
|
||||
|
||||
# database backup
|
||||
echo "Dumping database ..."
|
||||
kubectl --kubeconfig=${KUBECONFIG} -n default exec -it \
|
||||
$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-neo4j | awk '{ print $1 }') \
|
||||
-- neo4j-admin dump --database=graph.db --to=/var/lib/neo4j/$BACKUP_DATE-neo4j-dump
|
||||
-- neo4j-admin dump --to=/var/lib/neo4j/$BACKUP_DATE-neo4j-dump
|
||||
# copy neo4j backup to local drive
|
||||
echo "Copying database to local file system ..."
|
||||
kubectl --kubeconfig=${KUBECONFIG} cp \
|
||||
default/$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-neo4j |awk '{ print $1 }'):/var/lib/neo4j/$BACKUP_DATE-neo4j-dump $BACKUP_FOLDER/neo4j-dump
|
||||
# copy image data
|
||||
echo "Copying public uploads to local file system ..."
|
||||
kubectl --kubeconfig=${KUBECONFIG} cp \
|
||||
default/$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-backend |awk '{ print $1 }'):/app/public/uploads $BACKUP_FOLDER/public-uploads
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
|
||||
# check CONFIGURATION
|
||||
if [ -z ${CONFIGURATION} ]; then
|
||||
if [[ -z "$CONFIGURATION" ]]; then
|
||||
echo "You must provide a `CONFIGURATION` via environment variable"
|
||||
exit 1
|
||||
fi
|
||||
@ -16,9 +16,11 @@ KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeco
|
||||
|
||||
case $1 in
|
||||
on)
|
||||
echo "Network maintenance: on"
|
||||
kubectl --kubeconfig=${KUBECONFIG} patch ingress ingress-ocelot-webapp --type merge --patch-file ${SCRIPT_DIR}/../src/kubernetes/patches/patch.ingress.maintenance.on.yaml
|
||||
;;
|
||||
off)
|
||||
echo "Network maintenance: off"
|
||||
kubectl --kubeconfig=${KUBECONFIG} patch ingress ingress-ocelot-webapp --type merge --patch-file ${SCRIPT_DIR}/../src/kubernetes/patches/patch.ingress.maintenance.off.yaml
|
||||
;;
|
||||
*)
|
||||
|
||||
@ -5,7 +5,7 @@ SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
|
||||
# check CONFIGURATION
|
||||
if [ -z ${CONFIGURATION} ]; then
|
||||
if [[ -z "$CONFIGURATION" ]]; then
|
||||
echo "You must provide a `CONFIGURATION` via environment variable"
|
||||
exit 1
|
||||
fi
|
||||
@ -21,20 +21,24 @@ case $1 in
|
||||
${SCRIPT_DIR}/cluster.maintenance.sh on
|
||||
|
||||
# set Neo4j in offline mode (maintenance)
|
||||
echo "Neo4j maintenance: on"
|
||||
kubectl --kubeconfig=${KUBECONFIG} get deployment ocelot-neo4j -o json \
|
||||
| jq '.spec.template.spec.containers[] += {"command": ["tail", "-f", "/dev/null"]}' \
|
||||
| kubectl --kubeconfig=${KUBECONFIG} apply -f -
|
||||
|
||||
# wait for the container to restart
|
||||
echo "Wait 60s ..."
|
||||
sleep 60
|
||||
;;
|
||||
off)
|
||||
# set Neo4j in online mode
|
||||
echo "Neo4j maintenance: off"
|
||||
kubectl --kubeconfig=${KUBECONFIG} get deployment ocelot-neo4j -o json \
|
||||
| jq 'del(.spec.template.spec.containers[].command)' \
|
||||
| kubectl --kubeconfig=${KUBECONFIG} apply -f -
|
||||
|
||||
# wait for the container to restart
|
||||
echo "Wait 60s ..."
|
||||
sleep 60
|
||||
|
||||
# maintenance mode off
|
||||
|
||||
91
deployment/scripts/clusters.backup-multiple-servers.sh
Executable file
91
deployment/scripts/clusters.backup-multiple-servers.sh
Executable file
@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
|
||||
# time stamp
|
||||
printf "\n\nMultiple backups started at:\n "
|
||||
date
|
||||
|
||||
# base setup
|
||||
SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
|
||||
# save old CONFIGURATION for later reset
|
||||
export SAVE_CONFIGURATION=$CONFIGURATION
|
||||
|
||||
# export all variables in "../.env"
|
||||
set -a
|
||||
source ${SCRIPT_DIR}/../.env
|
||||
set +a
|
||||
|
||||
# check BACKUP_CONFIGURATIONS
|
||||
if [[ -z "$BACKUP_CONFIGURATIONS" ]]; then
|
||||
#%! echo "You must provide a BACKUP_CONFIGURATIONS via environment variable"
|
||||
printf "!!! You must provide a BACKUP_CONFIGURATIONS via environment variable !!!\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check BACKUP_SAVED_BACKUPS_NUMBER
|
||||
if [[ -z ${BACKUP_SAVED_BACKUPS_NUMBER} ]]; then
|
||||
#%! echo "You must provide a BACKUP_SAVED_BACKUPS_NUMBER via environment variable"
|
||||
printf "!!! You must provide a BACKUP_SAVED_BACKUPS_NUMBER via environment variable !!!\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# convert configurations to array
|
||||
IFS=' ' read -a CONFIGURATIONS_ARRAY <<< "$BACKUP_CONFIGURATIONS"
|
||||
|
||||
# display the clusters
|
||||
printf "Backup the clusters:\n"
|
||||
for i in "${CONFIGURATIONS_ARRAY[@]}"
|
||||
do
|
||||
echo " $i"
|
||||
done
|
||||
|
||||
# deleting backups?
|
||||
if (( BACKUP_SAVED_BACKUPS_NUMBER >= 1 )); then
|
||||
printf "Keep the last %d backups for all networks.\n" $BACKUP_SAVED_BACKUPS_NUMBER
|
||||
else
|
||||
echo "!!! ATTENTION: No backups are deleted !!!"
|
||||
fi
|
||||
|
||||
echo "Cancel by ^C. You have 15 seconds"
|
||||
# wait for the admin to react
|
||||
sleep 15
|
||||
|
||||
printf "\n"
|
||||
|
||||
for i in "${CONFIGURATIONS_ARRAY[@]}"
|
||||
do
|
||||
export CONFIGURATION=$i
|
||||
# individual cluster backup
|
||||
${SCRIPT_DIR}/cluster.backup.sh
|
||||
|
||||
# deleting backups?
|
||||
if (( BACKUP_SAVED_BACKUPS_NUMBER >= 1 )); then
|
||||
# delete all oldest backups, but leave the last BACKUP_SAVED_BACKUPS_NUMBER
|
||||
|
||||
keep=$BACKUP_SAVED_BACKUPS_NUMBER
|
||||
path="$SCRIPT_DIR/../configurations/$CONFIGURATION/backup/"
|
||||
|
||||
cd $path
|
||||
|
||||
printf "In\n '$path'\n remove:\n"
|
||||
while [ `ls -1 | wc -l` -gt $keep ]; do
|
||||
oldest=`ls -c1 | sort -n | head -1`
|
||||
printf " %s\n" $oldest
|
||||
rm -rf $oldest
|
||||
done
|
||||
|
||||
printf "Keep the last %d backups:\n" $BACKUP_SAVED_BACKUPS_NUMBER
|
||||
ls -c1 | sort -n | awk '{print " " $0}'
|
||||
|
||||
cd $SCRIPT_DIR
|
||||
else
|
||||
echo "!!! ATTENTION: No backups are deleted !!!"
|
||||
fi
|
||||
|
||||
printf "\n"
|
||||
done
|
||||
|
||||
# reset CONFIGURATION to old
|
||||
export CONFIGURATION=$SAVE_CONFIGURATION
|
||||
echo "Reset to CONFIGURATION=$CONFIGURATION"
|
||||
@ -137,7 +137,7 @@ $ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-neo4j
|
||||
# bash: enter bash of Neo4j
|
||||
$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-neo4j | awk '{ print $1 }') -- bash
|
||||
# generate Dump
|
||||
neo4j% neo4j-admin dump --database=graph.db --to=/var/lib/neo4j/$(date +%F)-neo4j-dump
|
||||
neo4j% neo4j-admin dump --to=/var/lib/neo4j/$(date +%F)-neo4j-dump
|
||||
# exit bash
|
||||
neo4j% exit
|
||||
|
||||
@ -145,6 +145,9 @@ neo4j% exit
|
||||
$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-neo4j | awk '{ print $1 }') -- ls
|
||||
```
|
||||
|
||||
If you need a specific database name, add the option `--database=<name>` to the command `neo4j-admin dump`.
|
||||
To find out the default database name, see the [Neo4j readme](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/neo4j/README.md).
|
||||
|
||||
Lets copy the dump backup
|
||||
|
||||
```bash
|
||||
|
||||
@ -49,6 +49,49 @@ Skip `Patch & Minor Version Upgrades` for now.
|
||||
You don't need a 1-click app. Our helmet script will install the required NGINXs.
|
||||
Therefore, skip this step as well.
|
||||
|
||||
For a 1-click Kubernetes Dashboard or alternatives, follow the next steps.
|
||||
|
||||
## Install Kubernetes Dashboard
|
||||
|
||||
We recommend installing a Kubernetes Dashboard, as DigitalOcean no longer offers a pre-installed dashboard.
|
||||
|
||||
- 1-click-deployment of [Kubernetes Dashboard on DigitalOcean marketplace](https://marketplace.digitalocean.com/apps/kubernetes-dashboard)
|
||||
|
||||
There you will also find a section entitled `Getting Started`, which describes how you can log in from your local computer.
|
||||
|
||||
Very short description:
|
||||
|
||||
### In your DigitalOcean Account
|
||||
|
||||
For authentication, download the current cluster configuration file from DigitalOcean.
|
||||
|
||||
### In Terminal
|
||||
|
||||
Set the context of the cluster by command:
|
||||
|
||||
```bash
|
||||
$ kubectl config use-context <context-name>
|
||||
```
|
||||
|
||||
Port-forward the Kubernetes Dashboard to your local machine:
|
||||
|
||||
```bash
|
||||
# save pod name
|
||||
$ export POD_NAME=$(kubectl get pods -n kubernetes-dashboard -l "app.kubernetes.io/name=kubernetes-dashboard,app.kubernetes.io/instance=kubernetes-dashboard" -o jsonpath="{.items[0].metadata.name}")
|
||||
# forward port
|
||||
$ kubectl -n kubernetes-dashboard port-forward $POD_NAME 8443:8443
|
||||
```
|
||||
|
||||
### Log-In to Kubernetes Dashboard
|
||||
|
||||
Access the URL in your local web browser at `https://127.0.0.1:8443/`, and log in using your Kubernetes cluster credentials – downloaded config file. You may encounter a certificate warning, so make sure to override it.
|
||||
|
||||
## Alternatives to Kubernetes Dashboard
|
||||
|
||||
DigitalOcean has a website about Kubernetes Dashboard and alternatives:
|
||||
|
||||
- <https://www.digitalocean.com/community/conceptual-articles/kubernetes-visualization-tools?mkt_tok=MTEzLURUTi0yNjYAAAGQ0YS-wbZaWn5th-m86-fM7vgiLvxNipWpAsUrgd2z4YgiMB0aRgCIDYEiC0Y2c0H9tBsICZQ5ORKgssOgeSjOKSEfN3i7xUpzqXbdZiYxNL2Q>
|
||||
|
||||
## DNS Configuration
|
||||
|
||||
There are the following two ways to set up the DNS.
|
||||
@ -68,7 +111,7 @@ Take one of the IPs of perhaps two or more droplets in your cluster from the lis
|
||||
To understand what makes sense to do when managing your DNS with DigitalOcean, you need to know how DNS works:
|
||||
|
||||
DNS means `Domain Name System`. It resolves domains like `example.com` into an IP like `123.123.123.123`.
|
||||
DigitalOcean is not a domain registrar, but provides a DNS management service. If you use DigitalOcean's DNS management service, you can configure [your cluster](./README.md#dns) to always resolve the domain to the correct IP and automatically update it for that.
|
||||
DigitalOcean is not a domain registrar, but provides a DNS management service. If you use DigitalOcean's DNS management service, you can configure [your cluster](./README.md#dns) to always resolve the domain to the correct IP and automatically update it for that.
|
||||
The IPs of the DigitalOcean machines are not necessarily stable, so the cluster's DNS service will update the DNS records managed by DigitalOcean to the new IP as needed.
|
||||
|
||||
***CAUTION:** If you are using an external DNS, you currently have to do this manually, which can cause downtime.*
|
||||
|
||||
@ -20,4 +20,5 @@ data:
|
||||
NEO4J_dbms_security_procedures_unrestricted: "{{ .Values.NEO4J.DBMS_SECURITY_PROCEDURES_UNRESTRICTED }}"
|
||||
NEO4J_dbms_allow__format__migration: "true"
|
||||
NEO4J_dbms_allow__upgrade: "true"
|
||||
NEO4J_apoc_import_file_enabled: "{{ .Values.NEO4J.APOC_IMPORT_FILE_ENABLED }}"
|
||||
NEO4J_dbms_default__database: "{{ .Values.NEO4J.DBMS_DEFAULT_DATABASE }}"
|
||||
NEO4J_apoc_import_file_enabled: "{{ .Values.NEO4J.APOC_IMPORT_FILE_ENABLED }}"
|
||||
|
||||
@ -79,8 +79,8 @@ $ kubectl -n ocelot-social get pods
|
||||
$ kubectl cp ./neo4j-backup human-connection/<POD-ID>:/root/
|
||||
$ kubectl -n ocelot-social exec -it <POD-ID> bash
|
||||
# Once you're in the pod restore the backup and overwrite the default database
|
||||
# called `graph.db` with `--force`.
|
||||
# This will delete all existing data in database `graph.db`!
|
||||
# called `neo4j` with `--force`.
|
||||
# This will delete all existing data in database `neo4j`!
|
||||
> neo4j-admin load --from=/root/neo4j-backup --force
|
||||
> exit
|
||||
```
|
||||
|
||||
@ -21,6 +21,26 @@ services:
|
||||
# bind the local folder to the docker to allow live reload
|
||||
- ./webapp:/app
|
||||
|
||||
########################################################
|
||||
# FRONTEND #############################################
|
||||
########################################################
|
||||
frontend:
|
||||
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
|
||||
image: ocelotsocialnetwork/frontend:local-development
|
||||
build:
|
||||
target: development
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
ports:
|
||||
# port required for npm run dev
|
||||
- 24678:24678
|
||||
volumes:
|
||||
# This makes sure the docker container has its own node modules.
|
||||
# Therefore it is possible to have a different node version on the host machine
|
||||
- frontend_node_modules:/app/node_modules
|
||||
# bind the local folder to the docker to allow live reload
|
||||
- ./frontend:/app
|
||||
|
||||
########################################################
|
||||
# BACKEND ##############################################
|
||||
########################################################
|
||||
@ -77,4 +97,5 @@ services:
|
||||
|
||||
volumes:
|
||||
webapp_node_modules:
|
||||
frontend_node_modules:
|
||||
backend_node_modules:
|
||||
|
||||
@ -39,6 +39,36 @@ services:
|
||||
env_file:
|
||||
- ./webapp/.env
|
||||
|
||||
########################################################
|
||||
# FRONTEND #############################################
|
||||
########################################################
|
||||
frontend:
|
||||
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
|
||||
image: ocelotsocialnetwork/frontend:local-production
|
||||
container_name: frontend
|
||||
build:
|
||||
context: ./frontend
|
||||
target: production
|
||||
networks:
|
||||
- external-net
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
- 3002:3002
|
||||
environment:
|
||||
# Envs used in Dockerfile
|
||||
# - DOCKER_WORKDIR="/app"
|
||||
# - PORT="3002"
|
||||
- BUILD_DATE
|
||||
- BUILD_VERSION
|
||||
- BUILD_COMMIT
|
||||
- NODE_ENV="production"
|
||||
# Application only envs
|
||||
#- HOST=0.0.0.0 # This is nuxt specific, alternative value is HOST=webapp
|
||||
#- GRAPHQL_URI=http://backend:4000
|
||||
env_file:
|
||||
- ./frontend/.env
|
||||
|
||||
########################################################
|
||||
# BACKEND ##############################################
|
||||
########################################################
|
||||
@ -114,9 +144,12 @@ services:
|
||||
- NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.*
|
||||
- NEO4J_dbms_allow__format__migration=true
|
||||
- NEO4J_dbms_allow__upgrade=true
|
||||
# Uncomment following line for Neo4j Enterprise version instead of Community version
|
||||
# uncomment following line for Neo4j Enterprise version instead of Community version
|
||||
# TODO: clarify if that is the only thing needed to unlock the Enterprise version
|
||||
# - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
|
||||
# set the name of the database to be used
|
||||
# - NEO4J_dbms_default__database=graph.db
|
||||
# - NEO4J_dbms_default__database=neo4j
|
||||
# TODO: Remove the playground from production
|
||||
# bring the database in offline mode to export or load dumps
|
||||
# command: ["tail", "-f", "/dev/null"]
|
||||
|
||||
5
frontend/.dockerignore
Normal file
5
frontend/.dockerignore
Normal file
@ -0,0 +1,5 @@
|
||||
node_modules/
|
||||
build/
|
||||
coverage/
|
||||
.vuepress/.temp/
|
||||
.vuepress/.cache/
|
||||
5
frontend/.env.dist
Normal file
5
frontend/.env.dist
Normal file
@ -0,0 +1,5 @@
|
||||
# META
|
||||
PUBLIC_ENV__META__BASE_URL="http://localhost:3000"
|
||||
PUBLIC_ENV__META__DEFAULT_AUTHOR="IT Team 4 Change"
|
||||
PUBLIC_ENV__META__DEFAULT_DESCRIPTION="IT4C Frontend Boilerplate"
|
||||
PUBLIC_ENV__META__DEFAULT_TITLE="IT4C"
|
||||
5
frontend/.eslintignore
Normal file
5
frontend/.eslintignore
Normal file
@ -0,0 +1,5 @@
|
||||
node_modules/
|
||||
build/
|
||||
coverage/
|
||||
.storybook/
|
||||
.vuepress/
|
||||
182
frontend/.eslintrc.cjs
Normal file
182
frontend/.eslintrc.cjs
Normal file
@ -0,0 +1,182 @@
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: [
|
||||
'standard',
|
||||
'eslint:recommended',
|
||||
'plugin:@eslint-community/eslint-comments/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:security/recommended-legacy',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:@intlify/vue-i18n/recommended',
|
||||
'plugin:storybook/recommended',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
parser: '@typescript-eslint/parser',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'import', 'promise', 'security', 'vue', 'storybook'],
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: true,
|
||||
node: true,
|
||||
},
|
||||
'vue-i18n': {
|
||||
localeDir: './src/locales/*.json',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-console': 'error',
|
||||
'no-debugger': 'error',
|
||||
camelcase: 'error',
|
||||
indent: ['error', 2],
|
||||
'linebreak-style': ['error', 'unix'],
|
||||
semi: ['error', 'never'],
|
||||
// This makes sure our vike router does not throw errors
|
||||
'vue/multi-word-component-names': [
|
||||
'error',
|
||||
{
|
||||
ignores: ['+Page'],
|
||||
},
|
||||
],
|
||||
// Optional eslint-comments rule
|
||||
'@eslint-community/eslint-comments/no-unused-disable': 'error',
|
||||
'@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
|
||||
// import
|
||||
'import/export': 'error',
|
||||
'import/no-deprecated': 'error',
|
||||
'import/no-empty-named-blocks': 'error',
|
||||
'import/no-extraneous-dependencies': 'error',
|
||||
'import/no-mutable-exports': 'error',
|
||||
'import/no-unused-modules': 'error',
|
||||
'import/no-named-as-default': 'error',
|
||||
'import/no-named-as-default-member': 'error',
|
||||
'import/no-amd': 'error',
|
||||
'import/no-commonjs': 'error',
|
||||
'import/no-import-module-exports': 'error',
|
||||
'import/no-nodejs-modules': 'off',
|
||||
'import/unambiguous': 'off', // not compatible with scriptless vue files
|
||||
'import/default': 'error',
|
||||
'import/named': 'error',
|
||||
'import/namespace': 'error',
|
||||
'import/no-absolute-path': 'error',
|
||||
'import/no-cycle': 'error',
|
||||
'import/no-dynamic-require': 'error',
|
||||
'import/no-internal-modules': 'off',
|
||||
'import/no-relative-packages': 'error',
|
||||
'import/no-relative-parent-imports': [
|
||||
'error',
|
||||
{ ignore: ['#[src,root,components,pages,assets,layouts,stores,plugins,context,types]/*'] },
|
||||
],
|
||||
'import/no-self-import': 'error',
|
||||
'import/no-unresolved': 'error',
|
||||
'import/no-useless-path-segments': 'error',
|
||||
'import/no-webpack-loader-syntax': 'error',
|
||||
'import/consistent-type-specifier-style': 'error',
|
||||
'import/exports-last': 'off',
|
||||
'import/extensions': [
|
||||
'error',
|
||||
'never',
|
||||
{
|
||||
json: 'always',
|
||||
},
|
||||
],
|
||||
'import/first': 'error',
|
||||
'import/group-exports': 'off',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-anonymous-default-export': 'off', // todo - consider to enable again
|
||||
'import/no-default-export': 'off', // incompatible with vite & vike
|
||||
'import/no-duplicates': 'error',
|
||||
'import/no-named-default': 'error',
|
||||
'import/no-namespace': 'error',
|
||||
'import/no-unassigned-import': 'error',
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
|
||||
'newlines-between': 'always',
|
||||
alphabetize: {
|
||||
order: 'asc', // sort in ascending order. Options: ["ignore", "asc", "desc"]
|
||||
caseInsensitive: true, // ignore case. Options: [true, false]
|
||||
},
|
||||
distinctGroup: true,
|
||||
},
|
||||
],
|
||||
'import/prefer-default-export': 'off',
|
||||
// promise
|
||||
'promise/catch-or-return': 'error',
|
||||
'promise/no-return-wrap': 'error',
|
||||
'promise/param-names': 'error',
|
||||
'promise/always-return': 'error',
|
||||
'promise/no-native': 'off',
|
||||
'promise/no-nesting': 'warn',
|
||||
'promise/no-promise-in-callback': 'warn',
|
||||
'promise/no-callback-in-promise': 'warn',
|
||||
'promise/avoid-new': 'warn',
|
||||
'promise/no-new-statics': 'error',
|
||||
'promise/no-return-in-finally': 'warn',
|
||||
'promise/valid-params': 'warn',
|
||||
'promise/prefer-await-to-callbacks': 'error',
|
||||
'promise/no-multiple-resolved': 'error',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: ['./tsconfig.json', '**/tsconfig.json'],
|
||||
ecmaVersion: 'latest',
|
||||
parser: '@typescript-eslint/parser',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
'plugin:@typescript-eslint/strict',
|
||||
],
|
||||
rules: {
|
||||
// allow explicitly defined dangling promises
|
||||
'@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
|
||||
'no-void': ['error', { allowAsStatement: true }],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['!*.json'],
|
||||
plugins: ['prettier'],
|
||||
extends: ['plugin:prettier/recommended'],
|
||||
rules: {
|
||||
'prettier/prettier': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.json'],
|
||||
plugins: ['json'],
|
||||
extends: ['plugin:json/recommended-with-comments'],
|
||||
},
|
||||
{
|
||||
files: ['*.vue'],
|
||||
plugins: ['vuetify'],
|
||||
extends: ['plugin:vuetify/recommended'],
|
||||
},
|
||||
{
|
||||
files: ['*.[test,spec].[tj]s'],
|
||||
plugins: ['vitest'],
|
||||
extends: ['plugin:vitest/all'],
|
||||
},
|
||||
{
|
||||
files: ['*.yaml', '*.yml'],
|
||||
parser: 'yaml-eslint-parser',
|
||||
plugins: ['yml'],
|
||||
extends: ['plugin:yml/prettier'],
|
||||
},
|
||||
],
|
||||
}
|
||||
1
frontend/.github/.remarkignore
vendored
Normal file
1
frontend/.github/.remarkignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*
|
||||
13
frontend/.github/ISSUE_TEMPLATE.md
vendored
Normal file
13
frontend/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
<!--
|
||||
Please take a look at the issue templates at https://github.com/[ORGA/USER]/[REPO]/issues/new/choose
|
||||
before submitting a new issue. Following one of the issue templates will ensure maintainers can route your request efficiently.
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
## 💬 Issue
|
||||
<!-- Describe your Issue in detail. -->
|
||||
|
||||
<!-- Attach screenshots and drawings if needed. -->
|
||||
10
frontend/.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
10
frontend/.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: 🐛 Bug
|
||||
about: Create a report to help us improve
|
||||
labels: bug
|
||||
title: 🐛 [Bug]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
## 🐛 Bug
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the bug is.-->
|
||||
10
frontend/.github/ISSUE_TEMPLATE/devops.md
vendored
Normal file
10
frontend/.github/ISSUE_TEMPLATE/devops.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: 💥 DevOp
|
||||
about: Help us manage our deployed Software.
|
||||
labels: devops
|
||||
title: 💥 [DevOps]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
## 💥 DevOps
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->
|
||||
13
frontend/.github/ISSUE_TEMPLATE/epic.md
vendored
Normal file
13
frontend/.github/ISSUE_TEMPLATE/epic.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
name: 🌟 Epic
|
||||
about: Define a big development Step
|
||||
labels: epic
|
||||
title: 🌟 [EPIC]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
<!-- THIS ISSUE-TYPE IS NOT FOR YOU! -->
|
||||
<!-- Proceed only if you know what you are doing - have a chat with Project's Team first -->
|
||||
|
||||
## 🌟 EPIC
|
||||
<!-- Describe your Epic in detail. Include screenshots and drawings -->
|
||||
10
frontend/.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
10
frontend/.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: 🚀 Feature
|
||||
about: Suggest an idea for this project
|
||||
labels: feature
|
||||
title: 🚀 [Feature]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
## 🚀 Feature
|
||||
<!-- Give a short summary of the Feature. Use Screenshots if you want. -->
|
||||
13
frontend/.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
13
frontend/.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
name: 💬 Question
|
||||
about: If you need help understanding our Software.
|
||||
labels: question
|
||||
title: 💬 [Question]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
<!-- Question the project's team -->
|
||||
<!-- If you need an answer right away, consider to take other means of communication with the project's team -->
|
||||
|
||||
## 💬 Question
|
||||
<!-- Describe your Question in detail. Include screenshots and drawings if needed. -->
|
||||
10
frontend/.github/ISSUE_TEMPLATE/refactor.md
vendored
Normal file
10
frontend/.github/ISSUE_TEMPLATE/refactor.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: 🔧 Refactor
|
||||
about: Help us improve our code by refactoring it.
|
||||
labels: refactor
|
||||
title: 🔧 [Refactor]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
## 🔧 Refactor
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->
|
||||
13
frontend/.github/ISSUE_TEMPLATE/release.md
vendored
Normal file
13
frontend/.github/ISSUE_TEMPLATE/release.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
name: 🎂 Release
|
||||
about: Define a Release
|
||||
labels: release
|
||||
title: 🎂 [RELEASE]
|
||||
---
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
<!-- THIS ISSUE-TYPE IS NOT FOR YOU! -->
|
||||
<!-- Proceed only if you know what you are doing - have a chat with Project's Team first -->
|
||||
|
||||
## 🎂 RELEASE
|
||||
<!-- Describe your Release in detail. Include screenshots and drawings -->
|
||||
15
frontend/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
15
frontend/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<!-- You can find the latest issue templates here https://github.com/ulfgebhardt/issue-templates -->
|
||||
|
||||
## 🍰 Pullrequest
|
||||
<!-- Describe the Pullrequest. Use Screenshots if possible. -->
|
||||
|
||||
### Issues
|
||||
<!-- Which Issues does this fix, which are related?
|
||||
- fixes #XXX
|
||||
- relates #XXX
|
||||
-->
|
||||
- None
|
||||
|
||||
### Todo
|
||||
<!-- In case some parts are still missing, list them here. -->
|
||||
- [X] None
|
||||
21
frontend/.github/workflows/frontend.deploy.docs.yml
vendored
Normal file
21
frontend/.github/workflows/frontend.deploy.docs.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: "frontend:deploy:docs to github"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: vuepress-deploy
|
||||
uses: jenkey2011/vuepress-deploy@master
|
||||
env:
|
||||
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
#TARGET_REPO: username/repo
|
||||
#TARGET_BRANCH: master
|
||||
BUILD_SCRIPT: npm install && npm run docs:build
|
||||
BUILD_DIR: build/docs/
|
||||
VUEPRESS_BASE: "boilerplate-frontend"
|
||||
9
frontend/.gitignore
vendored
Normal file
9
frontend/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
node_modules/
|
||||
build/
|
||||
coverage/
|
||||
!.storybook/
|
||||
!.vuepress/
|
||||
.vuepress/.temp/
|
||||
.vuepress/.cache/
|
||||
build-storybook.log
|
||||
.env
|
||||
14
frontend/.prettierrc.json
Normal file
14
frontend/.prettierrc.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"quoteProps": "as-needed",
|
||||
"jsxSingleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": false,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
16
frontend/.remarkrc.json
Normal file
16
frontend/.remarkrc.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"plugins": [
|
||||
"remark-gfm",
|
||||
"remark-preset-lint-consistent",
|
||||
"remark-preset-lint-markdown-style-guide",
|
||||
"remark-preset-lint-recommended",
|
||||
[
|
||||
"remark-lint-maximum-line-length",
|
||||
false
|
||||
],
|
||||
[
|
||||
"remark-lint-list-item-indent",
|
||||
"space"
|
||||
]
|
||||
]
|
||||
}
|
||||
26
frontend/.storybook/StoryWrapper.vue
Normal file
26
frontend/.storybook/StoryWrapper.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<!-- .storybook/StoryWrapper.vue -->
|
||||
<template>
|
||||
<v-app :theme="themeName">
|
||||
<v-main>
|
||||
<slot name="story"></slot>
|
||||
</v-main>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export const DEFAULT_THEME = 'light'
|
||||
export default {
|
||||
props: {
|
||||
themeName: {
|
||||
default: DEFAULT_THEME,
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.v-application .v-application__wrap {
|
||||
min-height: unset;
|
||||
}
|
||||
</style>
|
||||
22
frontend/.storybook/main.ts
Normal file
22
frontend/.storybook/main.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import type { StorybookConfig } from '@storybook/vue3-vite'
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/vue3-vite',
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: 'tag',
|
||||
},
|
||||
core: {
|
||||
disableTelemetry: true, // 👈 Disables telemetry
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
54
frontend/.storybook/preview.ts
Normal file
54
frontend/.storybook/preview.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { setup } from '@storybook/vue3'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import { setPageContext } from '#context/usePageContext'
|
||||
import i18n from '#plugins/i18n'
|
||||
import CreateVuetify from '#plugins/vuetify'
|
||||
|
||||
import { withVuetifyTheme } from './withVuetifyTheme.decorator'
|
||||
|
||||
import type { Preview } from '@storybook/vue3'
|
||||
|
||||
setup((app) => {
|
||||
// Registers your app's plugins into Storybook
|
||||
const pinia = createPinia()
|
||||
app.use(pinia)
|
||||
app.use(i18n)
|
||||
app.use(CreateVuetify(i18n))
|
||||
|
||||
setPageContext(app, { urlPathname: '' })
|
||||
})
|
||||
|
||||
export const decorators = [withVuetifyTheme]
|
||||
|
||||
export const globalTypes = {
|
||||
theme: {
|
||||
name: 'Theme',
|
||||
description: 'Global theme for components',
|
||||
defaultValue: 'light',
|
||||
toolbar: {
|
||||
icon: 'paintbrush',
|
||||
// Array of plain string values or MenuItem shape
|
||||
items: [
|
||||
{ value: 'light', title: 'Light', left: '🌞' },
|
||||
{ value: 'dark', title: 'Dark', left: '🌛' },
|
||||
],
|
||||
// Change title based on selected value
|
||||
dynamicTitle: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default preview
|
||||
20
frontend/.storybook/withVuetifyTheme.decorator.ts
Normal file
20
frontend/.storybook/withVuetifyTheme.decorator.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { h } from 'vue'
|
||||
|
||||
import StoryWrapper, { DEFAULT_THEME } from './StoryWrapper.vue'
|
||||
|
||||
export const withVuetifyTheme = (storyFn, context) => {
|
||||
// Pull our global theme variable, fallback to DEFAULT_THEME
|
||||
const themeName = context.globals.theme || DEFAULT_THEME
|
||||
const story = storyFn()
|
||||
|
||||
return () => {
|
||||
return h(
|
||||
StoryWrapper,
|
||||
{ themeName }, // Props for StoryWrapper
|
||||
{
|
||||
// Puts your story into StoryWrapper's "story" slot with your story args
|
||||
story: () => h(story, { ...context.args }),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
9
frontend/.stylelintrc.json
Normal file
9
frontend/.stylelintrc.json
Normal 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"
|
||||
]
|
||||
}
|
||||
13
frontend/.vuepress/config.ts
Normal file
13
frontend/.vuepress/config.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { defaultTheme } from '@vuepress/theme-default'
|
||||
import { viteBundler } from '@vuepress/bundler-vite'
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
|
||||
export default defineUserConfig({
|
||||
title: 'IT4C Frontend Boilerplate Documentation',
|
||||
description: 'IT4C Frontend Boilerplate Documentation',
|
||||
dest: 'build/docs',
|
||||
base: process.env.VUEPRESS_BASE ? `/${process.env.VUEPRESS_BASE}/` : '/',
|
||||
pagePatterns: ['**/*.md', '**/LICENSE', '!.vuepress', '!node_modules'],
|
||||
bundler: viteBundler({}),
|
||||
theme: defaultTheme({}),
|
||||
})
|
||||
122
frontend/Dockerfile
Normal file
122
frontend/Dockerfile
Normal file
@ -0,0 +1,122 @@
|
||||
FROM node:21-alpine3.17 as base
|
||||
|
||||
# ENVs (available in production aswell, can be overwritten by commandline or env file)
|
||||
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
|
||||
ENV DOCKER_WORKDIR="/app"
|
||||
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
|
||||
ENV BUILD_DATE="1970-01-01T00:00:00.00Z"
|
||||
## We cannot do $(npm run version).${BUILD_NUMBER} here so we default to 0.0.0.0
|
||||
ENV BUILD_VERSION="0.0.0.0"
|
||||
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
|
||||
ENV BUILD_COMMIT="0000000"
|
||||
## SET NODE_ENV
|
||||
ENV NODE_ENV="production"
|
||||
## App relevant Envs
|
||||
ENV PORT="3002"
|
||||
|
||||
# Labels
|
||||
LABEL org.label-schema.build-date="${BUILD_DATE}"
|
||||
LABEL org.label-schema.name="it4c:frontend"
|
||||
LABEL org.label-schema.description="IT4C Frontend Boilerplate"
|
||||
LABEL org.label-schema.usage="https://github.com/IT4Change/boilerplate-frontend/blob/master/README.md"
|
||||
LABEL org.label-schema.url="https://github.com/IT4Change/boilerplate-frontend"
|
||||
LABEL org.label-schema.vcs-url="https://github.com/IT4Change/boilerplate-frontend/tree/master/"
|
||||
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
|
||||
LABEL org.label-schema.vendor="IT4C"
|
||||
LABEL org.label-schema.version="${BUILD_VERSION}"
|
||||
LABEL org.label-schema.schema-version="1.0"
|
||||
LABEL maintainer="info@it4c.dev"
|
||||
|
||||
# Install Additional Software
|
||||
## install: node-gyp dependencies
|
||||
# RUN apk --no-cache add g++ make python3
|
||||
|
||||
# Settings
|
||||
## Expose Container Port
|
||||
EXPOSE ${PORT}
|
||||
EXPOSE 24678
|
||||
|
||||
## Workdir
|
||||
RUN mkdir -p ${DOCKER_WORKDIR}
|
||||
WORKDIR ${DOCKER_WORKDIR}
|
||||
|
||||
##################################################################################
|
||||
# DEVELOPMENT (Connected to the local environment, to reload on demand) ##########
|
||||
##################################################################################
|
||||
FROM base as development
|
||||
|
||||
# We don't need to copy or build anything since we gonna bind to the
|
||||
# local filesystem which will need a rebuild anyway
|
||||
|
||||
# Run command
|
||||
# (for development we need to execute npm install since the
|
||||
# node_modules are on another volume and need updating)
|
||||
CMD /bin/sh -c "npm install && npm run dev"
|
||||
|
||||
##################################################################################
|
||||
# STORYBOOK ######################################################################
|
||||
##################################################################################
|
||||
FROM base as storybook
|
||||
|
||||
# We don't need to copy or build anything since we gonna bind to the
|
||||
# local filesystem which will need a rebuild anyway
|
||||
|
||||
# Run command
|
||||
# (for development we need to execute npm install since the
|
||||
# node_modules are on another volume and need updating)
|
||||
CMD /bin/sh -c "npm install && npm run storybook"
|
||||
|
||||
##################################################################################
|
||||
# DOCUMENTATION ##################################################################
|
||||
##################################################################################
|
||||
FROM base as documentation
|
||||
|
||||
# We don't need to copy or build anything since we gonna bind to the
|
||||
# local filesystem which will need a rebuild anyway
|
||||
|
||||
# Run command
|
||||
# (for development we need to execute npm install since the
|
||||
# node_modules are on another volume and need updating)
|
||||
CMD /bin/sh -c "npm install && npm run docs:dev"
|
||||
|
||||
##################################################################################
|
||||
# BUILD (Does contain all files and is therefore bloated) ########################
|
||||
##################################################################################
|
||||
FROM base as build
|
||||
|
||||
# Copy everything
|
||||
COPY . .
|
||||
# npm install
|
||||
RUN npm install --include=dev --frozen-lockfile --non-interactive
|
||||
# npm build
|
||||
RUN npm run build
|
||||
|
||||
##################################################################################
|
||||
# TEST ###########################################################################
|
||||
##################################################################################
|
||||
#FROM build as test
|
||||
|
||||
# Install Additional Software
|
||||
# RUN apk add --no-cache bash jq
|
||||
|
||||
# Run command
|
||||
#CMD /bin/sh -c "yarn run dev"
|
||||
|
||||
##################################################################################
|
||||
# PRODUCTION (Does contain only "binary"- and static-files to reduce image size) #
|
||||
##################################################################################
|
||||
FROM base as production
|
||||
|
||||
# Copy "binary"-files from build image
|
||||
COPY --from=build ${DOCKER_WORKDIR}/build ./build
|
||||
# Copy server
|
||||
COPY --from=build ${DOCKER_WORKDIR}/server ./server
|
||||
# Copy package.json & tsconfig.json
|
||||
COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json
|
||||
COPY --from=build ${DOCKER_WORKDIR}/package-lock.json ./package-lock.json
|
||||
COPY --from=build ${DOCKER_WORKDIR}/tsconfig.json ./tsconfig.json
|
||||
# Install production packages
|
||||
RUN npm install --omit=dev --frozen-lockfile --non-interactive
|
||||
|
||||
# Run command
|
||||
CMD /bin/sh -c "npm run server:prod"
|
||||
201
frontend/LICENSE
Normal file
201
frontend/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2023 Ulf Gebhardt
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
197
frontend/README.md
Normal file
197
frontend/README.md
Normal file
@ -0,0 +1,197 @@
|
||||
# boilerplate-frontend
|
||||
[![nodejs][badge-nodejs-img]][badge-nodejs-href]
|
||||
[![npm][badge-npm-img]][badge-npm-href]
|
||||
[![docker][badge-docker-img]][badge-docker-href]
|
||||
[![jq][badge-jq-img]][badge-jq-href]
|
||||
[![vue][badge-vue-img]][badge-vue-href]
|
||||
[![vike][badge-vike-img]][badge-vike-href]
|
||||
[![vuetify][badge-vuetify-img]][badge-vuetify-href]
|
||||
[![pinia][badge-pinia-img]][badge-pinia-href]
|
||||
[![vue-i18n][badge-vue-i18n-img]][badge-vue-i18n-href]
|
||||
[![eslint][badge-eslint-img]][badge-eslint-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]
|
||||
[![storybook][badge-storybook-img]][badge-storybook-href]
|
||||
[![vuepress][badge-vuepress-img]][badge-vuepress-href]
|
||||
[![chromatic][badge-chromatic-img]][badge-chromatic-href]
|
||||
|
||||
The IT4C Boilerplate for frontends
|
||||
|
||||

|
||||
|
||||
## Requirements & Technology
|
||||
|
||||
To be able to build this project you need `nodejs`, `npm` and optional `docker` and `jq`.
|
||||
|
||||
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`, `remark-cli` and `stylelint`.
|
||||
|
||||
This projects utilizes `storybook` and `chromatic` to develop, document & test frontend components and `vuepress` for static documentation generation.
|
||||
|
||||
## Commands
|
||||
|
||||
The following commands are available:
|
||||
|
||||
| Command | Description |
|
||||
|-----------------------------|--------------------------------------------------|
|
||||
| `npm install` | Project setup |
|
||||
| `npm run build` | Compiles and minifies for production |
|
||||
| `npm run server:prod` | Runs productions server |
|
||||
| **Develop** | |
|
||||
| `npm run dev` | Compiles and hot-reloads for development |
|
||||
| `npm run server:dev` | Run development server |
|
||||
| `npm run server:prod:ts` | Run production server without build (ts-node) |
|
||||
| `npm run server:build` | Build Server into an executable cjs file |
|
||||
| **Test** | |
|
||||
| `npm run test:lint` | Run all linters |
|
||||
| `npm run test:lint:eslint` | Run linter eslint |
|
||||
| `npm run test:lint:locales` | Run linter locales |
|
||||
| `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:update` | Run unit tests, coverage and update snapshots |
|
||||
| `npm run test:unit:dev` | Run all unit tests in watch mode |
|
||||
| `npm test` | Run all tests & linters |
|
||||
| **Storybook** | |
|
||||
| `npm run storybook` | Run Storybook |
|
||||
| `npm run storybook:build` | Build static storybook |
|
||||
| `npm run storybook:test` | Run tests against all storybook stories |
|
||||
| **Documentation** | |
|
||||
| `npm run docs:dev` | Run Documentation in development mode |
|
||||
| `npm run docs:build` | Build static documentation |
|
||||
| **Chromatic** | |
|
||||
| `npm run chromatic` | Run Chromatic. See Chromatic section for details |
|
||||
| **Maintenance** | |
|
||||
| `npm run update` | Check for updates |
|
||||
|
||||
### Docker
|
||||
|
||||
Docker can be run in development mode utilizing `docker-compose.overwrite.yml`:
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
|
||||
Docker can be run in production mode:
|
||||
```bash
|
||||
docker compose -f docker-compose.yml up
|
||||
```
|
||||
|
||||
### Chromatic
|
||||
|
||||
In order to use the chromatic workflow you need to provide a `CHROMATIC_PROJECT_TOKEN` in the repository secrets.
|
||||
|
||||
If you want to run chromatic from the command line you either have to provide this variable as well
|
||||
```bash
|
||||
export CHROMATIC_PROJECT_TOKEN=...
|
||||
npm run chromatic
|
||||
```
|
||||
or you have to append it via parameter:
|
||||
```bash
|
||||
npm run chromatic -- --project-token=...
|
||||
```
|
||||
|
||||
### Update
|
||||
|
||||
You can get a list of packes to update by running `npm run update`.
|
||||
|
||||
Appending `-u ` will also update the packages in the `package.json`. You have to run `npm install` again after.
|
||||
|
||||
```bash
|
||||
npm run update -- -u
|
||||
npm install
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
The following endpoints are provided given the right command is executed or all three if `docker compose` is used:
|
||||
|
||||
| Endpoint | Description |
|
||||
|------------------------------------------------|---------------|
|
||||
| [http://localhost:3000](http://localhost:3000) | Web |
|
||||
| [http://localhost:6006](http://localhost:6006) | Storybook |
|
||||
| [http://localhost:8080](http://localhost:8080) | Documentation |
|
||||
|
||||
## How to use as part of a project
|
||||
|
||||
If you want to use this as part of a larger project, e.g. in conjunction with a backend also utilizing a boilerplate you cannot use the template mechanic provided by github for this repository.
|
||||
|
||||
You can use the following commands to include the whole git history of the boilerplate and be able to update according to changes to this repo using another remote.
|
||||
|
||||
```bash
|
||||
git remote add xxx_boilerplate_frontend git@github.com:IT4Change/boilerplate-frontend.git
|
||||
git fetch xxx_boilerplate_frontend
|
||||
git merge -s ours --no-commit --allow-unrelated-histories xxx_boilerplate_frontend/master
|
||||
git read-tree --prefix=xxx/ -u xxx_boilerplate_frontend/master
|
||||
git commit -m "Imported boilerplate_frontend as a subtree under xxx/."
|
||||
```
|
||||
|
||||
To update the subtree you can use
|
||||
|
||||
```bash
|
||||
git subtree pull -P xxx/ xxx_boilerplate_frontend master
|
||||
git commit -m "Updated boilerplate_frontend in subtree under xxx/."
|
||||
```
|
||||
|
||||
Where `xxx` refers to the folder and product part you want to use the boilerplate in. This assumes that you might need several copies of the frontend boilerplate for you product.
|
||||
|
||||
This mechanic was taken from this [source](https://stackoverflow.com/questions/1683531/how-to-import-existing-git-repository-into-another/8396318#8396318)
|
||||
|
||||
## Known Problems
|
||||
|
||||
- [ ] [Image flicker](https://github.com/vuetifyjs/vuetify/issues/18772)
|
||||
- [ ] [Black Buttons](https://github.com/vuetifyjs/vuetify/issues/18773)
|
||||
|
||||
## License
|
||||
|
||||
[Apache 2.0](./LICENSE)
|
||||
|
||||
<!-- Badges -->
|
||||
[badge-nodejs-img]: https://img.shields.io/badge/nodejs-%3E%3D20.5.0-blue
|
||||
[badge-nodejs-href]: https://nodejs.org/
|
||||
|
||||
[badge-npm-img]: https://img.shields.io/badge/npm-latest-blue
|
||||
[badge-npm-href]: https://www.npmjs.com/package/npm
|
||||
|
||||
[badge-docker-img]: https://img.shields.io/badge/docker-latest-blue
|
||||
[badge-docker-href]: https://www.docker.com/
|
||||
|
||||
[badge-jq-img]: https://img.shields.io/badge/jq-latest-blue
|
||||
[badge-jq-href]: https://jqlang.github.io/jq/
|
||||
|
||||
[badge-vue-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vue&label=vue&color=green
|
||||
[badge-vue-href]: https://vuejs.org/
|
||||
|
||||
[badge-vike-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vike&label=vike&color=green
|
||||
[badge-vike-href]: https://vike.dev/
|
||||
|
||||
[badge-vuetify-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vuetify&label=vuetify&color=green
|
||||
[badge-vuetify-href]: https://vuetifyjs.com/
|
||||
|
||||
[badge-pinia-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.pinia&label=pinia&color=green
|
||||
[badge-pinia-href]: https://pinia.vuejs.org/
|
||||
|
||||
[badge-vue-i18n-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies%5B%27vue-i18n%27%5D&label=vue-i18n&color=green
|
||||
[badge-vue-i18n-href]: https://vue-i18n.intlify.dev/
|
||||
|
||||
[badge-eslint-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.eslint&label=eslint&color=yellow
|
||||
[badge-eslint-href]: https://eslint.org/
|
||||
|
||||
[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-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-href]: https://vitest.dev/
|
||||
|
||||
[badge-storybook-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.storybook&label=storybook&color=orange
|
||||
[badge-storybook-href]: https://storybook.js.org/
|
||||
|
||||
[badge-vuepress-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.vuepress&label=vuepress&color=orange
|
||||
[badge-vuepress-href]: https://vuepress.vuejs.org/
|
||||
|
||||
[badge-chromatic-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=devDependencies.chromatic&label=chromatic&color=orange
|
||||
[badge-chromatic-href]: https://www.chromatic.com/
|
||||
64
frontend/docker-compose.override.yml
Normal file
64
frontend/docker-compose.override.yml
Normal file
@ -0,0 +1,64 @@
|
||||
version: '3.4'
|
||||
services:
|
||||
# ######################################################
|
||||
# FRONTEND #############################################
|
||||
# ######################################################
|
||||
frontend:
|
||||
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
|
||||
image: it4c/frontend:local-development
|
||||
build:
|
||||
target: development
|
||||
environment:
|
||||
- NODE_ENV="development"
|
||||
# - DEBUG=true
|
||||
volumes:
|
||||
# This makes sure the docker container has its own node modules.
|
||||
# Therefore it is possible to have a different node version on the host machine
|
||||
- frontend_node_modules:/app/node_modules
|
||||
# bind the local folder to the docker to allow live reload
|
||||
- ./:/app
|
||||
|
||||
# ######################################################
|
||||
# STORYBOOK ############################################
|
||||
# ######################################################
|
||||
storybook:
|
||||
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
|
||||
image: it4c/frontend:local-storybook
|
||||
build:
|
||||
target: storybook
|
||||
environment:
|
||||
- NODE_ENV="development"
|
||||
# - DEBUG=true
|
||||
ports:
|
||||
- 6006:6006
|
||||
volumes:
|
||||
# This makes sure the docker container has its own node modules.
|
||||
# Therefore it is possible to have a different node version on the host machine
|
||||
- storybook_node_modules:/app/node_modules
|
||||
# bind the local folder to the docker to allow live reload
|
||||
- ./:/app
|
||||
|
||||
# ######################################################
|
||||
# DOCUMENTATION ########################################
|
||||
# ######################################################
|
||||
documentation:
|
||||
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
|
||||
image: it4c/frontend:local-documentation
|
||||
build:
|
||||
target: documentation
|
||||
environment:
|
||||
- NODE_ENV="development"
|
||||
# - DEBUG=true
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
# This makes sure the docker container has its own node modules.
|
||||
# Therefore it is possible to have a different node version on the host machine
|
||||
- documentation_node_modules:/app/node_modules
|
||||
# bind the local folder to the docker to allow live reload
|
||||
- ./:/app
|
||||
|
||||
volumes:
|
||||
frontend_node_modules:
|
||||
storybook_node_modules:
|
||||
documentation_node_modules:
|
||||
33
frontend/docker-compose.yml
Normal file
33
frontend/docker-compose.yml
Normal file
@ -0,0 +1,33 @@
|
||||
# This file defines the production settings. It is overwritten by docker-compose.override.yml,
|
||||
# which defines the development settings. The override.yml is loaded by default. Therefore it
|
||||
# is required to explicitly define if you want an production build:
|
||||
# > docker-compose -f docker-compose.yml up
|
||||
version: '3.4'
|
||||
services:
|
||||
frontend:
|
||||
# name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there
|
||||
image: it4c/frontend:local-production
|
||||
build:
|
||||
context: .
|
||||
target: production
|
||||
networks:
|
||||
- external-net
|
||||
- internal-net
|
||||
ports:
|
||||
- 3000:3000
|
||||
environment:
|
||||
# Envs used in Dockerfile
|
||||
# - DOCKER_WORKDIR="/app"
|
||||
# - PORT=3000
|
||||
# - BUILD_DATE="1970-01-01T00:00:00.00Z"
|
||||
# - BUILD_VERSION="0.0.0.0"
|
||||
# - BUILD_COMMIT="0000000"
|
||||
- NODE_ENV="production"
|
||||
# env_file:
|
||||
# - ./.env
|
||||
# - ./frontend/.env
|
||||
|
||||
networks:
|
||||
external-net:
|
||||
internal-net:
|
||||
internal: true
|
||||
31621
frontend/package-lock.json
generated
Normal file
31621
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
156
frontend/package.json
Normal file
156
frontend/package.json
Normal file
@ -0,0 +1,156 @@
|
||||
{
|
||||
"name": "ocelot-social-frontend",
|
||||
"version": "3.2.0",
|
||||
"description": "ocelot.social new Frontend (in development and not fully implemented) by IT4C Boilerplate for frontends",
|
||||
"main": "build/index.js",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/IT4Change/boilerplate-frontend.git"
|
||||
},
|
||||
"keywords": [
|
||||
"nodejs",
|
||||
"npm",
|
||||
"docker",
|
||||
"jq",
|
||||
"vue",
|
||||
"vike",
|
||||
"vuetify",
|
||||
"pinia",
|
||||
"vue-i18n",
|
||||
"eslint",
|
||||
"remark-cli",
|
||||
"stylelint",
|
||||
"vitest",
|
||||
"storybook",
|
||||
"vuepress",
|
||||
"chromatic"
|
||||
],
|
||||
"author": {
|
||||
"name": "Ulf Gebhardt"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/IT4Change/boilerplate-frontend/issues"
|
||||
},
|
||||
"homepage": "https://github.com/IT4Change/boilerplate-frontend#readme",
|
||||
"scripts": {
|
||||
"dev": "npm run server:dev",
|
||||
"prod": "npm run build && npm run server:prod",
|
||||
"build": "vite build && npm run server:build",
|
||||
"server": "node --loader ts-node/esm ./server/index.ts",
|
||||
"server:dev": "npm run server",
|
||||
"server:prod": "node ./build/index.cjs",
|
||||
"server:prod:ts": "cross-env NODE_ENV=production npm run server",
|
||||
"server:build": "tsx scripts/buildServer/buildServer",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"storybook:build": "storybook build -o build/storybook",
|
||||
"storybook:test": "test-storybook",
|
||||
"test:lint": "npm run test:lint:eslint && npm run test:lint:remark && npm run test:lint:style && npm run test:lint:locales",
|
||||
"test:lint:eslint": "eslint --ext .vue,.ts,.tsx,.js,.jsx,.cjs,.mjs,.json,.yml,.yaml --max-warnings 0 .",
|
||||
"test:lint:locales": "scripts/locales/locales.sh src/locales",
|
||||
"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:update": "npm run test:unit:dev -- run --coverage -u",
|
||||
"test:unit:dev": "vitest",
|
||||
"test": "npm run test:lint && npm run test:unit",
|
||||
"docs:dev": "vuepress dev .",
|
||||
"docs:build": "vuepress build .",
|
||||
"chromatic": "npx chromatic --build-script-name storybook:build",
|
||||
"update": "npx npm-check-updates"
|
||||
},
|
||||
"dependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^2.0.0",
|
||||
"@mdi/font": "^7.4.47",
|
||||
"@types/compression": "^1.7.5",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.11.20",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/compiler-sfc": "^3.4.19",
|
||||
"@vue/server-renderer": "3.4.19",
|
||||
"@vuepress/theme-default": "^2.0.0-rc.17",
|
||||
"compression": "^1.7.4",
|
||||
"cross-env": "^7.0.3",
|
||||
"express": "^4.18.2",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"sass": "^1.71.1",
|
||||
"sass-loader": "^14.1.1",
|
||||
"sirv": "^2.0.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3",
|
||||
"vike": "^0.4.163",
|
||||
"vite": "^5.1.4",
|
||||
"vue": "3.4.19",
|
||||
"vue-i18n": "^9.9.1",
|
||||
"vuetify": "^3.5.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "^4.1.0",
|
||||
"@intlify/eslint-plugin-vue-i18n": "^2.0.0",
|
||||
"@storybook/addon-essentials": "^7.6.17",
|
||||
"@storybook/addon-interactions": "^7.6.17",
|
||||
"@storybook/addon-links": "^7.6.17",
|
||||
"@storybook/blocks": "^7.6.17",
|
||||
"@storybook/test-runner": "^0.16.0",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@storybook/vue3": "^7.6.17",
|
||||
"@storybook/vue3-vite": "^7.6.17",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
||||
"@typescript-eslint/parser": "^7.0.2",
|
||||
"@vitest/coverage-v8": "^1.3.1",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"@vuepress/bundler-vite": "^2.0.0-rc.8",
|
||||
"chromatic": "^11.0.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-security": "^2.1.1",
|
||||
"eslint-plugin-storybook": "^0.8.0",
|
||||
"eslint-plugin-vitest": "^0.3.22",
|
||||
"eslint-plugin-vue": "^9.22.0",
|
||||
"eslint-plugin-vuetify": "^2.1.1",
|
||||
"eslint-plugin-yml": "^1.12.2",
|
||||
"happy-dom": "^13.5.0",
|
||||
"prettier": "^3.2.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"remark-cli": "^12.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"remark-preset-lint-consistent": "^5.1.2",
|
||||
"remark-preset-lint-markdown-style-guide": "^5.1.3",
|
||||
"remark-preset-lint-recommended": "^6.1.3",
|
||||
"storybook": "^7.6.17",
|
||||
"stylelint": "^16.2.1",
|
||||
"stylelint-config-css-modules": "^4.4.0",
|
||||
"stylelint-config-recess-order": "^4.6.0",
|
||||
"stylelint-config-recommended-vue": "^1.5.0",
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
"stylelint-config-standard-scss": "^13.0.0",
|
||||
"tsx": "^4.7.1",
|
||||
"vite-plugin-checker": "^0.6.4",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-vuetify": "^2.0.1",
|
||||
"vitest": "^1.3.1",
|
||||
"vue-tsc": "^1.8.27",
|
||||
"vuepress": "^2.0.0-rc.8"
|
||||
},
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*",
|
||||
"#pages/*": "./src/pages/*",
|
||||
"#assets/*": "./src/assets/*",
|
||||
"#layouts/*": "./src/layouts/*",
|
||||
"#stores/*": "./src/stores/*",
|
||||
"#src/*": "./src/*",
|
||||
"#plugins/*": "./renderer/plugins/*",
|
||||
"#context/*": "./renderer/context/*",
|
||||
"#types/*": "./types/*",
|
||||
"#root/*": "./*"
|
||||
}
|
||||
}
|
||||
16
frontend/renderer/+config.ts
Normal file
16
frontend/renderer/+config.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// See https://vike.dev/data-fetching
|
||||
export default {
|
||||
clientRouting: true,
|
||||
prefetchStaticAssets: 'viewport',
|
||||
passToClient: ['pageProps', /* 'urlPathname', */ 'routeParams'],
|
||||
meta: {
|
||||
title: {
|
||||
// Make the value of `title` available on both the server- and client-side
|
||||
env: { server: true, client: true },
|
||||
},
|
||||
description: {
|
||||
// Make the value of `description` available only on the server-side
|
||||
env: { server: true },
|
||||
},
|
||||
},
|
||||
}
|
||||
18
frontend/renderer/+onRenderClient.ts
Normal file
18
frontend/renderer/+onRenderClient.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { PageContext } from 'vike/types'
|
||||
|
||||
import { createApp } from './app'
|
||||
import { getTitle } from './utils'
|
||||
|
||||
let instance: ReturnType<typeof createApp>
|
||||
/* async */ function render(pageContext: PageContext) {
|
||||
if (!instance) {
|
||||
instance = createApp(pageContext)
|
||||
instance.app.mount('#app')
|
||||
} else {
|
||||
instance.app.changePage(pageContext)
|
||||
}
|
||||
|
||||
document.title = getTitle(pageContext)
|
||||
}
|
||||
|
||||
export default render
|
||||
74
frontend/renderer/+onRenderHtml.ts
Normal file
74
frontend/renderer/+onRenderHtml.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { renderToString as renderToString_ } from '@vue/server-renderer'
|
||||
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
|
||||
import { PageContext, PageContextServer } from 'vike/types'
|
||||
|
||||
import logoUrl from '#assets/favicon.ico'
|
||||
import image from '#assets/it4c-logo2-clean-bg_alpha-128x128.png'
|
||||
import { META } from '#src/env'
|
||||
|
||||
import { createApp } from './app'
|
||||
import { getDescription, getTitle } from './utils'
|
||||
|
||||
import type { App } from 'vue'
|
||||
|
||||
async function render(pageContext: PageContextServer & PageContext) {
|
||||
const { app, i18n } = createApp(pageContext, false)
|
||||
|
||||
const locale = i18n.global.locale.value
|
||||
|
||||
const appHtml = await renderToString(app)
|
||||
|
||||
// See https://vike.dev/head
|
||||
const title = getTitle(pageContext)
|
||||
const description = getDescription(pageContext)
|
||||
|
||||
const documentHtml = escapeInject`<!DOCTYPE html>
|
||||
<html lang="${locale}">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="${logoUrl}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="${description}" />
|
||||
<meta name="author" content="${META.DEFAULT_AUTHOR}">
|
||||
<meta property="og:title" content="${title}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="${META.BASE_URL}" />
|
||||
<meta property="og:description" content="${description}" />
|
||||
<meta property="og:image" content="${META.BASE_URL}${image}" />
|
||||
<meta property="og:image:alt" content="${title}" />
|
||||
<meta property="og:image:width" content="1200"/>
|
||||
<meta property="og:image:height" content="601"/>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<!--<meta name="twitter:site" content="@YourTwitterUsername" />-->
|
||||
<meta name="twitter:title" content="${title}" />
|
||||
<meta name="twitter:text:title" content="${title}" />
|
||||
<meta name="twitter:description" content="${description}" />
|
||||
<meta name="twitter:image" content="${META.BASE_URL}${image}" />
|
||||
<meta name="twitter:image:alt" content="${title}" />
|
||||
<title>${title}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">${dangerouslySkipEscape(appHtml)}</div>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
return {
|
||||
documentHtml,
|
||||
pageContext: {
|
||||
// We can add some `pageContext` here, which is useful if we want to do page redirection https://vike.dev/page-redirection
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async function renderToString(app: App) {
|
||||
let err: unknown
|
||||
// Workaround: renderToString_() swallows errors in production, see https://github.com/vuejs/core/issues/7876
|
||||
app.config.errorHandler = (err_) => {
|
||||
err = err_
|
||||
}
|
||||
const appHtml = await renderToString_(app)
|
||||
if (err) throw err
|
||||
return appHtml
|
||||
}
|
||||
|
||||
export default render
|
||||
71
frontend/renderer/app.ts
Normal file
71
frontend/renderer/app.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import { PageContext } from 'vike/types'
|
||||
import { createSSRApp, defineComponent, h, markRaw, reactive, Component } from 'vue'
|
||||
|
||||
import PageShell from '#components/PageShell.vue'
|
||||
import { setPageContext } from '#context/usePageContext'
|
||||
import i18n from '#plugins/i18n'
|
||||
import pinia from '#plugins/pinia'
|
||||
import CreateVuetify from '#plugins/vuetify'
|
||||
|
||||
const vuetify = CreateVuetify(i18n)
|
||||
|
||||
function createApp(pageContext: PageContext, isClient = true) {
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
let rootComponent: InstanceType<typeof PageWithWrapper>
|
||||
const PageWithWrapper = defineComponent({
|
||||
data: () => ({
|
||||
Page: markRaw(pageContext.Page),
|
||||
pageProps: markRaw(pageContext.pageProps || {}),
|
||||
isClient,
|
||||
}),
|
||||
created() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
rootComponent = this
|
||||
},
|
||||
render() {
|
||||
return h(
|
||||
PageShell as Component,
|
||||
{},
|
||||
{
|
||||
default: () => {
|
||||
return h(this.Page, this.pageProps)
|
||||
},
|
||||
},
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
if (isClient) {
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
}
|
||||
|
||||
const app = createSSRApp(PageWithWrapper)
|
||||
app.use(pinia)
|
||||
app.use(i18n)
|
||||
app.use(vuetify)
|
||||
|
||||
objectAssign(app, {
|
||||
changePage: (pageContext: PageContext) => {
|
||||
Object.assign(pageContextReactive, pageContext)
|
||||
rootComponent.Page = markRaw(pageContext.Page)
|
||||
rootComponent.pageProps = markRaw(pageContext.pageProps || {})
|
||||
},
|
||||
})
|
||||
|
||||
const pageContextReactive = reactive(pageContext)
|
||||
|
||||
setPageContext(app, pageContextReactive)
|
||||
|
||||
return { app, i18n }
|
||||
}
|
||||
|
||||
// Same as `Object.assign()` but with type inference
|
||||
function objectAssign<Obj extends object, ObjAddendum>(
|
||||
obj: Obj,
|
||||
objAddendum: ObjAddendum,
|
||||
): asserts obj is Obj & ObjAddendum {
|
||||
Object.assign(obj, objAddendum)
|
||||
}
|
||||
|
||||
export { createApp }
|
||||
22
frontend/renderer/context/usePageContext.ts
Normal file
22
frontend/renderer/context/usePageContext.ts
Normal file
@ -0,0 +1,22 @@
|
||||
// `usePageContext` allows us to access `pageContext` in any Vue component.
|
||||
// See https://vike.dev/pageContext-anywhere
|
||||
|
||||
import { PageContext } from 'vike/types'
|
||||
import { inject } from 'vue'
|
||||
|
||||
import type { App, InjectionKey } from 'vue'
|
||||
|
||||
export const vikePageContext: InjectionKey<PageContext> = Symbol('pageContext')
|
||||
|
||||
function usePageContext() {
|
||||
const pageContext = inject(vikePageContext)
|
||||
if (!pageContext) throw new Error('setPageContext() not called in parent')
|
||||
return pageContext
|
||||
}
|
||||
|
||||
function setPageContext(app: App, pageContext: PageContext) {
|
||||
app.provide(vikePageContext, pageContext)
|
||||
}
|
||||
|
||||
export { usePageContext }
|
||||
export { setPageContext }
|
||||
14
frontend/renderer/plugins/i18n.ts
Normal file
14
frontend/renderer/plugins/i18n.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
import de from '#src/locales/de.json'
|
||||
// import { de as $vuetify } from 'vuetify/locale'
|
||||
import en from '#src/locales/en.json'
|
||||
// import { en as $vuetify } from 'vuetify/locale'
|
||||
|
||||
export default createI18n({
|
||||
legacy: false, // Vuetify does not support the legacy mode of vue-i18n
|
||||
globalInjection: true,
|
||||
locale: 'de',
|
||||
fallbackLocale: 'en',
|
||||
messages: { de, en },
|
||||
})
|
||||
4
frontend/renderer/plugins/pinia.ts
Normal file
4
frontend/renderer/plugins/pinia.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
const pinia = createPinia()
|
||||
export default pinia
|
||||
16
frontend/renderer/plugins/vuetify.ts
Normal file
16
frontend/renderer/plugins/vuetify.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import '@mdi/font/css/materialdesignicons.css'
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import 'vuetify/styles'
|
||||
import { I18n, useI18n } from 'vue-i18n'
|
||||
import { createVuetify } from 'vuetify'
|
||||
import { createVueI18nAdapter } from 'vuetify/locale/adapters/vue-i18n'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export default (i18n: I18n<any, NonNullable<unknown>, NonNullable<unknown>, string, false>) =>
|
||||
createVuetify({
|
||||
locale: {
|
||||
adapter: createVueI18nAdapter({ i18n, useI18n }),
|
||||
},
|
||||
ssr: true,
|
||||
})
|
||||
19
frontend/renderer/utils.ts
Normal file
19
frontend/renderer/utils.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { PageContext } from 'vike/types'
|
||||
|
||||
import { META } from '#src/env'
|
||||
|
||||
function getTitle(pageContext: PageContext) {
|
||||
// The value exported by /pages/**/+title.js is available at pageContext.config.title
|
||||
const val = pageContext.config.title
|
||||
if (typeof val === 'string') return val
|
||||
if (typeof val === 'function') return String(val(pageContext))
|
||||
return META.DEFAULT_TITLE
|
||||
}
|
||||
function getDescription(pageContext: PageContext) {
|
||||
const val = pageContext.config.description
|
||||
if (typeof val === 'string') return val
|
||||
if (typeof val === 'function') return val(pageContext)
|
||||
return META.DEFAULT_DESCRIPTION
|
||||
}
|
||||
|
||||
export { getTitle, getDescription }
|
||||
56
frontend/scripts/buildServer/buildServer.ts
Normal file
56
frontend/scripts/buildServer/buildServer.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { build } from 'esbuild'
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import fs, { ensureDir, remove } from 'fs-extra'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = path.dirname(__filename)
|
||||
|
||||
async function buildServer() {
|
||||
const result = await build({
|
||||
absWorkingDir: process.cwd(),
|
||||
entryPoints: [path.join(path.resolve(__dirname, '../../server/'), 'index.ts')],
|
||||
outfile: 'index.cjs',
|
||||
write: false,
|
||||
minify: true,
|
||||
platform: 'node',
|
||||
bundle: true,
|
||||
format: 'cjs',
|
||||
sourcemap: false,
|
||||
treeShaking: true,
|
||||
define: { 'import.meta.url': 'importMetaUrl', 'process.env.NODE_ENV': '"production"' },
|
||||
inject: [path.resolve(__dirname, './import.meta.url-polyfill.ts')],
|
||||
banner: {
|
||||
js: `/* eslint-disable prettier/prettier */`,
|
||||
},
|
||||
tsconfig: path.resolve(__dirname, './tsconfig.buildServer.json'),
|
||||
plugins: [
|
||||
{
|
||||
name: 'externalize-deps',
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /.*/ }, (args) => {
|
||||
const id = args.path
|
||||
if (id[0] !== '.' && !path.isAbsolute(id)) {
|
||||
return {
|
||||
external: true,
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
const { text } = result.outputFiles[0]
|
||||
const filePath = path.join(path.resolve(__dirname, '../../build/'), 'index.cjs')
|
||||
if (fs.existsSync(filePath)) {
|
||||
await remove(filePath)
|
||||
}
|
||||
await ensureDir(path.dirname(filePath))
|
||||
// eslint-disable-next-line import/no-named-as-default-member
|
||||
await fs.writeFile(filePath, text)
|
||||
}
|
||||
|
||||
void buildServer()
|
||||
7
frontend/scripts/buildServer/import.meta.url-polyfill.ts
Normal file
7
frontend/scripts/buildServer/import.meta.url-polyfill.ts
Normal file
@ -0,0 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
export const importMetaUrl =
|
||||
typeof document === 'undefined'
|
||||
? (new (require('url').URL)('file:' + __filename) as URL).href
|
||||
: (document.currentScript && (document.currentScript as any).src) ||
|
||||
new URL('main.js', document.baseURI).href
|
||||
16
frontend/scripts/buildServer/tsconfig.buildServer.json
Normal file
16
frontend/scripts/buildServer/tsconfig.buildServer.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"isolatedModules": true,
|
||||
"lib": ["esnext", "dom", "DOM.Iterable"],
|
||||
"strict": false,
|
||||
"sourceMap": false,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"declaration": false
|
||||
}
|
||||
}
|
||||
1
frontend/scripts/locales/keys.jq
Normal file
1
frontend/scripts/locales/keys.jq
Normal file
@ -0,0 +1 @@
|
||||
path(..)|[.[]|tostring]|join(".")
|
||||
44
frontend/scripts/locales/locales.sh
Executable file
44
frontend/scripts/locales/locales.sh
Executable file
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "You have to supply at least one argument specifying the folder to lint"
|
||||
fi
|
||||
|
||||
FILES="$1"
|
||||
|
||||
tmp=$(mktemp)
|
||||
exit_code=0
|
||||
|
||||
for locale_file in $FILES/*.json
|
||||
do
|
||||
jq -f $(dirname "$0")/sort.jq $locale_file > "$tmp"
|
||||
# check sort order and fix it if required
|
||||
if [ "$2" == "--fix" ]
|
||||
then
|
||||
mv "$tmp" $locale_file
|
||||
else
|
||||
if diff -q "$tmp" $locale_file > /dev/null ;
|
||||
then
|
||||
: # all good
|
||||
else
|
||||
exit_code=$?
|
||||
echo "$(basename -- $locale_file) is not sorted by keys"
|
||||
fi
|
||||
fi
|
||||
# check keys
|
||||
if [ -n "$LAST_FILE" ]; then
|
||||
listPaths="jq -f $(dirname "$0")/keys.jq"
|
||||
diffString="<( cat $LAST_FILE | $listPaths ) <( cat $locale_file | $listPaths )"
|
||||
if eval "diff -q $diffString";
|
||||
then
|
||||
: # all good
|
||||
else
|
||||
eval "diff -y $diffString | grep '[|<>]'";
|
||||
printf "\n$LAST_FILE\" and $locale_file translation keys do not match, see diff above.\n"
|
||||
exit_code=1
|
||||
fi
|
||||
fi
|
||||
LAST_FILE=$locale_file
|
||||
done
|
||||
|
||||
exit $exit_code
|
||||
13
frontend/scripts/locales/sort.jq
Normal file
13
frontend/scripts/locales/sort.jq
Normal file
@ -0,0 +1,13 @@
|
||||
def walk(f):
|
||||
. as $in
|
||||
| if type == "object" then
|
||||
reduce keys_unsorted[] as $key
|
||||
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
|
||||
elif type == "array" then map( walk(f) ) | f
|
||||
else f
|
||||
end;
|
||||
|
||||
def keys_sort_by(f):
|
||||
to_entries | sort_by(.key|f ) | from_entries;
|
||||
|
||||
walk(if type == "object" then keys_sort_by(ascii_upcase) else . end)
|
||||
6
frontend/scripts/tests/mock.$t.ts
Normal file
6
frontend/scripts/tests/mock.$t.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { config } from '@vue/test-utils'
|
||||
|
||||
config.global.mocks = {
|
||||
...config.global.mocks,
|
||||
$t: (tKey: string) => "$t('" + tKey + "')", // just return translation key
|
||||
}
|
||||
8
frontend/scripts/tests/mock.vikePageContext.ts
Normal file
8
frontend/scripts/tests/mock.vikePageContext.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { config } from '@vue/test-utils'
|
||||
|
||||
import { vikePageContext } from '#context/usePageContext'
|
||||
|
||||
config.global.provide = {
|
||||
...config.global.provide,
|
||||
[vikePageContext as symbol]: { urlPathname: '/some-url' },
|
||||
}
|
||||
14
frontend/scripts/tests/plugin.i18n-vuetify.ts
Normal file
14
frontend/scripts/tests/plugin.i18n-vuetify.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { config } from '@vue/test-utils'
|
||||
|
||||
import i18n from '#plugins/i18n'
|
||||
import vuetify from '#plugins/vuetify'
|
||||
|
||||
config.global.plugins.push(i18n)
|
||||
config.global.plugins.push(vuetify(i18n))
|
||||
|
||||
config.global.mocks = {
|
||||
...config.global.mocks,
|
||||
i18n$t: i18n.global.t,
|
||||
i18n$d: i18n.global.d,
|
||||
i18n$n: i18n.global.n,
|
||||
}
|
||||
5
frontend/scripts/tests/plugin.pinia.ts
Normal file
5
frontend/scripts/tests/plugin.pinia.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { config } from '@vue/test-utils'
|
||||
|
||||
import pinia from '#plugins/pinia'
|
||||
|
||||
config.global.plugins.push(pinia)
|
||||
97
frontend/server/index.ts
Normal file
97
frontend/server/index.ts
Normal file
@ -0,0 +1,97 @@
|
||||
// This file isn't processed by Vite, see https://github.com/vikejs/vike/issues/562
|
||||
// Consequently:
|
||||
// - When changing this file, you needed to manually restart your server for your changes to take effect.
|
||||
// - To use your environment variables defined in your .env files, you need to install dotenv, see https://vike.dev/env
|
||||
// - To use your path aliases defined in your vite.config.js, you need to tell Node.js about them, see https://vike.dev/path-aliases
|
||||
|
||||
// If you want Vite to process your server code then use one of these:
|
||||
// - vavite (https://github.com/cyco130/vavite)
|
||||
// - See vavite + Vike examples at https://github.com/cyco130/vavite/tree/main/examples
|
||||
// - vite-node (https://github.com/antfu/vite-node)
|
||||
// - HatTip (https://github.com/hattipjs/hattip)
|
||||
// - You can use Bati (https://batijs.github.io/) to scaffold a Vike + HatTip app. Note that Bati generates apps that use the V1 design (https://vike.dev/migration/v1-design) and Vike packages (https://vike.dev/vike-packages)
|
||||
|
||||
import compression from 'compression'
|
||||
import express from 'express'
|
||||
import { renderPage } from 'vike/server'
|
||||
|
||||
import { root } from './root.js'
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
|
||||
void startServer()
|
||||
|
||||
async function startServer() {
|
||||
const app = express()
|
||||
|
||||
// Vite integration
|
||||
if (isProduction) {
|
||||
// In production, we need to serve our static assets ourselves.
|
||||
// (In dev, Vite's middleware serves our static assets.)
|
||||
const sirv = (await import('sirv')).default
|
||||
// assets 1y caching
|
||||
app.use(
|
||||
'/assets',
|
||||
sirv(`${root}/build/client/assets`, {
|
||||
maxAge: 31536000, // 1Y
|
||||
immutable: true,
|
||||
gzip: true,
|
||||
}),
|
||||
)
|
||||
// cache things for 10min
|
||||
app.use(
|
||||
sirv(`${root}/build/client`, {
|
||||
maxAge: 600,
|
||||
immutable: true,
|
||||
gzip: true,
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
// We instantiate Vite's development server and integrate its middleware to our server.
|
||||
// ⚠️ We instantiate it only in development. (It isn't needed in production and it
|
||||
// would unnecessarily bloat our production server.)
|
||||
const vite = await import('vite')
|
||||
const viteDevMiddleware = (
|
||||
await vite.createServer({
|
||||
root,
|
||||
server: { middlewareMode: true },
|
||||
})
|
||||
).middlewares
|
||||
app.use(viteDevMiddleware)
|
||||
|
||||
// on the fly compression
|
||||
app.use(compression())
|
||||
}
|
||||
|
||||
// ...
|
||||
// Other middlewares (e.g. some RPC middleware such as Telefunc)
|
||||
// ...
|
||||
|
||||
// Vike middleware. It should always be our last middleware (because it's a
|
||||
// catch-all middleware superseding any middleware placed after it).
|
||||
app.get('*', (req, res, next) => {
|
||||
void (async (req, res, next) => {
|
||||
const pageContextInit = {
|
||||
urlOriginal: req.originalUrl,
|
||||
}
|
||||
const pageContext = await renderPage(pageContextInit)
|
||||
const { httpResponse } = pageContext
|
||||
if (!httpResponse) {
|
||||
next()
|
||||
} else {
|
||||
const { body, statusCode, headers, earlyHints } = httpResponse
|
||||
if (res.writeEarlyHints)
|
||||
res.writeEarlyHints({ link: earlyHints.map((e) => e.earlyHintLink) })
|
||||
headers.forEach(([name, value]) => res.setHeader(name, value))
|
||||
res.status(statusCode)
|
||||
// For HTTP streams use httpResponse.pipe() instead, see https://vike.dev/stream
|
||||
res.send(body)
|
||||
}
|
||||
})(req, res, next)
|
||||
})
|
||||
|
||||
const port = process.env.PORT || 3000
|
||||
app.listen(port)
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`🚀 Server running at http://localhost:${port}`)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user