mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into stage2
This commit is contained in:
commit
910e33deff
18
.github/workflows/push.yml
vendored
18
.github/workflows/push.yml
vendored
@ -1,18 +0,0 @@
|
|||||||
name: on-push
|
|
||||||
on: push
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Build the stack
|
|
||||||
run: |
|
|
||||||
git submodule update --init --recursive
|
|
||||||
docker-compose up -d
|
|
||||||
- name: Test
|
|
||||||
env:
|
|
||||||
GN_INSTANCE_FOLDER: /tmp/gradio-node-instance
|
|
||||||
GN_CONTAINER_NAME: gradido-node-build
|
|
||||||
run: docker run gradido-node-test
|
|
||||||
timeout-minutes: 2
|
|
||||||
|
|
||||||
171
.github/workflows/test.yml
vendored
171
.github/workflows/test.yml
vendored
@ -4,34 +4,13 @@ name: gradido test CI
|
|||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
##############################################################################
|
|
||||||
# JOB: PREPARE #####################################################
|
|
||||||
##############################################################################
|
|
||||||
#prepare:
|
|
||||||
# name: Prepare
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# # needs: [nothing]
|
|
||||||
# steps:
|
|
||||||
# ##########################################################################
|
|
||||||
# # CHECKOUT CODE ##########################################################
|
|
||||||
# ##########################################################################
|
|
||||||
# - name: Checkout code
|
|
||||||
# uses: actions/checkout@v2
|
|
||||||
# ##########################################################################
|
|
||||||
# # TODO: DO STUFF ??? #####################################################
|
|
||||||
# ##########################################################################
|
|
||||||
# - name: Check translation files
|
|
||||||
# run: |
|
|
||||||
# scripts/translations/sort.sh
|
|
||||||
# scripts/translations/missing-keys.sh
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# JOB: DOCKER BUILD TEST FRONTEND ############################################
|
# JOB: DOCKER BUILD TEST FRONTEND ############################################
|
||||||
##############################################################################
|
##############################################################################
|
||||||
build_test_frontend:
|
build_test_frontend:
|
||||||
name: Docker Build Test - Frontend
|
name: Docker Build Test - Frontend
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
#needs: [nothing] # [prepare]
|
#needs: [nothing]
|
||||||
steps:
|
steps:
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# CHECKOUT CODE ##########################################################
|
# CHECKOUT CODE ##########################################################
|
||||||
@ -39,7 +18,7 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# NEO4J ##################################################################
|
# FRONTEND ###############################################################
|
||||||
##########################################################################
|
##########################################################################
|
||||||
- name: Frontend | Build `test` image
|
- name: Frontend | Build `test` image
|
||||||
run: |
|
run: |
|
||||||
@ -78,30 +57,58 @@ jobs:
|
|||||||
# path: /tmp/backend.tar
|
# path: /tmp/backend.tar
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# JOB: DOCKER BUILD TEST WEBAPP ##############################################
|
# JOB: DOCKER BUILD TEST LOGIN SERVER ########################################
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#build_test_webapp:
|
build_test_login_server:
|
||||||
# name: Docker Build Test - WebApp
|
name: Docker Build Test - Login Server
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# needs: [prepare]
|
#needs: [nothing]
|
||||||
# steps:
|
steps:
|
||||||
# ##########################################################################
|
##########################################################################
|
||||||
# # CHECKOUT CODE ##########################################################
|
# CHECKOUT CODE ##########################################################
|
||||||
# ##########################################################################
|
##########################################################################
|
||||||
# - name: Checkout code
|
- name: Checkout code
|
||||||
# uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
# ##########################################################################
|
with:
|
||||||
# # BUILD WEBAPP DOCKER IMAGE (build) ######################################
|
submodules: recursive
|
||||||
# ##########################################################################
|
##########################################################################
|
||||||
# - name: webapp | Build `test` image
|
# BUILD LOGIN SERVER DOCKER IMAGE (build) ################################
|
||||||
# run: |
|
##########################################################################
|
||||||
# docker build --target test -t "ocelotsocialnetwork/webapp:test" webapp/
|
- name: login server | Build `test` image
|
||||||
# docker save "ocelotsocialnetwork/webapp:test" > /tmp/webapp.tar
|
run: |
|
||||||
# - name: Upload Artifact
|
docker build --target login_server_debug -t "gradido/loginserver:test" -f ./login_server/Dockerfile.debug login_server/
|
||||||
# uses: actions/upload-artifact@v2
|
docker save "gradido/loginserver:test" > /tmp/loginserver.tar
|
||||||
# with:
|
- name: Upload Artifact
|
||||||
# name: docker-webapp-test
|
uses: actions/upload-artifact@v2
|
||||||
# path: /tmp/webapp.tar
|
with:
|
||||||
|
name: docker-loginserver-test
|
||||||
|
path: /tmp/loginserver.tar
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# JOB: DOCKER BUILD TEST COMMUNITY SERVER ####################################
|
||||||
|
##############################################################################
|
||||||
|
build_test_community_server:
|
||||||
|
name: Docker Build Test - Community Server
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
#needs: [nothing]
|
||||||
|
steps:
|
||||||
|
##########################################################################
|
||||||
|
# CHECKOUT CODE ##########################################################
|
||||||
|
##########################################################################
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
##########################################################################
|
||||||
|
# BUILD COMMUNITY SERVER DOCKER IMAGE (build) ############################
|
||||||
|
##########################################################################
|
||||||
|
- name: community server | Build `test` image
|
||||||
|
run: |
|
||||||
|
docker build -t "gradido/communityserver:test" -f ./community_server/Dockerfile ./
|
||||||
|
docker save "gradido/communityserver:test" > /tmp/communityserver.tar
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: docker-communityserver-test
|
||||||
|
path: /tmp/communityserver.tar
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# JOB: LINT FRONTEND #########################################################
|
# JOB: LINT FRONTEND #########################################################
|
||||||
@ -207,38 +214,46 @@ jobs:
|
|||||||
# run: docker-compose exec -T backend yarn test
|
# run: docker-compose exec -T backend yarn test
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# JOB: UNIT TEST WEBAPP ######################################################
|
# JOB: UNIT TEST FRONTEND ###################################################
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#unit_test_webapp:
|
unit_test_frontend:
|
||||||
# name: Unit tests - webapp
|
name: Unit tests - Frontend
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [build_test_frontend]
|
||||||
|
steps:
|
||||||
|
##########################################################################
|
||||||
|
# CHECKOUT CODE ##########################################################
|
||||||
|
##########################################################################
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
##########################################################################
|
||||||
|
# DOWNLOAD DOCKER IMAGES #################################################
|
||||||
|
##########################################################################
|
||||||
|
- name: Download Docker Image (Webapp)
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: docker-frontend-test
|
||||||
|
path: /tmp
|
||||||
|
- name: Load Docker Image
|
||||||
|
run: docker load < /tmp/frontend.tar
|
||||||
|
##########################################################################
|
||||||
|
# UNIT TESTS FRONTEND ####################################################
|
||||||
|
##########################################################################
|
||||||
|
- name: frontend | Unit tests
|
||||||
|
run: docker run --rm gradido/frontend:test yarn run test
|
||||||
|
|
||||||
|
|
||||||
|
#test:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
# needs: [build_test_webapp]
|
|
||||||
# steps:
|
# steps:
|
||||||
# ##########################################################################
|
# - uses: actions/checkout@v2
|
||||||
# # CHECKOUT CODE ##########################################################
|
# - name: Build the stack
|
||||||
# ##########################################################################
|
# run: |
|
||||||
# - name: Checkout code
|
# git submodule update --init --recursive
|
||||||
# uses: actions/checkout@v2
|
# docker-compose up -d
|
||||||
# ##########################################################################
|
# - name: Test
|
||||||
# # DOWNLOAD DOCKER IMAGES #################################################
|
# env:
|
||||||
# ##########################################################################
|
# GN_INSTANCE_FOLDER: /tmp/gradio-node-instance
|
||||||
# - name: Download Docker Image (Webapp)
|
# GN_CONTAINER_NAME: gradido-node-build
|
||||||
# uses: actions/download-artifact@v2
|
# run: docker run gradido-node-test
|
||||||
# with:
|
# timeout-minutes: 2
|
||||||
# name: docker-webapp-test
|
|
||||||
# path: /tmp
|
|
||||||
# - name: Load Docker Image
|
|
||||||
# run: docker load < /tmp/webapp.tar
|
|
||||||
# ##########################################################################
|
|
||||||
# # UNIT TESTS WEBAPP #####################################################
|
|
||||||
# ##########################################################################
|
|
||||||
# # TODO: Why do we need those .envs?
|
|
||||||
# - name: backend | copy env files webapp
|
|
||||||
# run: cp webapp/.env.template webapp/.env
|
|
||||||
# - name: backend | copy env files backend
|
|
||||||
# run: cp backend/.env.template backend/.env
|
|
||||||
# - name: backend | docker-compose
|
|
||||||
# run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps webapp
|
|
||||||
# - name: webapp | Unit tests
|
|
||||||
# #run: docker run --rm ocelotsocialnetwork/webapp:build yarn run test
|
|
||||||
# run: docker-compose exec -T webapp yarn test
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.log
|
*.log
|
||||||
/node_modules/*
|
/node_modules/*
|
||||||
|
.vscode
|
||||||
|
|||||||
62
CHANGELOG.md
62
CHANGELOG.md
@ -4,4 +4,66 @@ 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).
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||||
|
|
||||||
|
#### [0.9.4](https://github.com/gradido/gradido/compare/0.9.3...0.9.4)
|
||||||
|
|
||||||
|
- Build on run [`#103`](https://github.com/gradido/gradido/pull/103)
|
||||||
|
- update debug docker to use dependencies container pushed to docker hub [`1f002f4`](https://github.com/gradido/gradido/commit/1f002f4ed0b12d4b2bf63efceabe546d0c5b58ea)
|
||||||
|
- removed email tasks complete [`8a143be`](https://github.com/gradido/gradido/commit/8a143be8423d7bd894d4f512848895df8b9694b0)
|
||||||
|
- build login-server on docker-compose up in a docker volume so it rebuild only neccessary parts if some c++ files have changed [`0da5279`](https://github.com/gradido/gradido/commit/0da527917523530186e6effe63dc001fc99bd3e3)
|
||||||
|
|
||||||
|
#### [0.9.3](https://github.com/gradido/gradido/compare/0.9.2...0.9.3)
|
||||||
|
|
||||||
|
> 30 March 2021
|
||||||
|
|
||||||
|
- new version 0.9.3 [`#110`](https://github.com/gradido/gradido/pull/110)
|
||||||
|
- feat: Frontend tests for Content Footer [`#102`](https://github.com/gradido/gradido/pull/102)
|
||||||
|
- add check session state json function and doc [`#96`](https://github.com/gradido/gradido/pull/96)
|
||||||
|
- activity page stap 2 [`#86`](https://github.com/gradido/gradido/pull/86)
|
||||||
|
- qrcode scanner fixed, datum in activitäten fixed, sprache not null fixed [`#88`](https://github.com/gradido/gradido/pull/88)
|
||||||
|
- add additional docker container which is running skeema on startup to… [`#83`](https://github.com/gradido/gradido/pull/83)
|
||||||
|
- New fix up frontend for presentation [`#85`](https://github.com/gradido/gradido/pull/85)
|
||||||
|
- feat: Tougher eslint rules [`#77`](https://github.com/gradido/gradido/pull/77)
|
||||||
|
- feat: improve translations [`#81`](https://github.com/gradido/gradido/pull/81)
|
||||||
|
- use_correct_send_api [`#80`](https://github.com/gradido/gradido/pull/80)
|
||||||
|
- fix bug with access rights [`#78`](https://github.com/gradido/gradido/pull/78)
|
||||||
|
- make response.html better accessible [`#75`](https://github.com/gradido/gradido/pull/75)
|
||||||
|
- feat: Lokalize Validation Messages [`#67`](https://github.com/gradido/gradido/pull/67)
|
||||||
|
- feat: Localize links to gradito.net [`#74`](https://github.com/gradido/gradido/pull/74)
|
||||||
|
- fix-padding [`#73`](https://github.com/gradido/gradido/pull/73)
|
||||||
|
- Correctly use transactions API in frontend [`#69`](https://github.com/gradido/gradido/pull/69)
|
||||||
|
- Qr code scanner [`#72`](https://github.com/gradido/gradido/pull/72)
|
||||||
|
- Login fail message [`#71`](https://github.com/gradido/gradido/pull/71)
|
||||||
|
- Setup unit tests for frontend [`#55`](https://github.com/gradido/gradido/pull/55)
|
||||||
|
- Update doc [`#63`](https://github.com/gradido/gradido/pull/63)
|
||||||
|
- Add Feature in user search old frontend because Support has requested the feature long ago [`#56`](https://github.com/gradido/gradido/pull/56)
|
||||||
|
- sprache angepasst, for login, pwd, sigin [`#54`](https://github.com/gradido/gradido/pull/54)
|
||||||
|
- Improve workflows [`#53`](https://github.com/gradido/gradido/pull/53)
|
||||||
|
- setup eslint with tougher rules [`1f13507`](https://github.com/gradido/gradido/commit/1f13507eacfd93c2248fb841de5f481c9eb1e6bd)
|
||||||
|
- semicolon rule implemented [`6762a02`](https://github.com/gradido/gradido/commit/6762a028f2a3e4f2713b26bed81029defe686ad7)
|
||||||
|
- dev meeting, bernd [`a99de7f`](https://github.com/gradido/gradido/commit/a99de7f5d1f7557c0877eae565aa4263d65aaaf3)
|
||||||
|
|
||||||
|
#### [0.9.2](https://github.com/gradido/gradido/compare/0.9.1...0.9.2)
|
||||||
|
|
||||||
|
> 18 March 2021
|
||||||
|
|
||||||
|
- v0.9.2 [`#51`](https://github.com/gradido/gradido/pull/51)
|
||||||
|
- Reload after login fixed [`#50`](https://github.com/gradido/gradido/pull/50)
|
||||||
|
- Monorepo login server [`#48`](https://github.com/gradido/gradido/pull/48)
|
||||||
|
- Stage0 [`#3`](https://github.com/gradido/gradido/pull/3)
|
||||||
|
- Add auto-sign Transaction functionality [`5592275`](https://github.com/gradido/gradido/commit/55922753a7ffd9552be132501d744da491c409b5)
|
||||||
|
- read in login the real client ip X-Real-IP from nginx forwarded not from community server [`512d307`](https://github.com/gradido/gradido/commit/512d307a19b955bb6e26ae8b274def354829b50f)
|
||||||
|
- move check if all passwords allow direct into pwdValidation so it will work with every code which ask for password [`e2c38c1`](https://github.com/gradido/gradido/commit/e2c38c1a0fc25a4a2bc922c4bbc44d86b6d00d8b)
|
||||||
|
|
||||||
#### 0.9.1
|
#### 0.9.1
|
||||||
|
|
||||||
|
> 13 March 2021
|
||||||
|
|
||||||
|
- Login gbb [`#12`](https://github.com/gradido/gradido/pull/12)
|
||||||
|
- Admin prework axios json [`#10`](https://github.com/gradido/gradido/pull/10)
|
||||||
|
- Merge pull request #1 from gradido/master [`#8`](https://github.com/gradido/gradido/pull/8)
|
||||||
|
- [WIP] 2 create a dockerfile for the frontend application [`#6`](https://github.com/gradido/gradido/pull/6)
|
||||||
|
- Master - first step [`#1`](https://github.com/gradido/gradido/pull/1)
|
||||||
|
- Add docker compose [`#7`](https://github.com/gradido/gradido/pull/7)
|
||||||
|
- style 404 side :) [`c7bdf89`](https://github.com/gradido/gradido/commit/c7bdf8978594b932615e48f9bb1c19d3c3bf3fcf)
|
||||||
|
- publish workflow test [`df6f66f`](https://github.com/gradido/gradido/commit/df6f66ffe70baa9ed3f70b460a6c0c14011bb944)
|
||||||
|
- many translations. translation structure [`bf68547`](https://github.com/gradido/gradido/commit/bf685479767d19c246c4d6abe3577dc3cb666346)
|
||||||
|
|||||||
2
community_server/.gitmodules
vendored
2
community_server/.gitmodules
vendored
@ -1,3 +1,3 @@
|
|||||||
[submodule "src/protobuf"]
|
[submodule "src/protobuf"]
|
||||||
path = src/protobuf
|
path = src/protobuf
|
||||||
url = git@github.com:gradido/gradido_protocol.git
|
url = git@github.com:gradido/gradido_protocol.git
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
FROM phpdockerio/php74-fpm
|
FROM phpdockerio/php74-fpm
|
||||||
|
|
||||||
# install php fpm
|
# install php fpm
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get -y --no-install-recommends install curl unzip php7.4-curl php7.4-fpm php7.4-mbstring php7.4-intl php7.4-xml php7.4-pdo php7.4-mysql \
|
&& apt-get -y --no-install-recommends install curl unzip php7.4-curl php7.4-fpm php7.4-mbstring php7.4-intl php7.4-xml php7.4-pdo php7.4-mysql \
|
||||||
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
|
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
|
||||||
|
|
||||||
WORKDIR /var/www/cakephp
|
WORKDIR /var/www/cakephp
|
||||||
RUN mkdir logs && mkdir tmp && chmod 777 logs && chmod 777 tmp
|
RUN mkdir logs && mkdir tmp && chmod 777 logs && chmod 777 tmp
|
||||||
COPY ./community_server/ .
|
COPY ./community_server/ .
|
||||||
COPY ./configs/community_server/app.php ./config/
|
COPY ./configs/community_server/app.php ./config/
|
||||||
|
|
||||||
RUN composer update
|
RUN composer update
|
||||||
RUN composer dump-autoload
|
RUN composer dump-autoload
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
fastcgi_param QUERY_STRING $query_string;
|
fastcgi_param QUERY_STRING $query_string;
|
||||||
fastcgi_param REQUEST_METHOD $request_method;
|
fastcgi_param REQUEST_METHOD $request_method;
|
||||||
fastcgi_param CONTENT_TYPE $content_type;
|
fastcgi_param CONTENT_TYPE $content_type;
|
||||||
fastcgi_param CONTENT_LENGTH $content_length;
|
fastcgi_param CONTENT_LENGTH $content_length;
|
||||||
|
|
||||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||||
fastcgi_param REQUEST_URI $request_uri;
|
fastcgi_param REQUEST_URI $request_uri;
|
||||||
fastcgi_param DOCUMENT_URI $document_uri;
|
fastcgi_param DOCUMENT_URI $document_uri;
|
||||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||||
fastcgi_param REQUEST_SCHEME $scheme;
|
fastcgi_param REQUEST_SCHEME $scheme;
|
||||||
fastcgi_param HTTPS $https if_not_empty;
|
fastcgi_param HTTPS $https if_not_empty;
|
||||||
|
|
||||||
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||||
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||||
|
|
||||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||||
fastcgi_param REMOTE_PORT $remote_port;
|
fastcgi_param REMOTE_PORT $remote_port;
|
||||||
fastcgi_param SERVER_ADDR $server_addr;
|
fastcgi_param SERVER_ADDR $server_addr;
|
||||||
fastcgi_param SERVER_PORT $server_port;
|
fastcgi_param SERVER_PORT $server_port;
|
||||||
fastcgi_param SERVER_NAME $server_name;
|
fastcgi_param SERVER_NAME $server_name;
|
||||||
|
|
||||||
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
||||||
fastcgi_param REDIRECT_STATUS 200;
|
fastcgi_param REDIRECT_STATUS 200;
|
||||||
@ -1,88 +1,88 @@
|
|||||||
types {
|
types {
|
||||||
text/html html htm shtml;
|
text/html html htm shtml;
|
||||||
text/css css;
|
text/css css;
|
||||||
text/xml xml;
|
text/xml xml;
|
||||||
image/gif gif;
|
image/gif gif;
|
||||||
image/jpeg jpeg jpg;
|
image/jpeg jpeg jpg;
|
||||||
application/javascript js;
|
application/javascript js;
|
||||||
application/atom+xml atom;
|
application/atom+xml atom;
|
||||||
application/rss+xml rss;
|
application/rss+xml rss;
|
||||||
|
|
||||||
text/mathml mml;
|
text/mathml mml;
|
||||||
text/plain txt;
|
text/plain txt;
|
||||||
text/vnd.sun.j2me.app-descriptor jad;
|
text/vnd.sun.j2me.app-descriptor jad;
|
||||||
text/vnd.wap.wml wml;
|
text/vnd.wap.wml wml;
|
||||||
text/x-component htc;
|
text/x-component htc;
|
||||||
|
|
||||||
image/png png;
|
image/png png;
|
||||||
image/tiff tif tiff;
|
image/tiff tif tiff;
|
||||||
image/vnd.wap.wbmp wbmp;
|
image/vnd.wap.wbmp wbmp;
|
||||||
image/x-icon ico;
|
image/x-icon ico;
|
||||||
image/x-jng jng;
|
image/x-jng jng;
|
||||||
image/x-ms-bmp bmp;
|
image/x-ms-bmp bmp;
|
||||||
image/svg+xml svg svgz;
|
image/svg+xml svg svgz;
|
||||||
image/webp webp;
|
image/webp webp;
|
||||||
|
|
||||||
application/font-woff woff;
|
application/font-woff woff;
|
||||||
application/java-archive jar war ear;
|
application/java-archive jar war ear;
|
||||||
application/json json;
|
application/json json;
|
||||||
application/mac-binhex40 hqx;
|
application/mac-binhex40 hqx;
|
||||||
application/msword doc;
|
application/msword doc;
|
||||||
application/pdf pdf;
|
application/pdf pdf;
|
||||||
application/postscript ps eps ai;
|
application/postscript ps eps ai;
|
||||||
application/rtf rtf;
|
application/rtf rtf;
|
||||||
application/vnd.apple.mpegurl m3u8;
|
application/vnd.apple.mpegurl m3u8;
|
||||||
application/vnd.ms-excel xls;
|
application/vnd.ms-excel xls;
|
||||||
application/vnd.ms-fontobject eot;
|
application/vnd.ms-fontobject eot;
|
||||||
application/vnd.ms-powerpoint ppt;
|
application/vnd.ms-powerpoint ppt;
|
||||||
application/vnd.wap.wmlc wmlc;
|
application/vnd.wap.wmlc wmlc;
|
||||||
application/vnd.google-earth.kml+xml kml;
|
application/vnd.google-earth.kml+xml kml;
|
||||||
application/vnd.google-earth.kmz kmz;
|
application/vnd.google-earth.kmz kmz;
|
||||||
application/x-7z-compressed 7z;
|
application/x-7z-compressed 7z;
|
||||||
application/x-cocoa cco;
|
application/x-cocoa cco;
|
||||||
application/x-java-archive-diff jardiff;
|
application/x-java-archive-diff jardiff;
|
||||||
application/x-java-jnlp-file jnlp;
|
application/x-java-jnlp-file jnlp;
|
||||||
application/x-makeself run;
|
application/x-makeself run;
|
||||||
application/x-perl pl pm;
|
application/x-perl pl pm;
|
||||||
application/x-pilot prc pdb;
|
application/x-pilot prc pdb;
|
||||||
application/x-rar-compressed rar;
|
application/x-rar-compressed rar;
|
||||||
application/x-redhat-package-manager rpm;
|
application/x-redhat-package-manager rpm;
|
||||||
application/x-sea sea;
|
application/x-sea sea;
|
||||||
application/x-shockwave-flash swf;
|
application/x-shockwave-flash swf;
|
||||||
application/x-stuffit sit;
|
application/x-stuffit sit;
|
||||||
application/x-tcl tcl tk;
|
application/x-tcl tcl tk;
|
||||||
application/x-x509-ca-cert der pem crt;
|
application/x-x509-ca-cert der pem crt;
|
||||||
application/x-xpinstall xpi;
|
application/x-xpinstall xpi;
|
||||||
application/xhtml+xml xhtml;
|
application/xhtml+xml xhtml;
|
||||||
application/xspf+xml xspf;
|
application/xspf+xml xspf;
|
||||||
application/zip zip;
|
application/zip zip;
|
||||||
|
|
||||||
application/octet-stream bin exe dll;
|
application/octet-stream bin exe dll;
|
||||||
application/octet-stream deb;
|
application/octet-stream deb;
|
||||||
application/octet-stream dmg;
|
application/octet-stream dmg;
|
||||||
application/octet-stream iso img;
|
application/octet-stream iso img;
|
||||||
application/octet-stream msi msp msm;
|
application/octet-stream msi msp msm;
|
||||||
|
|
||||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
|
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
|
||||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
|
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
|
||||||
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
|
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
|
||||||
|
|
||||||
audio/midi mid midi kar;
|
audio/midi mid midi kar;
|
||||||
audio/mpeg mp3;
|
audio/mpeg mp3;
|
||||||
audio/ogg ogg;
|
audio/ogg ogg;
|
||||||
audio/x-m4a m4a;
|
audio/x-m4a m4a;
|
||||||
audio/x-realaudio ra;
|
audio/x-realaudio ra;
|
||||||
|
|
||||||
video/3gpp 3gpp 3gp;
|
video/3gpp 3gpp 3gp;
|
||||||
video/mp2t ts;
|
video/mp2t ts;
|
||||||
video/mp4 mp4;
|
video/mp4 mp4;
|
||||||
video/mpeg mpeg mpg;
|
video/mpeg mpeg mpg;
|
||||||
video/quicktime mov;
|
video/quicktime mov;
|
||||||
video/webm webm;
|
video/webm webm;
|
||||||
video/x-flv flv;
|
video/x-flv flv;
|
||||||
video/x-m4v m4v;
|
video/x-m4v m4v;
|
||||||
video/x-mng mng;
|
video/x-mng mng;
|
||||||
video/x-ms-asf asx asf;
|
video/x-ms-asf asx asf;
|
||||||
video/x-ms-wmv wmv;
|
video/x-ms-wmv wmv;
|
||||||
video/x-msvideo avi;
|
video/x-msvideo avi;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,86 +1,86 @@
|
|||||||
|
|
||||||
server {
|
server {
|
||||||
|
|
||||||
listen 80 ;
|
listen 80 ;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name 0.0.0.0;
|
server_name 0.0.0.0;
|
||||||
|
|
||||||
#include /etc/nginx/common/protect.conf;
|
#include /etc/nginx/common/protect.conf;
|
||||||
#include /etc/nginx/common/protect_add_header.conf;
|
#include /etc/nginx/common/protect_add_header.conf;
|
||||||
#include /etc/nginx/common/ssl.conf;
|
#include /etc/nginx/common/ssl.conf;
|
||||||
|
|
||||||
|
|
||||||
root /usr/share/nginx/html/webroot;
|
root /usr/share/nginx/html/webroot;
|
||||||
index index.php;
|
index index.php;
|
||||||
|
|
||||||
location ~* \.(png|jpg|ico|webp)\$ {
|
location ~* \.(png|jpg|ico|webp)\$ {
|
||||||
expires 30d;
|
expires 30d;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~* \.(js|css) {
|
location ~* \.(js|css) {
|
||||||
# expires 1d;
|
# expires 1d;
|
||||||
expires 1d;
|
expires 1d;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ \.php\$ {
|
location ~ \.php\$ {
|
||||||
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
|
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
|
||||||
# Check that the PHP script exists before passing it
|
# Check that the PHP script exists before passing it
|
||||||
try_files $fastcgi_script_name =404;
|
try_files $fastcgi_script_name =404;
|
||||||
|
|
||||||
# Bypass the fact that try_files resets $fastcgi_path_info
|
# Bypass the fact that try_files resets $fastcgi_path_info
|
||||||
# see: http://trac.nginx.org/nginx/ticket/321
|
# see: http://trac.nginx.org/nginx/ticket/321
|
||||||
set $path_info $fastcgi_path_info;
|
set $path_info $fastcgi_path_info;
|
||||||
fastcgi_param PATH_INFO $path_info;
|
fastcgi_param PATH_INFO $path_info;
|
||||||
|
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
include fastcgi.conf;
|
include fastcgi.conf;
|
||||||
|
|
||||||
#fastcgi_pass unix:/run/php/php7.3-fpm.sock;
|
#fastcgi_pass unix:/run/php/php7.3-fpm.sock;
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ /\.ht {
|
location ~ /\.ht {
|
||||||
deny all;
|
deny all;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /account {
|
location /account {
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade \$http_upgrade;
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
proxy_set_header Connection 'upgrade';
|
proxy_set_header Connection 'upgrade';
|
||||||
proxy_cache_bypass \$http_upgrade;
|
proxy_cache_bypass \$http_upgrade;
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
proxy_set_header X-Forwarded-For \$remote_addr;
|
proxy_set_header X-Forwarded-For \$remote_addr;
|
||||||
proxy_set_header Host \$host;
|
proxy_set_header Host \$host;
|
||||||
rewrite /account/(.*) /\$1 break;
|
rewrite /account/(.*) /\$1 break;
|
||||||
|
|
||||||
#proxy_next_upstream error timeout invalid_header http_502 non_idempotent;
|
#proxy_next_upstream error timeout invalid_header http_502 non_idempotent;
|
||||||
proxy_pass http://login-server:1200;
|
proxy_pass http://login-server:1200;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
location /login_api {
|
location /login_api {
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade \$http_upgrade;
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
proxy_set_header Connection 'upgrade';
|
proxy_set_header Connection 'upgrade';
|
||||||
proxy_cache_bypass \$http_upgrade;
|
proxy_cache_bypass \$http_upgrade;
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
proxy_set_header X-Forwarded-For \$remote_addr;
|
proxy_set_header X-Forwarded-For \$remote_addr;
|
||||||
proxy_set_header Host \$host;
|
proxy_set_header Host \$host;
|
||||||
rewrite /login_api/(.*) /\$1 break;
|
rewrite /login_api/(.*) /\$1 break;
|
||||||
|
|
||||||
proxy_pass http://login-server:1201;
|
proxy_pass http://login-server:1201;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
try_files \$uri \$uri/ /index.php?\$args;
|
try_files \$uri \$uri/ /index.php?\$args;
|
||||||
}
|
}
|
||||||
|
|
||||||
# access_log /var/log/nginx/access.log main;
|
# access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit f0b1d113cee2a76e9dbb098b315f4acaf38410d0
|
|
||||||
@ -1,8 +1,8 @@
|
|||||||
CREATE TABLE `community_profiles` (
|
CREATE TABLE `community_profiles` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`state_user_id` int(10) unsigned NOT NULL,
|
`state_user_id` int(10) unsigned NOT NULL,
|
||||||
`profile_img` longblob,
|
`profile_img` longblob,
|
||||||
`profile_desc` varchar(2000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
`profile_desc` varchar(2000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `state_user_id` (`state_user_id`)
|
KEY `state_user_id` (`state_user_id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|||||||
@ -60,7 +60,7 @@ class JsonRequestClientComponent extends Component
|
|||||||
]), '/getRunningUserTasks');
|
]), '/getRunningUserTasks');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUsers($session_id, $searchString)
|
public function getUsers($session_id, $searchString, $accountState)
|
||||||
{
|
{
|
||||||
if($searchString == "") {
|
if($searchString == "") {
|
||||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'search string is empty'];
|
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'search string is empty'];
|
||||||
@ -71,7 +71,8 @@ class JsonRequestClientComponent extends Component
|
|||||||
|
|
||||||
return $this->sendRequest(json_encode([
|
return $this->sendRequest(json_encode([
|
||||||
'session_id' => $session_id,
|
'session_id' => $session_id,
|
||||||
'search' => $searchString
|
'search' => $searchString,
|
||||||
|
'account_state' => $accountState,
|
||||||
]), '/getUsers');
|
]), '/getUsers');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -197,6 +197,7 @@ class StateBalancesController extends AppController
|
|||||||
if ($result !== true) {
|
if ($result !== true) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $session->read('StateUser');
|
$user = $session->read('StateUser');
|
||||||
$update_balance_result = $this->updateBalance($user['id']);
|
$update_balance_result = $this->updateBalance($user['id']);
|
||||||
if($update_balance_result !== true) {
|
if($update_balance_result !== true) {
|
||||||
@ -406,7 +407,7 @@ class StateBalancesController extends AppController
|
|||||||
$this->set('calculated_balance', $calculated_balance);
|
$this->set('calculated_balance', $calculated_balance);
|
||||||
|
|
||||||
$this->set('transactions', array_reverse($transactions_reversed));
|
$this->set('transactions', array_reverse($transactions_reversed));
|
||||||
$this->set('transactionExecutingCount', $session->read('Transaction.executing'));
|
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
|
||||||
$this->set('balance', $session->read('StateUser.balance'));
|
$this->set('balance', $session->read('StateUser.balance'));
|
||||||
$this->set('timeUsed', microtime(true) - $startTime);
|
$this->set('timeUsed', microtime(true) - $startTime);
|
||||||
$this->set('gdtSum', $gdtSum);
|
$this->set('gdtSum', $gdtSum);
|
||||||
@ -423,6 +424,7 @@ class StateBalancesController extends AppController
|
|||||||
}
|
}
|
||||||
$session = $this->getRequest()->getSession();
|
$session = $this->getRequest()->getSession();
|
||||||
$user = $session->read('StateUser');
|
$user = $session->read('StateUser');
|
||||||
|
$this->updateBalances($user['id']);
|
||||||
|
|
||||||
$public_key_bin = hex2bin($user['public_hex']);
|
$public_key_bin = hex2bin($user['public_hex']);
|
||||||
$stateUserQuery = $this->StateBalances->StateUsers
|
$stateUserQuery = $this->StateBalances->StateUsers
|
||||||
@ -580,7 +582,7 @@ class StateBalancesController extends AppController
|
|||||||
return $this->returnJson([
|
return $this->returnJson([
|
||||||
'state' => 'success',
|
'state' => 'success',
|
||||||
'transactions' => $transactions,
|
'transactions' => $transactions,
|
||||||
'transactionExecutingCount' => $session->read('Transaction.executing'),
|
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||||
'count' => count($transactions),
|
'count' => count($transactions),
|
||||||
'gdtSum' => $gdtSum,
|
'gdtSum' => $gdtSum,
|
||||||
'timeUsed' => microtime(true) - $startTime
|
'timeUsed' => microtime(true) - $startTime
|
||||||
|
|||||||
@ -197,7 +197,7 @@ class StateUserTransactionsController extends AppController
|
|||||||
return $this->returnJson([
|
return $this->returnJson([
|
||||||
'state' => 'success',
|
'state' => 'success',
|
||||||
'transactions' => $transactions,
|
'transactions' => $transactions,
|
||||||
'transactionExecutingCount' => $session->read('Transaction.executing'),
|
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||||
'count' => $all_user_transactions_count,
|
'count' => $all_user_transactions_count,
|
||||||
'timeUsed' => microtime(true) - $startTime
|
'timeUsed' => microtime(true) - $startTime
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -70,14 +70,14 @@ class StateUsersController extends AppController
|
|||||||
$this->set(compact('stateUsers'));
|
$this->set(compact('stateUsers'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listIdentHashes()
|
/*public function listIdentHashes()
|
||||||
{
|
{
|
||||||
$stateUsers = $this->StateUsers->find('all')->toArray();
|
$stateUsers = $this->StateUsers->find('all')->toArray();
|
||||||
foreach($stateUsers as $i => $user) {
|
foreach($stateUsers as $i => $user) {
|
||||||
$stateUsers[$i]->identHash = TransactionCreation::DRMakeStringHash($user->email);
|
$stateUsers[$i]->identHash = TransactionCreation::DRMakeStringHash($user->email);
|
||||||
}
|
}
|
||||||
$this->set('stateUsers', $stateUsers);
|
$this->set('stateUsers', $stateUsers);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public function login($session_id)
|
public function login($session_id)
|
||||||
{
|
{
|
||||||
@ -128,9 +128,14 @@ class StateUsersController extends AppController
|
|||||||
//$this->set('timeUsed', $timeUsed);
|
//$this->set('timeUsed', $timeUsed);
|
||||||
$csfr_token = $this->request->getParam('_csrfToken');
|
$csfr_token = $this->request->getParam('_csrfToken');
|
||||||
$this->set(compact('timeUsed', 'searchForm', 'csfr_token'));
|
$this->set(compact('timeUsed', 'searchForm', 'csfr_token'));
|
||||||
|
$empty_string = '... empty ...';
|
||||||
if ($this->request->is('post')) {
|
if ($this->request->is('post')) {
|
||||||
|
$finalUserEntrys = [];
|
||||||
$requestData = $this->request->getData();
|
$requestData = $this->request->getData();
|
||||||
|
$account_state = $requestData['account_state'];
|
||||||
|
if($requestData['search'] == '' && $account_state != 'all') {
|
||||||
|
$requestData['search'] = $empty_string;
|
||||||
|
}
|
||||||
|
|
||||||
if($searchForm->validate($requestData)) {
|
if($searchForm->validate($requestData)) {
|
||||||
//var_dump($requestData);
|
//var_dump($requestData);
|
||||||
@ -140,7 +145,7 @@ class StateUsersController extends AppController
|
|||||||
$searchType = 'email';
|
$searchType = 'email';
|
||||||
}
|
}
|
||||||
// find users on login server
|
// find users on login server
|
||||||
$resultJson = $this->JsonRequestClient->getUsers($session->read('session_id'), $searchString);
|
$resultJson = $this->JsonRequestClient->getUsers($session->read('session_id'), $searchString, $account_state);
|
||||||
$loginServerUser = [];
|
$loginServerUser = [];
|
||||||
if($resultJson['state'] == 'success') {
|
if($resultJson['state'] == 'success') {
|
||||||
$dataJson = $resultJson['data'];
|
$dataJson = $resultJson['data'];
|
||||||
@ -168,18 +173,31 @@ class StateUsersController extends AppController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// find user on community server db
|
// find user on community server db
|
||||||
$globalSearch = '%' . $searchString . '%';
|
|
||||||
|
|
||||||
|
|
||||||
$communityUsers = $this->StateUsers
|
$communityUsers = $this->StateUsers
|
||||||
->find('all')
|
->find('all')
|
||||||
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]]);
|
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]]);
|
||||||
|
|
||||||
|
if($account_state == 'email not activated') {
|
||||||
|
if(count($pubkeySorted) > 0) {
|
||||||
|
$communityUsers->where(['hex(public_key) IN' => array_keys($pubkeySorted)]);
|
||||||
|
} else {
|
||||||
|
$communityUsers = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$globalSearch = '%' . $searchString . '%';
|
||||||
$communityUsers->where(['OR' => [
|
$communityUsers->where(['OR' => [
|
||||||
'first_name LIKE' => $globalSearch,
|
'first_name LIKE' => $globalSearch,
|
||||||
'last_name LIKE' => $globalSearch,
|
'last_name LIKE' => $globalSearch,
|
||||||
'email LIKE' => $globalSearch
|
'email LIKE' => $globalSearch
|
||||||
]]);
|
]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//var_dump($communityUsers->toArray());
|
//var_dump($communityUsers->toArray());
|
||||||
|
if($communityUsers) {
|
||||||
foreach($communityUsers as $u) {
|
foreach($communityUsers as $u) {
|
||||||
$pubkey_hex = bin2hex(stream_get_contents($u->public_key));
|
$pubkey_hex = bin2hex(stream_get_contents($u->public_key));
|
||||||
$u->public_hex = $pubkey_hex;
|
$u->public_hex = $pubkey_hex;
|
||||||
@ -188,7 +206,8 @@ class StateUsersController extends AppController
|
|||||||
}
|
}
|
||||||
array_push($pubkeySorted[$pubkey_hex]['community'], $u);
|
array_push($pubkeySorted[$pubkey_hex]['community'], $u);
|
||||||
}
|
}
|
||||||
$finalUserEntrys = [];
|
}
|
||||||
|
|
||||||
// detect states
|
// detect states
|
||||||
foreach($pubkeySorted as $pubhex => $user) {
|
foreach($pubkeySorted as $pubhex => $user) {
|
||||||
$finalUser = [];
|
$finalUser = [];
|
||||||
|
|||||||
@ -54,12 +54,12 @@ class TransactionCreationsController extends AppController
|
|||||||
];
|
];
|
||||||
$transactionCreations = $this->paginate($this->TransactionCreations);
|
$transactionCreations = $this->paginate($this->TransactionCreations);
|
||||||
$identHashes = [];
|
$identHashes = [];
|
||||||
foreach ($transactionCreations as $creation) {
|
/*foreach ($transactionCreations as $creation) {
|
||||||
$identHash = TransactionCreation::DRMakeStringHash($creation->state_user->email);
|
$identHash = TransactionCreation::DRMakeStringHash($creation->state_user->email);
|
||||||
$identHashes[$creation->state_user->id] = $identHash;
|
$identHashes[$creation->state_user->id] = $identHash;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
$this->set(compact('transactionCreations', 'identHashes'));
|
//$this->set(compact('transactionCreations', 'identHashes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,7 +125,7 @@ class TransactionCreationsController extends AppController
|
|||||||
|
|
||||||
if (count($receiverProposal) > $receiverIndex) {
|
if (count($receiverProposal) > $receiverIndex) {
|
||||||
$pubKeyHex = $receiverProposal[$receiverIndex]['key'];
|
$pubKeyHex = $receiverProposal[$receiverIndex]['key'];
|
||||||
$identHash = TransactionCreation::DRMakeStringHash($receiverProposal[$receiverIndex]['email']);
|
//$identHash = TransactionCreation::DRMakeStringHash($receiverProposal[$receiverIndex]['email']);
|
||||||
}
|
}
|
||||||
$builderResult = TransactionCreation::build(
|
$builderResult = TransactionCreation::build(
|
||||||
$amountCent,
|
$amountCent,
|
||||||
@ -323,7 +323,7 @@ class TransactionCreationsController extends AppController
|
|||||||
$this->set('firstDayLastMonth', $firstDayLastMonth);
|
$this->set('firstDayLastMonth', $firstDayLastMonth);
|
||||||
$this->set('activeUser', $user);
|
$this->set('activeUser', $user);
|
||||||
$this->set('creationForm', $creationForm);
|
$this->set('creationForm', $creationForm);
|
||||||
$this->set('transactionExecutingCount', $session->read('Transaction.executing'));
|
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
|
||||||
$this->set('timeUsed', microtime(true) - $startTime);
|
$this->set('timeUsed', microtime(true) - $startTime);
|
||||||
$this->set('countUsers', $countUsers);
|
$this->set('countUsers', $countUsers);
|
||||||
$this->set('limit', $limit);
|
$this->set('limit', $limit);
|
||||||
@ -373,7 +373,20 @@ class TransactionCreationsController extends AppController
|
|||||||
$pendings[$id] = $localAmountCent;
|
$pendings[$id] = $localAmountCent;
|
||||||
}
|
}
|
||||||
$pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key));
|
$pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key));
|
||||||
|
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
|
||||||
|
'session_id' => $session->read('session_id'),
|
||||||
|
'email' => $receiverUser->email,
|
||||||
|
'ask' => ['user.identHash']
|
||||||
|
]), '/getUserInfos');
|
||||||
|
|
||||||
|
$identHash = 0;
|
||||||
|
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
|
||||||
|
$identHash = $requestAnswear['data']['userData']['identHash'];
|
||||||
|
} else {
|
||||||
|
$this->Flash->error(__('Error by requesting LoginServer, please try again'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//$identHash = TransactionCreation::DRMakeStringHash($receiverUser->email);
|
||||||
$localTargetDateFrozen = FrozenDate::now();
|
$localTargetDateFrozen = FrozenDate::now();
|
||||||
$localTargetDateFrozen = $localTargetDateFrozen
|
$localTargetDateFrozen = $localTargetDateFrozen
|
||||||
->year($localTargetDate['year'])
|
->year($localTargetDate['year'])
|
||||||
|
|||||||
@ -11,7 +11,9 @@ class UserSearchForm extends Form
|
|||||||
|
|
||||||
protected function _buildSchema(Schema $schema)
|
protected function _buildSchema(Schema $schema)
|
||||||
{
|
{
|
||||||
return $schema->addField('search', ['type' => 'string']);
|
return $schema
|
||||||
|
->addField('search', ['type' => 'string'])
|
||||||
|
->addField('account_state', ['type' => 'select']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validationDefault(Validator $validator)
|
function validationDefault(Validator $validator)
|
||||||
|
|||||||
@ -59,7 +59,8 @@ class StateBalance extends Entity
|
|||||||
if($decay_duration === 0) {
|
if($decay_duration === 0) {
|
||||||
return $this->amount;
|
return $this->amount;
|
||||||
}
|
}
|
||||||
return $this->amount * pow(0.99999997802044727, $decay_duration);
|
return $this->amount;
|
||||||
|
//return $this->amount * pow(0.99999997802044727, $decay_duration);
|
||||||
|
|
||||||
}
|
}
|
||||||
public function partDecay($target_date)
|
public function partDecay($target_date)
|
||||||
@ -68,7 +69,8 @@ class StateBalance extends Entity
|
|||||||
if($decay_duration <= 0) {
|
if($decay_duration <= 0) {
|
||||||
return $this->amount;
|
return $this->amount;
|
||||||
}
|
}
|
||||||
return $this->amount * pow(0.99999997802044727, $decay_duration);
|
return 0;
|
||||||
|
//return $this->amount * pow(0.99999997802044727, $decay_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decayDuration($target_date)
|
public function decayDuration($target_date)
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace Model\Transactions;
|
namespace Model\Transactions;
|
||||||
|
|
||||||
use Cake\ORM\TableRegistry;
|
use Cake\ORM\TableRegistry;
|
||||||
|
use Cake\I18n\Date;
|
||||||
|
|
||||||
class TransactionBody extends TransactionBase {
|
class TransactionBody extends TransactionBase {
|
||||||
private $mProtoTransactionBody = null;
|
private $mProtoTransactionBody = null;
|
||||||
@ -75,6 +76,7 @@ class TransactionBody extends TransactionBase {
|
|||||||
|
|
||||||
$transactionEntity->transaction_type_id = $this->transactionTypeId;
|
$transactionEntity->transaction_type_id = $this->transactionTypeId;
|
||||||
$transactionEntity->memo = $this->getMemo();
|
$transactionEntity->memo = $this->getMemo();
|
||||||
|
$transactionEntity->received = new Date();
|
||||||
|
|
||||||
if ($transactionsTable->save($transactionEntity)) {
|
if ($transactionsTable->save($transactionEntity)) {
|
||||||
// success
|
// success
|
||||||
|
|||||||
@ -63,24 +63,6 @@ class TransactionCreation extends TransactionBase {
|
|||||||
return ['state' => 'success', 'transactionBody' => $transactionBody];
|
return ['state' => 'success', 'transactionBody' => $transactionBody];
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected function DRHashRotateLeft( $hash, $rotateBy )
|
|
||||||
{
|
|
||||||
return ($hash<<$rotateBy)|($hash>>(32-$rotateBy));
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function DRMakeStringHash($str)
|
|
||||||
{
|
|
||||||
$ret = 0;
|
|
||||||
|
|
||||||
if( $str )
|
|
||||||
{
|
|
||||||
for ($i=0; $i < strlen($str); $i++)
|
|
||||||
{
|
|
||||||
$ret = TransactionCreation::DRHashRotateLeft($ret, 7) + ord($str{$i});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAmount() {
|
public function getAmount() {
|
||||||
return $this->protoTransactionCreation->getReceiverAmount()->getAmount();
|
return $this->protoTransactionCreation->getReceiverAmount()->getAmount();
|
||||||
@ -272,7 +254,7 @@ class TransactionCreation extends TransactionBase {
|
|||||||
->setSubject(__('Gradido Schöpfung erhalten'))
|
->setSubject(__('Gradido Schöpfung erhalten'))
|
||||||
->send();
|
->send();
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
$this->addError('TransactionCreation::sendNotificationEmail', 'error sending notification email: ' . $e->getMessage());
|
// $this->addError('TransactionCreation::sendNotificationEmail', 'error sending notification email: ' . $e->getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -303,7 +285,7 @@ class TransactionCreation extends TransactionBase {
|
|||||||
|
|
||||||
// intval
|
// intval
|
||||||
//$protoCreation->setIdentHash(intval($identHashBytes));
|
//$protoCreation->setIdentHash(intval($identHashBytes));
|
||||||
$protoCreation->setIdentHash(self::DRMakeStringHash($stateUser->email));
|
//$protoCreation->setIdentHash(self::DRMakeStringHash($stateUser->email));
|
||||||
return new TransactionCreation($protoCreation);
|
return new TransactionCreation($protoCreation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,8 @@ class TransactionTransfer extends TransactionBase {
|
|||||||
foreach($sigPairs as $sigPair) {
|
foreach($sigPairs as $sigPair) {
|
||||||
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
|
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
|
||||||
$pubkey = bin2hex($sigPair->getPubKey());
|
$pubkey = bin2hex($sigPair->getPubKey());
|
||||||
$hash = TransactionCreation::DRMakeStringHash($pubkey);
|
//$hash = TransactionCreation::DRMakeStringHash($pubkey);
|
||||||
|
$hash = $pubkey;
|
||||||
if(!isset($sigPubHexs[$hash])) {
|
if(!isset($sigPubHexs[$hash])) {
|
||||||
$sigPubHexs[$hash] = [$pubkey];
|
$sigPubHexs[$hash] = [$pubkey];
|
||||||
} else {
|
} else {
|
||||||
@ -100,7 +101,8 @@ class TransactionTransfer extends TransactionBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// check if signature exist for sender
|
// check if signature exist for sender
|
||||||
$hash = TransactionCreation::DRMakeStringHash($senderPublicHex);
|
//$hash = TransactionCreation::DRMakeStringHash($senderPublicHex);
|
||||||
|
$hash = $senderPublicHex;
|
||||||
if(!isset($sigPubHexs[$hash]) || in_array($senderPublicHex, $sigPubHexs[$hash]) === FALSE) {
|
if(!isset($sigPubHexs[$hash]) || in_array($senderPublicHex, $sigPubHexs[$hash]) === FALSE) {
|
||||||
$this->addError($functionName, 'missing signature for sender');
|
$this->addError($functionName, 'missing signature for sender');
|
||||||
return false;
|
return false;
|
||||||
@ -253,7 +255,7 @@ class TransactionTransfer extends TransactionBase {
|
|||||||
->setSubject(__('Gradidos erhalten'))
|
->setSubject(__('Gradidos erhalten'))
|
||||||
->send();
|
->send();
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
$this->addError('TransactionTransfer::sendNotificationEmail', 'error sending notification email: ' . $e->getMessage());
|
//$this->addError('TransactionTransfer::sendNotificationEmail', 'error sending notification email: ' . $e->getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -1,29 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
?>
|
?>
|
||||||
<div class="grd_container_small">
|
<div class="grd_container_small">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>first name</th><th>last name</th><th>email</th><th>identHash</th><th>Public key hex
|
<th>first name</th><th>last name</th><th>email</th><th>identHash</th><th>Public key hex
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<?php foreach($stateUsers as $user) :?>
|
<?php foreach($stateUsers as $user) :?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?= $user->first_name ?></td>
|
<td><?= $user->first_name ?></td>
|
||||||
<td><?= $user->last_name ?></td>
|
<td><?= $user->last_name ?></td>
|
||||||
<td><?= $user->email ?></td>
|
<td><?= $user->email ?></td>
|
||||||
<td><?= $user->identHash ?></td>
|
<td><?= $user->identHash ?></td>
|
||||||
<td><?= bin2hex(stream_get_contents($user->public_key)) ?></td>
|
<td><?= bin2hex(stream_get_contents($user->public_key)) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,6 +11,19 @@ $this->assign('title', __('Benutzer suchen'));
|
|||||||
$this->loadHelper('Form', [
|
$this->loadHelper('Form', [
|
||||||
'templates' => 'horizontal_form',
|
'templates' => 'horizontal_form',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$stateOptions = [
|
||||||
|
'all' => __('Alle'),
|
||||||
|
//'account created'=>__('Konto angelegt'),
|
||||||
|
//'account not on login-server' => __('Konto nicht auf Login-Server'),
|
||||||
|
//'email activated' => __('Konto aktiviert'),
|
||||||
|
//'account copied to community' => __('Konto auf Gemeinschafts-Server'),
|
||||||
|
'email not activated' => __('Konto nicht aktiviert'),
|
||||||
|
//'account multiple times on login-server' => __('Konto mehrfach vorhanden'),
|
||||||
|
//'account not on community server' => __('Konto nicht auf Gemeinschafts-Server'),
|
||||||
|
//'no keys' => __('Keine Schlüssel generiert')
|
||||||
|
];
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<?= $this->Html->css([
|
<?= $this->Html->css([
|
||||||
'loginServer/style.css',
|
'loginServer/style.css',
|
||||||
@ -41,7 +54,8 @@ $this->loadHelper('Form', [
|
|||||||
<p class="form-header">Benutzer suchen</p>
|
<p class="form-header">Benutzer suchen</p>
|
||||||
<div class="form-body">
|
<div class="form-body">
|
||||||
<?= $this->Form->create($searchForm, []) ?>
|
<?= $this->Form->create($searchForm, []) ?>
|
||||||
<?= $this->Form->control('search', ['label' => __('Suchbegriff'), 'class' => 'form-control', 'id' => 'inlineFormInputGroup', 'placeholder' => __('Vorname/Nachname/E-Mail')]) ?>
|
<?= $this->Form->control('search', ['label' => __('Suchbegriff'), 'class' => 'form-control', 'id' => 'inlineFormInputGroup', 'placeholder' => __('Vorname/Nachname/E-Mail'), 'required' => false]) ?>
|
||||||
|
<?= $this->Form->control('account_state', ['label' => __('Konto Status'), 'class' => 'form-control', 'type' => 'select', 'options' => $stateOptions]) ?>
|
||||||
<?= $this->Form->button('<i class="material-icons-outlined">search</i> ' . __('Suchen'), ['class' => 'form-button']) ?>
|
<?= $this->Form->button('<i class="material-icons-outlined">search</i> ' . __('Suchen'), ['class' => 'form-button']) ?>
|
||||||
<?= $this->Form->hidden('order_row', ['id' => 'input-order-row']) ?>
|
<?= $this->Form->hidden('order_row', ['id' => 'input-order-row']) ?>
|
||||||
</div>
|
</div>
|
||||||
@ -59,7 +73,7 @@ $this->loadHelper('Form', [
|
|||||||
csfr_token = '<?= $csfr_token ?>';
|
csfr_token = '<?= $csfr_token ?>';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<?= $this->Html->script('userSearch') ?>
|
<?= $this->Html->script('userSearch.min') ?>
|
||||||
<!-- npm run build im mithril client! -->
|
<!-- npm run build im mithril client! -->
|
||||||
<!-- keybase://team/gradido/gradido_mithril_user_search -->
|
<!-- keybase://team/gradido/gradido_mithril_user_search -->
|
||||||
|
|
||||||
|
|||||||
@ -1,31 +1,31 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
$address_options = [];//__('Selbst eingeben:')];
|
$address_options = [];//__('Selbst eingeben:')];
|
||||||
foreach($receiverProposal as $i => $receiver) {
|
foreach($receiverProposal as $i => $receiver) {
|
||||||
//var_dump($receiver);
|
//var_dump($receiver);
|
||||||
array_push($address_options, [
|
array_push($address_options, [
|
||||||
'text' => $receiver['name'],
|
'text' => $receiver['name'],
|
||||||
'value' => $i+1,
|
'value' => $i+1,
|
||||||
'title' => $receiver['key']
|
'title' => $receiver['key']
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$this->assign('title', __('Schöpfungstransaktion'));
|
$this->assign('title', __('Schöpfungstransaktion'));
|
||||||
?>
|
?>
|
||||||
<div class="grd_container_small">
|
<div class="grd_container_small">
|
||||||
|
|
||||||
<?= $this->Form->create($creationForm) ?>
|
<?= $this->Form->create($creationForm) ?>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<?= $this->Form->control('memo'); ?>
|
<?= $this->Form->control('memo'); ?>
|
||||||
<?= $this->Form->control('amount'); ?>
|
<?= $this->Form->control('amount'); ?>
|
||||||
<?= $this->Form->control('receiver', ['options' => $address_options]); ?>
|
<?= $this->Form->control('receiver', ['options' => $address_options]); ?>
|
||||||
<!--<?= $this->Form->control('receiver_pubkey_hex', []) ?>-->
|
<!--<?= $this->Form->control('receiver_pubkey_hex', []) ?>-->
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<?= $this->Form->button(__('Transaktion(en) abschließen'), ['name' => 'next', 'class' => 'grd-form-bn grd-form-bn-succeed grd_clickable grd-width-200']) ?>
|
<?= $this->Form->button(__('Transaktion(en) abschließen'), ['name' => 'next', 'class' => 'grd-form-bn grd-form-bn-succeed grd_clickable grd-width-200']) ?>
|
||||||
<?= $this->Form->button(__('Weitere Transaktion erstellen'), ['name' => 'add', 'class' => 'grd-form-bn grd_clickable grd-width-200']) ?>
|
<?= $this->Form->button(__('Weitere Transaktion erstellen'), ['name' => 'add', 'class' => 'grd-form-bn grd_clickable grd-width-200']) ?>
|
||||||
<?= $this->Form->end() ?>
|
<?= $this->Form->end() ?>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,46 +1,46 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="transactions form large-9 medium-8 columns content">
|
<div class="transactions form large-9 medium-8 columns content">
|
||||||
<h1>Synchronize state_user_transactions with transactions</h1>
|
<h1>Synchronize state_user_transactions with transactions</h1>
|
||||||
<p>transactions count: <?= $count1 ?></p>
|
<p>transactions count: <?= $count1 ?></p>
|
||||||
<p>state_user_transaction count: <?= $count2 ?></p>
|
<p>state_user_transaction count: <?= $count2 ?></p>
|
||||||
<p>Missing count: <?= count($missing_transactions); ?></p>
|
<p>Missing count: <?= count($missing_transactions); ?></p>
|
||||||
<p>First 10 Missing ids: </p>
|
<p>First 10 Missing ids: </p>
|
||||||
<p><?php
|
<p><?php
|
||||||
foreach($missing_transactions as $i => $id) {
|
foreach($missing_transactions as $i => $id) {
|
||||||
if($i > 10) break;
|
if($i > 10) break;
|
||||||
if($i > 0) echo ', ';
|
if($i > 0) echo ', ';
|
||||||
echo $id['id'];
|
echo $id['id'];
|
||||||
} ?></p>
|
} ?></p>
|
||||||
|
|
||||||
<?php if(isset($entities) && isset($results)) : ?>
|
<?php if(isset($entities) && isset($results)) : ?>
|
||||||
<h2>Synchronize errors: </h2>
|
<h2>Synchronize errors: </h2>
|
||||||
<ul>
|
<ul>
|
||||||
<?php
|
<?php
|
||||||
$succeed = 0;
|
$succeed = 0;
|
||||||
//var_dump($results);
|
//var_dump($results);
|
||||||
if($results) :
|
if($results) :
|
||||||
foreach($results as $i => $result) :
|
foreach($results as $i => $result) :
|
||||||
if(false != $result) {
|
if(false != $result) {
|
||||||
$succeed++;
|
$succeed++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<li>Error saving entity: <?= json_encode($entities[$i]) ?> with error: <?= json_encode($entities[$i]->getErrors()) ?></li>
|
<li>Error saving entity: <?= json_encode($entities[$i]) ?> with error: <?= json_encode($entities[$i]->getErrors()) ?></li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<li><success>Succeed: <?= $succeed ?></success></li>
|
<li><success>Succeed: <?= $succeed ?></success></li>
|
||||||
</ul>
|
</ul>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?= $this->Form->create() ?>
|
<?= $this->Form->create() ?>
|
||||||
<?= $this->Form->button(__('Synchronize')) ?>
|
<?= $this->Form->button(__('Synchronize')) ?>
|
||||||
<?= $this->Form->end() ?>
|
<?= $this->Form->end() ?>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,408 +1,408 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Cake\Cache\Engine\FileEngine;
|
use Cake\Cache\Engine\FileEngine;
|
||||||
use Cake\Database\Connection;
|
use Cake\Database\Connection;
|
||||||
use Cake\Database\Driver\Mysql;
|
use Cake\Database\Driver\Mysql;
|
||||||
use Cake\Error\ExceptionRenderer;
|
use Cake\Error\ExceptionRenderer;
|
||||||
use Cake\Log\Engine\FileLog;
|
use Cake\Log\Engine\FileLog;
|
||||||
use Cake\Mailer\Transport\MailTransport;
|
use Cake\Mailer\Transport\MailTransport;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
/**
|
/**
|
||||||
* Debug Level:
|
* Debug Level:
|
||||||
*
|
*
|
||||||
* Production Mode:
|
* Production Mode:
|
||||||
* false: No error messages, errors, or warnings shown.
|
* false: No error messages, errors, or warnings shown.
|
||||||
*
|
*
|
||||||
* Development Mode:
|
* Development Mode:
|
||||||
* true: Errors and warnings shown.
|
* true: Errors and warnings shown.
|
||||||
*/
|
*/
|
||||||
'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN),
|
'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure basic information about the application.
|
* Configure basic information about the application.
|
||||||
*
|
*
|
||||||
* - namespace - The namespace to find app classes under.
|
* - namespace - The namespace to find app classes under.
|
||||||
* - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time.
|
* - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time.
|
||||||
* - encoding - The encoding used for HTML + database connections.
|
* - encoding - The encoding used for HTML + database connections.
|
||||||
* - base - The base directory the app resides in. If false this
|
* - base - The base directory the app resides in. If false this
|
||||||
* will be auto detected.
|
* will be auto detected.
|
||||||
* - dir - Name of app directory.
|
* - dir - Name of app directory.
|
||||||
* - webroot - The webroot directory.
|
* - webroot - The webroot directory.
|
||||||
* - wwwRoot - The file path to webroot.
|
* - wwwRoot - The file path to webroot.
|
||||||
* - baseUrl - To configure CakePHP to *not* use mod_rewrite and to
|
* - baseUrl - To configure CakePHP to *not* use mod_rewrite and to
|
||||||
* use CakePHP pretty URLs, remove these .htaccess
|
* use CakePHP pretty URLs, remove these .htaccess
|
||||||
* files:
|
* files:
|
||||||
* /.htaccess
|
* /.htaccess
|
||||||
* /webroot/.htaccess
|
* /webroot/.htaccess
|
||||||
* And uncomment the baseUrl key below.
|
* And uncomment the baseUrl key below.
|
||||||
* - fullBaseUrl - A base URL to use for absolute links. When set to false (default)
|
* - fullBaseUrl - A base URL to use for absolute links. When set to false (default)
|
||||||
* CakePHP generates required value based on `HTTP_HOST` environment variable.
|
* CakePHP generates required value based on `HTTP_HOST` environment variable.
|
||||||
* However, you can define it manually to optimize performance or if you
|
* However, you can define it manually to optimize performance or if you
|
||||||
* are concerned about people manipulating the `Host` header.
|
* are concerned about people manipulating the `Host` header.
|
||||||
* - imageBaseUrl - Web path to the public images directory under webroot.
|
* - imageBaseUrl - Web path to the public images directory under webroot.
|
||||||
* - cssBaseUrl - Web path to the public css directory under webroot.
|
* - cssBaseUrl - Web path to the public css directory under webroot.
|
||||||
* - jsBaseUrl - Web path to the public js directory under webroot.
|
* - jsBaseUrl - Web path to the public js directory under webroot.
|
||||||
* - paths - Configure paths for non class based resources. Supports the
|
* - paths - Configure paths for non class based resources. Supports the
|
||||||
* `plugins`, `templates`, `locales` subkeys, which allow the definition of
|
* `plugins`, `templates`, `locales` subkeys, which allow the definition of
|
||||||
* paths for plugins, view templates and locale files respectively.
|
* paths for plugins, view templates and locale files respectively.
|
||||||
*/
|
*/
|
||||||
'App' => [
|
'App' => [
|
||||||
'namespace' => 'App',
|
'namespace' => 'App',
|
||||||
'encoding' => env('APP_ENCODING', 'UTF-8'),
|
'encoding' => env('APP_ENCODING', 'UTF-8'),
|
||||||
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
|
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
|
||||||
'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'),
|
'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'),
|
||||||
'base' => false,
|
'base' => false,
|
||||||
'dir' => 'src',
|
'dir' => 'src',
|
||||||
'webroot' => 'webroot',
|
'webroot' => 'webroot',
|
||||||
'wwwRoot' => WWW_ROOT,
|
'wwwRoot' => WWW_ROOT,
|
||||||
//'baseUrl' => env('SCRIPT_NAME'),
|
//'baseUrl' => env('SCRIPT_NAME'),
|
||||||
'fullBaseUrl' => false,
|
'fullBaseUrl' => false,
|
||||||
'imageBaseUrl' => 'img/',
|
'imageBaseUrl' => 'img/',
|
||||||
'cssBaseUrl' => 'css/',
|
'cssBaseUrl' => 'css/',
|
||||||
'jsBaseUrl' => 'js/',
|
'jsBaseUrl' => 'js/',
|
||||||
'paths' => [
|
'paths' => [
|
||||||
'plugins' => [ROOT . DS . 'plugins' . DS],
|
'plugins' => [ROOT . DS . 'plugins' . DS],
|
||||||
'templates' => [APP . 'Template' . DS],
|
'templates' => [APP . 'Template' . DS],
|
||||||
'locales' => [APP . 'Locale' . DS],
|
'locales' => [APP . 'Locale' . DS],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Security and encryption configuration
|
* Security and encryption configuration
|
||||||
*
|
*
|
||||||
* - salt - A random string used in security hashing methods.
|
* - salt - A random string used in security hashing methods.
|
||||||
* The salt value is also used as the encryption key.
|
* The salt value is also used as the encryption key.
|
||||||
* You should treat it as extremely sensitive data.
|
* You should treat it as extremely sensitive data.
|
||||||
*/
|
*/
|
||||||
'Security' => [
|
'Security' => [
|
||||||
'salt' => env('SECURITY_SALT', '7ddf685a27d997ef36e51bdd626e7fc6b50a3abfb2971e8e59974d421116a150'),
|
'salt' => env('SECURITY_SALT', '7ddf685a27d997ef36e51bdd626e7fc6b50a3abfb2971e8e59974d421116a150'),
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply timestamps with the last modified time to static assets (js, css, images).
|
* Apply timestamps with the last modified time to static assets (js, css, images).
|
||||||
* Will append a querystring parameter containing the time the file was modified.
|
* Will append a querystring parameter containing the time the file was modified.
|
||||||
* This is useful for busting browser caches.
|
* This is useful for busting browser caches.
|
||||||
*
|
*
|
||||||
* Set to true to apply timestamps when debug is true. Set to 'force' to always
|
* Set to true to apply timestamps when debug is true. Set to 'force' to always
|
||||||
* enable timestamping regardless of debug value.
|
* enable timestamping regardless of debug value.
|
||||||
*/
|
*/
|
||||||
'Asset' => [
|
'Asset' => [
|
||||||
//'timestamp' => true,
|
//'timestamp' => true,
|
||||||
// 'cacheTime' => '+1 year'
|
// 'cacheTime' => '+1 year'
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the cache adapters.
|
* Configure the cache adapters.
|
||||||
*/
|
*/
|
||||||
'Cache' => [
|
'Cache' => [
|
||||||
'default' => [
|
'default' => [
|
||||||
'className' => FileEngine::class,
|
'className' => FileEngine::class,
|
||||||
'path' => CACHE,
|
'path' => CACHE,
|
||||||
'url' => env('CACHE_DEFAULT_URL', null),
|
'url' => env('CACHE_DEFAULT_URL', null),
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the cache used for general framework caching.
|
* Configure the cache used for general framework caching.
|
||||||
* Translation cache files are stored with this configuration.
|
* Translation cache files are stored with this configuration.
|
||||||
* Duration will be set to '+2 minutes' in bootstrap.php when debug = true
|
* Duration will be set to '+2 minutes' in bootstrap.php when debug = true
|
||||||
* If you set 'className' => 'Null' core cache will be disabled.
|
* If you set 'className' => 'Null' core cache will be disabled.
|
||||||
*/
|
*/
|
||||||
'_cake_core_' => [
|
'_cake_core_' => [
|
||||||
'className' => FileEngine::class,
|
'className' => FileEngine::class,
|
||||||
'prefix' => 'myapp_cake_core_',
|
'prefix' => 'myapp_cake_core_',
|
||||||
'path' => CACHE . 'persistent/',
|
'path' => CACHE . 'persistent/',
|
||||||
'serialize' => true,
|
'serialize' => true,
|
||||||
'duration' => '+1 years',
|
'duration' => '+1 years',
|
||||||
'url' => env('CACHE_CAKECORE_URL', null),
|
'url' => env('CACHE_CAKECORE_URL', null),
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the cache for model and datasource caches. This cache
|
* Configure the cache for model and datasource caches. This cache
|
||||||
* configuration is used to store schema descriptions, and table listings
|
* configuration is used to store schema descriptions, and table listings
|
||||||
* in connections.
|
* in connections.
|
||||||
* Duration will be set to '+2 minutes' in bootstrap.php when debug = true
|
* Duration will be set to '+2 minutes' in bootstrap.php when debug = true
|
||||||
*/
|
*/
|
||||||
'_cake_model_' => [
|
'_cake_model_' => [
|
||||||
'className' => FileEngine::class,
|
'className' => FileEngine::class,
|
||||||
'prefix' => 'myapp_cake_model_',
|
'prefix' => 'myapp_cake_model_',
|
||||||
'path' => CACHE . 'models/',
|
'path' => CACHE . 'models/',
|
||||||
'serialize' => true,
|
'serialize' => true,
|
||||||
'duration' => '+1 years',
|
'duration' => '+1 years',
|
||||||
'url' => env('CACHE_CAKEMODEL_URL', null),
|
'url' => env('CACHE_CAKEMODEL_URL', null),
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the cache for routes. The cached routes collection is built the
|
* Configure the cache for routes. The cached routes collection is built the
|
||||||
* first time the routes are processed via `config/routes.php`.
|
* first time the routes are processed via `config/routes.php`.
|
||||||
* Duration will be set to '+2 seconds' in bootstrap.php when debug = true
|
* Duration will be set to '+2 seconds' in bootstrap.php when debug = true
|
||||||
*/
|
*/
|
||||||
'_cake_routes_' => [
|
'_cake_routes_' => [
|
||||||
'className' => FileEngine::class,
|
'className' => FileEngine::class,
|
||||||
'prefix' => 'myapp_cake_routes_',
|
'prefix' => 'myapp_cake_routes_',
|
||||||
'path' => CACHE,
|
'path' => CACHE,
|
||||||
'serialize' => true,
|
'serialize' => true,
|
||||||
'duration' => '+1 years',
|
'duration' => '+1 years',
|
||||||
'url' => env('CACHE_CAKEROUTES_URL', null),
|
'url' => env('CACHE_CAKEROUTES_URL', null),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the Error and Exception handlers used by your application.
|
* Configure the Error and Exception handlers used by your application.
|
||||||
*
|
*
|
||||||
* By default errors are displayed using Debugger, when debug is true and logged
|
* By default errors are displayed using Debugger, when debug is true and logged
|
||||||
* by Cake\Log\Log when debug is false.
|
* by Cake\Log\Log when debug is false.
|
||||||
*
|
*
|
||||||
* In CLI environments exceptions will be printed to stderr with a backtrace.
|
* In CLI environments exceptions will be printed to stderr with a backtrace.
|
||||||
* In web environments an HTML page will be displayed for the exception.
|
* In web environments an HTML page will be displayed for the exception.
|
||||||
* With debug true, framework errors like Missing Controller will be displayed.
|
* With debug true, framework errors like Missing Controller will be displayed.
|
||||||
* When debug is false, framework errors will be coerced into generic HTTP errors.
|
* When debug is false, framework errors will be coerced into generic HTTP errors.
|
||||||
*
|
*
|
||||||
* Options:
|
* Options:
|
||||||
*
|
*
|
||||||
* - `errorLevel` - int - The level of errors you are interested in capturing.
|
* - `errorLevel` - int - The level of errors you are interested in capturing.
|
||||||
* - `trace` - boolean - Whether or not backtraces should be included in
|
* - `trace` - boolean - Whether or not backtraces should be included in
|
||||||
* logged errors/exceptions.
|
* logged errors/exceptions.
|
||||||
* - `log` - boolean - Whether or not you want exceptions logged.
|
* - `log` - boolean - Whether or not you want exceptions logged.
|
||||||
* - `exceptionRenderer` - string - The class responsible for rendering
|
* - `exceptionRenderer` - string - The class responsible for rendering
|
||||||
* uncaught exceptions. If you choose a custom class you should place
|
* uncaught exceptions. If you choose a custom class you should place
|
||||||
* the file for that class in src/Error. This class needs to implement a
|
* the file for that class in src/Error. This class needs to implement a
|
||||||
* render method.
|
* render method.
|
||||||
* - `skipLog` - array - List of exceptions to skip for logging. Exceptions that
|
* - `skipLog` - array - List of exceptions to skip for logging. Exceptions that
|
||||||
* extend one of the listed exceptions will also be skipped for logging.
|
* extend one of the listed exceptions will also be skipped for logging.
|
||||||
* E.g.:
|
* E.g.:
|
||||||
* `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']`
|
* `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']`
|
||||||
* - `extraFatalErrorMemory` - int - The number of megabytes to increase
|
* - `extraFatalErrorMemory` - int - The number of megabytes to increase
|
||||||
* the memory limit by when a fatal error is encountered. This allows
|
* the memory limit by when a fatal error is encountered. This allows
|
||||||
* breathing room to complete logging or error handling.
|
* breathing room to complete logging or error handling.
|
||||||
*/
|
*/
|
||||||
'Error' => [
|
'Error' => [
|
||||||
'errorLevel' => E_ALL,
|
'errorLevel' => E_ALL,
|
||||||
'exceptionRenderer' => ExceptionRenderer::class,
|
'exceptionRenderer' => ExceptionRenderer::class,
|
||||||
'skipLog' => [],
|
'skipLog' => [],
|
||||||
'log' => true,
|
'log' => true,
|
||||||
'trace' => true,
|
'trace' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email configuration.
|
* Email configuration.
|
||||||
*
|
*
|
||||||
* By defining transports separately from delivery profiles you can easily
|
* By defining transports separately from delivery profiles you can easily
|
||||||
* re-use transport configuration across multiple profiles.
|
* re-use transport configuration across multiple profiles.
|
||||||
*
|
*
|
||||||
* You can specify multiple configurations for production, development and
|
* You can specify multiple configurations for production, development and
|
||||||
* testing.
|
* testing.
|
||||||
*
|
*
|
||||||
* Each transport needs a `className`. Valid options are as follows:
|
* Each transport needs a `className`. Valid options are as follows:
|
||||||
*
|
*
|
||||||
* Mail - Send using PHP mail function
|
* Mail - Send using PHP mail function
|
||||||
* Smtp - Send using SMTP
|
* Smtp - Send using SMTP
|
||||||
* Debug - Do not send the email, just return the result
|
* Debug - Do not send the email, just return the result
|
||||||
*
|
*
|
||||||
* You can add custom transports (or override existing transports) by adding the
|
* You can add custom transports (or override existing transports) by adding the
|
||||||
* appropriate file to src/Mailer/Transport. Transports should be named
|
* appropriate file to src/Mailer/Transport. Transports should be named
|
||||||
* 'YourTransport.php', where 'Your' is the name of the transport.
|
* 'YourTransport.php', where 'Your' is the name of the transport.
|
||||||
*/
|
*/
|
||||||
'EmailTransport' => [
|
'EmailTransport' => [
|
||||||
'default' => [
|
'default' => [
|
||||||
'className' => MailTransport::class,
|
'className' => MailTransport::class,
|
||||||
/*
|
/*
|
||||||
* The following keys are used in SMTP transports:
|
* The following keys are used in SMTP transports:
|
||||||
*/
|
*/
|
||||||
'host' => 'localhost',
|
'host' => 'localhost',
|
||||||
'port' => 25,
|
'port' => 25,
|
||||||
'timeout' => 30,
|
'timeout' => 30,
|
||||||
'username' => null,
|
'username' => null,
|
||||||
'password' => null,
|
'password' => null,
|
||||||
'client' => null,
|
'client' => null,
|
||||||
'tls' => null,
|
'tls' => null,
|
||||||
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
|
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email delivery profiles
|
* Email delivery profiles
|
||||||
*
|
*
|
||||||
* Delivery profiles allow you to predefine various properties about email
|
* Delivery profiles allow you to predefine various properties about email
|
||||||
* messages from your application and give the settings a name. This saves
|
* messages from your application and give the settings a name. This saves
|
||||||
* duplication across your application and makes maintenance and development
|
* duplication across your application and makes maintenance and development
|
||||||
* easier. Each profile accepts a number of keys. See `Cake\Mailer\Email`
|
* easier. Each profile accepts a number of keys. See `Cake\Mailer\Email`
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
'Email' => [
|
'Email' => [
|
||||||
'default' => [
|
'default' => [
|
||||||
'transport' => 'default',
|
'transport' => 'default',
|
||||||
'from' => 'you@localhost',
|
'from' => 'you@localhost',
|
||||||
//'charset' => 'utf-8',
|
//'charset' => 'utf-8',
|
||||||
//'headerCharset' => 'utf-8',
|
//'headerCharset' => 'utf-8',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection information used by the ORM to connect
|
* Connection information used by the ORM to connect
|
||||||
* to your application's datastores.
|
* to your application's datastores.
|
||||||
*
|
*
|
||||||
* ### Notes
|
* ### Notes
|
||||||
* - Drivers include Mysql Postgres Sqlite Sqlserver
|
* - Drivers include Mysql Postgres Sqlite Sqlserver
|
||||||
* See vendor\cakephp\cakephp\src\Database\Driver for complete list
|
* See vendor\cakephp\cakephp\src\Database\Driver for complete list
|
||||||
* - Do not use periods in database name - it may lead to error.
|
* - Do not use periods in database name - it may lead to error.
|
||||||
* See https://github.com/cakephp/cakephp/issues/6471 for details.
|
* See https://github.com/cakephp/cakephp/issues/6471 for details.
|
||||||
* - 'encoding' is recommended to be set to full UTF-8 4-Byte support.
|
* - 'encoding' is recommended to be set to full UTF-8 4-Byte support.
|
||||||
* E.g set it to 'utf8mb4' in MariaDB and MySQL and 'utf8' for any
|
* E.g set it to 'utf8mb4' in MariaDB and MySQL and 'utf8' for any
|
||||||
* other RDBMS.
|
* other RDBMS.
|
||||||
*/
|
*/
|
||||||
'Datasources' => [
|
'Datasources' => [
|
||||||
'default' => [
|
'default' => [
|
||||||
'className' => Connection::class,
|
'className' => Connection::class,
|
||||||
'driver' => Mysql::class,
|
'driver' => Mysql::class,
|
||||||
'persistent' => false,
|
'persistent' => false,
|
||||||
'host' => 'mariadb',
|
'host' => 'mariadb',
|
||||||
/*
|
/*
|
||||||
* CakePHP will use the default DB port based on the driver selected
|
* CakePHP will use the default DB port based on the driver selected
|
||||||
* MySQL on MAMP uses port 8889, MAMP users will want to uncomment
|
* MySQL on MAMP uses port 8889, MAMP users will want to uncomment
|
||||||
* the following line and set the port accordingly
|
* the following line and set the port accordingly
|
||||||
*/
|
*/
|
||||||
//'port' => 'non_standard_port_number',
|
//'port' => 'non_standard_port_number',
|
||||||
'username' => 'root',
|
'username' => 'root',
|
||||||
'password' => '',
|
'password' => '',
|
||||||
'database' => 'gradido_community',
|
'database' => 'gradido_community',
|
||||||
/*
|
/*
|
||||||
* You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6).
|
* You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6).
|
||||||
*/
|
*/
|
||||||
//'encoding' => 'utf8mb4',
|
//'encoding' => 'utf8mb4',
|
||||||
'timezone' => 'UTC',
|
'timezone' => 'UTC',
|
||||||
'flags' => [],
|
'flags' => [],
|
||||||
'cacheMetadata' => true,
|
'cacheMetadata' => true,
|
||||||
'log' => false,
|
'log' => false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set identifier quoting to true if you are using reserved words or
|
* Set identifier quoting to true if you are using reserved words or
|
||||||
* special characters in your table or column names. Enabling this
|
* special characters in your table or column names. Enabling this
|
||||||
* setting will result in queries built using the Query Builder having
|
* setting will result in queries built using the Query Builder having
|
||||||
* identifiers quoted when creating SQL. It should be noted that this
|
* identifiers quoted when creating SQL. It should be noted that this
|
||||||
* decreases performance because each query needs to be traversed and
|
* decreases performance because each query needs to be traversed and
|
||||||
* manipulated before being executed.
|
* manipulated before being executed.
|
||||||
*/
|
*/
|
||||||
'quoteIdentifiers' => false,
|
'quoteIdentifiers' => false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* During development, if using MySQL < 5.6, uncommenting the
|
* During development, if using MySQL < 5.6, uncommenting the
|
||||||
* following line could boost the speed at which schema metadata is
|
* following line could boost the speed at which schema metadata is
|
||||||
* fetched from the database. It can also be set directly with the
|
* fetched from the database. It can also be set directly with the
|
||||||
* mysql configuration directive 'innodb_stats_on_metadata = 0'
|
* mysql configuration directive 'innodb_stats_on_metadata = 0'
|
||||||
* which is the recommended value in production environments
|
* which is the recommended value in production environments
|
||||||
*/
|
*/
|
||||||
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
||||||
|
|
||||||
'url' => env('DATABASE_URL', null),
|
'url' => env('DATABASE_URL', null),
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The test connection is used during the test suite.
|
* The test connection is used during the test suite.
|
||||||
*/
|
*/
|
||||||
'test' => [
|
'test' => [
|
||||||
'className' => Connection::class,
|
'className' => Connection::class,
|
||||||
'driver' => Mysql::class,
|
'driver' => Mysql::class,
|
||||||
'persistent' => false,
|
'persistent' => false,
|
||||||
'host' => 'localhost',
|
'host' => 'localhost',
|
||||||
//'port' => 'non_standard_port_number',
|
//'port' => 'non_standard_port_number',
|
||||||
'username' => 'my_app',
|
'username' => 'my_app',
|
||||||
'password' => 'secret',
|
'password' => 'secret',
|
||||||
'database' => 'test_myapp',
|
'database' => 'test_myapp',
|
||||||
//'encoding' => 'utf8mb4',
|
//'encoding' => 'utf8mb4',
|
||||||
'timezone' => 'UTC',
|
'timezone' => 'UTC',
|
||||||
'cacheMetadata' => true,
|
'cacheMetadata' => true,
|
||||||
'quoteIdentifiers' => false,
|
'quoteIdentifiers' => false,
|
||||||
'log' => false,
|
'log' => false,
|
||||||
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
||||||
'url' => env('DATABASE_TEST_URL', null),
|
'url' => env('DATABASE_TEST_URL', null),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures logging options
|
* Configures logging options
|
||||||
*/
|
*/
|
||||||
'Log' => [
|
'Log' => [
|
||||||
'debug' => [
|
'debug' => [
|
||||||
'className' => FileLog::class,
|
'className' => FileLog::class,
|
||||||
'path' => LOGS,
|
'path' => LOGS,
|
||||||
'file' => 'debug',
|
'file' => 'debug',
|
||||||
'url' => env('LOG_DEBUG_URL', null),
|
'url' => env('LOG_DEBUG_URL', null),
|
||||||
'scopes' => false,
|
'scopes' => false,
|
||||||
'levels' => ['notice', 'info', 'debug'],
|
'levels' => ['notice', 'info', 'debug'],
|
||||||
],
|
],
|
||||||
'error' => [
|
'error' => [
|
||||||
'className' => FileLog::class,
|
'className' => FileLog::class,
|
||||||
'path' => LOGS,
|
'path' => LOGS,
|
||||||
'file' => 'error',
|
'file' => 'error',
|
||||||
'url' => env('LOG_ERROR_URL', null),
|
'url' => env('LOG_ERROR_URL', null),
|
||||||
'scopes' => false,
|
'scopes' => false,
|
||||||
'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
|
'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
|
||||||
],
|
],
|
||||||
// To enable this dedicated query log, you need set your datasource's log flag to true
|
// To enable this dedicated query log, you need set your datasource's log flag to true
|
||||||
'queries' => [
|
'queries' => [
|
||||||
'className' => FileLog::class,
|
'className' => FileLog::class,
|
||||||
'path' => LOGS,
|
'path' => LOGS,
|
||||||
'file' => 'queries',
|
'file' => 'queries',
|
||||||
'url' => env('LOG_QUERIES_URL', null),
|
'url' => env('LOG_QUERIES_URL', null),
|
||||||
'scopes' => ['queriesLog'],
|
'scopes' => ['queriesLog'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session configuration.
|
* Session configuration.
|
||||||
*
|
*
|
||||||
* Contains an array of settings to use for session configuration. The
|
* Contains an array of settings to use for session configuration. The
|
||||||
* `defaults` key is used to define a default preset to use for sessions, any
|
* `defaults` key is used to define a default preset to use for sessions, any
|
||||||
* settings declared here will override the settings of the default config.
|
* settings declared here will override the settings of the default config.
|
||||||
*
|
*
|
||||||
* ## Options
|
* ## Options
|
||||||
*
|
*
|
||||||
* - `cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'. Avoid using `.` in cookie names,
|
* - `cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'. Avoid using `.` in cookie names,
|
||||||
* as PHP will drop sessions from cookies with `.` in the name.
|
* as PHP will drop sessions from cookies with `.` in the name.
|
||||||
* - `cookiePath` - The url path for which session cookie is set. Maps to the
|
* - `cookiePath` - The url path for which session cookie is set. Maps to the
|
||||||
* `session.cookie_path` php.ini config. Defaults to base path of app.
|
* `session.cookie_path` php.ini config. Defaults to base path of app.
|
||||||
* - `timeout` - The time in minutes the session should be valid for.
|
* - `timeout` - The time in minutes the session should be valid for.
|
||||||
* Pass 0 to disable checking timeout.
|
* Pass 0 to disable checking timeout.
|
||||||
* Please note that php.ini's session.gc_maxlifetime must be equal to or greater
|
* Please note that php.ini's session.gc_maxlifetime must be equal to or greater
|
||||||
* than the largest Session['timeout'] in all served websites for it to have the
|
* than the largest Session['timeout'] in all served websites for it to have the
|
||||||
* desired effect.
|
* desired effect.
|
||||||
* - `defaults` - The default configuration set to use as a basis for your session.
|
* - `defaults` - The default configuration set to use as a basis for your session.
|
||||||
* There are four built-in options: php, cake, cache, database.
|
* There are four built-in options: php, cake, cache, database.
|
||||||
* - `handler` - Can be used to enable a custom session handler. Expects an
|
* - `handler` - Can be used to enable a custom session handler. Expects an
|
||||||
* array with at least the `engine` key, being the name of the Session engine
|
* array with at least the `engine` key, being the name of the Session engine
|
||||||
* class to use for managing the session. CakePHP bundles the `CacheSession`
|
* class to use for managing the session. CakePHP bundles the `CacheSession`
|
||||||
* and `DatabaseSession` engines.
|
* and `DatabaseSession` engines.
|
||||||
* - `ini` - An associative array of additional ini values to set.
|
* - `ini` - An associative array of additional ini values to set.
|
||||||
*
|
*
|
||||||
* The built-in `defaults` options are:
|
* The built-in `defaults` options are:
|
||||||
*
|
*
|
||||||
* - 'php' - Uses settings defined in your php.ini.
|
* - 'php' - Uses settings defined in your php.ini.
|
||||||
* - 'cake' - Saves session files in CakePHP's /tmp directory.
|
* - 'cake' - Saves session files in CakePHP's /tmp directory.
|
||||||
* - 'database' - Uses CakePHP's database sessions.
|
* - 'database' - Uses CakePHP's database sessions.
|
||||||
* - 'cache' - Use the Cache class to save sessions.
|
* - 'cache' - Use the Cache class to save sessions.
|
||||||
*
|
*
|
||||||
* To define a custom session handler, save it at src/Network/Session/<name>.php.
|
* To define a custom session handler, save it at src/Network/Session/<name>.php.
|
||||||
* Make sure the class implements PHP's `SessionHandlerInterface` and set
|
* Make sure the class implements PHP's `SessionHandlerInterface` and set
|
||||||
* Session.handler to <name>
|
* Session.handler to <name>
|
||||||
*
|
*
|
||||||
* To use database sessions, load the SQL file located at config/schema/sessions.sql
|
* To use database sessions, load the SQL file located at config/schema/sessions.sql
|
||||||
*/
|
*/
|
||||||
'Session' => [
|
'Session' => [
|
||||||
'defaults' => 'php',
|
'defaults' => 'php',
|
||||||
],
|
],
|
||||||
// Gradido specific configuration
|
// Gradido specific configuration
|
||||||
// Login Server ip and port
|
// Login Server ip and port
|
||||||
'LoginServer' => [
|
'LoginServer' => [
|
||||||
'host' => 'http://login-server',
|
'host' => 'http://login-server',
|
||||||
'port' => 1201
|
'port' => 1201
|
||||||
],
|
],
|
||||||
'API' => [
|
'API' => [
|
||||||
'allowedCaller' => ['login-server']
|
'allowedCaller' => ['login-server']
|
||||||
],
|
],
|
||||||
'ServerAdminEmail' => 'info@gradido.net',
|
'ServerAdminEmail' => 'info@gradido.net',
|
||||||
'noReplyEmail' => 'no-reply@gradido.net',
|
'noReplyEmail' => 'no-reply@gradido.net',
|
||||||
'disableEmail' => true,
|
'disableEmail' => true,
|
||||||
|
|
||||||
'GroupNode' => false
|
'GroupNode' => false
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,51 +1,56 @@
|
|||||||
HTTPServer.port = 1200
|
HTTPServer.port = 1200
|
||||||
JSONServer.port = 1201
|
JSONServer.port = 1201
|
||||||
Gradido.group_id = 1
|
Gradido.group_id = 1
|
||||||
|
|
||||||
crypto.server_admin_public = f909a866baec97c5460b8d7a93b72d3d4d20cc45d9f15d78bd83944eb9286b7f
|
crypto.server_admin_public = f909a866baec97c5460b8d7a93b72d3d4d20cc45d9f15d78bd83944eb9286b7f
|
||||||
crypto.server_key = a51ef8ac7ef1abf162fb7a65261acd7a
|
crypto.server_key = a51ef8ac7ef1abf162fb7a65261acd7a
|
||||||
# TODO auto-generate in docker build step
|
# TODO auto-generate in docker build step
|
||||||
crypto.app_secret = 21ffbbc616fe
|
crypto.app_secret = 21ffbbc616fe
|
||||||
|
|
||||||
# Server admin Passphrase
|
# Server admin Passphrase
|
||||||
# nerve execute merit pool talk hockey basic win cargo spin disagree ethics swear price purchase say clutch decrease slow half forest reform cheese able
|
# nerve execute merit pool talk hockey basic win cargo spin disagree ethics swear price purchase say clutch decrease slow half forest reform cheese able
|
||||||
#
|
#
|
||||||
|
|
||||||
phpServer.url = http://localhost/
|
phpServer.url = http://localhost/
|
||||||
phpServer.host = nginx
|
phpServer.host = nginx
|
||||||
|
|
||||||
loginServer.path = http://localhost/account
|
loginServer.path = http://localhost/account
|
||||||
loginServer.default_locale = de
|
loginServer.default_locale = de
|
||||||
loginServer.db.host = mariadb
|
loginServer.db.host = mariadb
|
||||||
loginServer.db.name = gradido_login
|
loginServer.db.name = gradido_login
|
||||||
loginServer.db.user = root
|
loginServer.db.user = root
|
||||||
loginServer.db.password =
|
loginServer.db.password =
|
||||||
loginServer.db.port = 3306
|
loginServer.db.port = 3306
|
||||||
|
|
||||||
email.disable = true
|
frontend.checkEmailPath = http://localhost/account/checkEmail
|
||||||
#email.username =
|
|
||||||
#email.sender =
|
email.disable = true
|
||||||
#email.admin_receiver =
|
|
||||||
#email.password =
|
#email.username =
|
||||||
#email.smtp.url =
|
#email.sender =
|
||||||
#email.smtp.port =
|
#email.admin_receiver =
|
||||||
|
#email.password =
|
||||||
# binary is default, for debugging also json is possible
|
#email.smtp.url =
|
||||||
#hedera.consensus.message_format = json
|
#email.smtp.port =
|
||||||
# TESTNET or MAINNET, TESTNET is default
|
|
||||||
hedera.nettype = TESTNET
|
# binary is default, for debugging also json is possible
|
||||||
|
#hedera.consensus.message_format = json
|
||||||
# server setup types: test, staging or production
|
# TESTNET or MAINNET, TESTNET is default
|
||||||
ServerSetupType=test
|
hedera.nettype = TESTNET
|
||||||
|
|
||||||
|
# server setup types: test, staging or production
|
||||||
# Session timeout in minutes
|
ServerSetupType=test
|
||||||
#
|
|
||||||
session.timeout = 15
|
|
||||||
|
# Session timeout in minutes
|
||||||
# Disabling security features for faster develop and testing
|
#
|
||||||
unsecure.allow_passwort_via_json_request = 1
|
session.timeout = 15
|
||||||
unsecure.allow_auto_sign_transactions = 1
|
|
||||||
unsecure.allow_cors_all = 1
|
# Disabling security features for faster develop and testing
|
||||||
# default disable, passwords must contain a number, a lower character, a high character, special character, and be at least 8 characters long
|
unsecure.allow_passwort_via_json_request = 1
|
||||||
unsecure.allow_all_passwords = 1
|
unsecure.allow_auto_sign_transactions = 1
|
||||||
|
unsecure.allow_cors_all = 1
|
||||||
|
# default disable, passwords must contain a number, a lower character, a high character, special character, and be at least 8 characters long
|
||||||
|
|
||||||
|
unsecure.allow_all_passwords = 1
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
worker_count = 2
|
worker_count = 2
|
||||||
io_worker_count = 1
|
io_worker_count = 1
|
||||||
data_root_folder = /opt/instance/.gradido
|
data_root_folder = /opt/instance/.gradido
|
||||||
hedera_mirror_endpoint = hcs.testnet.mirrornode.hedera.com:5600
|
hedera_mirror_endpoint = hcs.testnet.mirrornode.hedera.com:5600
|
||||||
sibling_node_file = /opt/instance/.gradido/sibling_nodes.txt
|
sibling_node_file = /opt/instance/.gradido/sibling_nodes.txt
|
||||||
#group_requests_endpoint = 0.0.0.0:13701
|
#group_requests_endpoint = 0.0.0.0:13701
|
||||||
#record_requests_endpoint = 0.0.0.0:13702
|
#record_requests_endpoint = 0.0.0.0:13702
|
||||||
#manage_network_requests_endpoint = 0.0.0.0:13703
|
#manage_network_requests_endpoint = 0.0.0.0:13703
|
||||||
grpc_endpoint = 0.0.0.0:13701
|
grpc_endpoint = 0.0.0.0:13701
|
||||||
json_rpc_port = 13702
|
json_rpc_port = 13702
|
||||||
|
|
||||||
|
|
||||||
# larger value, larger batch, less concurrency
|
# larger value, larger batch, less concurrency
|
||||||
blockchain_append_batch_size = 1000
|
blockchain_append_batch_size = 1000
|
||||||
#blochchain_init_batch_size = 1000
|
#blochchain_init_batch_size = 1000
|
||||||
#block_record_outbound_batch_size = 100
|
#block_record_outbound_batch_size = 100
|
||||||
general_batch_size = 1000
|
general_batch_size = 1000
|
||||||
group_register_topic_id = 0.0.79574
|
group_register_topic_id = 0.0.79574
|
||||||
|
|
||||||
topic_reset_allowed = 1
|
topic_reset_allowed = 1
|
||||||
|
|||||||
@ -38,6 +38,10 @@ services:
|
|||||||
## NGINX ################################################
|
## NGINX ################################################
|
||||||
#########################################################
|
#########################################################
|
||||||
nginx:
|
nginx:
|
||||||
|
depends_on:
|
||||||
|
- frontend
|
||||||
|
- community-server
|
||||||
|
- login-server
|
||||||
volumes:
|
volumes:
|
||||||
- ./logs:/var/log/nginx
|
- ./logs:/var/log/nginx
|
||||||
|
|
||||||
@ -57,7 +61,22 @@ services:
|
|||||||
- external-net
|
- external-net
|
||||||
volumes:
|
volumes:
|
||||||
- /sessions
|
- /sessions
|
||||||
|
|
||||||
|
#########################################################
|
||||||
|
## skeema for updating dbs if changes happend ###########
|
||||||
|
#########################################################
|
||||||
|
skeema:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./skeema/Dockerfile
|
||||||
|
target: skeema_run
|
||||||
|
container_name: skeema
|
||||||
|
depends_on:
|
||||||
|
- mariadb
|
||||||
|
networks:
|
||||||
|
- internal-net
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
frontend_node_modules:
|
frontend_node_modules:
|
||||||
conan:
|
conan:
|
||||||
|
|
||||||
|
|||||||
@ -1,138 +1,138 @@
|
|||||||
# This file defines the production settings. It is overwritten by docker-compose.override.yml,
|
# 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
|
# 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:
|
# is required to explicitly define if you want an production build:
|
||||||
# > docker-compose -f docker-compose.yml up
|
# > docker-compose -f docker-compose.yml up
|
||||||
|
|
||||||
version: "3.4"
|
version: "3.4"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
########################################################
|
########################################################
|
||||||
# FRONTEND #############################################
|
# FRONTEND #############################################
|
||||||
########################################################
|
########################################################
|
||||||
frontend:
|
frontend:
|
||||||
image: gradido/frontend:latest
|
image: gradido/frontend:latest
|
||||||
build:
|
build:
|
||||||
context: ./frontend
|
context: ./frontend
|
||||||
target: production
|
target: production
|
||||||
networks:
|
networks:
|
||||||
- external-net
|
- external-net
|
||||||
depends_on:
|
depends_on:
|
||||||
- nginx
|
- nginx
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
environment:
|
environment:
|
||||||
# Envs used in Dockerfile
|
# Envs used in Dockerfile
|
||||||
# - DOCKER_WORKDIR="/app"
|
# - DOCKER_WORKDIR="/app"
|
||||||
# - PORT="8080"
|
# - PORT="8080"
|
||||||
- BUILD_DATE
|
- BUILD_DATE
|
||||||
- BUILD_VERSION
|
- BUILD_VERSION
|
||||||
- BUILD_COMMIT
|
- BUILD_COMMIT
|
||||||
- NODE_ENV="production"
|
- NODE_ENV="production"
|
||||||
# Application only envs
|
# Application only envs
|
||||||
#- HOST=0.0.0.0 # This is nuxt specific, alternative value is HOST=webapp
|
#- HOST=0.0.0.0 # This is nuxt specific, alternative value is HOST=webapp
|
||||||
#env_file:
|
#env_file:
|
||||||
# - ./frontend/.env
|
# - ./frontend/.env
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## MARIADB ##############################################
|
## MARIADB ##############################################
|
||||||
#########################################################
|
#########################################################
|
||||||
mariadb:
|
mariadb:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./mariadb/Dockerfile
|
dockerfile: ./mariadb/Dockerfile
|
||||||
target: mariadb_server
|
target: mariadb_server
|
||||||
container_name: mariadb
|
container_name: mariadb
|
||||||
environment:
|
environment:
|
||||||
- MARIADB_ALLOW_EMPTY_PASSWORD=1
|
- MARIADB_ALLOW_EMPTY_PASSWORD=1
|
||||||
- MARIADB_USER=root
|
- MARIADB_USER=root
|
||||||
networks:
|
networks:
|
||||||
- internal-net
|
- internal-net
|
||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
volumes:
|
volumes:
|
||||||
- db_vol:/var/lib/mysql
|
- db_vol:/var/lib/mysql
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## LOGIN SERVER #########################################
|
## LOGIN SERVER #########################################
|
||||||
#########################################################
|
#########################################################
|
||||||
login-server:
|
login-server:
|
||||||
build:
|
build:
|
||||||
context: ./login_server/
|
context: ./login_server/
|
||||||
target: login_server
|
target: login_server
|
||||||
container_name: login-server
|
container_name: login-server
|
||||||
depends_on:
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
networks:
|
networks:
|
||||||
- internal-net
|
- internal-net
|
||||||
ports:
|
ports:
|
||||||
- 1200:1200
|
- 1200:1200
|
||||||
- 1201:1201
|
- 1201:1201
|
||||||
volumes:
|
volumes:
|
||||||
- ./configs/login_server:/etc/grd_login
|
- ./configs/login_server:/etc/grd_login
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## NGINX ################################################
|
## NGINX ################################################
|
||||||
#########################################################
|
#########################################################
|
||||||
## nginx, connect login-server and community-server together (and php-fpm to community-server)
|
## nginx, connect login-server and community-server together (and php-fpm to community-server)
|
||||||
nginx:
|
nginx:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./nginx/Dockerfile
|
dockerfile: ./nginx/Dockerfile
|
||||||
container_name: nginx
|
container_name: nginx
|
||||||
networks:
|
networks:
|
||||||
- external-net
|
- external-net
|
||||||
- internal-net
|
- internal-net
|
||||||
depends_on:
|
depends_on:
|
||||||
- community-server
|
- community-server
|
||||||
- login-server
|
- login-server
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## COMMUNITY SERVER (cakephp with php-fpm) ##############
|
## COMMUNITY SERVER (cakephp with php-fpm) ##############
|
||||||
#########################################################
|
#########################################################
|
||||||
community-server:
|
community-server:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./community_server/Dockerfile
|
dockerfile: ./community_server/Dockerfile
|
||||||
container_name: community-server
|
container_name: community-server
|
||||||
environment:
|
environment:
|
||||||
- DB_PASSWORD=''
|
- DB_PASSWORD=''
|
||||||
- DB_USER='root'
|
- DB_USER='root'
|
||||||
- DB_DATABASE='gradido_community'
|
- DB_DATABASE='gradido_community'
|
||||||
depends_on:
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
networks:
|
networks:
|
||||||
- internal-net
|
- internal-net
|
||||||
volumes:
|
volumes:
|
||||||
- ./community_server/config/php-fpm/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini
|
- ./community_server/config/php-fpm/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## GRADIDO NODE v1 ######################################
|
## GRADIDO NODE v1 ######################################
|
||||||
#########################################################
|
#########################################################
|
||||||
# gradido-node:
|
# gradido-node:
|
||||||
# build:
|
# build:
|
||||||
# context: .
|
# context: .
|
||||||
# dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile
|
# dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile
|
||||||
# volumes:
|
# volumes:
|
||||||
# - ${GN_INSTANCE_FOLDER}:/opt/instance
|
# - ${GN_INSTANCE_FOLDER}:/opt/instance
|
||||||
# container_name: ${GN_CONTAINER_NAME}
|
# container_name: ${GN_CONTAINER_NAME}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## GRADIDO NODE test ###################################
|
## GRADIDO NODE test ###################################
|
||||||
#########################################################
|
#########################################################
|
||||||
# gradido-node-test:
|
# gradido-node-test:
|
||||||
# build:
|
# build:
|
||||||
# context: .
|
# context: .
|
||||||
# dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile
|
# dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile
|
||||||
# container_name: gn-test
|
# container_name: gn-test
|
||||||
# working_dir: /opt/gn/build
|
# working_dir: /opt/gn/build
|
||||||
# command: ["./unit_tests"]
|
# command: ["./unit_tests"]
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
external-net:
|
external-net:
|
||||||
internal-net:
|
internal-net:
|
||||||
internal: true
|
internal: true
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
db_vol:
|
db_vol:
|
||||||
|
|||||||
@ -1,131 +1,131 @@
|
|||||||
# community server api
|
# community server api
|
||||||
|
|
||||||
In this examples I assume that you use gradido with or docker-compose build on your local maschine
|
In this examples I assume that you use gradido with or docker-compose build on your local maschine
|
||||||
|
|
||||||
## Konto Overview
|
## Konto Overview
|
||||||
return current account balance
|
return current account balance
|
||||||
|
|
||||||
GET http://localhost/state-balances/ajaxGetBalance/-127182
|
GET http://localhost/state-balances/ajaxGetBalance/-127182
|
||||||
|
|
||||||
If session is valid, return:
|
If session is valid, return:
|
||||||
```json
|
```json
|
||||||
{"state":"success","balance":174500}
|
{"state":"success","balance":174500}
|
||||||
```
|
```
|
||||||
- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 174500 = 17,45 GDD
|
- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 174500 = 17,45 GDD
|
||||||
|
|
||||||
## List Transactions
|
## List Transactions
|
||||||
List all transactions from logged in user, currently without paging
|
List all transactions from logged in user, currently without paging
|
||||||
Ajax:
|
Ajax:
|
||||||
GET http://localhost/state-balances/ajaxListTransactions/-127182/
|
GET http://localhost/state-balances/ajaxListTransactions/-127182/
|
||||||
or
|
or
|
||||||
GET http://localhost/state-balances/ajaxListTransactions/-127182/DESC
|
GET http://localhost/state-balances/ajaxListTransactions/-127182/DESC
|
||||||
to get transaction in descending order
|
to get transaction in descending order
|
||||||
|
|
||||||
Antwort:
|
Antwort:
|
||||||
Wenn alles okay:
|
Wenn alles okay:
|
||||||
```json
|
```json
|
||||||
{"state":"success", "transactions":
|
{"state":"success", "transactions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "Max Mustermann",
|
"name": "Max Mustermann",
|
||||||
"email": "Maxim Mustermann",
|
"email": "Maxim Mustermann",
|
||||||
"type": "send",
|
"type": "send",
|
||||||
"transaction_id": 2,
|
"transaction_id": 2,
|
||||||
"date": "2021-02-19T13:25:36+00:00",
|
"date": "2021-02-19T13:25:36+00:00",
|
||||||
"balance": 1920000,
|
"balance": 1920000,
|
||||||
"memo": "a piece of cake :)",
|
"memo": "a piece of cake :)",
|
||||||
"pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7"
|
"pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"transactionExecutingCount": 0,
|
"transactionExecutingCount": 0,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"gdtSum": 0,
|
"gdtSum": 0,
|
||||||
"timeUsed": 0.04562687873840332
|
"timeUsed": 0.04562687873840332
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- name: name of other involved party or empty if unknown (if other party don't belong to group)
|
- name: name of other involved party or empty if unknown (if other party don't belong to group)
|
||||||
- if type is send, name is name of receiver
|
- if type is send, name is name of receiver
|
||||||
- if type is receive, name is name of sender
|
- if type is receive, name is name of sender
|
||||||
- if type is creation currently I use a static string ("Gradido Akademie)
|
- if type is creation currently I use a static string ("Gradido Akademie)
|
||||||
- email: optional, only if type is send or receive and other user is known
|
- email: optional, only if type is send or receive and other user is known
|
||||||
- pubkey: optional, only if type is send or receive and other user isn't known
|
- pubkey: optional, only if type is send or receive and other user isn't known
|
||||||
- type: type of transaction
|
- type: type of transaction
|
||||||
- creation: user has get gradidos created
|
- creation: user has get gradidos created
|
||||||
- send: user has send another user gradidos
|
- send: user has send another user gradidos
|
||||||
- receiver: user has received gradidos from another user
|
- receiver: user has received gradidos from another user
|
||||||
- transaction_id: id of transaction in db, in stage2 also the hedera sequence number of transaction
|
- transaction_id: id of transaction in db, in stage2 also the hedera sequence number of transaction
|
||||||
- date: date of ordering transaction (booking date)
|
- date: date of ordering transaction (booking date)
|
||||||
- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 1920000 = 192,00 GDD
|
- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 1920000 = 192,00 GDD
|
||||||
- memo: Details about transaction
|
- memo: Details about transaction
|
||||||
- pubkey: optional, if other party isn't known, hexadecimal representation of 32 Byte public key of user [0-9a-f]
|
- pubkey: optional, if other party isn't known, hexadecimal representation of 32 Byte public key of user [0-9a-f]
|
||||||
|
|
||||||
- transactionExecutingCount: how many transaction for this user currently pending and waiting for signing
|
- transactionExecutingCount: how many transaction for this user currently pending and waiting for signing
|
||||||
- count: sum of finished transactions user is involved
|
- count: sum of finished transactions user is involved
|
||||||
- gdtSum: sum of gdt of user in cent with 2 places (Nachkommastellen)
|
- gdtSum: sum of gdt of user in cent with 2 places (Nachkommastellen)
|
||||||
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
||||||
|
|
||||||
## Creation Transaction
|
## Creation Transaction
|
||||||
Make a creation transaction
|
Make a creation transaction
|
||||||
With new Option set in Login-Server:
|
With new Option set in Login-Server:
|
||||||
```ini
|
```ini
|
||||||
unsecure.allow_auto_sign_transactions = 1
|
unsecure.allow_auto_sign_transactions = 1
|
||||||
```
|
```
|
||||||
transactions can be auto-signed directly with handing in transaction.
|
transactions can be auto-signed directly with handing in transaction.
|
||||||
Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
|
Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
|
||||||
|
|
||||||
POST http://localhost/transaction-creations/ajaxCreate
|
POST http://localhost/transaction-creations/ajaxCreate
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"session_id" : -127182,
|
"session_id" : -127182,
|
||||||
"email": "max.musterman@gmail.de",
|
"email": "max.musterman@gmail.de",
|
||||||
"amount": 10000000,
|
"amount": 10000000,
|
||||||
"target_date":"2021-02-19T13:25:36+00:00",
|
"target_date":"2021-02-19T13:25:36+00:00",
|
||||||
"memo":"AGE",
|
"memo":"AGE",
|
||||||
"auto_sign": true
|
"auto_sign": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
return if everything is ok:
|
return if everything is ok:
|
||||||
```json
|
```json
|
||||||
{"state":"success", "timeUsed": 0.0122}
|
{"state":"success", "timeUsed": 0.0122}
|
||||||
```
|
```
|
||||||
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
||||||
|
|
||||||
## Send Coins Transaction
|
## Send Coins Transaction
|
||||||
Make a simple GDD Transaction, send Coins from one user to other.
|
Make a simple GDD Transaction, send Coins from one user to other.
|
||||||
With new Option set in Login-Server:
|
With new Option set in Login-Server:
|
||||||
```ini
|
```ini
|
||||||
unsecure.allow_auto_sign_transactions = 1
|
unsecure.allow_auto_sign_transactions = 1
|
||||||
```
|
```
|
||||||
transactions can be auto-signed directly with handing in transaction.
|
transactions can be auto-signed directly with handing in transaction.
|
||||||
Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
|
Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
|
||||||
|
|
||||||
POST http://localhost/transaction-send-coins/ajaxCreate
|
POST http://localhost/transaction-send-coins/ajaxCreate
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"session_id" : -127182,
|
"session_id" : -127182,
|
||||||
"amount": 2000000,
|
"amount": 2000000,
|
||||||
"email": "max.musterman@gmail.de",
|
"email": "max.musterman@gmail.de",
|
||||||
"memo":"Thank you :)",
|
"memo":"Thank you :)",
|
||||||
"auto_sign": true
|
"auto_sign": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- amout: amount to transfer, 2000000 = 200,00 GDD
|
- amout: amount to transfer, 2000000 = 200,00 GDD
|
||||||
- email: receiver email address, must be differ from user email
|
- email: receiver email address, must be differ from user email
|
||||||
- memo: Details about transaction
|
- memo: Details about transaction
|
||||||
- auto_sign: set to true to directly sign transaction if unsecure.allow_auto_sign_transactions = 1 is set
|
- auto_sign: set to true to directly sign transaction if unsecure.allow_auto_sign_transactions = 1 is set
|
||||||
|
|
||||||
return if everything is ok:
|
return if everything is ok:
|
||||||
```json
|
```json
|
||||||
{"state":"success", "timeUsed": 0.0122}
|
{"state":"success", "timeUsed": 0.0122}
|
||||||
```
|
```
|
||||||
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
||||||
|
|
||||||
Than the transaction was created on community server, send to login-server, signed (if unsecure.allow_auto_sign_transactions = 1 and auto_sign = true)
|
Than the transaction was created on community server, send to login-server, signed (if unsecure.allow_auto_sign_transactions = 1 and auto_sign = true)
|
||||||
and send back to community server and put into db.
|
and send back to community server and put into db.
|
||||||
After you get this answear you see the new transaction if you list transactions or call for the balance.
|
After you get this answear you see the new transaction if you list transactions or call for the balance.
|
||||||
|
|
||||||
Without auto-sign the transaction is pending on login-server and waits for the user to review it at
|
Without auto-sign the transaction is pending on login-server and waits for the user to review it at
|
||||||
http://localhost/account/checkTransactions
|
http://localhost/account/checkTransactions
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,8 +15,10 @@ mit:
|
|||||||
```ini
|
```ini
|
||||||
unsercure.allow_cors_all = 1
|
unsercure.allow_cors_all = 1
|
||||||
```
|
```
|
||||||
Wird bei allen JSON-Requests zum Header: Access-Control-Allow-Origin:*
|
Wird bei allen JSON-Requests zum Header hinzugefügt:
|
||||||
hinzugefügt.
|
- Access-Control-Allow-Origin:*
|
||||||
|
- Access-Control-Allow-Headers: "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"
|
||||||
|
|
||||||
|
|
||||||
In diesen Beispielen gehe ich jetzt davon aus, das du das gesamte Gradido Projekt mit Docker gebaut hast und auf dem lokalen Rechner laufen lässt.
|
In diesen Beispielen gehe ich jetzt davon aus, das du das gesamte Gradido Projekt mit Docker gebaut hast und auf dem lokalen Rechner laufen lässt.
|
||||||
|
|
||||||
@ -81,4 +83,233 @@ data: {"session_id": -127182}
|
|||||||
Wenn alles okay ist erhältst du:
|
Wenn alles okay ist erhältst du:
|
||||||
```json
|
```json
|
||||||
{"state":"success"}
|
{"state":"success"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Update User Data
|
||||||
|
Update first name, last name, user language and enable/disable user
|
||||||
|
Language currently supported de and en
|
||||||
|
User will be disabled if he wants a account delete but has transactions.
|
||||||
|
Until transactions are saved in real blockchain, we need this data because the public key
|
||||||
|
is in db only saved in state_users so we wenn delete this entry, validating all transactions not longer possible.
|
||||||
|
Disabled User cannot login and cannot receive transactions.
|
||||||
|
In update Object only one of the sets needs to be there.
|
||||||
|
|
||||||
|
Update password can only be used if in Login-Server config:
|
||||||
|
```ini
|
||||||
|
unsecure.allow_passwort_via_json_request = 1
|
||||||
|
```
|
||||||
|
is set
|
||||||
|
|
||||||
|
POST http://localhost/login_api/updateUserInfos
|
||||||
|
```json
|
||||||
|
{"session_id": -127182, "email": "max.musterman@gmail.de", "update": {
|
||||||
|
"User.first_name": "Max",
|
||||||
|
"User.last_name" : "Musterman",
|
||||||
|
"User.disabled": 0,
|
||||||
|
"User.language": "de"
|
||||||
|
"User.password": "1234"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
also valid
|
||||||
|
```json
|
||||||
|
{"session_id": -127182, "email": "max.musterman@gmail.de", "update": {
|
||||||
|
"User.last_name" : "Musterman"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It returns if everything is okay
|
||||||
|
```json
|
||||||
|
{"state":"success", "valid_values": 4, "errors":[]}
|
||||||
|
```
|
||||||
|
- valid_values: should contain count of entrys in update if no error occured (User.password will not be counted)
|
||||||
|
- errors: contain on error string for every entry in update, which type isn't like expected
|
||||||
|
- password:
|
||||||
|
- "new password is the same as old password": no change taking place
|
||||||
|
- "password changed, coludn"t load private key for re-encryption": password was successfully changed, is at the moment only a warning as long as user_backups are unencrypted, safe to ignore
|
||||||
|
- "stored pubkey and private key didn't match": error by re-encryption keys, no changes saved
|
||||||
|
- "User.password isn't valid": if password validation failed, followed by reasons why (additional array in array)
|
||||||
|
example:
|
||||||
|
```json
|
||||||
|
{"errors":[
|
||||||
|
"User.password isn't valid",[
|
||||||
|
"Passwort: Dein Passwort ist zu kurz!\n",
|
||||||
|
"Passwort: Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-_) ein!\n"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"state":"success",
|
||||||
|
"valid_values":0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Retrieve User Data
|
||||||
|
Retrieve different user data, in ask only one field is needed, or every possible combination
|
||||||
|
from the available fields
|
||||||
|
|
||||||
|
Normal User can only retrieve data for himself, admins (login-server admin) can retrieve data from every user
|
||||||
|
Email is also the email address of user from which data are asked
|
||||||
|
|
||||||
|
POST http://localhost/login_api/getUserInfos
|
||||||
|
```json
|
||||||
|
{"session_id": -127182, "email": "max.musterman@gmail.de", "ask": [
|
||||||
|
"EmailVerificationCode.Register",
|
||||||
|
"loginServer.path",
|
||||||
|
"user.pubkeyhex",
|
||||||
|
"user.first_name",
|
||||||
|
"user.last_name",
|
||||||
|
"user.disabled",
|
||||||
|
"user.email_checked",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
returns if no error occured:
|
||||||
|
```json
|
||||||
|
{"state": "success", "userData": {
|
||||||
|
"EmailVerificationCode.Register": "2718271129122",
|
||||||
|
"pubkeyhex": "131c7f68dd94b2be4c913400ff7ff4cdc03ac2bda99c2d29edcacb3b065c67e6",
|
||||||
|
"first_name": "Max",
|
||||||
|
"last_name": "Musterman",
|
||||||
|
"disabled": 0,
|
||||||
|
"email_checked": 1
|
||||||
|
}, "server": {
|
||||||
|
"loginServer.path": "http://localhost/account"
|
||||||
|
},
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Return only the fields which are defined in ask
|
||||||
|
- EmailVerificationCode.Register: return the email verification code for check email (create one if none exist), work only if logged in user is admin and the email isn't from him
|
||||||
|
- loginServer.path: the redirect path to login-server, for example for login with login-server html frontend
|
||||||
|
- user.pubkeyhex: public key of user in hex-format
|
||||||
|
- user.first_name: first name of user
|
||||||
|
- user.last_name: last name of user
|
||||||
|
- user.disabled: User will be disabled if he wants a account delete but has transactions.
|
||||||
|
Until transactions are saved in real blockchain, we need this data because the public key
|
||||||
|
is in db only saved in state_users so we wenn delete this entry, validating all transactions not longer possible.
|
||||||
|
Disabled User cannot login and cannot receive transactions.
|
||||||
|
- email_checked: If user has clicked on link in verification email (register), can only transfer gradidos if email_checked is 1
|
||||||
|
|
||||||
|
- errors: array of strings if error occure
|
||||||
|
|
||||||
|
## Login by Email Verification Code
|
||||||
|
Used for replace http://localhost/account/checkEmail
|
||||||
|
Can be used to set check_email to 1 (will be done automaticly if called with valid email verification code of type register or registerDirect)
|
||||||
|
Can be used for password reset (additional step required: call update user info with new password)
|
||||||
|
|
||||||
|
GET http://localhost/login_api/loginViaEmailVerificationCode?emailVerificationCode=382738273892983
|
||||||
|
|
||||||
|
return
|
||||||
|
```json
|
||||||
|
{"state":"success", "email_verification_code_type":"resetPassword","info":[],"session_id":1853761475}
|
||||||
|
```
|
||||||
|
- email_verification_code_type
|
||||||
|
- resetPassword: for password resets, will be deleted immediately, is a only one use code
|
||||||
|
- registerDirect: code generated by register for check email
|
||||||
|
- register: code generated by auto-register via elopage for check email
|
||||||
|
- info can contain additional info strings
|
||||||
|
- "user hasn't password": if user hasn't set a password yet (for example if he was registered via elopage)
|
||||||
|
- "email already activated": if email was already checked
|
||||||
|
- session_id: session_id for new session
|
||||||
|
|
||||||
|
## Send Emails
|
||||||
|
Let send Login-Server Password reset E-Mail to User
|
||||||
|
Can be also used for admin interface to resend email verification code
|
||||||
|
|
||||||
|
POST http://localhost/login_api/sendEmail
|
||||||
|
```json
|
||||||
|
{"email": "max.musterman@gmail.de", "email_text":7, "email_verification_code_type":"resetPassword" }
|
||||||
|
```
|
||||||
|
also valid:
|
||||||
|
```json
|
||||||
|
{"email": "max.musterman@gmail.de", "email_text":"user reset Password", "email_verification_code_type":"resetPassword" }
|
||||||
|
```
|
||||||
|
or:
|
||||||
|
```json
|
||||||
|
{"session_id": -127182, "email": "max.musterman@gmail.de", "email_text":5, "email_verification_code_type":"register" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- session_id: not needed for resetPassword emails
|
||||||
|
- email_type: choose which email text should be used (number or string can be used)
|
||||||
|
- "email user verification code" (2): default text used when new user has registered
|
||||||
|
- "email user verification code resend" (3): text used when user hasn't activated his account 7 days after register
|
||||||
|
- "email user verification code resend after long time" (4): text used when user hasn't activated his account more than 7 days after register
|
||||||
|
- "email admin user verification code" (5): used if admin trigger sending the email with email verification code
|
||||||
|
- "email admin user verification code resend" (6): used if admin trigger sending the email with email verification code again
|
||||||
|
- "user reset Password" (7): used for reset password email text
|
||||||
|
- "email custom tex" (8): used if custom email text should be used (than email_custom_text and email_custom_subject must also be filled)
|
||||||
|
- email_verification_code_type
|
||||||
|
- resetPassword: for password resets, will be deleted immediately, is a only one use code, can be used without session_id
|
||||||
|
- registerDirect: code generated by register for check email, can only be used by admins for another user
|
||||||
|
- register: code generated by auto-register via elopage for check email, can only be used by admins for another user
|
||||||
|
- email_custom_text (optional): can be used to send email with custom text
|
||||||
|
placeholder for email text, will be replaced
|
||||||
|
- [first_name] first name
|
||||||
|
- [last_name] last name
|
||||||
|
- [duration] time span since user has created account (ex.: 10 Days) with largest unit, day is last unit
|
||||||
|
- [link] login-server checkEmail link with email verification code (ex.: http://localhost/account/checkEmail/382738273892983)
|
||||||
|
- [code] email verification code if you like to use your one link
|
||||||
|
- email_custom_subject (optional): for custom email the subject
|
||||||
|
|
||||||
|
return
|
||||||
|
```json
|
||||||
|
{"state":"success"}
|
||||||
|
```
|
||||||
|
if everything is okay
|
||||||
|
return
|
||||||
|
```json
|
||||||
|
{"state":"warning", "msg":"email already sended"}
|
||||||
|
```
|
||||||
|
if emails was successfully sended but was already sended in past also.
|
||||||
|
|
||||||
|
return with "state":"error" and additional "msg" if error occured (no email sended):
|
||||||
|
- "email already send less than a hour before": User has already get a password reset email and haven't used the link yet
|
||||||
|
- "not supported email type": with "email_verification_code_type":"resetPassword" only email type 7 or 8 allowed
|
||||||
|
- "admin needed": only admins can send email verification emails because this emails normally sended out automaticly
|
||||||
|
- "invalid email": if email wasn't found in db
|
||||||
|
- "invalid session": if session wasn't found (only checked if session_id is set and != 0)
|
||||||
|
- "invalid email type": could not parse email type
|
||||||
|
- "invalid verification code type": could not parse email verification code type
|
||||||
|
- "json exception": error parsing input json, more infos can be found in details
|
||||||
|
|
||||||
|
|
||||||
|
## Check Running Transactions / password encryption
|
||||||
|
Check if transactions on login-server for user are processed
|
||||||
|
|
||||||
|
GET http://localhost/login_api/getRunningUserTasks?email=max.musterman%40gmail.de
|
||||||
|
**OR**
|
||||||
|
POST http://localhost/login_api/getRunningUserTasks
|
||||||
|
```json
|
||||||
|
{"email":"max.musterman@gmail.de"}
|
||||||
|
```
|
||||||
|
|
||||||
|
return
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"state":"success",
|
||||||
|
"runningTasks": {
|
||||||
|
"password creation": 0,
|
||||||
|
"sign transaction": 1,
|
||||||
|
"prepare transaction": 1,
|
||||||
|
"ready for sign transaction":0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
return only entrys which > 0
|
||||||
|
- password creation: after register or password change, login possible after tasks is finish
|
||||||
|
- sign transaction: after check transaction in backend, before transaction is in db
|
||||||
|
- prepare transaction: after sending transaction to login-server, before they can be checked
|
||||||
|
- ready for sign transaction: transactions ready for signing from user
|
||||||
|
|
||||||
|
## Check Session State
|
||||||
|
GET http://localhost/login_api/checkSessionState?session_id=-127182
|
||||||
|
|
||||||
|
return if session is still open
|
||||||
|
```json
|
||||||
|
{"state":"success"}
|
||||||
|
```
|
||||||
|
else return
|
||||||
|
```json
|
||||||
|
{"state":"not found", "msg": "session not found"}
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
160
docu/neue-struktur.drawio
Normal file
160
docu/neue-struktur.drawio
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
<mxfile>
|
||||||
|
<diagram id="5IrTVgsBGhx6YnP7yutc" name="Page-1">
|
||||||
|
<mxGraphModel dx="974" dy="537" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="4">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="2" value="Frontend" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="60" y="70" width="190" height="210" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="3" target="4">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="3" value="Login Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="410" y="70" width="80" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="5">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="3">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="4" value="Community Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="410" y="200" width="80" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="5" value="Node Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="610" y="140" width="80" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="13" value="CakePHP<br>Frontend" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="410" y="280" width="80" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="14" value="Einzel HTML" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="410" y="30" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="17" target="27">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="17" value="Frontend" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="60" y="460" width="190" height="210" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="20" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="20" target="23">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="20" value="Login Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="540" y="460" width="80" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="23" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="23" target="20">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="23" value="Community Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="540" y="590" width="80" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="24" value="Node Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="740" y="540" width="80" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="25" value="CakePHP<br>Frontend" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="540" y="680" width="80" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="26" value="Einzel HTML" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="540" y="410" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="27" target="20">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="27" target="23">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="27" value="GraphQL" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="460" width="80" height="210" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="31" target="27">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="31" value="Test<br>(Backend)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e3c800;strokeColor=#B09500;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="370" width="80" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="32" target="17">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="32" value="Test<br>(Frontend)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e3c800;strokeColor=#B09500;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="60" y="370" width="190" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="36" target="48">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="36" value="Frontend" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="60" y="840" width="190" height="210" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="60" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="43" target="54">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="43" target="55">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="43" value="Node Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="560" y="902.5" width="85" height="85" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="53" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="48" target="43">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="48" value="GraphQL" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="840" width="200" height="210" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="49" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="50" target="48">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="50" value="Test<br>(Backend)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e3c800;strokeColor=#B09500;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="750" width="200" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="52" target="36">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="52" value="Test<br>(Frontend)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e3c800;strokeColor=#B09500;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="60" y="750" width="190" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="61" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="54" target="55">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="65" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="54" target="56">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="54" value="Node Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="645" y="817.5" width="85" height="85" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="55" target="56">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="66" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="55" target="43">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="55" value="Node Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="730" y="902.5" width="85" height="85" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="63" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="56" target="43">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="67" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="56" target="54">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="56" value="Node Server" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="645" y="987.5" width="85" height="85" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
BIN
docu/neue-struktur.png
Normal file
BIN
docu/neue-struktur.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
@ -1,3 +1,4 @@
|
|||||||
LOGIN_API_URL=http://localhost/login_api/
|
LOGIN_API_URL=http://localhost/login_api/
|
||||||
COMMUNITY_API_STATE_BALANCE_URL=http://localhost/state-balances/
|
COMMUNITY_API_STATE_BALANCE_URL=http://localhost/state-balances/
|
||||||
COMMUNITY_API_TRANSACTION_CREATION_URL=http://localhost/transaction-creations/
|
COMMUNITY_API_TRANSACTION_CREATION_URL=http://localhost/transaction-creations/
|
||||||
|
VUE_PATH=/vue
|
||||||
3
frontend/.eslintignore
Normal file
3
frontend/.eslintignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
**/*.min.js
|
||||||
|
dist
|
||||||
@ -1,14 +1,30 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
env: {
|
env: {
|
||||||
node: true
|
browser: true,
|
||||||
},
|
node: true,
|
||||||
extends: ['plugin:vue/essential'],
|
jest: true
|
||||||
rules: {
|
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: 'babel-eslint'
|
parser: 'babel-eslint'
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/essential',
|
||||||
|
'plugin:prettier/recommended'
|
||||||
|
],
|
||||||
|
// required to lint *.vue files
|
||||||
|
plugins: [
|
||||||
|
'vue',
|
||||||
|
'prettier',
|
||||||
|
'jest'
|
||||||
|
],
|
||||||
|
// add your custom rules here
|
||||||
|
rules: {
|
||||||
|
'no-console': ['error'],
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
|
'vue/component-name-in-template-casing': ['error', 'kebab-case'],
|
||||||
|
'prettier/prettier': ['error', {
|
||||||
|
htmlWhitespaceSensitivity: 'ignore'
|
||||||
|
}],
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
2
frontend/.gitignore
vendored
2
frontend/.gitignore
vendored
@ -18,3 +18,5 @@ package-lock.json
|
|||||||
*.ntvs*
|
*.ntvs*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
|
|
||||||
|
*~
|
||||||
8
frontend/.prettierrc.js
Normal file
8
frontend/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
semi: false,
|
||||||
|
printWidth: 100,
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: "all",
|
||||||
|
tabWidth: 2,
|
||||||
|
bracketSpacing: true
|
||||||
|
};
|
||||||
21
frontend/DEV-README.md
Normal file
21
frontend/DEV-README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
DEV README von Alex
|
||||||
|
|
||||||
|
default Page:
|
||||||
|
´´´
|
||||||
|
<template>
|
||||||
|
<div>default</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'default',
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
|
watch: {},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
´´´
|
||||||
|
|
||||||
@ -1,14 +1,12 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"presets": [
|
presets: ['@babel/preset-env'],
|
||||||
"@vue/app"
|
plugins: [
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
[
|
[
|
||||||
"component",
|
'component',
|
||||||
{
|
{
|
||||||
"libraryName": "element-ui",
|
libraryName: 'element-ui',
|
||||||
"styleLibraryName": "theme-chalk"
|
styleLibraryName: 'theme-chalk',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
// This configuration file is not used anywhere in the code, it's a hack to handle InteliJ relative path imports
|
// This configuration file is not used anywhere in the code, it's a hack to handle InteliJ relative path imports
|
||||||
// Keep in sync with actual webpack aliases
|
// Keep in sync with actual webpack aliases
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, 'src')
|
'@': path.resolve(__dirname, 'src'),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
24
frontend/jest.config.js
Normal file
24
frontend/jest.config.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
module.exports = {
|
||||||
|
verbose: true,
|
||||||
|
collectCoverageFrom: ['**/*.{js,vue}', '!**/node_modules/**', '!**/?(*.)+(spec|test).js?(x)'],
|
||||||
|
moduleFileExtensions: [
|
||||||
|
'js',
|
||||||
|
//'jsx',
|
||||||
|
'json',
|
||||||
|
'vue',
|
||||||
|
],
|
||||||
|
coverageReporters: ['lcov'],
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^@/(.*)$': '<rootDir>/src/$1',
|
||||||
|
'\\.(css|less)$': 'identity-obj-proxy',
|
||||||
|
},
|
||||||
|
transform: {
|
||||||
|
'^.+\\.vue$': '<rootDir>/node_modules/vue-jest',
|
||||||
|
'^.+\\.(js|jsx)?$': '<rootDir>/node_modules/babel-jest',
|
||||||
|
},
|
||||||
|
setupFiles: ['<rootDir>/test/testSetup.js'],
|
||||||
|
testMatch: ['**/?(*.)+(spec|test).js?(x)'],
|
||||||
|
// snapshotSerializers: ['jest-serializer-vue'],
|
||||||
|
transformIgnorePatterns: ['<rootDir>/node_modules/'],
|
||||||
|
preset: '@vue/cli-plugin-unit-jest',
|
||||||
|
}
|
||||||
@ -1,17 +1,27 @@
|
|||||||
{
|
{
|
||||||
"name": "bootstrap-vue-gradido-wallet",
|
"name": "bootstrap-vue-gradido-wallet",
|
||||||
"version": "0.9.1",
|
"version": "0.9.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"serve": "vue-cli-service serve --open",
|
"serve": "vue-cli-service serve --open",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"lint": "vue-cli-service lint",
|
"lint": "eslint --ext .js,.vue .",
|
||||||
"dev": "yarn run serve",
|
"dev": "yarn run serve",
|
||||||
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
|
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
|
||||||
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@babel/core": "^7.13.13",
|
||||||
|
"@babel/node": "^7.13.13",
|
||||||
|
"@babel/preset-env": "^7.13.12",
|
||||||
|
"@vue/cli-plugin-unit-jest": "^4.5.12",
|
||||||
|
"@vue/test-utils": "^1.1.3",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
|
"babel-jest": "^26.6.3",
|
||||||
|
"babel-plugin-require-context-hook": "^1.0.0",
|
||||||
|
"babel-preset-vue": "^2.0.2",
|
||||||
"bootstrap": "4.3.1",
|
"bootstrap": "4.3.1",
|
||||||
"bootstrap-vue": "^2.5.0",
|
"bootstrap-vue": "^2.5.0",
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.3",
|
||||||
@ -22,18 +32,30 @@
|
|||||||
"element-ui": "2.4.11",
|
"element-ui": "2.4.11",
|
||||||
"es6-promise": "^4.1.1",
|
"es6-promise": "^4.1.1",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"eslint-plugin-vue": "^7.5.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
|
"eslint-config-standard": "^16.0.2",
|
||||||
|
"eslint-loader": "^4.0.2",
|
||||||
|
"eslint-plugin-import": "^2.22.1",
|
||||||
|
"eslint-plugin-jest": "^24.3.2",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-prettier": "^3.3.1",
|
||||||
|
"eslint-plugin-promise": "^4.3.1",
|
||||||
|
"eslint-plugin-standard": "^5.0.0",
|
||||||
|
"eslint-plugin-vue": "^7.8.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"flatpickr": "^4.5.7",
|
"flatpickr": "^4.5.7",
|
||||||
"fuse.js": "^3.2.0",
|
"fuse.js": "^3.2.0",
|
||||||
"google-maps": "^3.2.1",
|
"google-maps": "^3.2.1",
|
||||||
|
"identity-obj-proxy": "^3.0.0",
|
||||||
|
"jest": "^26.6.3",
|
||||||
"nouislider": "^12.1.0",
|
"nouislider": "^12.1.0",
|
||||||
"particles-bg-vue": "1.2.3",
|
"particles-bg-vue": "1.2.3",
|
||||||
"perfect-scrollbar": "^1.3.0",
|
"perfect-scrollbar": "^1.3.0",
|
||||||
|
"prettier": "^2.2.1",
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"quill": "^1.3.6",
|
"quill": "^1.3.6",
|
||||||
"sweetalert2": "^9.5.4",
|
"sweetalert2": "^9.5.4",
|
||||||
"vee-validate": "^3.2.1",
|
"vee-validate": "^3.4.5",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-bootstrap-typeahead": "^0.2.6",
|
"vue-bootstrap-typeahead": "^0.2.6",
|
||||||
"vue-chartjs": "^3.5.0",
|
"vue-chartjs": "^3.5.0",
|
||||||
@ -44,6 +66,7 @@
|
|||||||
"vue-flatpickr-component": "^8.1.2",
|
"vue-flatpickr-component": "^8.1.2",
|
||||||
"vue-good-table": "^2.21.3",
|
"vue-good-table": "^2.21.3",
|
||||||
"vue-i18n": "^8.22.4",
|
"vue-i18n": "^8.22.4",
|
||||||
|
"vue-jest": "^3.0.7",
|
||||||
"vue-moment": "^4.1.0",
|
"vue-moment": "^4.1.0",
|
||||||
"vue-qrcode": "^0.3.5",
|
"vue-qrcode": "^0.3.5",
|
||||||
"vue-qrcode-reader": "^2.3.16",
|
"vue-qrcode-reader": "^2.3.16",
|
||||||
@ -73,6 +96,6 @@
|
|||||||
"last 2 versions",
|
"last 2 versions",
|
||||||
"not ie <= 10"
|
"not ie <= 10"
|
||||||
],
|
],
|
||||||
"author": "Bernd Hückstädt - https://www.gradido.net/",
|
"author": "Gradido-Akademie - https://www.gradido.net/",
|
||||||
"description": "Gradido Wallet"
|
"description": "Gradido, the Natural Economy of Life, is a way to worldwide prosperity and peace in harmony with nature. - Gradido, die Natürliche Ökonomie des lebens, ist ein Weg zu weltweitem Wohlstand und Frieden in Harmonie mit der Natur."
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
frontend/public/img/icons/icons-translation.png
Normal file
BIN
frontend/public/img/icons/icons-translation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@ -1,11 +1,11 @@
|
|||||||
<!--
|
<!--
|
||||||
|
|
||||||
=========================================================
|
=========================================================
|
||||||
* Gradido Wallet - v0.0.1
|
* Gradido Konto - v0.0.1
|
||||||
=========================================================
|
=========================================================
|
||||||
|
|
||||||
* Product Page: https://www.gradido.net
|
* Product Page: https://www.gradido.net
|
||||||
* Copyright 2020 Bernd Hückstädt - Gradido (https://www.gradido.net)
|
* Copyright 2021 Gradido-Akademie - (https://www.gradido.net)
|
||||||
|
|
||||||
* Coded by www.gradido.net
|
* Coded by www.gradido.net
|
||||||
|
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<link rel="icon" type="image/png" sizes="96x96" href="<%= webpackConfig.output.publicPath %>favicon.png">
|
<link rel="icon" type="image/png" sizes="96x96" href="<%= webpackConfig.output.publicPath %>favicon.png">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
|
|
||||||
<title>Gradido Wallet</title>
|
<title>Gradido Account</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express')
|
||||||
var serveStatic = require('serve-static');
|
var serveStatic = require('serve-static')
|
||||||
var app = express();
|
var app = express()
|
||||||
app.use(serveStatic(__dirname + "/dist"));
|
app.use(serveStatic(__dirname + '/dist'))
|
||||||
var port = process.env.PORT || 5000;
|
var port = process.env.PORT || 5000
|
||||||
app.listen(port);
|
app.listen(port)
|
||||||
// console.log('http://localhost:5000 server started.');
|
// console.log('http://localhost:5000 server started.');
|
||||||
|
|||||||
@ -1,37 +1,65 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" class="font-sans text-gray-800">
|
<div id="app" class="font-sans text-gray-800">
|
||||||
<header class="">
|
<header>
|
||||||
|
<b-col class="text-center">
|
||||||
|
<b-dropdown
|
||||||
|
size="sm"
|
||||||
|
split
|
||||||
|
variant="secondary"
|
||||||
|
:text="$t('language') + ' - ' + $i18n.locale"
|
||||||
|
class="m-md-2"
|
||||||
|
>
|
||||||
|
<b-dropdown-divider></b-dropdown-divider>
|
||||||
|
<b-dropdown-item @click.prevent="setLocale('de')">Deutsch</b-dropdown-item>
|
||||||
|
<b-dropdown-item @click.prevent="setLocale('en')">English</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
|
</b-col>
|
||||||
</header>
|
</header>
|
||||||
<div class="">
|
<div class="">
|
||||||
<particles-bg type="custom" :config="config" :bg="true" />
|
<particles-bg type="custom" :config="config" :bg="true" />
|
||||||
<router-view />
|
<router-view />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ParticlesBg } from "particles-bg-vue";
|
import { ParticlesBg } from 'particles-bg-vue'
|
||||||
import icon from "./icon.js";
|
import icon from './icon.js'
|
||||||
|
import { localeChanged } from 'vee-validate'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
components: {
|
components: {
|
||||||
ParticlesBg
|
ParticlesBg,
|
||||||
},
|
},
|
||||||
created () {
|
data() {
|
||||||
//console.log("this.$cookies.get('gdd_session_id') ", this.$cookies.get('gdd_session_id') )
|
return {
|
||||||
console.log(" $cookies.isKey('gdd_session_id') ", this.$cookies.isKey("gdd_session_id") )
|
session_id: null,
|
||||||
if ( this.$cookies.isKey('gdd_session_id') ) {
|
email: '',
|
||||||
//this.$store.state.email = this.$cookies.get('gdd_u')
|
language: 'en',
|
||||||
console.log("login to kontooverview")
|
}
|
||||||
this.$router.push('/KontoOverview')
|
},
|
||||||
}else {
|
created() {
|
||||||
console.log("login to LOGIN")
|
//console.log('xx', $cookies.get('gdd_lang'))
|
||||||
this.$router.push("/Login")
|
//console.log('%cWillkommen bei Gradido %cgreen text', 'font-weight:bold', 'color: green')
|
||||||
}
|
if ($cookies.isKey('gdd_session_id') == true) {
|
||||||
},
|
//console.log('%cHey %c' + $cookies.get('gdd_u') + '', 'font-weight:bold', 'color: orange')
|
||||||
data() {
|
this.$store.commit('session_id', $cookies.get('gdd_session_id'))
|
||||||
|
this.$store.commit('email', $cookies.get('gdd_u'))
|
||||||
|
if ($cookies.get('gdd_lang') != 'de' || $cookies.get('gdd_lang') != 'de') {
|
||||||
|
this.$store.commit('language', 'de')
|
||||||
|
} else {
|
||||||
|
this.$store.commit('language', $cookies.get('gdd_lang'))
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$i18n.locale = $cookies.get('gdd_lang')
|
||||||
|
this.$router.push('overview')
|
||||||
|
} else {
|
||||||
|
//console.log('app.vue to Logout')
|
||||||
|
this.$store.dispatch('logout')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
return {
|
return {
|
||||||
config: {
|
config: {
|
||||||
num: [1, 7],
|
num: [1, 7],
|
||||||
@ -43,33 +71,64 @@ export default {
|
|||||||
body: icon,
|
body: icon,
|
||||||
alpha: [0.6, 0],
|
alpha: [0.6, 0],
|
||||||
scale: [0.1, 0.4],
|
scale: [0.1, 0.4],
|
||||||
position: "all",
|
position: 'all',
|
||||||
cross: "dead",
|
cross: 'dead',
|
||||||
random: 2,
|
random: 2,
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setLocale(locale) {
|
||||||
|
this.$i18n.locale = locale
|
||||||
|
this.$store.commit('language', this.$i18n.locale)
|
||||||
|
localeChanged(locale)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.btn {
|
.btn-primary pim {
|
||||||
background-color: #5A7B02;
|
background-color: #5a7b02;
|
||||||
border-color: #5e72e4;
|
border-color: #5e72e4;
|
||||||
}
|
}
|
||||||
a, .copyright{
|
a,
|
||||||
color: #5A7B02;
|
.copyright {
|
||||||
}
|
color: #5a7b02;
|
||||||
gradido-global-color-text{color: #3D443B }
|
}
|
||||||
gradido-global-color-accent{color: #047006 }
|
gradido-global-color-text {
|
||||||
gradido-global-color-6e0a9c9e{color: #000 }
|
color: #3d443b;
|
||||||
gradido-global-color-2d0fb154{color: #047006 }
|
}
|
||||||
gradido-global-color-16efe88c{color: #7EBC55 }
|
gradido-global-color-accent {
|
||||||
gradido-global-color-1939326{color: #F6FFF6 }
|
color: #047006;
|
||||||
gradido-global-color-9d79fc1{color: #047006 }
|
}
|
||||||
gradido-global-color-6347f4d{color: #5A7B02 }
|
gradido-global-color-6e0a9c9e {
|
||||||
gradido-global-color-4fbc19a{color: #014034 }
|
color: #000;
|
||||||
gradido-global-color-d341874{color: #B6D939 }
|
}
|
||||||
gradido-global-color-619d338{color: #8EBFB1 }
|
gradido-global-color-2d0fb154 {
|
||||||
gradido-global-color-44819a9{color: #026873 }
|
color: #047006;
|
||||||
|
}
|
||||||
|
gradido-global-color-16efe88c {
|
||||||
|
color: #7ebc55;
|
||||||
|
}
|
||||||
|
gradido-global-color-1939326 {
|
||||||
|
color: #f6fff6;
|
||||||
|
}
|
||||||
|
gradido-global-color-9d79fc1 {
|
||||||
|
color: #047006;
|
||||||
|
}
|
||||||
|
gradido-global-color-6347f4d {
|
||||||
|
color: #5a7b02;
|
||||||
|
}
|
||||||
|
gradido-global-color-4fbc19a {
|
||||||
|
color: #014034;
|
||||||
|
}
|
||||||
|
gradido-global-color-d341874 {
|
||||||
|
color: #b6d939;
|
||||||
|
}
|
||||||
|
gradido-global-color-619d338 {
|
||||||
|
color: #8ebfb1;
|
||||||
|
}
|
||||||
|
gradido-global-color-44819a9 {
|
||||||
|
color: #026873;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,33 +1,33 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios'
|
||||||
import CONFIG from '../config'
|
import CONFIG from '../config'
|
||||||
|
|
||||||
const apiGet = async (url) => {
|
const apiGet = async (url) => {
|
||||||
try {
|
try {
|
||||||
const result = await axios.get(url);
|
const result = await axios.get(url)
|
||||||
if(result.status !== 200){
|
if (result.status !== 200) {
|
||||||
throw new Error('HTTP Status Error '+result.status)
|
throw new Error('HTTP Status Error ' + result.status)
|
||||||
}
|
}
|
||||||
if(result.data.state !== 'success'){
|
if (result.data.state !== 'success') {
|
||||||
throw new Error(result.data.msg)
|
throw new Error(result.data.msg)
|
||||||
}
|
}
|
||||||
return { success: true, result }
|
return { success: true, result }
|
||||||
} catch(error){
|
} catch (error) {
|
||||||
return { success: false, result: error}
|
return { success: false, result: error }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiPost = async (url, payload) => {
|
const apiPost = async (url, payload) => {
|
||||||
try {
|
try {
|
||||||
const result = await axios.post(url, payload);
|
const result = await axios.post(url, payload)
|
||||||
if(result.status !== 200){
|
if (result.status !== 200) {
|
||||||
throw new Error('HTTP Status Error '+result.status)
|
throw new Error('HTTP Status Error ' + result.status)
|
||||||
}
|
}
|
||||||
if(result.data.state !== 'success'){
|
if (result.data.state !== 'success') {
|
||||||
throw new Error(result.data.msg)
|
throw new Error(result.data.msg)
|
||||||
}
|
}
|
||||||
return { success: true, result }
|
return { success: true, result }
|
||||||
} catch(error){
|
} catch (error) {
|
||||||
return { success: false, result: error}
|
return { success: false, result: error }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,17 +38,27 @@ const communityAPI = {
|
|||||||
transactions: async (session_id) => {
|
transactions: async (session_id) => {
|
||||||
return apiGet(CONFIG.COMMUNITY_API_STATE_BALANCE_URL + 'ajaxListTransactions/' + session_id)
|
return apiGet(CONFIG.COMMUNITY_API_STATE_BALANCE_URL + 'ajaxListTransactions/' + session_id)
|
||||||
},
|
},
|
||||||
create: async (session_id, email, amount, memo, target_date = new Date() ) => {
|
/*create: async (session_id, email, amount, memo, target_date = new Date() ) => {
|
||||||
const payload = {
|
const payload = {
|
||||||
session_id,
|
session_id,
|
||||||
email,
|
email,
|
||||||
amount,
|
amount,
|
||||||
target_date,
|
target_date,
|
||||||
memo,
|
memo,
|
||||||
auto_sign: true
|
auto_sign: true,
|
||||||
}
|
}
|
||||||
return apiPost(CONFIG.COMMUNITY_API_TRANSACTION_CREATION_URL + 'ajaxCreate/', payload)
|
return apiPost(CONFIG.COMMUNITY_API_TRANSACTION_CREATION_URL + 'ajaxCreate/', payload)
|
||||||
}
|
},*/
|
||||||
|
send: async (session_id, email, amount, memo) => {
|
||||||
|
const payload = {
|
||||||
|
session_id,
|
||||||
|
email,
|
||||||
|
amount,
|
||||||
|
memo,
|
||||||
|
auto_sign: true,
|
||||||
|
}
|
||||||
|
return apiPost(CONFIG.COMMUNITY_API_TRANSACTION_SEND_COINS + 'ajaxCreate/', payload)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default communityAPI
|
export default communityAPI
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios'
|
||||||
import CONFIG from '../config'
|
import CONFIG from '../config'
|
||||||
|
|
||||||
// control email-text sended with email verification code
|
// control email-text sended with email verification code
|
||||||
@ -7,18 +7,36 @@ const EMAIL_TYPE = {
|
|||||||
ADMIN: 5, // if user was registered by an admin
|
ADMIN: 5, // if user was registered by an admin
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiPost = async (url, payload) => {
|
const apiGet = async (url) => {
|
||||||
try {
|
try {
|
||||||
const result = await axios.post(url, payload);
|
const result = await axios.get(url)
|
||||||
if(result.status !== 200){
|
if (result.status !== 200) {
|
||||||
throw new Error('HTTP Status Error '+result.status)
|
throw new Error('HTTP Status Error ' + result.status)
|
||||||
}
|
}
|
||||||
if(result.data.state !== 'success'){
|
if (result.data.state !== 'success') {
|
||||||
throw new Error(result.data.msg)
|
throw new Error(result.data.msg)
|
||||||
}
|
}
|
||||||
return { success: true, result }
|
return { success: true, result }
|
||||||
} catch(error){
|
} catch (error) {
|
||||||
return { success: false, result: error}
|
return { success: false, result: error }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiPost = async (url, payload) => {
|
||||||
|
try {
|
||||||
|
const result = await axios.post(url, payload)
|
||||||
|
if (result.status !== 200) {
|
||||||
|
throw new Error('HTTP Status Error ' + result.status)
|
||||||
|
}
|
||||||
|
if (result.data.state === 'warning') {
|
||||||
|
return { success: true, result: error }
|
||||||
|
}
|
||||||
|
if (result.data.state !== 'success') {
|
||||||
|
throw new Error(result.data.msg)
|
||||||
|
}
|
||||||
|
return { success: true, result }
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, result: error }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,20 +49,20 @@ const loginAPI = {
|
|||||||
return apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', payload)
|
return apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', payload)
|
||||||
},
|
},
|
||||||
logout: async (session_id) => {
|
logout: async (session_id) => {
|
||||||
const payload= { session_id }
|
const payload = { session_id }
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'logout', payload)
|
return apiPost(CONFIG.LOGIN_API_URL + 'logout', payload)
|
||||||
},
|
},
|
||||||
create : async (email, first_name, last_name, password) => {
|
create: async (email, first_name, last_name, password) => {
|
||||||
const payload = {
|
const payload = {
|
||||||
email,
|
email,
|
||||||
first_name,
|
first_name,
|
||||||
last_name,
|
last_name,
|
||||||
password,
|
password,
|
||||||
emailType: EMAIL_TYPE.DEFAULT,
|
emailType: EMAIL_TYPE.DEFAULT,
|
||||||
login_after_register: true
|
login_after_register: true,
|
||||||
}
|
}
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload)
|
return apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default loginAPI
|
export default loginAPI
|
||||||
|
|||||||
@ -1,50 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-badge
|
<b-badge :variant="type" :pill="rounded" :size="size" :class="{ 'badge-circle': circle }">
|
||||||
:variant="type"
|
|
||||||
:pill="rounded"
|
|
||||||
:size="size"
|
|
||||||
:class="{'badge-circle': circle }">
|
|
||||||
<slot>
|
<slot>
|
||||||
<i v-if="icon" :class="icon"></i>
|
<i v-if="icon" :class="icon"></i>
|
||||||
</slot>
|
</slot>
|
||||||
</b-badge>
|
</b-badge>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "badge",
|
name: 'badge',
|
||||||
props: {
|
props: {
|
||||||
tag: {
|
tag: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "span",
|
default: 'span',
|
||||||
description: "Html tag to use for the badge."
|
description: 'Html tag to use for the badge.',
|
||||||
},
|
},
|
||||||
rounded: {
|
rounded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: "Whether badge is of pill type"
|
description: 'Whether badge is of pill type',
|
||||||
},
|
},
|
||||||
circle: {
|
circle: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: "Whether badge is circle"
|
description: 'Whether badge is circle',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
description: "Icon name. Will be overwritten by slot if slot is used"
|
description: 'Icon name. Will be overwritten by slot if slot is used',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "default",
|
default: 'default',
|
||||||
description: "Badge type (primary|info|danger|default|warning|success)"
|
description: 'Badge type (primary|info|danger|default|warning|success)',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
description: 'Badge size (md, lg)',
|
description: 'Badge size (md, lg)',
|
||||||
default: ''
|
default: '',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
>
|
>
|
||||||
<slot v-if="!dismissible"></slot>
|
<slot v-if="!dismissible"></slot>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|
||||||
<template v-if="icon || $slots.icon">
|
<template v-if="icon || $slots.icon">
|
||||||
<slot name="icon">
|
<slot name="icon">
|
||||||
<span class="alert-icon" data-notify="icon">
|
<span class="alert-icon" data-notify="icon">
|
||||||
@ -17,14 +16,16 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<span class="alert-text"> <slot></slot> </span>
|
<span class="alert-text"><slot></slot></span>
|
||||||
|
|
||||||
<slot name="dismiss-icon">
|
<slot name="dismiss-icon">
|
||||||
<button type="button"
|
<button
|
||||||
class="close"
|
type="button"
|
||||||
data-dismiss="alert"
|
class="close"
|
||||||
aria-label="Close"
|
data-dismiss="alert"
|
||||||
@click="dismissAlert">
|
aria-label="Close"
|
||||||
|
@click="dismissAlert"
|
||||||
|
>
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</slot>
|
</slot>
|
||||||
@ -33,39 +34,43 @@
|
|||||||
</fade-transition>
|
</fade-transition>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { FadeTransition } from 'vue2-transitions';
|
import { FadeTransition } from 'vue2-transitions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'base-alert',
|
name: 'base-alert',
|
||||||
components: {
|
components: {
|
||||||
FadeTransition
|
FadeTransition,
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
//console.log('base-alert gesetzt in =>', this.$route.path)
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'default',
|
||||||
|
description: 'Alert type',
|
||||||
},
|
},
|
||||||
props: {
|
dismissible: {
|
||||||
type: {
|
type: Boolean,
|
||||||
type: String,
|
default: false,
|
||||||
default: 'default',
|
description: 'Whether alert is dismissible (closeable)',
|
||||||
description: 'Alert type'
|
|
||||||
},
|
|
||||||
dismissible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
description: 'Whether alert is dismissible (closeable)'
|
|
||||||
},
|
|
||||||
icon: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
description: 'Alert icon to display'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
icon: {
|
||||||
return {
|
type: String,
|
||||||
visible: true
|
default: '',
|
||||||
};
|
description: 'Alert icon to display',
|
||||||
},
|
},
|
||||||
methods: {
|
},
|
||||||
dismissAlert() {
|
data() {
|
||||||
this.visible = false;
|
return {
|
||||||
}
|
visible: true,
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
methods: {
|
||||||
|
dismissAlert() {
|
||||||
|
this.visible = false
|
||||||
|
this.$store.state.loginfail = false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
{ 'btn-wd': wide },
|
{ 'btn-wd': wide },
|
||||||
{ 'btn-icon btn-fab': icon },
|
{ 'btn-icon btn-fab': icon },
|
||||||
{ 'btn-link': link },
|
{ 'btn-link': link },
|
||||||
{ disabled: disabled }
|
{ disabled: disabled },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<slot name="loading">
|
<slot name="loading">
|
||||||
@ -34,42 +34,42 @@ export default {
|
|||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'default',
|
default: 'default',
|
||||||
description: 'Button type (primary|secondary|danger etc)'
|
description: 'Button type (primary|secondary|danger etc)',
|
||||||
},
|
},
|
||||||
nativeType: {
|
nativeType: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'button',
|
default: 'button',
|
||||||
description: 'Button native type (e.g button, input etc)'
|
description: 'Button native type (e.g button, input etc)',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Button size (sm|lg)'
|
description: 'Button size (sm|lg)',
|
||||||
},
|
},
|
||||||
outline: {
|
outline: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Whether button is outlined (only border has color)'
|
description: 'Whether button is outlined (only border has color)',
|
||||||
},
|
},
|
||||||
link: {
|
link: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Whether button is a link (no borders or background)'
|
description: 'Whether button is a link (no borders or background)',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClick(evt) {
|
handleClick(evt) {
|
||||||
this.$emit('click', evt);
|
this.$emit('click', evt)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.base-button {
|
.base-button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
i {
|
i {
|
||||||
padding: 0 3px;
|
padding: 0 3px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -9,22 +9,19 @@
|
|||||||
<component
|
<component
|
||||||
:is="titleTag"
|
:is="titleTag"
|
||||||
class="btn-rotate"
|
class="btn-rotate"
|
||||||
:class="[{'dropdown-toggle': hasToggle}, titleClasses]"
|
:class="[{ 'dropdown-toggle': hasToggle }, titleClasses]"
|
||||||
:aria-expanded="isOpen"
|
:aria-expanded="isOpen"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
>
|
>
|
||||||
<slot name="title" :is-open="isOpen">
|
<slot name="title" :is-open="isOpen">
|
||||||
<i :class="icon"></i> {{ title }}
|
<i :class="icon"></i>
|
||||||
|
{{ title }}
|
||||||
</slot>
|
</slot>
|
||||||
</component>
|
</component>
|
||||||
</slot>
|
</slot>
|
||||||
<ul
|
<ul
|
||||||
class="dropdown-menu"
|
class="dropdown-menu"
|
||||||
:class="[
|
:class="[{ show: isOpen }, { 'dropdown-menu-right': menuOnRight }, menuClasses]"
|
||||||
{ show: isOpen },
|
|
||||||
{ 'dropdown-menu-right': menuOnRight },
|
|
||||||
menuClasses
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
@ -37,60 +34,60 @@ export default {
|
|||||||
tag: {
|
tag: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'div',
|
default: 'div',
|
||||||
description: 'Dropdown html tag (e.g div, ul etc)'
|
description: 'Dropdown html tag (e.g div, ul etc)',
|
||||||
},
|
},
|
||||||
titleTag: {
|
titleTag: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'button',
|
default: 'button',
|
||||||
description: 'Dropdown title (toggle) html tag'
|
description: 'Dropdown title (toggle) html tag',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
description: 'Dropdown title'
|
description: 'Dropdown title',
|
||||||
},
|
},
|
||||||
direction: {
|
direction: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'down', // up | down
|
default: 'down', // up | down
|
||||||
description: 'Dropdown menu direction (up|down)'
|
description: 'Dropdown menu direction (up|down)',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
description: 'Dropdown icon'
|
description: 'Dropdown icon',
|
||||||
},
|
},
|
||||||
titleClasses: {
|
titleClasses: {
|
||||||
type: [String, Object, Array],
|
type: [String, Object, Array],
|
||||||
description: 'Title css classes'
|
description: 'Title css classes',
|
||||||
},
|
},
|
||||||
menuClasses: {
|
menuClasses: {
|
||||||
type: [String, Object],
|
type: [String, Object],
|
||||||
description: 'Menu css classes'
|
description: 'Menu css classes',
|
||||||
},
|
},
|
||||||
menuOnRight: {
|
menuOnRight: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Whether menu should appear on the right'
|
description: 'Whether menu should appear on the right',
|
||||||
},
|
},
|
||||||
hasToggle: {
|
hasToggle: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Whether dropdown has arrow icon shown',
|
description: 'Whether dropdown has arrow icon shown',
|
||||||
default: true
|
default: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isOpen: false
|
isOpen: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleDropDown() {
|
toggleDropDown() {
|
||||||
this.isOpen = !this.isOpen;
|
this.isOpen = !this.isOpen
|
||||||
this.$emit('change', this.isOpen);
|
this.$emit('change', this.isOpen)
|
||||||
},
|
},
|
||||||
closeDropDown() {
|
closeDropDown() {
|
||||||
this.isOpen = false;
|
this.isOpen = false
|
||||||
this.$emit('change', false);
|
this.$emit('change', false)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.dropdown {
|
.dropdown {
|
||||||
|
|||||||
@ -1,23 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="header" :class="{[`bg-${type}`]: type}">
|
<div class="header" :class="{ [`bg-${type}`]: type }">
|
||||||
<b-container fluid>
|
<b-container fluid>
|
||||||
<div class="header-body">
|
<div class="header-body">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</b-container>
|
</b-container>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'base-header',
|
name: 'base-header',
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'success',
|
default: 'success',
|
||||||
description: 'Header background type'
|
description: 'Header background type',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,14 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<b-pagination first-number last-number :per-page="perPage" :size="size" :value="value" @change="(val) => $emit('change', val)" :align="align" :total-rows="total">
|
<b-pagination
|
||||||
|
first-number
|
||||||
|
last-number
|
||||||
|
:per-page="perPage"
|
||||||
|
:size="size"
|
||||||
|
:value="value"
|
||||||
|
@change="(val) => $emit('change', val)"
|
||||||
|
:align="align"
|
||||||
|
:total-rows="total"
|
||||||
|
>
|
||||||
<template v-slot:prev-text>
|
<template v-slot:prev-text>
|
||||||
<a class="page-link" aria-label="Previous">
|
<a class="page-link" aria-label="Previous">
|
||||||
<span aria-hidden="true"><i class="fa fa-angle-left" aria-hidden="true"></i></span>
|
<span aria-hidden="true">
|
||||||
|
<i class="fa fa-angle-left" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:next-text>
|
<template v-slot:next-text>
|
||||||
<a class="page-link" aria-label="Next">
|
<a class="page-link" aria-label="Next">
|
||||||
<span aria-hidden="true"><i class="fa fa-angle-right" aria-hidden="true"></i></span>
|
<span aria-hidden="true">
|
||||||
|
<i class="fa fa-angle-right" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</b-pagination>
|
</b-pagination>
|
||||||
@ -16,41 +29,39 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "base-pagination",
|
name: 'base-pagination',
|
||||||
props: {
|
props: {
|
||||||
pageCount: {
|
pageCount: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
description:
|
description: 'Pagination page count. This should be specified in combination with perPage',
|
||||||
"Pagination page count. This should be specified in combination with perPage"
|
|
||||||
},
|
},
|
||||||
perPage: {
|
perPage: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 10,
|
default: 10,
|
||||||
description:
|
description: 'Pagination per page. Should be specified with total or pageCount',
|
||||||
"Pagination per page. Should be specified with total or pageCount"
|
|
||||||
},
|
},
|
||||||
total: {
|
total: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
description:
|
description:
|
||||||
"Can be specified instead of pageCount. The page count in this case will be total/perPage"
|
'Can be specified instead of pageCount. The page count in this case will be total/perPage',
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1,
|
default: 1,
|
||||||
description: "Pagination value"
|
description: 'Pagination value',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
description: "Pagination size"
|
description: 'Pagination size',
|
||||||
},
|
},
|
||||||
align: {
|
align: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
description: "Pagination alignment (e.g center|start|end)"
|
description: 'Pagination alignment (e.g center|start|end)',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -3,82 +3,77 @@
|
|||||||
<div :class="`progress-${type}`" v-if="showLabel">
|
<div :class="`progress-${type}`" v-if="showLabel">
|
||||||
<div class="progress-label">
|
<div class="progress-label">
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
<span>{{label}}</span>
|
<span>{{ label }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-percentage">
|
<div class="progress-percentage">
|
||||||
<slot>
|
<slot>
|
||||||
<span>{{value}}%</span>
|
<span>{{ value }}%</span>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<b-progress
|
<b-progress :size="size" :class="[progressClasses]" :style="`height: ${height}px`">
|
||||||
:size="size"
|
|
||||||
:class="[progressClasses]"
|
|
||||||
:style="`height: ${height}px`">
|
|
||||||
<b-progress-bar :class="computedClasses" :value="value"></b-progress-bar>
|
<b-progress-bar :class="computedClasses" :value="value"></b-progress-bar>
|
||||||
</b-progress>
|
</b-progress>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "base-progress",
|
name: 'base-progress',
|
||||||
props: {
|
props: {
|
||||||
striped: {
|
striped: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: "Whether progress is striped"
|
description: 'Whether progress is striped',
|
||||||
},
|
|
||||||
animated: {
|
|
||||||
type: Boolean,
|
|
||||||
description:
|
|
||||||
"Whether progress is animated (works only with `striped` prop together)"
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
description: "Progress label (shown on the left above progress)"
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: Number,
|
|
||||||
default: 3,
|
|
||||||
description: "Progress line height"
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: "default",
|
|
||||||
description: "Progress type (e.g danger, primary etc)"
|
|
||||||
},
|
|
||||||
showLabel: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
progressClasses: {
|
|
||||||
type: [Array, String],
|
|
||||||
default: '',
|
|
||||||
description: 'Progress css classes'
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: Number,
|
|
||||||
default: 0,
|
|
||||||
validator: value => {
|
|
||||||
return value >= 0 && value <= 100;
|
|
||||||
},
|
|
||||||
description: "Progress value"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
animated: {
|
||||||
computedClasses() {
|
type: Boolean,
|
||||||
return [
|
description: 'Whether progress is animated (works only with `striped` prop together)',
|
||||||
{ "progress-bar-striped": this.striped },
|
},
|
||||||
{ "progress-bar-animated": this.animated },
|
label: {
|
||||||
{ [`bg-${this.type}`]: this.type }
|
type: String,
|
||||||
];
|
description: 'Progress label (shown on the left above progress)',
|
||||||
}
|
},
|
||||||
}
|
height: {
|
||||||
};
|
type: Number,
|
||||||
|
default: 3,
|
||||||
|
description: 'Progress line height',
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'default',
|
||||||
|
description: 'Progress type (e.g danger, primary etc)',
|
||||||
|
},
|
||||||
|
showLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
progressClasses: {
|
||||||
|
type: [Array, String],
|
||||||
|
default: '',
|
||||||
|
description: 'Progress css classes',
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
validator: (value) => {
|
||||||
|
return value >= 0 && value <= 100
|
||||||
|
},
|
||||||
|
description: 'Progress value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
computedClasses() {
|
||||||
|
return [
|
||||||
|
{ 'progress-bar-striped': this.striped },
|
||||||
|
{ 'progress-bar-animated': this.animated },
|
||||||
|
{ [`bg-${this.type}`]: this.type },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -2,56 +2,55 @@
|
|||||||
<div class="slider" :disabled="disabled"></div>
|
<div class="slider" :disabled="disabled"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import noUiSlider from 'nouislider';
|
import noUiSlider from 'nouislider'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'base-slider',
|
name: 'base-slider',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: [String, Array, Number],
|
type: [String, Array, Number],
|
||||||
description: 'slider value'
|
description: 'slider value',
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: 'whether the slider is disabled'
|
description: 'whether the slider is disabled',
|
||||||
},
|
},
|
||||||
start: {
|
start: {
|
||||||
type: [Number, Array],
|
type: [Number, Array],
|
||||||
default: 0,
|
default: 0,
|
||||||
description:
|
description:
|
||||||
'[noUi Slider start](https://refreshless.com/nouislider/slider-options/#section-start)'
|
'[noUi Slider start](https://refreshless.com/nouislider/slider-options/#section-start)',
|
||||||
},
|
},
|
||||||
connect: {
|
connect: {
|
||||||
type: [Boolean, Array],
|
type: [Boolean, Array],
|
||||||
default: () => [true, false],
|
default: () => [true, false],
|
||||||
description:
|
description:
|
||||||
'[noUi Slider connect](https://refreshless.com/nouislider/slider-options/#section-connect)'
|
'[noUi Slider connect](https://refreshless.com/nouislider/slider-options/#section-connect)',
|
||||||
},
|
},
|
||||||
range: {
|
range: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {
|
return {
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 100
|
max: 100,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
description:
|
description:
|
||||||
'[noUi Slider range](https://refreshless.com/nouislider/slider-values/#section-range)'
|
'[noUi Slider range](https://refreshless.com/nouislider/slider-values/#section-range)',
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {};
|
return {}
|
||||||
},
|
},
|
||||||
description:
|
description: '[noUi Slider options](https://refreshless.com/nouislider/slider-options/)',
|
||||||
'[noUi Slider options](https://refreshless.com/nouislider/slider-options/)'
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
slider: null
|
slider: null,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createSlider() {
|
createSlider() {
|
||||||
@ -59,38 +58,35 @@ export default {
|
|||||||
start: this.value || this.start,
|
start: this.value || this.start,
|
||||||
connect: Array.isArray(this.value) ? true : this.connect,
|
connect: Array.isArray(this.value) ? true : this.connect,
|
||||||
range: this.range,
|
range: this.range,
|
||||||
...this.options
|
...this.options,
|
||||||
});
|
})
|
||||||
const slider = this.$el.noUiSlider;
|
const slider = this.$el.noUiSlider
|
||||||
slider.on('slide', () => {
|
slider.on('slide', () => {
|
||||||
let value = slider.get();
|
let value = slider.get()
|
||||||
if (value !== this.value) {
|
if (value !== this.value) {
|
||||||
this.$emit('input', value);
|
this.$emit('input', value)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.createSlider();
|
this.createSlider()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value(newValue, oldValue) {
|
value(newValue, oldValue) {
|
||||||
const slider = this.$el.noUiSlider;
|
const slider = this.$el.noUiSlider
|
||||||
const sliderValue = slider.get();
|
const sliderValue = slider.get()
|
||||||
if (newValue !== oldValue && sliderValue !== newValue) {
|
if (newValue !== oldValue && sliderValue !== newValue) {
|
||||||
if (Array.isArray(sliderValue) && Array.isArray(newValue)) {
|
if (Array.isArray(sliderValue) && Array.isArray(newValue)) {
|
||||||
if (
|
if (oldValue.length === newValue.length && oldValue.every((v, i) => v === newValue[i])) {
|
||||||
oldValue.length === newValue.length &&
|
slider.set(newValue)
|
||||||
oldValue.every((v, i) => v === newValue[i])
|
|
||||||
) {
|
|
||||||
slider.set(newValue);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
slider.set(newValue);
|
slider.set(newValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -10,10 +10,7 @@
|
|||||||
<tbody :class="tbodyClasses">
|
<tbody :class="tbodyClasses">
|
||||||
<tr v-for="(item, index) in data" :key="index">
|
<tr v-for="(item, index) in data" :key="index">
|
||||||
<slot :row="item" :index="index">
|
<slot :row="item" :index="index">
|
||||||
<td
|
<td v-for="(column, index) in columns" :key="index">
|
||||||
v-for="(column, index) in columns"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
{{ itemValue(item, column) }}
|
{{ itemValue(item, column) }}
|
||||||
</td>
|
</td>
|
||||||
</slot>
|
</slot>
|
||||||
@ -28,42 +25,42 @@ export default {
|
|||||||
columns: {
|
columns: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
description: 'Table columns'
|
description: 'Table columns',
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
description: 'Table data'
|
description: 'Table data',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String, // striped | hover
|
type: String, // striped | hover
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Whether table is striped or hover type'
|
description: 'Whether table is striped or hover type',
|
||||||
},
|
},
|
||||||
theadClasses: {
|
theadClasses: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
description: '<thead> css classes'
|
description: '<thead> css classes',
|
||||||
},
|
},
|
||||||
tbodyClasses: {
|
tbodyClasses: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
description: '<tbody> css classes'
|
description: '<tbody> css classes',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
tableClass() {
|
tableClass() {
|
||||||
return this.type && `table-${this.type}`;
|
return this.type && `table-${this.type}`
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hasValue(item, column) {
|
hasValue(item, column) {
|
||||||
return item[column.toLowerCase()] !== 'undefined';
|
return item[column.toLowerCase()] !== 'undefined'
|
||||||
},
|
},
|
||||||
itemValue(item, column) {
|
itemValue(item, column) {
|
||||||
return item[column.toLowerCase()];
|
return item[column.toLowerCase()]
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav aria-label="breadcrumb">
|
<nav aria-label="breadcrumb">
|
||||||
<b-breadcrumb
|
<b-breadcrumb :class="[{ [`bg-${type}`]: type }, listClasses]">
|
||||||
:class="[{[`bg-${type}`]: type}, listClasses]">
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</b-breadcrumb>
|
</b-breadcrumb>
|
||||||
</nav>
|
</nav>
|
||||||
@ -13,14 +12,14 @@ export default {
|
|||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Breadcrumb background type'
|
description: 'Breadcrumb background type',
|
||||||
},
|
},
|
||||||
listClasses: {
|
listClasses: {
|
||||||
type: [String, Object],
|
type: [String, Object],
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Breadcrumb list classes'
|
description: 'Breadcrumb list classes',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -10,9 +10,9 @@ export default {
|
|||||||
active: {
|
active: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: 'Whether breadcrumb item is active'
|
description: 'Whether breadcrumb item is active',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -1,43 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<bread-crumb list-classes="breadcrumb-links breadcrumb-dark">
|
<bread-crumb list-classes="breadcrumb-links breadcrumb-dark">
|
||||||
<BreadCrumbItem>
|
<bread-crumb-item>
|
||||||
<router-link to="/">
|
<router-link to="/overview">
|
||||||
<i class="fas fa-home"></i>
|
<i class="fas fa-home"></i>
|
||||||
</router-link>
|
</router-link>
|
||||||
</BreadCrumbItem>
|
</bread-crumb-item>
|
||||||
<BreadCrumbItem
|
<bread-crumb-item
|
||||||
v-for="(route, index) in $route.matched.slice()"
|
v-for="(route, index) in $route.matched.slice()"
|
||||||
:key="route.name"
|
:key="route.name"
|
||||||
:active="index === $route.matched.length - 1"
|
:active="index === $route.matched.length - 1"
|
||||||
style="display:inline-block"
|
style="display: inline-block"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link :to="{ name: route.name }" v-if="index < $route.matched.length - 1">
|
||||||
:to="{ name: route.name }"
|
|
||||||
v-if="index < $route.matched.length - 1"
|
|
||||||
>
|
|
||||||
{{ route.name }}
|
{{ route.name }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<span v-else>{{ route.name }}</span>
|
<span v-else>{{ route.name }}</span>
|
||||||
</BreadCrumbItem>
|
</bread-crumb-item>
|
||||||
</bread-crumb>
|
</bread-crumb>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BreadCrumb from './Breadcrumb';
|
import BreadCrumb from './Breadcrumb'
|
||||||
import BreadCrumbItem from './BreadcrumbItem';
|
import BreadCrumbItem from './BreadcrumbItem'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'route-breadcrumb',
|
name: 'route-breadcrumb',
|
||||||
components: {
|
components: {
|
||||||
BreadCrumb,
|
BreadCrumb,
|
||||||
BreadCrumbItem
|
BreadCrumbItem,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getBreadName(route) {
|
||||||
|
return route.name
|
||||||
},
|
},
|
||||||
methods: {
|
},
|
||||||
getBreadName(route) {
|
}
|
||||||
return route.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,39 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="btn-group-toggle" data-toggle="buttons">
|
<div class="btn-group-toggle" data-toggle="buttons">
|
||||||
<label class="btn" :class="[{ active: value }, buttonClasses]">
|
<label class="btn" :class="[{ active: value }, buttonClasses]">
|
||||||
<input v-model="model" type="checkbox" checked="" autocomplete="off">
|
<input v-model="model" type="checkbox" checked="" autocomplete="off" />
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'button-checkbox',
|
name: 'button-checkbox',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Checked value'
|
description: 'Checked value',
|
||||||
},
|
|
||||||
buttonClasses: {
|
|
||||||
type: [String, Object],
|
|
||||||
description: 'Inner button css classes'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
buttonClasses: {
|
||||||
|
type: [String, Object],
|
||||||
|
description: 'Inner button css classes',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'change',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
model: {
|
model: {
|
||||||
prop: 'value',
|
get() {
|
||||||
event: 'change'
|
return this.value
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('change', val)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
},
|
||||||
model: {
|
}
|
||||||
get() {
|
|
||||||
return this.value
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$emit('change', val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,47 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="btn-group-toggle" data-toggle="buttons">
|
<div class="btn-group-toggle" data-toggle="buttons">
|
||||||
<label v-for="(option, index) in options"
|
<label
|
||||||
:key="index"
|
v-for="(option, index) in options"
|
||||||
class="btn"
|
:key="index"
|
||||||
:class="[{ active: value === option.value }, buttonClasses]">
|
class="btn"
|
||||||
<input :value="option.value" v-model="model" type="radio" id="option1" autocomplete="off" checked="">
|
:class="[{ active: value === option.value }, buttonClasses]"
|
||||||
{{option.label}}
|
>
|
||||||
|
<input
|
||||||
|
:value="option.value"
|
||||||
|
v-model="model"
|
||||||
|
type="radio"
|
||||||
|
id="option1"
|
||||||
|
autocomplete="off"
|
||||||
|
checked=""
|
||||||
|
/>
|
||||||
|
{{ option.label }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'button-radio-group',
|
name: 'button-radio-group',
|
||||||
props: {
|
props: {
|
||||||
options: {
|
options: {
|
||||||
type: Array,
|
type: Array,
|
||||||
description: 'Radio options. Should be an array of objects {value: "", label: ""}',
|
description: 'Radio options. Should be an array of objects {value: "", label: ""}',
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
description: 'Radio value'
|
|
||||||
},
|
|
||||||
buttonClasses: {
|
|
||||||
type: [String, Object],
|
|
||||||
description: 'Inner button css classes'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
description: 'Radio value',
|
||||||
|
},
|
||||||
|
buttonClasses: {
|
||||||
|
type: [String, Object],
|
||||||
|
description: 'Inner button css classes',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'change',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
model: {
|
model: {
|
||||||
prop: 'value',
|
get() {
|
||||||
event: 'change'
|
return this.value
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('change', val)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
},
|
||||||
model: {
|
}
|
||||||
get() {
|
|
||||||
return this.value
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$emit('change', val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-card
|
<b-card
|
||||||
no-body
|
no-body
|
||||||
:class="[
|
:class="[
|
||||||
{'card-lift--hover': hover},
|
{ 'card-lift--hover': hover },
|
||||||
{'shadow': shadow},
|
{ shadow: shadow },
|
||||||
{[`shadow-${shadowSize}`]: shadowSize},
|
{ [`shadow-${shadowSize}`]: shadowSize },
|
||||||
{[`bg-gradient-${gradient}`]: gradient},
|
{ [`bg-gradient-${gradient}`]: gradient },
|
||||||
{[`bg-${type}`]: type}
|
{ [`bg-${type}`]: type },
|
||||||
]">
|
]"
|
||||||
|
>
|
||||||
<slot name="image"></slot>
|
<slot name="image"></slot>
|
||||||
<b-card-header :class="headerClasses" v-if="$slots.header">
|
<b-card-header :class="headerClasses" v-if="$slots.header">
|
||||||
<slot name="header">
|
<slot name="header"></slot>
|
||||||
</slot>
|
|
||||||
</b-card-header>
|
</b-card-header>
|
||||||
<b-card-body :class="bodyClasses" v-if="!noBody">
|
<b-card-body :class="bodyClasses" v-if="!noBody">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
@ -26,48 +25,47 @@
|
|||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "card",
|
name: 'card',
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
description: "Card type"
|
description: 'Card type',
|
||||||
},
|
},
|
||||||
gradient: {
|
gradient: {
|
||||||
type: String,
|
type: String,
|
||||||
description: "Card background gradient type (warning,danger etc)"
|
description: 'Card background gradient type (warning,danger etc)',
|
||||||
},
|
},
|
||||||
hover: {
|
hover: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: "Whether card should move on hover"
|
description: 'Whether card should move on hover',
|
||||||
},
|
},
|
||||||
shadow: {
|
shadow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: "Whether card has shadow"
|
description: 'Whether card has shadow',
|
||||||
},
|
},
|
||||||
shadowSize: {
|
shadowSize: {
|
||||||
type: String,
|
type: String,
|
||||||
description: "Card shadow size"
|
description: 'Card shadow size',
|
||||||
},
|
},
|
||||||
noBody: {
|
noBody: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: "Whether card should have wrapper body class"
|
description: 'Whether card should have wrapper body class',
|
||||||
},
|
},
|
||||||
bodyClasses: {
|
bodyClasses: {
|
||||||
type: [String, Object, Array],
|
type: [String, Object, Array],
|
||||||
description: "Card body css classes"
|
description: 'Card body css classes',
|
||||||
},
|
},
|
||||||
headerClasses: {
|
headerClasses: {
|
||||||
type: [String, Object, Array],
|
type: [String, Object, Array],
|
||||||
description: "Card header css classes"
|
description: 'Card header css classes',
|
||||||
},
|
},
|
||||||
footerClasses: {
|
footerClasses: {
|
||||||
type: [String, Object, Array],
|
type: [String, Object, Array],
|
||||||
description: "Card footer css classes"
|
description: 'Card footer css classes',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,57 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<card class="card-stats" :show-footer-line="true">
|
<card class="card-stats" :show-footer-line="true">
|
||||||
<b-row>
|
<b-row>
|
||||||
|
|
||||||
<b-col>
|
<b-col>
|
||||||
<slot>
|
<slot>
|
||||||
<h5 class="card-title text-uppercase text-muted mb-0" v-if="title">{{title}}</h5>
|
<h5 class="card-title text-uppercase text-muted mb-0" v-if="title">
|
||||||
<span class="h2 font-weight-bold mb-0" v-if="subTitle">{{subTitle}}</span>
|
{{ title }}
|
||||||
|
</h5>
|
||||||
|
<span class="h2 font-weight-bold mb-0" v-if="subTitle">
|
||||||
|
{{ subTitle }}
|
||||||
|
</span>
|
||||||
</slot>
|
</slot>
|
||||||
</b-col>
|
</b-col>
|
||||||
|
|
||||||
<b-col cols="auto" v-if="$slots.icon || icon">
|
<b-col cols="auto" v-if="$slots.icon || icon">
|
||||||
<slot name="icon">
|
<slot name="icon">
|
||||||
<div class="icon icon-shape text-white rounded-circle shadow"
|
<div
|
||||||
:class="[`bg-${type}`, iconClasses]">
|
class="icon icon-shape text-white rounded-circle shadow"
|
||||||
|
:class="[`bg-${type}`, iconClasses]"
|
||||||
|
>
|
||||||
<i :class="icon"></i>
|
<i :class="icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="auto" v-if="$slots.img || img">
|
<b-col cols="auto" v-if="$slots.img || img">
|
||||||
<slot name="img">
|
<slot name="img">
|
||||||
|
|
||||||
<img :src="img" width="80" />
|
<img :src="img" width="80" />
|
||||||
|
|
||||||
</slot>
|
</slot>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
|
||||||
<p class="mt-3 mb-0 text-sm">
|
<p class="mt-3 mb-0 text-sm">
|
||||||
<slot name="footer">
|
<slot name="footer"></slot>
|
||||||
|
|
||||||
</slot>
|
|
||||||
</p>
|
</p>
|
||||||
</card>
|
</card>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Card from './Card.vue';
|
import Card from './Card.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'stats-card',
|
name: 'stats-card',
|
||||||
components: {
|
components: {
|
||||||
Card
|
Card,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'primary',
|
||||||
},
|
},
|
||||||
props: {
|
icon: String,
|
||||||
type: {
|
img: String,
|
||||||
type: String,
|
title: String,
|
||||||
default: 'primary'
|
subTitle: String,
|
||||||
},
|
iconClasses: [String, Array],
|
||||||
icon: String,
|
},
|
||||||
img: String,
|
}
|
||||||
title: String,
|
|
||||||
subTitle: String,
|
|
||||||
iconClasses: [String, Array]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Bar, mixins } from 'vue-chartjs';
|
import { Bar, mixins } from 'vue-chartjs'
|
||||||
import globalOptionsMixin from "@/components/Charts/globalOptionsMixin";
|
import globalOptionsMixin from '@/components/Charts/globalOptionsMixin'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'bar-chart',
|
name: 'bar-chart',
|
||||||
@ -8,23 +8,23 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
extraOptions: {
|
extraOptions: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({}),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ctx: null
|
ctx: null,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$watch(
|
this.$watch(
|
||||||
'chartData',
|
'chartData',
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
if (!oldVal) {
|
if (!oldVal) {
|
||||||
this.renderChart(this.chartData, this.extraOptions);
|
this.renderChart(this.chartData, this.extraOptions)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
)
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Line, mixins } from 'vue-chartjs';
|
import { Line, mixins } from 'vue-chartjs'
|
||||||
import globalOptionsMixin from "@/components/Charts/globalOptionsMixin";
|
import globalOptionsMixin from '@/components/Charts/globalOptionsMixin'
|
||||||
export default {
|
export default {
|
||||||
name: 'line-chart',
|
name: 'line-chart',
|
||||||
extends: Line,
|
extends: Line,
|
||||||
@ -7,23 +7,23 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
extraOptions: {
|
extraOptions: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({}),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ctx: null
|
ctx: null,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$watch(
|
this.$watch(
|
||||||
'chartData',
|
'chartData',
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
if (!oldVal) {
|
if (!oldVal) {
|
||||||
this.renderChart(this.chartData, this.extraOptions);
|
this.renderChart(this.chartData, this.extraOptions)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
)
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { parseOptions } from "@/components/Charts/optionHelpers";
|
import { parseOptions } from '@/components/Charts/optionHelpers'
|
||||||
import Chart from 'chart.js'
|
import Chart from 'chart.js'
|
||||||
|
|
||||||
export const Charts = {
|
export const Charts = {
|
||||||
mode: 'light',//(themeMode) ? themeMode : 'light';
|
mode: 'light', //(themeMode) ? themeMode : 'light';
|
||||||
fonts: {
|
fonts: {
|
||||||
base: 'Open Sans'
|
base: 'Open Sans',
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
gray: {
|
gray: {
|
||||||
@ -16,114 +16,115 @@ export const Charts = {
|
|||||||
600: '#8898aa',
|
600: '#8898aa',
|
||||||
700: '#525f7f',
|
700: '#525f7f',
|
||||||
800: '#32325d',
|
800: '#32325d',
|
||||||
900: '#212529'
|
900: '#212529',
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
'default': '#172b4d',
|
default: '#172b4d',
|
||||||
'primary': '#5e72e4',
|
primary: '#5e72e4',
|
||||||
'secondary': '#f4f5f7',
|
secondary: '#f4f5f7',
|
||||||
'info': '#11cdef',
|
info: '#11cdef',
|
||||||
'success': '#2dce89',
|
success: '#2dce89',
|
||||||
'danger': '#f5365c',
|
danger: '#f5365c',
|
||||||
'warning': '#fb6340'
|
warning: '#fb6340',
|
||||||
},
|
},
|
||||||
black: '#12263F',
|
black: '#12263F',
|
||||||
white: '#FFFFFF',
|
white: '#FFFFFF',
|
||||||
transparent: 'transparent',
|
transparent: 'transparent',
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
function chartOptions() {
|
function chartOptions() {
|
||||||
let { colors, mode, fonts } = Charts;
|
let { colors, mode, fonts } = Charts
|
||||||
// Options
|
// Options
|
||||||
let options = {
|
let options = {
|
||||||
defaults: {
|
defaults: {
|
||||||
global: {
|
global: {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
defaultColor: (mode === 'dark') ? colors.gray[700] : colors.gray[600],
|
defaultColor: mode === 'dark' ? colors.gray[700] : colors.gray[600],
|
||||||
defaultFontColor: (mode === 'dark') ? colors.gray[700] : colors.gray[600],
|
defaultFontColor: mode === 'dark' ? colors.gray[700] : colors.gray[600],
|
||||||
defaultFontFamily: fonts.base,
|
defaultFontFamily: fonts.base,
|
||||||
defaultFontSize: 13,
|
defaultFontSize: 13,
|
||||||
layout: {
|
layout: {
|
||||||
padding: 0
|
padding: 0,
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
display: false,
|
display: false,
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
labels: {
|
labels: {
|
||||||
usePointStyle: true,
|
usePointStyle: true,
|
||||||
padding: 16
|
padding: 16,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
elements: {
|
elements: {
|
||||||
point: {
|
point: {
|
||||||
radius: 0,
|
radius: 0,
|
||||||
backgroundColor: colors.theme['primary']
|
backgroundColor: colors.theme['primary'],
|
||||||
},
|
},
|
||||||
line: {
|
line: {
|
||||||
tension: .4,
|
tension: 0.4,
|
||||||
borderWidth: 4,
|
borderWidth: 4,
|
||||||
borderColor: colors.theme['primary'],
|
borderColor: colors.theme['primary'],
|
||||||
backgroundColor: colors.transparent,
|
backgroundColor: colors.transparent,
|
||||||
borderCapStyle: 'rounded'
|
borderCapStyle: 'rounded',
|
||||||
},
|
},
|
||||||
rectangle: {
|
rectangle: {
|
||||||
backgroundColor: colors.theme['warning']
|
backgroundColor: colors.theme['warning'],
|
||||||
},
|
},
|
||||||
arc: {
|
arc: {
|
||||||
backgroundColor: colors.theme['primary'],
|
backgroundColor: colors.theme['primary'],
|
||||||
borderColor: (mode == 'dark') ? colors.gray[800] : colors.white,
|
borderColor: mode == 'dark' ? colors.gray[800] : colors.white,
|
||||||
borderWidth: 4
|
borderWidth: 4,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
tooltips: {
|
tooltips: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
mode: 'index',
|
mode: 'index',
|
||||||
intersect: false,
|
intersect: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
pie: {
|
pie: {
|
||||||
tooltips: {
|
tooltips: {
|
||||||
mode: 'point'
|
mode: 'point',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
doughnut: {
|
doughnut: {
|
||||||
tooltips: {
|
tooltips: {
|
||||||
mode: 'point'
|
mode: 'point',
|
||||||
},
|
},
|
||||||
cutoutPercentage: 83,
|
cutoutPercentage: 83,
|
||||||
legendCallback: function (chart) {
|
legendCallback: function (chart) {
|
||||||
let data = chart.data;
|
let data = chart.data
|
||||||
let content = '';
|
let content = ''
|
||||||
|
|
||||||
data.labels.forEach(function (label, index) {
|
data.labels.forEach(function (label, index) {
|
||||||
let bgColor = data.datasets[0].backgroundColor[index];
|
let bgColor = data.datasets[0].backgroundColor[index]
|
||||||
|
|
||||||
content += '<span class="chart-legend-item">';
|
content += '<span class="chart-legend-item">'
|
||||||
content += '<i class="chart-legend-indicator" style="background-color: ' + bgColor + '"></i>';
|
content +=
|
||||||
content += label;
|
'<i class="chart-legend-indicator" style="background-color: ' + bgColor + '"></i>'
|
||||||
content += '</span>';
|
content += label
|
||||||
});
|
content += '</span>'
|
||||||
|
})
|
||||||
|
|
||||||
return content;
|
return content
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
// yAxes
|
// yAxes
|
||||||
Chart.scaleService.updateScaleDefaults('linear', {
|
Chart.scaleService.updateScaleDefaults('linear', {
|
||||||
gridLines: {
|
gridLines: {
|
||||||
borderDash: [2],
|
borderDash: [2],
|
||||||
borderDashOffset: [2],
|
borderDashOffset: [2],
|
||||||
color: (mode === 'dark') ? colors.gray[900] : colors.gray[200],
|
color: mode === 'dark' ? colors.gray[900] : colors.gray[200],
|
||||||
drawBorder: false,
|
drawBorder: false,
|
||||||
drawTicks: true,
|
drawTicks: true,
|
||||||
zeroLineWidth: 1,
|
zeroLineWidth: 1,
|
||||||
zeroLineColor: (mode === 'dark') ? colors.gray[900] : colors.gray[200],
|
zeroLineColor: mode === 'dark' ? colors.gray[900] : colors.gray[200],
|
||||||
zeroLineBorderDash: [2],
|
zeroLineBorderDash: [2],
|
||||||
zeroLineBorderDashOffset: [2]
|
zeroLineBorderDashOffset: [2],
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
@ -132,9 +133,9 @@ function chartOptions() {
|
|||||||
if (!(value % 10)) {
|
if (!(value % 10)) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
// xAxes
|
// xAxes
|
||||||
Chart.scaleService.updateScaleDefaults('category', {
|
Chart.scaleService.updateScaleDefaults('category', {
|
||||||
@ -146,13 +147,13 @@ function chartOptions() {
|
|||||||
zeroLineWidth: 1,
|
zeroLineWidth: 1,
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
padding: 20
|
padding: 20,
|
||||||
},
|
},
|
||||||
maxBarThickness: 10
|
maxBarThickness: 10,
|
||||||
});
|
})
|
||||||
|
|
||||||
return options;
|
return options
|
||||||
};
|
}
|
||||||
|
|
||||||
let initialized = false
|
let initialized = false
|
||||||
|
|
||||||
@ -160,27 +161,29 @@ export function initGlobalOptions() {
|
|||||||
if (initialized) {
|
if (initialized) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
parseOptions(Chart, chartOptions());
|
parseOptions(Chart, chartOptions())
|
||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
export const basicOptions = {
|
export const basicOptions = {
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
legend: {
|
legend: {
|
||||||
display: false
|
display: false,
|
||||||
},
|
},
|
||||||
responsive: true
|
responsive: true,
|
||||||
};
|
}
|
||||||
export let blueChartOptions = {
|
export let blueChartOptions = {
|
||||||
scales: {
|
scales: {
|
||||||
yAxes: [{
|
yAxes: [
|
||||||
gridLines: {
|
{
|
||||||
color: Charts.colors.gray[700],
|
gridLines: {
|
||||||
zeroLineColor: Charts.colors.gray[700]
|
color: Charts.colors.gray[700],
|
||||||
}
|
zeroLineColor: Charts.colors.gray[700],
|
||||||
}]
|
},
|
||||||
}
|
},
|
||||||
};
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
export let lineChartOptionsBlue = {
|
export let lineChartOptionsBlue = {
|
||||||
...basicOptions,
|
...basicOptions,
|
||||||
@ -192,7 +195,7 @@ export let lineChartOptionsBlue = {
|
|||||||
xPadding: 12,
|
xPadding: 12,
|
||||||
mode: 'nearest',
|
mode: 'nearest',
|
||||||
intersect: 0,
|
intersect: 0,
|
||||||
position: 'nearest'
|
position: 'nearest',
|
||||||
},
|
},
|
||||||
responsive: true,
|
responsive: true,
|
||||||
scales: {
|
scales: {
|
||||||
@ -202,15 +205,15 @@ export let lineChartOptionsBlue = {
|
|||||||
gridLines: {
|
gridLines: {
|
||||||
drawBorder: false,
|
drawBorder: false,
|
||||||
color: 'rgba(29,140,248,0.0)',
|
color: 'rgba(29,140,248,0.0)',
|
||||||
zeroLineColor: 'transparent'
|
zeroLineColor: 'transparent',
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
suggestedMin: 60,
|
suggestedMin: 60,
|
||||||
suggestedMax: 125,
|
suggestedMax: 125,
|
||||||
padding: 20,
|
padding: 20,
|
||||||
fontColor: '#9e9e9e'
|
fontColor: '#9e9e9e',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
xAxes: [
|
xAxes: [
|
||||||
@ -219,13 +222,13 @@ export let lineChartOptionsBlue = {
|
|||||||
gridLines: {
|
gridLines: {
|
||||||
drawBorder: false,
|
drawBorder: false,
|
||||||
color: 'rgba(29,140,248,0.1)',
|
color: 'rgba(29,140,248,0.1)',
|
||||||
zeroLineColor: 'transparent'
|
zeroLineColor: 'transparent',
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
padding: 20,
|
padding: 20,
|
||||||
fontColor: '#9e9e9e'
|
fontColor: '#9e9e9e',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { initGlobalOptions } from "@/components/Charts/config";
|
import { initGlobalOptions } from '@/components/Charts/config'
|
||||||
import './roundedCornersExtension'
|
import './roundedCornersExtension'
|
||||||
export default {
|
export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
initGlobalOptions();
|
initGlobalOptions()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
export function parseOptions(parent, options) {
|
export function parseOptions(parent, options) {
|
||||||
for (let item in options) {
|
for (let item in options) {
|
||||||
if (typeof options[item] !== 'object') {
|
if (typeof options[item] !== 'object') {
|
||||||
parent[item] = options[item];
|
parent[item] = options[item]
|
||||||
} else {
|
} else {
|
||||||
parseOptions(parent[item], options[item]);
|
parseOptions(parent[item], options[item])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,64 +3,63 @@
|
|||||||
// Code from: https://codepen.io/jedtrow/full/ygRYgo
|
// Code from: https://codepen.io/jedtrow/full/ygRYgo
|
||||||
//
|
//
|
||||||
import Chart from 'chart.js'
|
import Chart from 'chart.js'
|
||||||
Chart.elements.Rectangle.prototype.draw = function() {
|
Chart.elements.Rectangle.prototype.draw = function () {
|
||||||
|
let ctx = this._chart.ctx
|
||||||
let ctx = this._chart.ctx;
|
let vm = this._view
|
||||||
let vm = this._view;
|
let left, right, top, bottom, signX, signY, borderSkipped, radius
|
||||||
let left, right, top, bottom, signX, signY, borderSkipped, radius;
|
let borderWidth = vm.borderWidth
|
||||||
let borderWidth = vm.borderWidth;
|
|
||||||
// Set Radius Here
|
// Set Radius Here
|
||||||
// If radius is large enough to cause drawing errors a max radius is imposed
|
// If radius is large enough to cause drawing errors a max radius is imposed
|
||||||
let cornerRadius = 6;
|
let cornerRadius = 6
|
||||||
|
|
||||||
if (!vm.horizontal) {
|
if (!vm.horizontal) {
|
||||||
// bar
|
// bar
|
||||||
left = vm.x - vm.width / 2;
|
left = vm.x - vm.width / 2
|
||||||
right = vm.x + vm.width / 2;
|
right = vm.x + vm.width / 2
|
||||||
top = vm.y;
|
top = vm.y
|
||||||
bottom = vm.base;
|
bottom = vm.base
|
||||||
signX = 1;
|
signX = 1
|
||||||
signY = bottom > top ? 1 : -1;
|
signY = bottom > top ? 1 : -1
|
||||||
borderSkipped = vm.borderSkipped || 'bottom';
|
borderSkipped = vm.borderSkipped || 'bottom'
|
||||||
} else {
|
} else {
|
||||||
// horizontal bar
|
// horizontal bar
|
||||||
left = vm.base;
|
left = vm.base
|
||||||
right = vm.x;
|
right = vm.x
|
||||||
top = vm.y - vm.height / 2;
|
top = vm.y - vm.height / 2
|
||||||
bottom = vm.y + vm.height / 2;
|
bottom = vm.y + vm.height / 2
|
||||||
signX = right > left ? 1 : -1;
|
signX = right > left ? 1 : -1
|
||||||
signY = 1;
|
signY = 1
|
||||||
borderSkipped = vm.borderSkipped || 'left';
|
borderSkipped = vm.borderSkipped || 'left'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canvas doesn't allow us to stroke inside the width so we can
|
// Canvas doesn't allow us to stroke inside the width so we can
|
||||||
// adjust the sizes to fit if we're setting a stroke on the line
|
// adjust the sizes to fit if we're setting a stroke on the line
|
||||||
if (borderWidth) {
|
if (borderWidth) {
|
||||||
// borderWidth shold be less than bar width and bar height.
|
// borderWidth shold be less than bar width and bar height.
|
||||||
let barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
|
let barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom))
|
||||||
borderWidth = borderWidth > barSize ? barSize : borderWidth;
|
borderWidth = borderWidth > barSize ? barSize : borderWidth
|
||||||
let halfStroke = borderWidth / 2;
|
let halfStroke = borderWidth / 2
|
||||||
// Adjust borderWidth when bar top position is near vm.base(zero).
|
// Adjust borderWidth when bar top position is near vm.base(zero).
|
||||||
let borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);
|
let borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0)
|
||||||
let borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);
|
let borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0)
|
||||||
let borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);
|
let borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0)
|
||||||
let borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);
|
let borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0)
|
||||||
// not become a vertical line?
|
// not become a vertical line?
|
||||||
if (borderLeft !== borderRight) {
|
if (borderLeft !== borderRight) {
|
||||||
top = borderTop;
|
top = borderTop
|
||||||
bottom = borderBottom;
|
bottom = borderBottom
|
||||||
}
|
}
|
||||||
// not become a horizontal line?
|
// not become a horizontal line?
|
||||||
if (borderTop !== borderBottom) {
|
if (borderTop !== borderBottom) {
|
||||||
left = borderLeft;
|
left = borderLeft
|
||||||
right = borderRight;
|
right = borderRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath()
|
||||||
ctx.fillStyle = vm.backgroundColor;
|
ctx.fillStyle = vm.backgroundColor
|
||||||
ctx.strokeStyle = vm.borderColor;
|
ctx.strokeStyle = vm.borderColor
|
||||||
ctx.lineWidth = borderWidth;
|
ctx.lineWidth = borderWidth
|
||||||
|
|
||||||
// Corner points, from bottom-left to bottom-right clockwise
|
// Corner points, from bottom-left to bottom-right clockwise
|
||||||
// | 1 2 |
|
// | 1 2 |
|
||||||
@ -69,62 +68,61 @@ Chart.elements.Rectangle.prototype.draw = function() {
|
|||||||
[left, bottom],
|
[left, bottom],
|
||||||
[left, top],
|
[left, top],
|
||||||
[right, top],
|
[right, top],
|
||||||
[right, bottom]
|
[right, bottom],
|
||||||
];
|
]
|
||||||
|
|
||||||
// Find first (starting) corner with fallback to 'bottom'
|
// Find first (starting) corner with fallback to 'bottom'
|
||||||
let borders = ['bottom', 'left', 'top', 'right'];
|
let borders = ['bottom', 'left', 'top', 'right']
|
||||||
let startCorner = borders.indexOf(borderSkipped, 0);
|
let startCorner = borders.indexOf(borderSkipped, 0)
|
||||||
if (startCorner === -1) {
|
if (startCorner === -1) {
|
||||||
startCorner = 0;
|
startCorner = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function cornerAt(index) {
|
function cornerAt(index) {
|
||||||
return corners[(startCorner + index) % 4];
|
return corners[(startCorner + index) % 4]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw rectangle from 'startCorner'
|
// Draw rectangle from 'startCorner'
|
||||||
let corner = cornerAt(0);
|
let corner = cornerAt(0)
|
||||||
ctx.moveTo(corner[0], corner[1]);
|
ctx.moveTo(corner[0], corner[1])
|
||||||
|
|
||||||
for (let i = 1; i < 4; i++) {
|
for (let i = 1; i < 4; i++) {
|
||||||
corner = cornerAt(i);
|
corner = cornerAt(i)
|
||||||
let nextCornerId = i + 1;
|
let nextCornerId = i + 1
|
||||||
if (nextCornerId == 4) {
|
if (nextCornerId == 4) {
|
||||||
nextCornerId = 0
|
nextCornerId = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextCorner = cornerAt(nextCornerId);
|
let nextCorner = cornerAt(nextCornerId)
|
||||||
|
|
||||||
let width = corners[2][0] - corners[1][0];
|
let width = corners[2][0] - corners[1][0]
|
||||||
let height = corners[0][1] - corners[1][1];
|
let height = corners[0][1] - corners[1][1]
|
||||||
let x = corners[1][0];
|
let x = corners[1][0]
|
||||||
let y = corners[1][1];
|
let y = corners[1][1]
|
||||||
|
|
||||||
let radius = cornerRadius;
|
let radius = cornerRadius
|
||||||
|
|
||||||
// Fix radius being too large
|
// Fix radius being too large
|
||||||
if (radius > height / 2) {
|
if (radius > height / 2) {
|
||||||
radius = height / 2;
|
radius = height / 2
|
||||||
}
|
}
|
||||||
if (radius > width / 2) {
|
if (radius > width / 2) {
|
||||||
radius = width / 2;
|
radius = width / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.moveTo(x + radius, y);
|
ctx.moveTo(x + radius, y)
|
||||||
ctx.lineTo(x + width - radius, y);
|
ctx.lineTo(x + width - radius, y)
|
||||||
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
|
||||||
ctx.lineTo(x + width, y + height - radius);
|
ctx.lineTo(x + width, y + height - radius)
|
||||||
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
|
||||||
ctx.lineTo(x + radius, y + height);
|
ctx.lineTo(x + radius, y + height)
|
||||||
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
|
||||||
ctx.lineTo(x, y + radius);
|
ctx.lineTo(x, y + radius)
|
||||||
ctx.quadraticCurveTo(x, y, x + radius, y);
|
ctx.quadraticCurveTo(x, y, x + radius, y)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.fill();
|
ctx.fill()
|
||||||
if (borderWidth) {
|
if (borderWidth) {
|
||||||
ctx.stroke();
|
ctx.stroke()
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
28
frontend/src/components/CloseButton.spec.js
Normal file
28
frontend/src/components/CloseButton.spec.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
|
||||||
|
import CloseButton from './CloseButton'
|
||||||
|
|
||||||
|
const localVue = global.localVue
|
||||||
|
|
||||||
|
describe('CloseButton', () => {
|
||||||
|
let wrapper
|
||||||
|
let propsData = {
|
||||||
|
target: 'Target',
|
||||||
|
expanded: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
const Wrapper = () => {
|
||||||
|
return mount(CloseButton, { localVue, propsData })
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('mount', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = Wrapper()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('emmits click event', () => {
|
||||||
|
wrapper.find('.navbar-toggler').trigger('click')
|
||||||
|
expect(wrapper.emitted('click')).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -9,7 +9,8 @@
|
|||||||
:aria-expanded="expanded"
|
:aria-expanded="expanded"
|
||||||
aria-label="Toggle navigation"
|
aria-label="Toggle navigation"
|
||||||
>
|
>
|
||||||
<span></span> <span></span>
|
<span></span>
|
||||||
|
<span></span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -18,18 +19,18 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
target: {
|
target: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
description: 'Close button target element'
|
description: 'Close button target element',
|
||||||
},
|
},
|
||||||
expanded: {
|
expanded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Whether button is expanded (aria-expanded attribute)'
|
description: 'Whether button is expanded (aria-expanded attribute)',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClick(evt) {
|
handleClick(evt) {
|
||||||
this.$emit('click', evt);
|
this.$emit('click', evt)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div id="accordion" role="tablist" aria-multiselectable="true" class="accordion">
|
||||||
id="accordion"
|
|
||||||
role="tablist"
|
|
||||||
aria-multiselectable="true"
|
|
||||||
class="accordion"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -16,18 +11,18 @@ export default {
|
|||||||
animationDuration: {
|
animationDuration: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 250,
|
default: 250,
|
||||||
description: 'Collapse animation duration'
|
description: 'Collapse animation duration',
|
||||||
},
|
},
|
||||||
multipleActive: {
|
multipleActive: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
description: 'Whether you can have multiple collapse items opened at the same time'
|
description: 'Whether you can have multiple collapse items opened at the same time',
|
||||||
},
|
},
|
||||||
activeIndex: {
|
activeIndex: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
description: 'Active collapse item index'
|
description: 'Active collapse item index',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
@ -35,50 +30,50 @@ export default {
|
|||||||
multipleActive: this.multipleActive,
|
multipleActive: this.multipleActive,
|
||||||
addItem: this.addItem,
|
addItem: this.addItem,
|
||||||
removeItem: this.removeItem,
|
removeItem: this.removeItem,
|
||||||
deactivateAll: this.deactivateAll
|
deactivateAll: this.deactivateAll,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
items: []
|
items: [],
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addItem(item) {
|
addItem(item) {
|
||||||
const index = this.$slots.default.indexOf(item.$vnode);
|
const index = this.$slots.default.indexOf(item.$vnode)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.items.splice(index, 0, item);
|
this.items.splice(index, 0, item)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeItem(item) {
|
removeItem(item) {
|
||||||
const items = this.items;
|
const items = this.items
|
||||||
const index = items.indexOf(item);
|
const index = items.indexOf(item)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
items.splice(index, 1);
|
items.splice(index, 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deactivateAll() {
|
deactivateAll() {
|
||||||
this.items.forEach(item => {
|
this.items.forEach((item) => {
|
||||||
item.active = false;
|
item.active = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
activateItem() {
|
activateItem() {
|
||||||
if (this.activeIndex !== -1) {
|
if (this.activeIndex !== -1) {
|
||||||
this.items[this.activeIndex].active = true;
|
this.items[this.activeIndex].active = true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.activateItem();
|
this.activateItem()
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
activeIndex() {
|
activeIndex() {
|
||||||
this.activateItem();
|
this.activateItem()
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
@click.prevent="activate"
|
@click.prevent="activate"
|
||||||
:aria-controls="`content-${itemId}`"
|
:aria-controls="`content-${itemId}`"
|
||||||
>
|
>
|
||||||
<slot name="title"> {{ title }} </slot>
|
<slot name="title">{{ title }}</slot>
|
||||||
<i class="tim-icons icon-minimal-down"></i>
|
<i class="tim-icons icon-minimal-down"></i>
|
||||||
</a>
|
</a>
|
||||||
</b-card-header>
|
</b-card-header>
|
||||||
@ -26,67 +26,66 @@
|
|||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { CollapseTransition } from 'vue2-transitions';
|
import { CollapseTransition } from 'vue2-transitions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'collapse-item',
|
name: 'collapse-item',
|
||||||
components: {
|
components: {
|
||||||
CollapseTransition
|
CollapseTransition,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Collapse item title'
|
description: 'Collapse item title',
|
||||||
},
|
},
|
||||||
id: String
|
id: String,
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
animationDuration: {
|
animationDuration: {
|
||||||
default: 250
|
default: 250,
|
||||||
},
|
},
|
||||||
multipleActive: {
|
multipleActive: {
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
addItem: {
|
addItem: {
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
removeItem: {
|
removeItem: {
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
deactivateAll: {
|
deactivateAll: {
|
||||||
default: () => {}
|
default: () => {},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
itemId() {
|
itemId() {
|
||||||
return this.id || this.title;
|
return this.id || this.title
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: false
|
active: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
activate() {
|
activate() {
|
||||||
let wasActive = this.active;
|
let wasActive = this.active
|
||||||
if (!this.multipleActive) {
|
if (!this.multipleActive) {
|
||||||
this.deactivateAll();
|
this.deactivateAll()
|
||||||
}
|
}
|
||||||
this.active = !wasActive;
|
this.active = !wasActive
|
||||||
console.log(this.active)
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.addItem(this);
|
this.addItem(this)
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.$el && this.$el.parentNode) {
|
if (this.$el && this.$el.parentNode) {
|
||||||
this.$el.parentNode.removeChild(this.$el);
|
this.$el.parentNode.removeChild(this.$el)
|
||||||
}
|
}
|
||||||
this.removeItem(this);
|
this.removeItem(this)
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="custom-control custom-checkbox"
|
<div
|
||||||
:class="[
|
class="custom-control custom-checkbox"
|
||||||
{disabled: disabled},
|
:class="[{ disabled: disabled }, { [`custom-checkbox-${type}`]: type }, inlineClass]"
|
||||||
{[`custom-checkbox-${type}`]: type},inlineClass]">
|
>
|
||||||
<input :id="cbId"
|
<input
|
||||||
class="custom-control-input"
|
:id="cbId"
|
||||||
:class="inputClasses"
|
class="custom-control-input"
|
||||||
type="checkbox"
|
:class="inputClasses"
|
||||||
:disabled="disabled"
|
type="checkbox"
|
||||||
v-model="model"/>
|
:disabled="disabled"
|
||||||
|
v-model="model"
|
||||||
|
/>
|
||||||
<label :for="cbId" class="custom-control-label">
|
<label :for="cbId" class="custom-control-label">
|
||||||
<slot>
|
<slot>
|
||||||
<span v-if="inline"> </span>
|
<span v-if="inline"> </span>
|
||||||
@ -17,62 +19,60 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "base-checkbox",
|
name: 'base-checkbox',
|
||||||
model: {
|
model: {
|
||||||
prop: "checked"
|
prop: 'checked',
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
checked: {
|
||||||
|
type: [Array, Boolean],
|
||||||
|
description: 'Whether checkbox is checked',
|
||||||
},
|
},
|
||||||
props: {
|
disabled: {
|
||||||
checked: {
|
type: Boolean,
|
||||||
type: [Array, Boolean],
|
description: 'Whether checkbox is disabled',
|
||||||
description: "Whether checkbox is checked"
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
description: "Whether checkbox is disabled"
|
|
||||||
},
|
|
||||||
inline: {
|
|
||||||
type: Boolean,
|
|
||||||
description: "Whether checkbox is inline"
|
|
||||||
},
|
|
||||||
inputClasses: {
|
|
||||||
type: [String, Object, Array],
|
|
||||||
description: "Checkbox input classes"
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
description: 'Checkbox type (e.g info, danger etc)'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
inline: {
|
||||||
return {
|
type: Boolean,
|
||||||
cbId: "",
|
description: 'Whether checkbox is inline',
|
||||||
touched: false
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
computed: {
|
inputClasses: {
|
||||||
model: {
|
type: [String, Object, Array],
|
||||||
get() {
|
description: 'Checkbox input classes',
|
||||||
return this.checked;
|
|
||||||
},
|
|
||||||
set(check) {
|
|
||||||
if (!this.touched) {
|
|
||||||
this.touched = true;
|
|
||||||
}
|
|
||||||
this.$emit("input", check);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inlineClass() {
|
|
||||||
if (this.inline) {
|
|
||||||
return `form-check-inline`;
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
created() {
|
type: {
|
||||||
this.cbId = Math.random()
|
type: String,
|
||||||
.toString(16)
|
description: 'Checkbox type (e.g info, danger etc)',
|
||||||
.slice(2);
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cbId: '',
|
||||||
|
touched: false,
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
computed: {
|
||||||
|
model: {
|
||||||
|
get() {
|
||||||
|
return this.checked
|
||||||
|
},
|
||||||
|
set(check) {
|
||||||
|
if (!this.touched) {
|
||||||
|
this.touched = true
|
||||||
|
}
|
||||||
|
this.$emit('input', check)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
inlineClass() {
|
||||||
|
if (this.inline) {
|
||||||
|
return `form-check-inline`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.cbId = Math.random().toString(16).slice(2)
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,24 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<validation-provider :rules="rules" :name="name" v-bind="$attrs" v-slot="{errors, valid, invalid, validated}">
|
<validation-provider
|
||||||
|
:rules="rules"
|
||||||
|
:name="name"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-slot="{ errors, valid, invalid, validated }"
|
||||||
|
>
|
||||||
<b-form-group>
|
<b-form-group>
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
<label v-if="label" :class="labelClasses">
|
<label v-if="label" :class="labelClasses">
|
||||||
{{label}}
|
{{ label }}
|
||||||
</label>
|
</label>
|
||||||
</slot>
|
</slot>
|
||||||
<div :class="[
|
<div
|
||||||
{'input-group': hasIcon},
|
:class="[
|
||||||
{'focused': focused},
|
{ 'input-group': hasIcon },
|
||||||
{'input-group-alternative': alternative},
|
{ focused: focused },
|
||||||
{'has-label': label || $slots.label},
|
{ 'input-group-alternative': alternative },
|
||||||
inputGroupClasses
|
{ 'has-label': label || $slots.label },
|
||||||
]">
|
inputGroupClasses,
|
||||||
|
]"
|
||||||
|
>
|
||||||
<div v-if="prependIcon || $slots.prepend" class="input-group-prepend">
|
<div v-if="prependIcon || $slots.prepend" class="input-group-prepend">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<slot name="prepend">
|
<slot name="prepend">
|
||||||
<i :class="prependIcon"></i>
|
<i :class="prependIcon"></i>
|
||||||
</slot>
|
</slot>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<slot v-bind="slotData">
|
<slot v-bind="slotData">
|
||||||
<input
|
<input
|
||||||
@ -29,24 +36,29 @@
|
|||||||
:valid="valid"
|
:valid="valid"
|
||||||
:required="required"
|
:required="required"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
:class="[{'is-valid': valid && validated && successMessage}, {'is-invalid': invalid && validated}, inputClasses]">
|
:class="[
|
||||||
|
{ 'is-valid': valid && validated && successMessage },
|
||||||
|
{ 'is-invalid': invalid && validated },
|
||||||
|
inputClasses,
|
||||||
|
]"
|
||||||
|
/>
|
||||||
</slot>
|
</slot>
|
||||||
<div v-if="appendIcon || $slots.append" class="input-group-append">
|
<div v-if="appendIcon || $slots.append" class="input-group-append">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<slot name="append">
|
<slot name="append">
|
||||||
<i :class="appendIcon"></i>
|
<i :class="appendIcon"></i>
|
||||||
</slot>
|
</slot>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<slot name="infoBlock"></slot>
|
<slot name="infoBlock"></slot>
|
||||||
</div>
|
</div>
|
||||||
<slot name="success">
|
<slot name="success">
|
||||||
<div class="valid-feedback" v-if="valid && validated && successMessage">
|
<div class="valid-feedback" v-if="valid && validated && successMessage">
|
||||||
{{successMessage}}
|
{{ successMessage }}
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
<slot name="error">
|
<slot name="error">
|
||||||
<div v-if="errors[0]" class="invalid-feedback" style="display: block;">
|
<div v-if="errors[0]" class="invalid-feedback" style="display: block">
|
||||||
{{ errors[0] }}
|
{{ errors[0] }}
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
@ -54,123 +66,122 @@
|
|||||||
</validation-provider>
|
</validation-provider>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
name: "base-input",
|
name: 'base-input',
|
||||||
props: {
|
props: {
|
||||||
required: {
|
required: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: "Whether input is required (adds an asterix *)"
|
description: 'Whether input is required (adds an asterix *)',
|
||||||
},
|
|
||||||
group: {
|
|
||||||
type: Boolean,
|
|
||||||
description: "Whether input is an input group (manual override in special cases)"
|
|
||||||
},
|
|
||||||
alternative: {
|
|
||||||
type: Boolean,
|
|
||||||
description: "Whether input is of alternative layout"
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
description: "Input label (text before input)"
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
type: String,
|
|
||||||
description: "Input error (below input)"
|
|
||||||
},
|
|
||||||
successMessage: {
|
|
||||||
type: String,
|
|
||||||
description: "Input success message",
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
labelClasses: {
|
|
||||||
type: String,
|
|
||||||
description: "Input label css classes",
|
|
||||||
default: "form-control-label"
|
|
||||||
},
|
|
||||||
inputClasses: {
|
|
||||||
type: String,
|
|
||||||
description: "Input css classes"
|
|
||||||
},
|
|
||||||
inputGroupClasses: {
|
|
||||||
type: String,
|
|
||||||
description: "Input group css classes"
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: [String, Number],
|
|
||||||
description: "Input value"
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
description: "Input type",
|
|
||||||
default: "text"
|
|
||||||
},
|
|
||||||
appendIcon: {
|
|
||||||
type: String,
|
|
||||||
description: "Append icon (right)"
|
|
||||||
},
|
|
||||||
prependIcon: {
|
|
||||||
type: String,
|
|
||||||
description: "Prepend icon (left)"
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
type: [String, Array, Object],
|
|
||||||
description: 'Vee validate validation rules',
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
description: 'Input name (used for validation)',
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
group: {
|
||||||
return {
|
type: Boolean,
|
||||||
focused: false
|
description: 'Whether input is an input group (manual override in special cases)',
|
||||||
};
|
|
||||||
},
|
},
|
||||||
computed: {
|
alternative: {
|
||||||
listeners() {
|
type: Boolean,
|
||||||
return {
|
description: 'Whether input is of alternative layout',
|
||||||
...this.$listeners,
|
|
||||||
input: this.updateValue,
|
|
||||||
focus: this.onFocus,
|
|
||||||
blur: this.onBlur
|
|
||||||
};
|
|
||||||
},
|
|
||||||
slotData() {
|
|
||||||
return {
|
|
||||||
focused: this.focused,
|
|
||||||
error: this.error,
|
|
||||||
...this.listeners
|
|
||||||
};
|
|
||||||
},
|
|
||||||
hasIcon() {
|
|
||||||
const { append, prepend } = this.$slots;
|
|
||||||
return (
|
|
||||||
append !== undefined ||
|
|
||||||
prepend !== undefined ||
|
|
||||||
this.appendIcon !== undefined ||
|
|
||||||
this.prependIcon !== undefined ||
|
|
||||||
this.group
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
label: {
|
||||||
updateValue(evt) {
|
type: String,
|
||||||
let value = evt.target.value;
|
description: 'Input label (text before input)',
|
||||||
this.$emit("input", value);
|
},
|
||||||
},
|
error: {
|
||||||
onFocus(evt) {
|
type: String,
|
||||||
this.focused = true;
|
description: 'Input error (below input)',
|
||||||
this.$emit("focus", evt);
|
},
|
||||||
},
|
successMessage: {
|
||||||
onBlur(evt) {
|
type: String,
|
||||||
this.focused = false;
|
description: 'Input success message',
|
||||||
this.$emit("blur", evt);
|
default: '',
|
||||||
}
|
},
|
||||||
|
labelClasses: {
|
||||||
|
type: String,
|
||||||
|
description: 'Input label css classes',
|
||||||
|
default: 'form-control-label',
|
||||||
|
},
|
||||||
|
inputClasses: {
|
||||||
|
type: String,
|
||||||
|
description: 'Input css classes',
|
||||||
|
},
|
||||||
|
inputGroupClasses: {
|
||||||
|
type: String,
|
||||||
|
description: 'Input group css classes',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
description: 'Input value',
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
description: 'Input type',
|
||||||
|
default: 'text',
|
||||||
|
},
|
||||||
|
appendIcon: {
|
||||||
|
type: String,
|
||||||
|
description: 'Append icon (right)',
|
||||||
|
},
|
||||||
|
prependIcon: {
|
||||||
|
type: String,
|
||||||
|
description: 'Prepend icon (left)',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
type: [String, Array, Object],
|
||||||
|
description: 'Vee validate validation rules',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
description: 'Input name (used for validation)',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
focused: false,
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
computed: {
|
||||||
|
listeners() {
|
||||||
|
return {
|
||||||
|
...this.$listeners,
|
||||||
|
input: this.updateValue,
|
||||||
|
focus: this.onFocus,
|
||||||
|
blur: this.onBlur,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
slotData() {
|
||||||
|
return {
|
||||||
|
focused: this.focused,
|
||||||
|
error: this.error,
|
||||||
|
...this.listeners,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasIcon() {
|
||||||
|
const { append, prepend } = this.$slots
|
||||||
|
return (
|
||||||
|
append !== undefined ||
|
||||||
|
prepend !== undefined ||
|
||||||
|
this.appendIcon !== undefined ||
|
||||||
|
this.prependIcon !== undefined ||
|
||||||
|
this.group
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateValue(evt) {
|
||||||
|
let value = evt.target.value
|
||||||
|
this.$emit('input', value)
|
||||||
|
},
|
||||||
|
onFocus(evt) {
|
||||||
|
this.focused = true
|
||||||
|
this.$emit('focus', evt)
|
||||||
|
},
|
||||||
|
onBlur(evt) {
|
||||||
|
this.focused = false
|
||||||
|
this.$emit('blur', evt)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="custom-control custom-radio" :class="[inlineClass, { disabled: disabled }]">
|
||||||
class="custom-control custom-radio"
|
|
||||||
:class="[inlineClass, { disabled: disabled }]">
|
|
||||||
<input
|
<input
|
||||||
:id="cbId"
|
:id="cbId"
|
||||||
class="custom-control-input"
|
class="custom-control-input"
|
||||||
@ -18,51 +16,49 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'base-radio',
|
name: 'base-radio',
|
||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
description: 'Radio label'
|
description: 'Radio label',
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
description: 'Whether radio is disabled'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: [String, Boolean],
|
|
||||||
description: 'Radio value'
|
|
||||||
},
|
|
||||||
inline: {
|
|
||||||
type: Boolean,
|
|
||||||
description: 'Whether radio is inline'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
disabled: {
|
||||||
return {
|
type: Boolean,
|
||||||
cbId: ''
|
description: 'Whether radio is disabled',
|
||||||
};
|
|
||||||
},
|
},
|
||||||
computed: {
|
value: {
|
||||||
model: {
|
type: [String, Boolean],
|
||||||
get() {
|
description: 'Radio value',
|
||||||
return this.value;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
this.$emit('input', value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inlineClass() {
|
|
||||||
if (this.inline) {
|
|
||||||
return `form-check-inline`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
created() {
|
inline: {
|
||||||
this.cbId = Math.random()
|
type: Boolean,
|
||||||
.toString(16)
|
description: 'Whether radio is inline',
|
||||||
.slice(2);
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cbId: '',
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
computed: {
|
||||||
|
model: {
|
||||||
|
get() {
|
||||||
|
return this.value
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('input', value)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
inlineClass() {
|
||||||
|
if (this.inline) {
|
||||||
|
return `form-check-inline`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.cbId = Math.random().toString(16).slice(2)
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
<b-row v-loading="true" id="loading"></b-row>
|
<b-row v-loading="true" id="loading"></b-row>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
import Vue from 'vue'
|
||||||
import { Loading } from 'element-ui';
|
import { Loading } from 'element-ui'
|
||||||
|
|
||||||
Vue.use(Loading.directive);
|
Vue.use(Loading.directive)
|
||||||
export default {};
|
export default {}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
#loading {
|
#loading {
|
||||||
|
|||||||
@ -1,125 +1,127 @@
|
|||||||
<template>
|
<template>
|
||||||
<SlideYUpTransition :duration="animationDuration">
|
<slide-y-up-transition :duration="animationDuration">
|
||||||
<b-modal class="modal fade"
|
<b-modal
|
||||||
ref="app-modal"
|
class="modal fade"
|
||||||
:size="size"
|
ref="app-modal"
|
||||||
:hide-header="!$slots.header"
|
:size="size"
|
||||||
:modal-class="[{'modal-mini': type === 'mini'}, ...modalClasses]"
|
:hide-header="!$slots.header"
|
||||||
@mousedown.self="closeModal"
|
:modal-class="[{ 'modal-mini': type === 'mini' }, ...modalClasses]"
|
||||||
tabindex="-1"
|
@mousedown.self="closeModal"
|
||||||
role="dialog"
|
tabindex="-1"
|
||||||
centered
|
role="dialog"
|
||||||
@close="closeModal"
|
centered
|
||||||
@hide="closeModal"
|
@close="closeModal"
|
||||||
:header-class="headerClasses"
|
@hide="closeModal"
|
||||||
:footer-class="footerClasses"
|
:header-class="headerClasses"
|
||||||
:content-class="[gradient ? `bg-gradient-${gradient}` : '', ...modalContentClasses]"
|
:footer-class="footerClasses"
|
||||||
:body-class="bodyClasses"
|
:content-class="[gradient ? `bg-gradient-${gradient}` : '', ...modalContentClasses]"
|
||||||
:aria-hidden="!show">
|
:body-class="bodyClasses"
|
||||||
|
:aria-hidden="!show"
|
||||||
|
>
|
||||||
<template v-slot:modal-header>
|
<template v-slot:modal-header>
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
<slot name="close-button">
|
<slot name="close-button">
|
||||||
<button type="button"
|
<button
|
||||||
class="close"
|
type="button"
|
||||||
v-if="showClose"
|
class="close"
|
||||||
@click="closeModal"
|
v-if="showClose"
|
||||||
data-dismiss="modal"
|
@click="closeModal"
|
||||||
aria-label="Close">
|
data-dismiss="modal"
|
||||||
<span :aria-hidden="!show">×</span>
|
aria-label="Close"
|
||||||
</button>
|
>
|
||||||
</slot>
|
<span :aria-hidden="!show">×</span>
|
||||||
|
</button>
|
||||||
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
<template v-slot:modal-footer>
|
<template v-slot:modal-footer>
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</b-modal>
|
</b-modal>
|
||||||
</SlideYUpTransition>
|
</slide-y-up-transition>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { SlideYUpTransition } from "vue2-transitions";
|
import { SlideYUpTransition } from 'vue2-transitions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "modal",
|
name: 'modal',
|
||||||
components: {
|
components: {
|
||||||
SlideYUpTransition
|
SlideYUpTransition,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
show: Boolean,
|
||||||
|
showClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
},
|
},
|
||||||
props: {
|
type: {
|
||||||
show: Boolean,
|
type: String,
|
||||||
showClose: {
|
default: '',
|
||||||
type: Boolean,
|
validator(value) {
|
||||||
default: true
|
let acceptedValues = ['', 'notice', 'mini']
|
||||||
|
return acceptedValues.indexOf(value) !== -1
|
||||||
},
|
},
|
||||||
type: {
|
description: 'Modal type (notice|mini|"") ',
|
||||||
type: String,
|
},
|
||||||
default: "",
|
modalClasses: {
|
||||||
validator(value) {
|
type: [Object, String],
|
||||||
let acceptedValues = ["", "notice", "mini"];
|
description: 'Modal dialog css classes',
|
||||||
return acceptedValues.indexOf(value) !== -1;
|
},
|
||||||
},
|
size: {
|
||||||
description: 'Modal type (notice|mini|"") '
|
type: String,
|
||||||
|
description: 'Modal size',
|
||||||
|
validator(value) {
|
||||||
|
let acceptedValues = ['', 'sm', 'lg']
|
||||||
|
return acceptedValues.indexOf(value) !== -1
|
||||||
},
|
},
|
||||||
modalClasses: {
|
},
|
||||||
type: [Object, String],
|
modalContentClasses: {
|
||||||
description: "Modal dialog css classes"
|
type: [Object, String],
|
||||||
},
|
description: 'Modal dialog content css classes',
|
||||||
size: {
|
},
|
||||||
type: String,
|
gradient: {
|
||||||
description: 'Modal size',
|
type: String,
|
||||||
validator(value) {
|
description: 'Modal gradient type (danger, primary etc)',
|
||||||
let acceptedValues = ["", "sm", "lg"];
|
},
|
||||||
return acceptedValues.indexOf(value) !== -1;
|
headerClasses: {
|
||||||
},
|
type: [Object, String],
|
||||||
},
|
description: 'Modal Header css classes',
|
||||||
modalContentClasses: {
|
},
|
||||||
type: [Object, String],
|
bodyClasses: {
|
||||||
description: "Modal dialog content css classes"
|
type: [Object, String],
|
||||||
},
|
description: 'Modal Body css classes',
|
||||||
gradient: {
|
},
|
||||||
type: String,
|
footerClasses: {
|
||||||
description: "Modal gradient type (danger, primary etc)"
|
type: [Object, String],
|
||||||
},
|
description: 'Modal Footer css classes',
|
||||||
headerClasses: {
|
},
|
||||||
type: [Object, String],
|
animationDuration: {
|
||||||
description: "Modal Header css classes"
|
type: Number,
|
||||||
},
|
default: 500,
|
||||||
bodyClasses: {
|
description: 'Modal transition duration',
|
||||||
type: [Object, String],
|
},
|
||||||
description: "Modal Body css classes"
|
},
|
||||||
},
|
methods: {
|
||||||
footerClasses: {
|
closeModal() {
|
||||||
type: [Object, String],
|
this.$emit('update:show', false)
|
||||||
description: "Modal Footer css classes"
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
animationDuration: {
|
},
|
||||||
type: Number,
|
watch: {
|
||||||
default: 500,
|
show(val) {
|
||||||
description: "Modal transition duration"
|
if (val) {
|
||||||
|
this.$refs['app-modal'].show()
|
||||||
|
} else {
|
||||||
|
this.$refs['app-modal'].hide()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
},
|
||||||
closeModal() {
|
}
|
||||||
this.$emit("update:show", false);
|
|
||||||
this.$emit("close");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show(val) {
|
|
||||||
if (val) {
|
|
||||||
this.$refs['app-modal'].show();
|
|
||||||
} else {
|
|
||||||
this.$refs['app-modal'].hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.modal-backdrop {
|
.modal-backdrop {
|
||||||
background-color: rgba(0, 0, 0, 0.6) !important;
|
background-color: rgba(0, 0, 0, 0.6) !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,85 +1,80 @@
|
|||||||
<template>
|
<template>
|
||||||
<!--Notice modal-->
|
<!--Notice modal-->
|
||||||
<modal :show.sync="$store.state.modals"
|
<modal
|
||||||
modal-classes="modal-danger"
|
:show.sync="$store.state.modals"
|
||||||
modal-content-classes="bg-gradient-danger">
|
modal-classes="modal-danger"
|
||||||
<h6 slot="header" class="modal-title">Your attention is required</h6>
|
modal-content-classes="bg-gradient-danger"
|
||||||
|
>
|
||||||
|
<h6 slot="header" class="modal-title">Your attention is required</h6>
|
||||||
|
|
||||||
<div class="py-3 text-center">
|
<div class="py-3 text-center">
|
||||||
|
<form ref="form" @submit.stop.prevent="handleSubmit">
|
||||||
<form ref="form" @submit.stop.prevent="handleSubmit">
|
<b-form-group
|
||||||
<b-form-group
|
label="Name"
|
||||||
label="Name"
|
label-for="name-input"
|
||||||
label-for="name-input"
|
invalid-feedback="Name is required"
|
||||||
invalid-feedback="Name is required"
|
:state="nameState"
|
||||||
:state="nameState"
|
>
|
||||||
>
|
<b-form-input id="name-input" v-model="name" :state="nameState" required></b-form-input>
|
||||||
<b-form-input
|
</b-form-group>
|
||||||
id="name-input"
|
</form>
|
||||||
v-model="name"
|
</div>
|
||||||
:state="nameState"
|
|
||||||
required
|
|
||||||
></b-form-input>
|
|
||||||
</b-form-group>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<base-button type="white">Ok</base-button>
|
<base-button type="white">Ok</base-button>
|
||||||
<base-button type="link" class="text-white ml-auto" @click="$store.state.modals = false">abbrechen</base-button>
|
<base-button type="link" class="ml-auto" @click="$store.state.modals = false">
|
||||||
</template>
|
abbrechen
|
||||||
</modal>
|
</base-button>
|
||||||
|
</template>
|
||||||
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'modal',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: '',
|
||||||
|
nameState: null,
|
||||||
|
submittedNames: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*Modal*/
|
||||||
|
checkFormValidity() {
|
||||||
|
const valid = this.$refs.form.checkValidity()
|
||||||
|
this.nameState = valid
|
||||||
|
return valid
|
||||||
|
},
|
||||||
|
resetModal() {
|
||||||
|
this.name = ''
|
||||||
|
this.nameState = null
|
||||||
|
},
|
||||||
|
handleOk(bvModalEvt) {
|
||||||
|
// Prevent modal from closing
|
||||||
|
bvModalEvt.preventDefault()
|
||||||
|
// Trigger submit handler
|
||||||
|
this.handleSubmit()
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
// Exit when the form isn't valid
|
||||||
|
if (!this.checkFormValidity()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Push the name to submitted names
|
||||||
|
this.submittedNames.push(this.name)
|
||||||
|
this.$store.state.modals = false
|
||||||
|
this.$store.commit('loginAsAdmin')
|
||||||
|
this.$router.push('/AdminOverview')
|
||||||
|
|
||||||
export default {
|
// Hide the modal manually
|
||||||
name: 'modal',
|
this.$nextTick(() => {
|
||||||
data() {
|
this.$bvModal.hide('modal-prevent-closing')
|
||||||
return {
|
})
|
||||||
name: '',
|
},
|
||||||
nameState: null,
|
}
|
||||||
submittedNames: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/*Modal*/
|
|
||||||
checkFormValidity() {
|
|
||||||
const valid = this.$refs.form.checkValidity()
|
|
||||||
this.nameState = valid
|
|
||||||
return valid
|
|
||||||
},
|
|
||||||
resetModal() {
|
|
||||||
this.name = ''
|
|
||||||
this.nameState = null
|
|
||||||
},
|
|
||||||
handleOk(bvModalEvt) {
|
|
||||||
// Prevent modal from closing
|
|
||||||
bvModalEvt.preventDefault()
|
|
||||||
// Trigger submit handler
|
|
||||||
this.handleSubmit()
|
|
||||||
},
|
|
||||||
handleSubmit() {
|
|
||||||
// Exit when the form isn't valid
|
|
||||||
if (!this.checkFormValidity()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Push the name to submitted names
|
|
||||||
this.submittedNames.push(this.name)
|
|
||||||
this.$store.state.modals = false
|
|
||||||
this.$store.commit('loginAsAdmin')
|
|
||||||
this.$router.push('/AdminOverview')
|
|
||||||
|
|
||||||
// Hide the modal manually
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$bvModal.hide('modal-prevent-closing')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.modal-backdrop {
|
.modal-backdrop {
|
||||||
background-color: rgba(0, 0, 0, 0.6) !important;
|
background-color: rgba(0, 0, 0, 0.6) !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -18,10 +18,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<b-navbar-toggle
|
<b-navbar-toggle target="nav-text-collapse" @click.stop="toggleMenu"></b-navbar-toggle>
|
||||||
target="nav-text-collapse"
|
|
||||||
@click.stop="toggleMenu">
|
|
||||||
</b-navbar-toggle>
|
|
||||||
|
|
||||||
<b-collapse
|
<b-collapse
|
||||||
is-nav
|
is-nav
|
||||||
@ -29,7 +26,8 @@
|
|||||||
class="navbar-custom-collapse collapse"
|
class="navbar-custom-collapse collapse"
|
||||||
:class="menuClasses"
|
:class="menuClasses"
|
||||||
:visible="show"
|
:visible="show"
|
||||||
v-click-outside="closeMenu">
|
v-click-outside="closeMenu"
|
||||||
|
>
|
||||||
<slot :close-menu="closeMenu"></slot>
|
<slot :close-menu="closeMenu"></slot>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
</div>
|
</div>
|
||||||
@ -43,29 +41,28 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description:
|
description:
|
||||||
'Whether navbar menu is shown (valid for viewports < specified by `expand` prop)'
|
'Whether navbar menu is shown (valid for viewports < specified by `expand` prop)',
|
||||||
},
|
},
|
||||||
transparent: {
|
transparent: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: 'Whether navbar is transparent'
|
description: 'Whether navbar is transparent',
|
||||||
},
|
},
|
||||||
expand: {
|
expand: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'lg',
|
default: 'lg',
|
||||||
description: 'Breakpoint where nav should expand'
|
description: 'Breakpoint where nav should expand',
|
||||||
},
|
},
|
||||||
menuClasses: {
|
menuClasses: {
|
||||||
type: [String, Object, Array],
|
type: [String, Object, Array],
|
||||||
default: '',
|
default: '',
|
||||||
description:
|
description: 'Navbar menu (items) classes. Can be used to align menu items to the right/left',
|
||||||
'Navbar menu (items) classes. Can be used to align menu items to the right/left'
|
|
||||||
},
|
},
|
||||||
containerClasses: {
|
containerClasses: {
|
||||||
type: [String, Object, Array],
|
type: [String, Object, Array],
|
||||||
default: 'container',
|
default: 'container',
|
||||||
description:
|
description:
|
||||||
'Container classes. Can be used to control container classes (contains both navbar brand and menu items)'
|
'Container classes. Can be used to control container classes (contains both navbar brand and menu items)',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -81,43 +78,43 @@ export default {
|
|||||||
'primary',
|
'primary',
|
||||||
'light',
|
'light',
|
||||||
'info',
|
'info',
|
||||||
'vue'
|
'vue',
|
||||||
].includes(value);
|
].includes(value)
|
||||||
},
|
},
|
||||||
description: 'Navbar color type'
|
description: 'Navbar color type',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
prop: 'show',
|
prop: 'show',
|
||||||
event: 'change'
|
event: 'change',
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
classes() {
|
classes() {
|
||||||
let color = `bg-${this.type}`;
|
let color = `bg-${this.type}`
|
||||||
let classes = [
|
let classes = [
|
||||||
{ 'navbar-transparent': this.transparent },
|
{ 'navbar-transparent': this.transparent },
|
||||||
{ [`navbar-expand-${this.expand}`]: this.expand }
|
{ [`navbar-expand-${this.expand}`]: this.expand },
|
||||||
];
|
]
|
||||||
if (this.position) {
|
if (this.position) {
|
||||||
classes.push(`navbar-${this.position}`);
|
classes.push(`navbar-${this.position}`)
|
||||||
}
|
}
|
||||||
if (!this.transparent) {
|
if (!this.transparent) {
|
||||||
classes.push(color);
|
classes.push(color)
|
||||||
}
|
}
|
||||||
return classes;
|
return classes
|
||||||
},
|
},
|
||||||
hasMenu() {
|
hasMenu() {
|
||||||
return this.$slots.default;
|
return this.$slots.default
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleMenu() {
|
toggleMenu() {
|
||||||
this.$emit('change', !this.show);
|
this.$emit('change', !this.show)
|
||||||
},
|
},
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
this.$emit('change', false);
|
this.$emit('change', false)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'navbar-toggle-button'
|
name: 'navbar-toggle-button',
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
>
|
>
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
<slot>
|
<slot>
|
||||||
<span></span>
|
<span></span>
|
||||||
</slot>
|
</slot>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
@ -19,14 +19,14 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
target: {
|
target: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
description: 'Button target element'
|
description: 'Button target element',
|
||||||
},
|
},
|
||||||
toggled: {
|
toggled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description: 'Whether button is toggled'
|
description: 'Whether button is toggled',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -3,207 +3,192 @@
|
|||||||
@click="tryClose"
|
@click="tryClose"
|
||||||
data-notify="container"
|
data-notify="container"
|
||||||
class="alert alert-notify alert-dismissible"
|
class="alert alert-notify alert-dismissible"
|
||||||
:class="[
|
:class="[{ 'alert-with-icon': icon }, verticalAlign, horizontalAlign, alertType]"
|
||||||
{ 'alert-with-icon': icon },
|
|
||||||
verticalAlign,
|
|
||||||
horizontalAlign,
|
|
||||||
alertType
|
|
||||||
]"
|
|
||||||
role="alert"
|
role="alert"
|
||||||
:style="customPosition"
|
:style="customPosition"
|
||||||
data-notify-position="top-center"
|
data-notify-position="top-center"
|
||||||
>
|
>
|
||||||
<template v-if="icon || $slots.icon">
|
<template v-if="icon || $slots.icon">
|
||||||
<slot name="icon">
|
<slot name="icon">
|
||||||
<span class="alert-icon" data-notify="icon">
|
<span class="alert-icon" data-notify="icon">
|
||||||
<i :class="icon"></i>
|
<i :class="icon"></i>
|
||||||
</span>
|
</span>
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<span class="alert-text">
|
<span class="alert-text">
|
||||||
|
|
||||||
<span v-if="title" class="title">
|
<span v-if="title" class="title">
|
||||||
<b>{{ title }}<br/></b>
|
<b>
|
||||||
|
{{ title }}
|
||||||
|
<br />
|
||||||
|
</b>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="message" v-html="message"></span>
|
<span v-if="message" v-html="message"></span>
|
||||||
<content-render
|
<content-render v-if="!message && component" :component="component"></content-render>
|
||||||
v-if="!message && component"
|
|
||||||
:component="component"
|
|
||||||
></content-render>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<slot name="dismiss-icon">
|
<slot name="dismiss-icon">
|
||||||
<button type="button"
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close" @click="close">
|
||||||
class="close"
|
|
||||||
data-dismiss="alert"
|
|
||||||
aria-label="Close"
|
|
||||||
@click="close">
|
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'notification',
|
name: 'notification',
|
||||||
components: {
|
components: {
|
||||||
contentRender: {
|
contentRender: {
|
||||||
props: ['component'],
|
props: ['component'],
|
||||||
render: function (createElement) {
|
render: function (createElement) {
|
||||||
return createElement(this.component)
|
return createElement(this.component)
|
||||||
}
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
props: {
|
},
|
||||||
message: String,
|
props: {
|
||||||
title: {
|
message: String,
|
||||||
type: String,
|
title: {
|
||||||
description: 'Notification title'
|
type: String,
|
||||||
},
|
description: 'Notification title',
|
||||||
icon: {
|
|
||||||
type: String,
|
|
||||||
description: 'Notification icon'
|
|
||||||
},
|
|
||||||
verticalAlign: {
|
|
||||||
type: String,
|
|
||||||
default: 'top',
|
|
||||||
validator: value => {
|
|
||||||
let acceptedValues = ['top', 'bottom'];
|
|
||||||
return acceptedValues.indexOf(value) !== -1;
|
|
||||||
},
|
|
||||||
description: 'Vertical alignment of notification (top|bottom)'
|
|
||||||
},
|
|
||||||
horizontalAlign: {
|
|
||||||
type: String,
|
|
||||||
default: 'right',
|
|
||||||
validator: value => {
|
|
||||||
let acceptedValues = ['left', 'center', 'right'];
|
|
||||||
return acceptedValues.indexOf(value) !== -1;
|
|
||||||
},
|
|
||||||
description: 'Horizontal alignment of notification (left|center|right)'
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'info',
|
|
||||||
validator: value => {
|
|
||||||
let acceptedValues = [
|
|
||||||
'default',
|
|
||||||
'info',
|
|
||||||
'primary',
|
|
||||||
'danger',
|
|
||||||
'warning',
|
|
||||||
'success'
|
|
||||||
];
|
|
||||||
return acceptedValues.indexOf(value) !== -1;
|
|
||||||
},
|
|
||||||
description: 'Notification type of notification (default|info|primary|danger|warning|success)'
|
|
||||||
},
|
|
||||||
timeout: {
|
|
||||||
type: Number,
|
|
||||||
default: 5000,
|
|
||||||
validator: value => {
|
|
||||||
return value >= 0;
|
|
||||||
},
|
|
||||||
description: 'Notification timeout (closes after X milliseconds). Default is 5000 (5s)'
|
|
||||||
},
|
|
||||||
timestamp: {
|
|
||||||
type: Date,
|
|
||||||
default: () => new Date(),
|
|
||||||
description: 'Notification timestamp (used internally to handle notification removal correctly)'
|
|
||||||
},
|
|
||||||
component: {
|
|
||||||
type: [Object, Function],
|
|
||||||
description: 'Custom content component. Cane be a `.vue` component or render function'
|
|
||||||
},
|
|
||||||
showClose: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
description: 'Whether to show close button'
|
|
||||||
},
|
|
||||||
closeOnClick: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
description: 'Whether to close notification when clicking it\' body'
|
|
||||||
},
|
|
||||||
clickHandler: {
|
|
||||||
type: Function,
|
|
||||||
description: 'Custom notification click handler'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
icon: {
|
||||||
return {
|
type: String,
|
||||||
elmHeight: 0
|
description: 'Notification icon',
|
||||||
};
|
|
||||||
},
|
},
|
||||||
computed: {
|
verticalAlign: {
|
||||||
hasIcon() {
|
type: String,
|
||||||
return this.icon && this.icon.length > 0;
|
default: 'top',
|
||||||
|
validator: (value) => {
|
||||||
|
let acceptedValues = ['top', 'bottom']
|
||||||
|
return acceptedValues.indexOf(value) !== -1
|
||||||
},
|
},
|
||||||
alertType() {
|
description: 'Vertical alignment of notification (top|bottom)',
|
||||||
return `alert-${this.type}`;
|
|
||||||
},
|
|
||||||
customPosition() {
|
|
||||||
let initialMargin = 20;
|
|
||||||
let alertHeight = this.elmHeight + 10;
|
|
||||||
let sameAlertsCount = this.$notifications.state.filter(alert => {
|
|
||||||
return (
|
|
||||||
alert.horizontalAlign === this.horizontalAlign &&
|
|
||||||
alert.verticalAlign === this.verticalAlign &&
|
|
||||||
alert.timestamp <= this.timestamp
|
|
||||||
);
|
|
||||||
}).length;
|
|
||||||
if (this.$notifications.settings.overlap) {
|
|
||||||
sameAlertsCount = 1;
|
|
||||||
}
|
|
||||||
let pixels = (sameAlertsCount - 1) * alertHeight + initialMargin;
|
|
||||||
let styles = {};
|
|
||||||
if (this.verticalAlign === 'top') {
|
|
||||||
styles.top = `${pixels}px`;
|
|
||||||
} else {
|
|
||||||
styles.bottom = `${pixels}px`;
|
|
||||||
}
|
|
||||||
return styles;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
horizontalAlign: {
|
||||||
close() {
|
type: String,
|
||||||
this.$emit('close', this.timestamp);
|
default: 'right',
|
||||||
|
validator: (value) => {
|
||||||
|
let acceptedValues = ['left', 'center', 'right']
|
||||||
|
return acceptedValues.indexOf(value) !== -1
|
||||||
},
|
},
|
||||||
tryClose(evt) {
|
description: 'Horizontal alignment of notification (left|center|right)',
|
||||||
if (this.clickHandler) {
|
|
||||||
this.clickHandler(evt, this);
|
|
||||||
}
|
|
||||||
if (this.closeOnClick) {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
type: {
|
||||||
this.elmHeight = this.$el.clientHeight;
|
type: String,
|
||||||
if (this.timeout) {
|
default: 'info',
|
||||||
setTimeout(this.close, this.timeout);
|
validator: (value) => {
|
||||||
}
|
let acceptedValues = ['default', 'info', 'primary', 'danger', 'warning', 'success']
|
||||||
|
return acceptedValues.indexOf(value) !== -1
|
||||||
|
},
|
||||||
|
description:
|
||||||
|
'Notification type of notification (default|info|primary|danger|warning|success)',
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
type: Number,
|
||||||
|
default: 5000,
|
||||||
|
validator: (value) => {
|
||||||
|
return value >= 0
|
||||||
|
},
|
||||||
|
description: 'Notification timeout (closes after X milliseconds). Default is 5000 (5s)',
|
||||||
|
},
|
||||||
|
timestamp: {
|
||||||
|
type: Date,
|
||||||
|
default: () => new Date(),
|
||||||
|
description:
|
||||||
|
'Notification timestamp (used internally to handle notification removal correctly)',
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
type: [Object, Function],
|
||||||
|
description: 'Custom content component. Cane be a `.vue` component or render function',
|
||||||
|
},
|
||||||
|
showClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
description: 'Whether to show close button',
|
||||||
|
},
|
||||||
|
closeOnClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
description: "Whether to close notification when clicking it' body",
|
||||||
|
},
|
||||||
|
clickHandler: {
|
||||||
|
type: Function,
|
||||||
|
description: 'Custom notification click handler',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
elmHeight: 0,
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
computed: {
|
||||||
|
hasIcon() {
|
||||||
|
return this.icon && this.icon.length > 0
|
||||||
|
},
|
||||||
|
alertType() {
|
||||||
|
return `alert-${this.type}`
|
||||||
|
},
|
||||||
|
customPosition() {
|
||||||
|
let initialMargin = 20
|
||||||
|
let alertHeight = this.elmHeight + 10
|
||||||
|
let sameAlertsCount = this.$notifications.state.filter((alert) => {
|
||||||
|
return (
|
||||||
|
alert.horizontalAlign === this.horizontalAlign &&
|
||||||
|
alert.verticalAlign === this.verticalAlign &&
|
||||||
|
alert.timestamp <= this.timestamp
|
||||||
|
)
|
||||||
|
}).length
|
||||||
|
if (this.$notifications.settings.overlap) {
|
||||||
|
sameAlertsCount = 1
|
||||||
|
}
|
||||||
|
let pixels = (sameAlertsCount - 1) * alertHeight + initialMargin
|
||||||
|
let styles = {}
|
||||||
|
if (this.verticalAlign === 'top') {
|
||||||
|
styles.top = `${pixels}px`
|
||||||
|
} else {
|
||||||
|
styles.bottom = `${pixels}px`
|
||||||
|
}
|
||||||
|
return styles
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.$emit('close', this.timestamp)
|
||||||
|
},
|
||||||
|
tryClose(evt) {
|
||||||
|
if (this.clickHandler) {
|
||||||
|
this.clickHandler(evt, this)
|
||||||
|
}
|
||||||
|
if (this.closeOnClick) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.elmHeight = this.$el.clientHeight
|
||||||
|
if (this.timeout) {
|
||||||
|
setTimeout(this.close, this.timeout)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.notifications .alert {
|
.notifications .alert {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
|
|
||||||
&[data-notify='container'] {
|
&[data-notify='container'] {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
|
||||||
|
|
||||||
&.center {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
&.left {
|
|
||||||
left: 20px;
|
|
||||||
}
|
|
||||||
&.right {
|
|
||||||
right: 20px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
&.left {
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
&.right {
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,55 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="notifications">
|
<div class="notifications">
|
||||||
<slide-y-up-transition :duration="transitionDuration"
|
<slide-y-up-transition :duration="transitionDuration" group mode="out-in">
|
||||||
group
|
|
||||||
mode="out-in">
|
|
||||||
<notification
|
<notification
|
||||||
v-for="notification in notifications"
|
v-for="notification in notifications"
|
||||||
v-bind="notification"
|
v-bind="notification"
|
||||||
:clickHandler="notification.onClick"
|
:clickHandler="notification.onClick"
|
||||||
:key="notification.timestamp.getTime()"
|
:key="notification.timestamp.getTime()"
|
||||||
@close="removeNotification"
|
@close="removeNotification"
|
||||||
>
|
></notification>
|
||||||
</notification>
|
|
||||||
</slide-y-up-transition>
|
</slide-y-up-transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Notification from './Notification.vue';
|
import Notification from './Notification.vue'
|
||||||
import { SlideYUpTransition } from 'vue2-transitions';
|
import { SlideYUpTransition } from 'vue2-transitions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SlideYUpTransition,
|
SlideYUpTransition,
|
||||||
Notification
|
Notification,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
transitionDuration: {
|
||||||
|
type: Number,
|
||||||
|
default: 200,
|
||||||
},
|
},
|
||||||
props: {
|
overlap: {
|
||||||
transitionDuration: {
|
type: Boolean,
|
||||||
type: Number,
|
default: false,
|
||||||
default: 200
|
|
||||||
},
|
|
||||||
overlap: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
},
|
||||||
return {
|
data() {
|
||||||
notifications: this.$notifications.state
|
return {
|
||||||
};
|
notifications: this.$notifications.state,
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
removeNotification(timestamp) {
|
|
||||||
this.$notifications.removeNotification(timestamp);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.$notifications.settings.overlap = this.overlap;
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
overlap: function (newVal) {
|
|
||||||
this.$notifications.settings.overlap = newVal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
methods: {
|
||||||
|
removeNotification(timestamp) {
|
||||||
|
this.$notifications.removeNotification(timestamp)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$notifications.settings.overlap = this.overlap
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
overlap: function (newVal) {
|
||||||
|
this.$notifications.settings.overlap = newVal
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import Notifications from './Notifications.vue';
|
import Notifications from './Notifications.vue'
|
||||||
|
|
||||||
const NotificationStore = {
|
const NotificationStore = {
|
||||||
state: [], // here the notifications will be added
|
state: [], // here the notifications will be added
|
||||||
@ -9,58 +9,58 @@ const NotificationStore = {
|
|||||||
type: 'info',
|
type: 'info',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
closeOnClick: true,
|
closeOnClick: true,
|
||||||
showClose: true
|
showClose: true,
|
||||||
},
|
},
|
||||||
setOptions(options) {
|
setOptions(options) {
|
||||||
this.settings = Object.assign(this.settings, options);
|
this.settings = Object.assign(this.settings, options)
|
||||||
},
|
},
|
||||||
removeNotification(timestamp) {
|
removeNotification(timestamp) {
|
||||||
const indexToDelete = this.state.findIndex(n => n.timestamp === timestamp);
|
const indexToDelete = this.state.findIndex((n) => n.timestamp === timestamp)
|
||||||
if (indexToDelete !== -1) {
|
if (indexToDelete !== -1) {
|
||||||
this.state.splice(indexToDelete, 1);
|
this.state.splice(indexToDelete, 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addNotification(notification) {
|
addNotification(notification) {
|
||||||
if (typeof notification === 'string' || notification instanceof String) {
|
if (typeof notification === 'string' || notification instanceof String) {
|
||||||
notification = { message: notification };
|
notification = { message: notification }
|
||||||
}
|
}
|
||||||
notification.timestamp = new Date();
|
notification.timestamp = new Date()
|
||||||
notification.timestamp.setMilliseconds(
|
notification.timestamp.setMilliseconds(
|
||||||
notification.timestamp.getMilliseconds() + this.state.length
|
notification.timestamp.getMilliseconds() + this.state.length,
|
||||||
);
|
)
|
||||||
notification = Object.assign({}, this.settings, notification);
|
notification = Object.assign({}, this.settings, notification)
|
||||||
this.state.push(notification);
|
this.state.push(notification)
|
||||||
},
|
},
|
||||||
notify(notification) {
|
notify(notification) {
|
||||||
if (Array.isArray(notification)) {
|
if (Array.isArray(notification)) {
|
||||||
notification.forEach(notificationInstance => {
|
notification.forEach((notificationInstance) => {
|
||||||
this.addNotification(notificationInstance);
|
this.addNotification(notificationInstance)
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
this.addNotification(notification);
|
this.addNotification(notification)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
const NotificationsPlugin = {
|
const NotificationsPlugin = {
|
||||||
install(Vue, options) {
|
install(Vue, options) {
|
||||||
let app = new Vue({
|
let app = new Vue({
|
||||||
data: {
|
data: {
|
||||||
notificationStore: NotificationStore
|
notificationStore: NotificationStore,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
notify(notification) {
|
notify(notification) {
|
||||||
this.notificationStore.notify(notification);
|
this.notificationStore.notify(notification)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
})
|
||||||
Vue.prototype.$notify = app.notify;
|
Vue.prototype.$notify = app.notify
|
||||||
Vue.prototype.$notifications = app.notificationStore;
|
Vue.prototype.$notifications = app.notificationStore
|
||||||
Vue.component('Notifications', Notifications);
|
Vue.component('Notifications', Notifications)
|
||||||
if (options) {
|
if (options) {
|
||||||
NotificationStore.setOptions(options);
|
NotificationStore.setOptions(options)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
export default NotificationsPlugin;
|
export default NotificationsPlugin
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<vue-bootstrap-typeahead
|
<vue-bootstrap-typeahead v-model="query" :data="users" @change="getUser" />
|
||||||
v-model="query"
|
|
||||||
:data="users"
|
|
||||||
@change="getUser"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import VueBootstrapTypeahead from 'vue-bootstrap-typeahead'
|
import VueBootstrapTypeahead from 'vue-bootstrap-typeahead'
|
||||||
|
|
||||||
// Global registration
|
// Global registration
|
||||||
//Vue.component('vue-bootstrap-typeahead', VueBootstrapTypeahead)
|
//Vue.component('vue-bootstrap-typeahead', VueBootstrapTypeahead)
|
||||||
@ -15,71 +11,71 @@
|
|||||||
|
|
||||||
// Local registration
|
// Local registration
|
||||||
export default {
|
export default {
|
||||||
name: "SearchUser",
|
name: 'SearchUser',
|
||||||
components: {
|
components: {
|
||||||
VueBootstrapTypeahead
|
VueBootstrapTypeahead,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
user: "",
|
user: '',
|
||||||
users: [
|
users: [
|
||||||
"Bob",
|
'Bob',
|
||||||
"Alice",
|
'Alice',
|
||||||
"Bernd",
|
'Bernd',
|
||||||
"Dario",
|
'Dario',
|
||||||
"Alex",
|
'Alex',
|
||||||
"Pauls",
|
'Pauls',
|
||||||
"Ulf",
|
'Ulf',
|
||||||
"Delaware",
|
'Delaware',
|
||||||
"Florida",
|
'Florida',
|
||||||
"Georgia",
|
'Georgia',
|
||||||
"Hawaii",
|
'Hawaii',
|
||||||
"Idaho",
|
'Idaho',
|
||||||
"Illnois",
|
'Illnois',
|
||||||
"Indiana",
|
'Indiana',
|
||||||
"Iowa",
|
'Iowa',
|
||||||
"Kansas",
|
'Kansas',
|
||||||
"Kentucky",
|
'Kentucky',
|
||||||
"Louisiana",
|
'Louisiana',
|
||||||
"Maine",
|
'Maine',
|
||||||
"Maryland",
|
'Maryland',
|
||||||
"Massachusetts",
|
'Massachusetts',
|
||||||
"Michigan",
|
'Michigan',
|
||||||
"Minnesota",
|
'Minnesota',
|
||||||
"Mississippi",
|
'Mississippi',
|
||||||
"Missouri",
|
'Missouri',
|
||||||
"Montana",
|
'Montana',
|
||||||
"Nebraska",
|
'Nebraska',
|
||||||
"Nevada",
|
'Nevada',
|
||||||
"New Hampshire",
|
'New Hampshire',
|
||||||
"New Jersey",
|
'New Jersey',
|
||||||
"New Mexico",
|
'New Mexico',
|
||||||
"New York",
|
'New York',
|
||||||
"North Carolina",
|
'North Carolina',
|
||||||
"North Dakota",
|
'North Dakota',
|
||||||
"Ohio",
|
'Ohio',
|
||||||
"Oklahoma",
|
'Oklahoma',
|
||||||
"Oregon",
|
'Oregon',
|
||||||
"Pennsylvania",
|
'Pennsylvania',
|
||||||
"Rhode Island",
|
'Rhode Island',
|
||||||
"South Carolina",
|
'South Carolina',
|
||||||
"South Dakota",
|
'South Dakota',
|
||||||
"Tennessee",
|
'Tennessee',
|
||||||
"Texas",
|
'Texas',
|
||||||
"Utah",
|
'Utah',
|
||||||
"Vermont",
|
'Vermont',
|
||||||
"Virginia",
|
'Virginia',
|
||||||
"Washington",
|
'Washington',
|
||||||
"West Virginia",
|
'West Virginia',
|
||||||
"Wisconsin",
|
'Wisconsin',
|
||||||
"Wyoming"
|
'Wyoming',
|
||||||
]
|
],
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getUser() {
|
|
||||||
alert(this.data.user)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
</script>
|
methods: {
|
||||||
|
getUser() {
|
||||||
|
alert(this.data.user)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@ -1,137 +1,133 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="navbar navbar-vertical fixed-left navbar-expand-md navbar-light bg-transparent" id="sidenav-main">
|
<nav
|
||||||
<div class="container-fluid">
|
class="navbar navbar-vertical fixed-left navbar-expand-md navbar-light bg-transparent"
|
||||||
|
id="sidenav-main"
|
||||||
<!--Toggler-->
|
>
|
||||||
<navbar-toggle-button @click.native="showSidebar">
|
<div class="container-fluid">
|
||||||
|
<!--Toggler-->
|
||||||
</navbar-toggle-button>
|
<navbar-toggle-button @click.native="showSidebar"></navbar-toggle-button>
|
||||||
<router-link class="navbar-brand" to="/">
|
<div class="navbar-brand">
|
||||||
<img :src="logo" class="navbar-brand-img" alt="...">
|
<img :src="logo" class="navbar-brand-img" alt="..." />
|
||||||
|
</div>
|
||||||
|
<b-row class="text-center">
|
||||||
|
<b-col>{{ $n($store.state.user.balance) }} GDD</b-col>
|
||||||
|
</b-row>
|
||||||
|
<slot name="mobile-right">
|
||||||
|
<ul class="nav align-items-center d-md-none">
|
||||||
|
<base-dropdown class="nav-item" menu-on-right tag="li" title-tag="a">
|
||||||
|
<a slot="title-container" class="nav-link" href="#" role="button">
|
||||||
|
<div class="media align-items-center">
|
||||||
|
<span class="avatar avatar-sm">
|
||||||
|
<vue-qrcode :value="$store.state.email" type="image/png"></vue-qrcode>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
xx
|
||||||
|
<router-link to="/overview" class="dropdown-item text-lg text-muted">
|
||||||
|
<i class="ni ni-single-02"></i>
|
||||||
|
<span>{{ $t('site.overview.account_overview') }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<router-link to="/profile" class="dropdown-item text-lg text-muted">
|
||||||
<slot name="mobile-right">
|
<i class="ni ni-single-02"></i>
|
||||||
<ul class="nav align-items-center d-md-none">
|
<span>{{ $t('site.navbar.my-profil') }}</span>
|
||||||
|
</router-link>
|
||||||
<base-dropdown class="nav-item" menu-on-right tag="li" title-tag="a">
|
<router-link to="/profileedit" class="dropdown-item text-lg text-muted">
|
||||||
<a slot="title-container" class="nav-link" href="#" role="button">
|
<i class="ni ni-settings-gear-65"></i>
|
||||||
<div class="media align-items-center">
|
<span>{{ $t('site.navbar.settings') }}</span>
|
||||||
<span class="avatar avatar-sm rounded-circle">
|
</router-link>
|
||||||
<img alt="Image placeholder" src="img/theme/team-1.jpg">
|
<router-link to="/transactions" class="dropdown-item text-lg text-muted">
|
||||||
</span>
|
<i class="ni ni-calendar-grid-58"></i>
|
||||||
</div>
|
<span>Transactions</span>
|
||||||
</a>
|
</router-link>
|
||||||
|
<!--
|
||||||
<router-link to="/KontoOverview" class="dropdown-item text-lg text-muted">
|
|
||||||
<i class="ni ni-single-02"></i>
|
|
||||||
<span>{{ $t('site.overview.account_overview')}}</span>
|
|
||||||
</router-link>
|
|
||||||
<router-link to="/profile" class="dropdown-item text-lg text-muted">
|
|
||||||
<i class="ni ni-single-02"></i>
|
|
||||||
<span>{{ $t('site.navbar.my-profil')}}</span>
|
|
||||||
</router-link>
|
|
||||||
<router-link to="/profileedit" class="dropdown-item text-lg text-muted">
|
|
||||||
<i class="ni ni-settings-gear-65"></i>
|
|
||||||
<span>{{ $t('site.navbar.settings') }}</span>
|
|
||||||
</router-link>
|
|
||||||
<router-link to="/activity" class="dropdown-item text-lg text-muted">
|
<router-link to="/activity" class="dropdown-item text-lg text-muted">
|
||||||
<i class="ni ni-calendar-grid-58"></i>
|
<i class="ni ni-calendar-grid-58"></i>
|
||||||
<span>{{ $t('site.navbar.activity') }}</span>
|
<span>{{ $t('site.navbar.activity') }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
-->
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<router-link @click="logout" class="dropdown-item text-lg text-muted">
|
<div @click="logout" class="dropdown-item text-lg text-muted">
|
||||||
<i class="ni ni-support-16"></i>
|
<i class="ni ni-support-16"></i>
|
||||||
<span>{{ $t('logout') }}</span>
|
{{ $t('logout') }}
|
||||||
</router-link>
|
|
||||||
</base-dropdown>
|
|
||||||
</ul>
|
|
||||||
</slot>
|
|
||||||
<slot></slot>
|
|
||||||
<div v-show="$sidebar.showSidebar" class="navbar-collapse collapse show" id="sidenav-collapse-main">
|
|
||||||
|
|
||||||
<div class="navbar-collapse-header d-md-none">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-6 collapse-brand">
|
|
||||||
<router-link to="/">
|
|
||||||
<img :src="logo">
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 collapse-close">
|
|
||||||
<navbar-toggle-button @click.native="closeSidebar"></navbar-toggle-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="navbar-nav">
|
|
||||||
<slot name="links">
|
|
||||||
</slot>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<hr class="my-3">
|
|
||||||
|
|
||||||
<ul class="navbar-nav mb-md-3">
|
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
|
|
||||||
<a class="nav-link text-lg bg-light" href="#!" @click="logout">
|
|
||||||
{{ $t('logout') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</base-dropdown>
|
||||||
|
</ul>
|
||||||
|
</slot>
|
||||||
|
<slot></slot>
|
||||||
|
<div
|
||||||
|
v-show="$sidebar.showSidebar"
|
||||||
|
class="navbar-collapse collapse show"
|
||||||
|
id="sidenav-collapse-main"
|
||||||
|
>
|
||||||
|
<div class="navbar-collapse-header d-md-none">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 collapse-brand">
|
||||||
|
<router-link to="/overview">
|
||||||
|
<img :src="logo" />
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
<div class="col-6 collapse-close">
|
||||||
|
<navbar-toggle-button @click.native="closeSidebar"></navbar-toggle-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<slot name="links"></slot>
|
||||||
|
</ul>
|
||||||
|
<hr class="my-3" />
|
||||||
|
<ul class="navbar-nav mb-md-3">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-lg" href="#!" @click="logout">
|
||||||
|
{{ $t('logout') }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import NavbarToggleButton from '@/components/NavbarToggleButton'
|
import NavbarToggleButton from '@/components/NavbarToggleButton'
|
||||||
|
import VueQrcode from 'vue-qrcode'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'sidebar',
|
name: 'sidebar',
|
||||||
components: {
|
components: {
|
||||||
NavbarToggleButton
|
NavbarToggleButton,
|
||||||
|
VueQrcode,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
logo: {
|
||||||
|
type: String,
|
||||||
|
default: 'img/brand/green.png',
|
||||||
|
description: 'Gradido Sidebar app logo',
|
||||||
},
|
},
|
||||||
props: {
|
autoClose: {
|
||||||
logo: {
|
type: Boolean,
|
||||||
type: String,
|
default: true,
|
||||||
default: 'img/brand/green.png',
|
description: 'Whether sidebar should autoclose on mobile when clicking an item',
|
||||||
description: 'Sidebar app logo'
|
|
||||||
},
|
|
||||||
autoClose: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
description: 'Whether sidebar should autoclose on mobile when clicking an item'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
provide() {
|
},
|
||||||
return {
|
provide() {
|
||||||
autoClose: this.autoClose
|
return {
|
||||||
};
|
autoClose: this.autoClose,
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closeSidebar() {
|
|
||||||
this.$sidebar.displaySidebar(false)
|
|
||||||
},
|
|
||||||
showSidebar() {
|
|
||||||
this.$sidebar.displaySidebar(true)
|
|
||||||
},
|
|
||||||
setLocale(locale) {
|
|
||||||
this.$i18n.locale = locale
|
|
||||||
//this.$router.push({
|
|
||||||
// params: { lang: locale }
|
|
||||||
//})
|
|
||||||
//this.hideDropdown()
|
|
||||||
},
|
|
||||||
logout(){
|
|
||||||
//console.log("DashboardNavbar.vue user logout() : ")
|
|
||||||
this.$store.dispatch('logout')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
if (this.$sidebar.showSidebar) {
|
|
||||||
this.$sidebar.showSidebar = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
methods: {
|
||||||
|
closeSidebar() {
|
||||||
|
this.$sidebar.displaySidebar(false)
|
||||||
|
},
|
||||||
|
showSidebar() {
|
||||||
|
this.$sidebar.displaySidebar(true)
|
||||||
|
},
|
||||||
|
logout() {
|
||||||
|
this.$store.dispatch('logout')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.$sidebar.showSidebar) {
|
||||||
|
this.$sidebar.showSidebar = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -15,31 +15,28 @@
|
|||||||
>
|
>
|
||||||
<template v-if="addLink">
|
<template v-if="addLink">
|
||||||
<span class="nav-link-text">
|
<span class="nav-link-text">
|
||||||
{{ link.name }} <b class="caret"></b>
|
{{ link.name }}
|
||||||
|
<b class="caret"></b>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<i :class="link.icon"></i>
|
<i :class="link.icon"></i>
|
||||||
<span class="nav-link-text">{{ link.name }} <b class="caret"></b></span>
|
<span class="nav-link-text">
|
||||||
|
{{ link.name }}
|
||||||
|
<b class="caret"></b>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<collapse-transition>
|
<collapse-transition>
|
||||||
<div
|
<div v-if="$slots.default || this.isMenu" v-show="!collapsed" class="collapse show">
|
||||||
v-if="$slots.default || this.isMenu"
|
|
||||||
v-show="!collapsed"
|
|
||||||
class="collapse show"
|
|
||||||
>
|
|
||||||
<ul class="nav nav-sm flex-column">
|
<ul class="nav nav-sm flex-column">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</collapse-transition>
|
</collapse-transition>
|
||||||
|
|
||||||
<slot
|
<slot name="title" v-if="children.length === 0 && !$slots.default && link.path">
|
||||||
name="title"
|
|
||||||
v-if="children.length === 0 && !$slots.default && link.path"
|
|
||||||
>
|
|
||||||
<component
|
<component
|
||||||
:to="link.path"
|
:to="link.path"
|
||||||
@click.native="linkClick"
|
@click.native="linkClick"
|
||||||
@ -61,19 +58,19 @@
|
|||||||
</b-nav-item>
|
</b-nav-item>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { CollapseTransition } from 'vue2-transitions';
|
import { CollapseTransition } from 'vue2-transitions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'sidebar-item',
|
name: 'sidebar-item',
|
||||||
components: {
|
components: {
|
||||||
CollapseTransition
|
CollapseTransition,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
menu: {
|
menu: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
description:
|
description:
|
||||||
"Whether the item is a menu. Most of the item it's not used and should be used only if you want to override the default behavior."
|
"Whether the item is a menu. Most of the item it's not used and should be used only if you want to override the default behavior.",
|
||||||
},
|
},
|
||||||
link: {
|
link: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -81,115 +78,109 @@ export default {
|
|||||||
return {
|
return {
|
||||||
name: '',
|
name: '',
|
||||||
path: '',
|
path: '',
|
||||||
children: []
|
children: [],
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
description:
|
description:
|
||||||
'Sidebar link. Can contain name, path, icon and other attributes. See examples for more info'
|
'Sidebar link. Can contain name, path, icon and other attributes. See examples for more info',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
addLink: this.addChild,
|
addLink: this.addChild,
|
||||||
removeLink: this.removeChild
|
removeLink: this.removeChild,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
addLink: { default: null },
|
addLink: { default: null },
|
||||||
removeLink: { default: null },
|
removeLink: { default: null },
|
||||||
autoClose: {
|
autoClose: {
|
||||||
default: true
|
default: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
children: [],
|
children: [],
|
||||||
collapsed: true
|
collapsed: true,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
baseComponent() {
|
baseComponent() {
|
||||||
return this.isMenu || this.link.isRoute ? 'li' : 'router-link';
|
return this.isMenu || this.link.isRoute ? 'li' : 'router-link'
|
||||||
},
|
},
|
||||||
linkPrefix() {
|
linkPrefix() {
|
||||||
if (this.link.name) {
|
if (this.link.name) {
|
||||||
let words = this.link.name.split(' ');
|
let words = this.link.name.split(' ')
|
||||||
return words.map(word => word.substring(0, 1)).join('');
|
return words.map((word) => word.substring(0, 1)).join('')
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
isMenu() {
|
isMenu() {
|
||||||
return this.children.length > 0 || this.menu === true;
|
return this.children.length > 0 || this.menu === true
|
||||||
},
|
},
|
||||||
isActive() {
|
isActive() {
|
||||||
if (this.$route && this.$route.path) {
|
if (this.$route && this.$route.path) {
|
||||||
let matchingRoute = this.children.find(c =>
|
let matchingRoute = this.children.find((c) => this.$route.path.startsWith(c.link.path))
|
||||||
this.$route.path.startsWith(c.link.path)
|
|
||||||
);
|
|
||||||
if (matchingRoute !== undefined) {
|
if (matchingRoute !== undefined) {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addChild(item) {
|
addChild(item) {
|
||||||
const index = this.$slots.default.indexOf(item.$vnode);
|
const index = this.$slots.default.indexOf(item.$vnode)
|
||||||
this.children.splice(index, 0, item);
|
this.children.splice(index, 0, item)
|
||||||
},
|
},
|
||||||
removeChild(item) {
|
removeChild(item) {
|
||||||
const tabs = this.children;
|
const tabs = this.children
|
||||||
const index = tabs.indexOf(item);
|
const index = tabs.indexOf(item)
|
||||||
tabs.splice(index, 1);
|
tabs.splice(index, 1)
|
||||||
},
|
},
|
||||||
elementType(link, isParent = true) {
|
elementType(link, isParent = true) {
|
||||||
if (link.isRoute === false) {
|
if (link.isRoute === false) {
|
||||||
return isParent ? 'li' : 'a';
|
return isParent ? 'li' : 'a'
|
||||||
} else {
|
} else {
|
||||||
return 'router-link';
|
return 'router-link'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
linkAbbreviation(name) {
|
linkAbbreviation(name) {
|
||||||
const matches = name.match(/\b(\w)/g);
|
const matches = name.match(/\b(\w)/g)
|
||||||
return matches.join('');
|
return matches.join('')
|
||||||
},
|
},
|
||||||
linkClick() {
|
linkClick() {
|
||||||
if (
|
if (this.autoClose && this.$sidebar && this.$sidebar.showSidebar === true) {
|
||||||
this.autoClose &&
|
this.$sidebar.displaySidebar(false)
|
||||||
this.$sidebar &&
|
|
||||||
this.$sidebar.showSidebar === true
|
|
||||||
) {
|
|
||||||
this.$sidebar.displaySidebar(false);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
collapseMenu() {
|
collapseMenu() {
|
||||||
this.collapsed = !this.collapsed;
|
this.collapsed = !this.collapsed
|
||||||
},
|
},
|
||||||
collapseSubMenu(link) {
|
collapseSubMenu(link) {
|
||||||
link.collapsed = !link.collapsed;
|
link.collapsed = !link.collapsed
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.addLink) {
|
if (this.addLink) {
|
||||||
this.addLink(this);
|
this.addLink(this)
|
||||||
}
|
}
|
||||||
if (this.link.collapsed !== undefined) {
|
if (this.link.collapsed !== undefined) {
|
||||||
this.collapsed = this.link.collapsed;
|
this.collapsed = this.link.collapsed
|
||||||
}
|
}
|
||||||
if (this.isActive && this.isMenu) {
|
if (this.isActive && this.isMenu) {
|
||||||
this.collapsed = false;
|
this.collapsed = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.$el && this.$el.parentNode) {
|
if (this.$el && this.$el.parentNode) {
|
||||||
this.$el.parentNode.removeChild(this.$el);
|
this.$el.parentNode.removeChild(this.$el)
|
||||||
}
|
}
|
||||||
if (this.removeLink) {
|
if (this.removeLink) {
|
||||||
this.removeLink(this);
|
this.removeLink(this)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.sidebar-menu-item {
|
.sidebar-menu-item {
|
||||||
|
|||||||
@ -1,43 +1,43 @@
|
|||||||
import Sidebar from './SideBar.vue';
|
import Sidebar from './SideBar.vue'
|
||||||
import SidebarItem from './SidebarItem.vue';
|
import SidebarItem from './SidebarItem.vue'
|
||||||
|
|
||||||
const SidebarStore = {
|
const SidebarStore = {
|
||||||
showSidebar: false,
|
showSidebar: false,
|
||||||
sidebarLinks: [],
|
sidebarLinks: [],
|
||||||
isMinimized: false,
|
isMinimized: false,
|
||||||
displaySidebar(value) {
|
displaySidebar(value) {
|
||||||
this.showSidebar = value;
|
this.showSidebar = value
|
||||||
},
|
},
|
||||||
toggleMinimize() {
|
toggleMinimize() {
|
||||||
document.body.classList.toggle('sidebar-mini');
|
document.body.classList.toggle('sidebar-mini')
|
||||||
// we simulate the window Resize so the charts will get updated in realtime.
|
// we simulate the window Resize so the charts will get updated in realtime.
|
||||||
const simulateWindowResize = setInterval(() => {
|
const simulateWindowResize = setInterval(() => {
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'))
|
||||||
}, 180);
|
}, 180)
|
||||||
|
|
||||||
// we stop the simulation of Window Resize after the animations are completed
|
// we stop the simulation of Window Resize after the animations are completed
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
clearInterval(simulateWindowResize);
|
clearInterval(simulateWindowResize)
|
||||||
}, 1000);
|
}, 1000)
|
||||||
|
|
||||||
this.isMinimized = !this.isMinimized;
|
this.isMinimized = !this.isMinimized
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
const SidebarPlugin = {
|
const SidebarPlugin = {
|
||||||
install(Vue, options) {
|
install(Vue, options) {
|
||||||
if (options && options.sidebarLinks) {
|
if (options && options.sidebarLinks) {
|
||||||
SidebarStore.sidebarLinks = options.sidebarLinks;
|
SidebarStore.sidebarLinks = options.sidebarLinks
|
||||||
}
|
}
|
||||||
let app = new Vue({
|
let app = new Vue({
|
||||||
data: {
|
data: {
|
||||||
sidebarStore: SidebarStore
|
sidebarStore: SidebarStore,
|
||||||
}
|
},
|
||||||
});
|
})
|
||||||
Vue.prototype.$sidebar = app.sidebarStore;
|
Vue.prototype.$sidebar = app.sidebarStore
|
||||||
Vue.component('side-bar', Sidebar);
|
Vue.component('side-bar', Sidebar)
|
||||||
Vue.component('sidebar-item', SidebarItem);
|
Vue.component('sidebar-item', SidebarItem)
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
export default SidebarPlugin;
|
export default SidebarPlugin
|
||||||
|
|||||||
@ -16,18 +16,18 @@ export default {
|
|||||||
inject: ['addTab', 'removeTab'],
|
inject: ['addTab', 'removeTab'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: false
|
active: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.addTab(this);
|
this.addTab(this)
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.$el && this.$el.parentNode) {
|
if (this.$el && this.$el.parentNode) {
|
||||||
this.$el.parentNode.removeChild(this.$el);
|
this.$el.parentNode.removeChild(this.$el)
|
||||||
}
|
}
|
||||||
this.removeTab(this);
|
this.removeTab(this)
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
:class="[
|
:class="[
|
||||||
{ 'col-md-4': vertical && !tabNavWrapperClasses },
|
{ 'col-md-4': vertical && !tabNavWrapperClasses },
|
||||||
{ 'col-12': centered && !tabNavWrapperClasses },
|
{ 'col-12': centered && !tabNavWrapperClasses },
|
||||||
tabNavWrapperClasses
|
tabNavWrapperClasses,
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<b-nav
|
<b-nav
|
||||||
@ -14,7 +14,7 @@
|
|||||||
`nav-pills-${type}`,
|
`nav-pills-${type}`,
|
||||||
{ 'flex-column': vertical },
|
{ 'flex-column': vertical },
|
||||||
{ 'justify-content-center': centered },
|
{ 'justify-content-center': centered },
|
||||||
tabNavClasses
|
tabNavClasses,
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<b-nav-item
|
<b-nav-item
|
||||||
@ -28,7 +28,7 @@
|
|||||||
@click.prevent="activateTab(tab)"
|
@click.prevent="activateTab(tab)"
|
||||||
:aria-expanded="tab.active"
|
:aria-expanded="tab.active"
|
||||||
>
|
>
|
||||||
<tab-item-content :tab="tab"> </tab-item-content>
|
<tab-item-content :tab="tab"></tab-item-content>
|
||||||
</b-nav-item>
|
</b-nav-item>
|
||||||
</b-nav>
|
</b-nav>
|
||||||
</div>
|
</div>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
:class="[
|
:class="[
|
||||||
{ 'tab-space': !vertical },
|
{ 'tab-space': !vertical },
|
||||||
{ 'col-md-8': vertical && !tabContentClasses },
|
{ 'col-md-8': vertical && !tabContentClasses },
|
||||||
tabContentClasses
|
tabContentClasses,
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
@ -52,110 +52,104 @@ export default {
|
|||||||
TabItemContent: {
|
TabItemContent: {
|
||||||
props: ['tab'],
|
props: ['tab'],
|
||||||
render(h) {
|
render(h) {
|
||||||
return h('div', [this.tab.$slots.title || this.tab.title]);
|
return h('div', [this.tab.$slots.title || this.tab.title])
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
addTab: this.addTab,
|
addTab: this.addTab,
|
||||||
removeTab: this.removeTab
|
removeTab: this.removeTab,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'primary',
|
default: 'primary',
|
||||||
validator: value => {
|
validator: (value) => {
|
||||||
let acceptedValues = [
|
let acceptedValues = ['primary', 'info', 'success', 'warning', 'danger']
|
||||||
'primary',
|
return acceptedValues.indexOf(value) !== -1
|
||||||
'info',
|
},
|
||||||
'success',
|
|
||||||
'warning',
|
|
||||||
'danger'
|
|
||||||
];
|
|
||||||
return acceptedValues.indexOf(value) !== -1;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
activeTab: {
|
activeTab: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Active tab name'
|
description: 'Active tab name',
|
||||||
},
|
},
|
||||||
tabNavWrapperClasses: {
|
tabNavWrapperClasses: {
|
||||||
type: [String, Object],
|
type: [String, Object],
|
||||||
default: '',
|
default: '',
|
||||||
description: 'ul wrapper css classes'
|
description: 'ul wrapper css classes',
|
||||||
},
|
},
|
||||||
tabNavClasses: {
|
tabNavClasses: {
|
||||||
type: [String, Object],
|
type: [String, Object],
|
||||||
default: '',
|
default: '',
|
||||||
description: 'ul css classes'
|
description: 'ul css classes',
|
||||||
},
|
},
|
||||||
tabContentClasses: {
|
tabContentClasses: {
|
||||||
type: [String, Object],
|
type: [String, Object],
|
||||||
default: '',
|
default: '',
|
||||||
description: 'tab content css classes'
|
description: 'tab content css classes',
|
||||||
},
|
},
|
||||||
vertical: Boolean,
|
vertical: Boolean,
|
||||||
centered: Boolean,
|
centered: Boolean,
|
||||||
value: String
|
value: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabs: []
|
tabs: [],
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
findAndActivateTab(title) {
|
findAndActivateTab(title) {
|
||||||
let tabToActivate = this.tabs.find(t => t.title === title);
|
let tabToActivate = this.tabs.find((t) => t.title === title)
|
||||||
if (tabToActivate) {
|
if (tabToActivate) {
|
||||||
this.activateTab(tabToActivate);
|
this.activateTab(tabToActivate)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
activateTab(tab) {
|
activateTab(tab) {
|
||||||
if (this.handleClick) {
|
if (this.handleClick) {
|
||||||
this.handleClick(tab);
|
this.handleClick(tab)
|
||||||
}
|
}
|
||||||
this.deactivateTabs();
|
this.deactivateTabs()
|
||||||
tab.active = true;
|
tab.active = true
|
||||||
},
|
},
|
||||||
deactivateTabs() {
|
deactivateTabs() {
|
||||||
this.tabs.forEach(tab => {
|
this.tabs.forEach((tab) => {
|
||||||
tab.active = false;
|
tab.active = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
addTab(tab) {
|
addTab(tab) {
|
||||||
const index = this.$slots.default.indexOf(tab.$vnode);
|
const index = this.$slots.default.indexOf(tab.$vnode)
|
||||||
if (!this.activeTab && index === 0) {
|
if (!this.activeTab && index === 0) {
|
||||||
tab.active = true;
|
tab.active = true
|
||||||
}
|
}
|
||||||
if (this.activeTab === tab.name) {
|
if (this.activeTab === tab.name) {
|
||||||
tab.active = true;
|
tab.active = true
|
||||||
}
|
}
|
||||||
this.tabs.splice(index, 0, tab);
|
this.tabs.splice(index, 0, tab)
|
||||||
},
|
},
|
||||||
removeTab(tab) {
|
removeTab(tab) {
|
||||||
const tabs = this.tabs;
|
const tabs = this.tabs
|
||||||
const index = tabs.indexOf(tab);
|
const index = tabs.indexOf(tab)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
tabs.splice(index, 1);
|
tabs.splice(index, 1)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.value) {
|
if (this.value) {
|
||||||
this.findAndActivateTab(this.value);
|
this.findAndActivateTab(this.value)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value(newVal) {
|
value(newVal) {
|
||||||
this.findAndActivateTab(newVal);
|
this.findAndActivateTab(newVal)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,30 +1,30 @@
|
|||||||
import BaseCheckbox from './Inputs/BaseCheckbox.vue';
|
import BaseCheckbox from './Inputs/BaseCheckbox.vue'
|
||||||
import BaseAlert from './BaseAlert.vue';
|
import BaseAlert from './BaseAlert.vue'
|
||||||
import BaseRadio from './Inputs/BaseRadio.vue';
|
import BaseRadio from './Inputs/BaseRadio.vue'
|
||||||
import BaseInput from './Inputs/BaseInput.vue';
|
import BaseInput from './Inputs/BaseInput.vue'
|
||||||
import Badge from './Badge';
|
import Badge from './Badge'
|
||||||
import BaseProgress from './BaseProgress.vue';
|
import BaseProgress from './BaseProgress.vue'
|
||||||
import BaseButton from './BaseButton.vue';
|
import BaseButton from './BaseButton.vue'
|
||||||
|
|
||||||
import BaseDropdown from './BaseDropdown.vue';
|
import BaseDropdown from './BaseDropdown.vue'
|
||||||
import BaseTable from './BaseTable.vue';
|
import BaseTable from './BaseTable.vue'
|
||||||
|
|
||||||
import Card from './Cards/Card.vue';
|
import Card from './Cards/Card.vue'
|
||||||
import StatsCard from './Cards/StatsCard.vue';
|
import StatsCard from './Cards/StatsCard.vue'
|
||||||
import BaseNav from './Navbar/BaseNav';
|
import BaseNav from './Navbar/BaseNav'
|
||||||
import NavbarToggleButton from './Navbar/NavbarToggleButton';
|
import NavbarToggleButton from './Navbar/NavbarToggleButton'
|
||||||
|
|
||||||
import TabPane from './Tabs/Tab.vue';
|
import TabPane from './Tabs/Tab.vue'
|
||||||
import Tabs from './Tabs/Tabs.vue';
|
import Tabs from './Tabs/Tabs.vue'
|
||||||
import Collapse from './Collapse/Collapse.vue';
|
import Collapse from './Collapse/Collapse.vue'
|
||||||
import CollapseItem from './Collapse/CollapseItem.vue';
|
import CollapseItem from './Collapse/CollapseItem.vue'
|
||||||
import Modal from './Modal.vue';
|
import Modal from './Modal.vue'
|
||||||
import BaseSlider from './BaseSlider.vue';
|
import BaseSlider from './BaseSlider.vue'
|
||||||
import LoadingPanel from './LoadingPanel.vue';
|
import LoadingPanel from './LoadingPanel.vue'
|
||||||
|
|
||||||
import BasePagination from './BasePagination.vue';
|
import BasePagination from './BasePagination.vue'
|
||||||
|
|
||||||
import SidebarPlugin from './SidebarPlugin';
|
import SidebarPlugin from './SidebarPlugin'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
BaseCheckbox,
|
BaseCheckbox,
|
||||||
@ -48,5 +48,5 @@ export {
|
|||||||
BaseButton,
|
BaseButton,
|
||||||
Collapse,
|
Collapse,
|
||||||
CollapseItem,
|
CollapseItem,
|
||||||
LoadingPanel
|
LoadingPanel,
|
||||||
};
|
}
|
||||||
|
|||||||
@ -11,8 +11,12 @@ const environment = {
|
|||||||
|
|
||||||
const server = {
|
const server = {
|
||||||
LOGIN_API_URL: process.env.LOGIN_API_URL || 'http://localhost/login_api/',
|
LOGIN_API_URL: process.env.LOGIN_API_URL || 'http://localhost/login_api/',
|
||||||
COMMUNITY_API_STATE_BALANCE_URL: process.env.COMMUNITY_API_STATE_BALANCE_URL || 'http://localhost/state-balances/',
|
COMMUNITY_API_STATE_BALANCE_URL:
|
||||||
COMMUNITY_API_TRANSACTION_CREATION_URL: process.env.COMMUNITY_API_TRANSACTION_CREATION_URL || 'http://localhost/transaction-creations/',
|
process.env.COMMUNITY_API_STATE_BALANCE_URL || 'http://localhost/state-balances/',
|
||||||
|
// Schöpfung
|
||||||
|
// COMMUNITY_API_TRANSACTION_CREATION_URL: process.env.COMMUNITY_API_TRANSACTION_CREATION_URL || 'http://localhost/transaction-creations/',
|
||||||
|
COMMUNITY_API_TRANSACTION_SEND_COINS:
|
||||||
|
process.env.COMMUNITY_API_TRANSACTION_SEND_COINS || 'http://localhost/transaction-send-coins/',
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
|
|||||||
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